From 810f463f46458e2ad56d82bf0aa3de63f9bcdb9c Mon Sep 17 00:00:00 2001 From: Marko Vejnovic Date: Sat, 23 May 2026 08:30:50 -0700 Subject: [PATCH 1/2] test: unit test for resolveLabels proving break bug drops labels MIME-Version: 1.0 Content-Type: text/plain; charset=UTF-8 Content-Transfer-Encoding: 8bit Extract resolveLabels as a standalone pure function from labelsToWatch for testability. Add TestResolveLabels with 6 subtests — last two ("local repo match does not stop processing subsequent labels" and "multiple local repo matches all resolved") fail, proving the break bug silently drops labels after the first @repo match. --- internal/ibazel/ibazel.go | 29 +++++++++------- internal/ibazel/ibazel_test.go | 63 ++++++++++++++++++++++++++++++++++ 2 files changed, 79 insertions(+), 13 deletions(-) diff --git a/internal/ibazel/ibazel.go b/internal/ibazel/ibazel.go index 9796b06d..06ccb7c1 100644 --- a/internal/ibazel/ibazel.go +++ b/internal/ibazel/ibazel.go @@ -628,18 +628,7 @@ func (i *IBazel) watchFiles(toWatch []string, watcher common.Watcher) { i.filesWatched[watcher] = filesWatched } -func (i *IBazel) labelsToWatch(labels []string) ([]string, error) { - localRepositories, err := i.realLocalRepositoryPaths() - if err != nil { - return nil, err - } - - workspacePath, err := i.workspaceFinder.FindWorkspace() - if err != nil { - log.Errorf("Error finding workspace: %v", err) - return nil, err - } - +func resolveLabels(labels []string, localRepositories map[string]string, workspacePath string) []string { toWatch := make([]string, 0, len(labels)) for _, label := range labels { if strings.HasPrefix(label, "@") { @@ -658,8 +647,22 @@ func (i *IBazel) labelsToWatch(labels []string) ([]string, error) { label = strings.Replace(strings.TrimPrefix(label, "//"), ":", string(filepath.Separator), 1) toWatch = append(toWatch, filepath.Join(workspacePath, label)) } + return toWatch +} + +func (i *IBazel) labelsToWatch(labels []string) ([]string, error) { + localRepositories, err := i.realLocalRepositoryPaths() + if err != nil { + return nil, err + } + + workspacePath, err := i.workspaceFinder.FindWorkspace() + if err != nil { + log.Errorf("Error finding workspace: %v", err) + return nil, err + } - return toWatch, nil + return resolveLabels(labels, localRepositories, workspacePath), nil } func (i *IBazel) queryArgs(args ...string) []string { diff --git a/internal/ibazel/ibazel_test.go b/internal/ibazel/ibazel_test.go index 99ea41a7..35c8fd0a 100644 --- a/internal/ibazel/ibazel_test.go +++ b/internal/ibazel/ibazel_test.go @@ -653,3 +653,66 @@ func TestParseTarget(t *testing.T) { }) } } + +func TestResolveLabels(t *testing.T) { + log.SetTesting(t) + + localRepositories := map[string]string{ + "nested": "/home/user/nested", + } + workspacePath := "/home/user/workspace" + + tests := []struct { + name string + labels []string + want []string + }{ + { + name: "local label only", + labels: []string{"//:src/main.sh"}, + want: []string{filepath.Join(workspacePath, "src/main.sh")}, + }, + { + name: "external repo label resolved to local path", + labels: []string{"@nested//:lib.sh"}, + want: []string{filepath.Join("/home/user/nested", "lib.sh")}, + }, + { + name: "unknown external repo skipped", + labels: []string{"@unknown//:foo.sh"}, + want: []string{}, + }, + { + name: "//external label skipped", + labels: []string{"//external/foo:bar.sh"}, + want: []string{}, + }, + { + name: "local repo match does not stop processing subsequent labels", + labels: []string{"@nested//:lib.sh", "//:src/main.sh"}, + want: []string{ + filepath.Join("/home/user/nested", "lib.sh"), + filepath.Join(workspacePath, "src/main.sh"), + }, + }, + { + name: "multiple local repo matches all resolved", + labels: []string{"@nested//:lib.sh", "@nested//:other.sh"}, + want: []string{ + filepath.Join("/home/user/nested", "lib.sh"), + filepath.Join("/home/user/nested", "other.sh"), + }, + }, + } + for _, test := range tests { + t.Run(test.name, func(t *testing.T) { + got := resolveLabels(test.labels, localRepositories, workspacePath) + if len(got) == 0 && len(test.want) == 0 { + return + } + if !reflect.DeepEqual(got, test.want) { + t.Errorf("resolveLabels(%v) = %v, want %v", test.labels, got, test.want) + } + }) + } +} From 5bd48ba780072203e956ea3e06a0b193aa5a606e Mon Sep 17 00:00:00 2001 From: Marko Vejnovic Date: Sat, 23 May 2026 08:30:57 -0700 Subject: [PATCH 2/2] fix: labelsToWatch short-circuiting faster than it should --- internal/ibazel/ibazel.go | 2 +- 1 file changed, 1 insertion(+), 1 deletion(-) diff --git a/internal/ibazel/ibazel.go b/internal/ibazel/ibazel.go index 06ccb7c1..244e0663 100644 --- a/internal/ibazel/ibazel.go +++ b/internal/ibazel/ibazel.go @@ -636,7 +636,7 @@ func resolveLabels(labels []string, localRepositories map[string]string, workspa if realPath, ok := localRepositories[repo]; ok { label = strings.Replace(target, ":", string(filepath.Separator), 1) toWatch = append(toWatch, filepath.Join(realPath, label)) - break + continue } continue }