@@ -10,7 +10,7 @@ import (
1010)
1111
1212// LinkContents will link the contents of src to desc
13- func LinkContents (src , dest string ) error {
13+ func LinkContents (src , dest string , visited map [ string ] bool ) error {
1414 if ! fileutils .DirExists (src ) {
1515 return errs .New ("src dir does not exist: %s" , src )
1616 }
@@ -24,12 +24,23 @@ func LinkContents(src, dest string) error {
2424 return errs .Wrap (err , "Could not resolve src and dest paths" )
2525 }
2626
27+ if visited == nil {
28+ visited = make (map [string ]bool )
29+ }
30+ if _ , exists := visited [src ]; exists {
31+ // We've encountered a recursive link. This is most often the case when the resolved src has
32+ // already been visited. In that case, just link the dest to the src (which may be a directory;
33+ // this is fine).
34+ return linkFile (src , dest )
35+ }
36+ visited [src ] = true
37+
2738 entries , err := os .ReadDir (src )
2839 if err != nil {
2940 return errs .Wrap (err , "Reading dir %s failed" , src )
3041 }
3142 for _ , entry := range entries {
32- if err := Link (filepath .Join (src , entry .Name ()), filepath .Join (dest , entry .Name ()), nil ); err != nil {
43+ if err := Link (filepath .Join (src , entry .Name ()), filepath .Join (dest , entry .Name ()), visited ); err != nil {
3344 return errs .Wrap (err , "Link failed" )
3445 }
3546 }
@@ -39,27 +50,23 @@ func LinkContents(src, dest string) error {
3950
4051// Link creates a link from src to target. MS decided to support Symlinks but only if you opt into developer mode (go figure),
4152// which we cannot reasonably force on our users. So on Windows we will instead create dirs and hardlinks.
42- func Link (src , dest string , visited map [string ]int ) error {
53+ func Link (src , dest string , visited map [string ]bool ) error {
4354 var err error
4455 src , dest , err = resolvePaths (src , dest )
4556 if err != nil {
4657 return errs .Wrap (err , "Could not resolve src and dest paths" )
4758 }
4859
4960 if visited == nil {
50- visited = make (map [string ]int )
61+ visited = make (map [string ]bool )
5162 }
52- if count , exists := visited [src ]; exists {
63+ if _ , exists := visited [src ]; exists {
5364 // We've encountered a recursive link. This is most often the case when the resolved src has
54- // already been visited. We will recurse into the directory no more than once, so that any
55- // runtime paths that reference the link will not silently fail.
56- if count > 1 {
57- return nil
58- }
59- visited [src ]++
60- } else {
61- visited [src ] = 1
65+ // already been visited. In that case, just link the dest to the src (which may be a directory;
66+ // this is fine).
67+ return linkFile (src , dest )
6268 }
69+ visited [src ] = true
6370
6471 if fileutils .IsDir (src ) {
6572 if err := fileutils .Mkdir (dest ); err != nil {
0 commit comments