diff --git a/glob.go b/glob.go index d2df9b7..e7fb4b3 100644 --- a/glob.go +++ b/glob.go @@ -124,6 +124,13 @@ func Glob(pattern string, opts ...OptFunc) ([]string, error) { // nolint:funlen, return nil, fmt.Errorf("cannot determine static prefix: %w", err) } + // Check if the file is valid symlink without following it + if prefixInfo, err := os.Lstat(pattern); err == nil { + if prefixInfo.Mode()&os.ModeSymlink == os.ModeSymlink { + return cleanFilepaths([]string{pattern}, options.prefix), nil + } + } + prefixInfo, err := fs.Stat(options.fs, prefix) if errors.Is(err, fs.ErrNotExist) { if !ContainsMatchers(pattern) { diff --git a/glob_test.go b/glob_test.go index 9831f2a..b73124a 100644 --- a/glob_test.go +++ b/glob_test.go @@ -450,6 +450,25 @@ func TestGlob(t *testing.T) { // nolint:funlen "a/b/4.txt", }, matches) }) + + t.Run("symlinks", func(t *testing.T) { + t.Parallel() + testFS := testFs(t, []string{ + "./a/file", + }, nil).(testfs.FS) + + fsPath := testFS.Path() + os.Symlink("file", filepath.Join(fsPath, "./a/working-symlink")) + os.Symlink("non-existent", filepath.Join(fsPath, "./a/broken-symlink")) + + matches, err := Glob("a/*", MatchDirectoryIncludesContents, WithFs(testFS)) + require.NoError(t, err) + require.Equal(t, []string{ + "a/broken-symlink", + "a/file", + "a/working-symlink", + }, matches) + }) } func TestQuoteMeta(t *testing.T) {