Handle dangling symlinks when following symlinks am: 0e306e7a89

Original change: https://android-review.googlesource.com/c/platform/build/blueprint/+/1851040

Change-Id: I7bf8c61931edc11888f1fc015dac7f596096ce32
This commit is contained in:
Colin Cross 2021-10-11 17:58:49 +00:00 committed by Automerger Merge Worker
commit 30faeb6ad6
2 changed files with 55 additions and 0 deletions

View file

@ -130,6 +130,10 @@ func startGlob(fs FileSystem, pattern string, excludes []string,
info, err = fs.Lstat(match)
} else {
info, err = fs.Stat(match)
if err != nil && os.IsNotExist(err) {
// ErrNotExist from Stat may be due to a dangling symlink, retry with lstat.
info, err = fs.Lstat(match)
}
}
if err != nil {
return GlobResult{}, err

View file

@ -721,6 +721,57 @@ func TestGlobDontFollowDanglingSymlinks(t *testing.T) {
}
}
var globFollowDanglingSymlinkTestCases = []globTestCase{
{
pattern: `**/*`,
matches: []string{"a/", "b/", "c/", "d/", "dangling", "e", "f", "a/a/", "a/a/a", "a/a/f", "b/a/", "b/a/a", "b/a/f", "c/a", "c/f", "d/a", "d/f"},
deps: []string{".", "a", "a/a", "b", "b/a", "c", "d"},
},
{
pattern: `dangling`,
matches: []string{"dangling"},
deps: []string{"dangling"},
},
}
func TestMockGlobFollowDanglingSymlinks(t *testing.T) {
files := []string{
"a/a/a",
"a/a/f -> ../../f",
"b -> a",
"c -> a/a",
"d -> c",
"e -> a/a/a",
"f",
"dangling -> missing",
}
mockFiles := make(map[string][]byte)
for _, f := range files {
mockFiles[f] = nil
}
mock := MockFs(mockFiles)
for _, testCase := range globFollowDanglingSymlinkTestCases {
t.Run(testCase.pattern, func(t *testing.T) {
testGlob(t, mock, testCase, FollowSymlinks)
})
}
}
func TestGlobFollowDanglingSymlinks(t *testing.T) {
os.Chdir("testdata/dangling")
defer os.Chdir("../..")
for _, testCase := range globFollowDanglingSymlinkTestCases {
t.Run(testCase.pattern, func(t *testing.T) {
testGlob(t, OsFs, testCase, FollowSymlinks)
})
}
}
func testGlob(t *testing.T, fs FileSystem, testCase globTestCase, follow ShouldFollowSymlinks) {
t.Helper()
result, err := fs.Glob(testCase.pattern, testCase.excludes, follow)