@@ -2,86 +2,12 @@ package main
22
33import (
44 "fmt"
5- "io/fs"
65 "log"
76 "os"
8- "path/filepath"
9- "sync"
107
118 "github.com/bazel-contrib/bazel-lib/tools/common"
129)
1310
14- type pathSet map [string ]bool
15-
16- var (
17- srcPaths = pathSet {}
18- hardlink = false
19- verbose = false
20- preserveMTime = false
21- )
22-
23- type walker struct {
24- queue chan <- common.CopyOpts
25- }
26-
27- func (w * walker ) copyDir (src string , dst string ) error {
28- // filepath.WalkDir walks the file tree rooted at root, calling fn for each file or directory in
29- // the tree, including root. See https://pkg.go.dev/path/filepath#WalkDir for more info.
30- return filepath .WalkDir (src , func (p string , dirEntry fs.DirEntry , err error ) error {
31- if err != nil {
32- return err
33- }
34-
35- r , err := common .FileRel (src , p )
36- if err != nil {
37- return err
38- }
39-
40- d := filepath .Join (dst , r )
41-
42- if dirEntry .IsDir () {
43- srcPaths [src ] = true
44- return os .MkdirAll (d , os .ModePerm )
45- }
46-
47- info , err := dirEntry .Info ()
48- if err != nil {
49- return err
50- }
51-
52- if info .Mode ()& os .ModeSymlink == os .ModeSymlink {
53- // symlink to directories are intentionally never followed by filepath.Walk to avoid infinite recursion
54- linkPath , err := common .Realpath (p )
55- if err != nil {
56- if os .IsNotExist (err ) {
57- return fmt .Errorf ("failed to get realpath of dangling symlink %s: %w" , p , err )
58- }
59- return fmt .Errorf ("failed to get realpath of %s: %w" , p , err )
60- }
61- if srcPaths [linkPath ] {
62- // recursive symlink; silently ignore
63- return nil
64- }
65- stat , err := os .Stat (linkPath )
66- if err != nil {
67- return fmt .Errorf ("failed to stat file %s pointed to by symlink %s: %w" , linkPath , p , err )
68- }
69- if stat .IsDir () {
70- // symlink points to a directory
71- return w .copyDir (linkPath , d )
72- } else {
73- // symlink points to a regular file
74- w .queue <- common .NewCopyOpts (linkPath , d , stat , hardlink , verbose , preserveMTime )
75- return nil
76- }
77- }
78-
79- // a regular file
80- w .queue <- common .NewCopyOpts (p , d , info , hardlink , verbose , preserveMTime )
81- return nil
82- })
83- }
84-
8511func main () {
8612 args := os .Args [1 :]
8713
@@ -93,31 +19,23 @@ func main() {
9319 src := args [0 ]
9420 dst := args [1 ]
9521
22+ var opts common.CopyOpts
9623 if len (args ) > 2 {
9724 for _ , a := range os .Args [2 :] {
98- if a == "--hardlink" {
99- hardlink = true
100- } else if a == "--verbose" {
101- verbose = true
102- } else if a == "--preserve-mtime" {
103- preserveMTime = true
25+ switch a {
26+ case "--hardlink" :
27+ opts .Hardlink = true
28+ case "--verbose" :
29+ opts .Verbose = true
30+ case "--preserve-mtime" :
31+ opts .PreserveMTime = true
10432 }
10533 }
10634 }
10735
108- queue := make (chan common.CopyOpts , 100 )
109- var wg sync.WaitGroup
110-
111- const numWorkers = 10
112- wg .Add (numWorkers )
113- for i := 0 ; i < numWorkers ; i ++ {
114- go common .NewCopyWorker (queue ).Run (& wg )
115- }
116-
117- walker := & walker {queue }
118- if err := walker .copyDir (src , dst ); err != nil {
36+ walker := common .NewWalker (100 , 10 )
37+ if err := walker .CopyDir (src , dst , opts ); err != nil {
11938 log .Fatal (err )
12039 }
121- close (queue )
122- wg .Wait ()
40+ walker .Close ()
12341}
0 commit comments