@@ -353,6 +353,131 @@ func TestLookup(t *testing.T) {
356+func TestLookupClosestBounded(t *testing.T) {
357+ t.Run("found in starting directory", func(t *testing.T) {
358+ testDir := t.TempDir()
360+ targetFile := filepath.Join(testDir, "target.txt")
361+ require.NoError(t, os.WriteFile(targetFile, []byte("test"), 0o644))
363+ foundPath, found := LookupClosestBounded(testDir, testDir, "target.txt")
364+ require.True(t, found)
365+ require.Equal(t, targetFile, foundPath)
368+ t.Run("found at boundary directory", func(t *testing.T) {
369+ boundary := t.TempDir()
371+ subDir := filepath.Join(boundary, "subdir")
372+ require.NoError(t, os.Mkdir(subDir, 0o755))
374+ targetFile := filepath.Join(boundary, "target.txt")
375+ require.NoError(t, os.WriteFile(targetFile, []byte("test"), 0o644))
377+ foundPath, found := LookupClosestBounded(subDir, boundary, "target.txt")
378+ require.True(t, found)
379+ require.Equal(t, targetFile, foundPath)
382+ t.Run("does not climb past boundary", func(t *testing.T) {
383+ parent := t.TempDir()
385+ // Target lives above the boundary.
386+ require.NoError(t, os.WriteFile(filepath.Join(parent, "target.txt"), []byte("test"), 0o644))
388+ boundary := filepath.Join(parent, "project")
389+ require.NoError(t, os.Mkdir(boundary, 0o755))
391+ subDir := filepath.Join(boundary, "subdir")
392+ require.NoError(t, os.Mkdir(subDir, 0o755))
394+ foundPath, found := LookupClosestBounded(subDir, boundary, "target.txt")
395+ require.False(t, found)
396+ require.Empty(t, foundPath)
399+ t.Run("empty boundary searches only starting directory", func(t *testing.T) {
400+ parent := t.TempDir()
402+ require.NoError(t, os.WriteFile(filepath.Join(parent, "target.txt"), []byte("test"), 0o644))
404+ subDir := filepath.Join(parent, "subdir")
405+ require.NoError(t, os.Mkdir(subDir, 0o755))
407+ foundPath, found := LookupClosestBounded(subDir, "", "target.txt")
408+ require.False(t, found)
409+ require.Empty(t, foundPath)
412+ t.Run("empty boundary still finds in starting directory", func(t *testing.T) {
413+ testDir := t.TempDir()
415+ targetFile := filepath.Join(testDir, "target.txt")
416+ require.NoError(t, os.WriteFile(targetFile, []byte("test"), 0o644))
418+ foundPath, found := LookupClosestBounded(testDir, "", "target.txt")
419+ require.True(t, found)
420+ require.Equal(t, targetFile, foundPath)
424+func TestLookupBounded(t *testing.T) {
425+ t.Run("returns matches at and below boundary", func(t *testing.T) {
426+ boundary := t.TempDir()
428+ subDir := filepath.Join(boundary, "subdir")
429+ require.NoError(t, os.Mkdir(subDir, 0o755))
431+ atBoundary := filepath.Join(boundary, "target.txt")
432+ atSub := filepath.Join(subDir, "target.txt")
433+ require.NoError(t, os.WriteFile(atBoundary, []byte("a"), 0o644))
434+ require.NoError(t, os.WriteFile(atSub, []byte("b"), 0o644))
436+ found, err := LookupBounded(subDir, boundary, "target.txt")
437+ require.NoError(t, err)
438+ require.Len(t, found, 2)
439+ require.Contains(t, found, atBoundary)
440+ require.Contains(t, found, atSub)
443+ t.Run("ignores matches above boundary", func(t *testing.T) {
444+ parent := t.TempDir()
446+ require.NoError(t, os.WriteFile(filepath.Join(parent, "target.txt"), []byte("nope"), 0o644))
448+ boundary := filepath.Join(parent, "project")
449+ require.NoError(t, os.Mkdir(boundary, 0o755))
451+ subDir := filepath.Join(boundary, "subdir")
452+ require.NoError(t, os.Mkdir(subDir, 0o755))
454+ // Target lives only above the boundary.
455+ found, err := LookupBounded(subDir, boundary, "target.txt")
456+ require.NoError(t, err)
457+ require.Empty(t, found)
460+ t.Run("empty boundary searches only starting directory", func(t *testing.T) {
461+ parent := t.TempDir()
463+ require.NoError(t, os.WriteFile(filepath.Join(parent, "target.txt"), []byte("nope"), 0o644))
465+ subDir := filepath.Join(parent, "subdir")
466+ require.NoError(t, os.Mkdir(subDir, 0o755))
468+ found, err := LookupBounded(subDir, "", "target.txt")
469+ require.NoError(t, err)
470+ require.Empty(t, found)
473+ t.Run("no targets returns nil", func(t *testing.T) {
475+ found, err := LookupBounded(dir, dir)
476+ require.NoError(t, err)
477+ require.Empty(t, found)
356func TestProbeEnt(t *testing.T) {
481func TestProbeEnt(t *testing.T) {
357 t.Run("existing file with correct owner", func(t *testing.T) {
482 t.Run("existing file with correct owner", func(t *testing.T) {
358 tempDir := t.TempDir()
483 tempDir := t.TempDir()