2
0
Fork 0
mirror of https://github.com/bazel-contrib/bazel-lib synced 2024-12-02 10:15:22 +00:00
bazel-lib/tools/common/copy.go
Thulio Ferraz Assis 2854f86e56
fix: limit copy concurrency (#351)
Signed-off-by: Thulio Ferraz Assis <3149049+f0rmiga@users.noreply.github.com>
2023-02-01 12:30:42 -08:00

87 lines
1.6 KiB
Go

package common
import (
"fmt"
"io"
"io/fs"
"log"
"os"
"sync"
)
// From https://opensource.com/article/18/6/copying-files-go
func CopyFile(src string, dst string) error {
source, err := os.Open(src)
if err != nil {
return err
}
defer source.Close()
destination, err := os.Create(dst)
if err != nil {
return err
}
defer destination.Close()
_, err = io.Copy(destination, source)
return err
}
func Copy(opts CopyOpts) {
if !opts.info.Mode().IsRegular() {
log.Fatalf("%s is not a regular file", opts.src)
}
if opts.hardlink {
// hardlink this file
if opts.verbose {
fmt.Printf("hardlink %v => %v\n", opts.src, opts.dst)
}
err := os.Link(opts.src, opts.dst)
if err != nil {
// fallback to copy
if opts.verbose {
fmt.Printf("hardlink failed: %v\n", err)
fmt.Printf("copy (fallback) %v => %v\n", opts.src, opts.dst)
}
err = CopyFile(opts.src, opts.dst)
if err != nil {
log.Fatal(err)
}
}
} else {
// copy this file
if opts.verbose {
fmt.Printf("copy %v => %v\n", opts.src, opts.dst)
}
err := CopyFile(opts.src, opts.dst)
if err != nil {
log.Fatal(err)
}
}
}
type CopyWorker struct {
queue <-chan CopyOpts
}
func NewCopyWorker(queue <-chan CopyOpts) *CopyWorker {
return &CopyWorker{queue: queue}
}
func (w *CopyWorker) Run(wg *sync.WaitGroup) {
defer wg.Done()
for opts := range w.queue {
Copy(opts)
}
}
type CopyOpts struct {
src, dst string
info fs.FileInfo
hardlink bool
verbose bool
}
func NewCopyOpts(src string, dst string, info fs.FileInfo, hardlink bool, verbose bool) CopyOpts {
return CopyOpts{src: src, dst: dst, info: info, hardlink: hardlink, verbose: verbose}
}