@@ -10,7 +10,7 @@ import (
1010)
1111
1212// LinkContents will link the contents of src to desc
13- func LinkContents (src , dest string , visited map [ string ] bool ) error {
13+ func LinkContents (src , dest string ) error {
1414 if ! fileutils .DirExists (src ) {
1515 return errs .New ("src dir does not exist: %s" , src )
1616 }
@@ -24,23 +24,12 @@ func LinkContents(src, dest string, visited map[string]bool) 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-
3827 entries , err := os .ReadDir (src )
3928 if err != nil {
4029 return errs .Wrap (err , "Reading dir %s failed" , src )
4130 }
4231 for _ , entry := range entries {
43- if err := Link (filepath .Join (src , entry .Name ()), filepath .Join (dest , entry .Name ()), visited ); err != nil {
32+ if err := Link (filepath .Join (src , entry .Name ()), filepath .Join (dest , entry .Name ()), nil ); err != nil {
4433 return errs .Wrap (err , "Link failed" )
4534 }
4635 }
@@ -50,23 +39,27 @@ func LinkContents(src, dest string, visited map[string]bool) error {
5039
5140// Link creates a link from src to target. MS decided to support Symlinks but only if you opt into developer mode (go figure),
5241// which we cannot reasonably force on our users. So on Windows we will instead create dirs and hardlinks.
53- func Link (src , dest string , visited map [string ]bool ) error {
42+ func Link (src , dest string , visited map [string ]int ) error {
5443 var err error
5544 src , dest , err = resolvePaths (src , dest )
5645 if err != nil {
5746 return errs .Wrap (err , "Could not resolve src and dest paths" )
5847 }
5948
6049 if visited == nil {
61- visited = make (map [string ]bool )
50+ visited = make (map [string ]int )
6251 }
63- if _ , exists := visited [src ]; exists {
52+ if count , exists := visited [src ]; exists {
6453 // We've encountered a recursive link. This is most often the case when the resolved src has
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 )
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
6862 }
69- visited [src ] = true
7063
7164 if fileutils .IsDir (src ) {
7265 if err := fileutils .Mkdir (dest ); err != nil {
0 commit comments