Merge "Add a function to find src labels in a specific directory" into main
diff --git a/android/bazel_paths.go b/android/bazel_paths.go
index 02ae5ca..86829ce 100644
--- a/android/bazel_paths.go
+++ b/android/bazel_paths.go
@@ -205,6 +205,21 @@
 	return labels
 }
 
+func BazelLabelForSrcPatternExcludes(ctx BazelConversionPathContext, dir, pattern string, excludes []string) bazel.LabelList {
+	topRelPaths, err := ctx.GlobWithDeps(filepath.Join(dir, pattern), excludes)
+	if err != nil {
+		ctx.ModuleErrorf("Could not search dir: %s for pattern %s due to %v\n", dir, pattern, err)
+	}
+	// An intermediate list of labels relative to `dir` that assumes that there no subpacakges beneath `dir`
+	dirRelLabels := []bazel.Label{}
+	for _, topRelPath := range topRelPaths {
+		dirRelPath := Rel(ctx, dir, topRelPath)
+		dirRelLabels = append(dirRelLabels, bazel.Label{Label: "./" + dirRelPath})
+	}
+	// Return the package boudary resolved labels
+	return TransformSubpackagePaths(ctx.Config(), dir, bazel.MakeLabelList(dirRelLabels))
+}
+
 // Returns true if a prefix + components[:i] is a package boundary.
 //
 // A package boundary is determined by a BUILD file in the directory. This can happen in 2 cases:
diff --git a/android/bazel_paths_test.go b/android/bazel_paths_test.go
index 75b77a3..bed719c 100644
--- a/android/bazel_paths_test.go
+++ b/android/bazel_paths_test.go
@@ -15,6 +15,7 @@
 package android
 
 import (
+	"fmt"
 	"path/filepath"
 	"testing"
 
@@ -114,8 +115,9 @@
 
 type TestBazelConversionPathContext struct {
 	TestBazelConversionContext
-	moduleDir string
-	cfg       Config
+	moduleDir       string
+	cfg             Config
+	mockGlobResults *[]string
 }
 
 func (ctx *TestBazelConversionPathContext) AddNinjaFileDeps(...string) {
@@ -123,7 +125,10 @@
 }
 
 func (ctx *TestBazelConversionPathContext) GlobWithDeps(string, []string) ([]string, error) {
-	panic("Unimplemented")
+	if ctx.mockGlobResults == nil {
+		return []string{}, fmt.Errorf("Set mock glob results first")
+	}
+	return *ctx.mockGlobResults, nil
 }
 
 func (ctx *TestBazelConversionPathContext) PropertyErrorf(string, string, ...interface{}) {
@@ -190,3 +195,46 @@
 		}
 	}
 }
+
+// Check that the files in a specific directory are returned with labels that respect package boundaries
+// Since the test uses a mock for GlobWithDeps, the params passed to BazelLabelForSrcPatternExcludes are no-ops
+func TestBazelLabelForSrcPatternExcludes(t *testing.T) {
+	cfg := NullConfig("out", "out/soong")
+	cfg.fs = pathtools.MockFs(map[string][]byte{
+		"x/Android.bp":   nil,
+		"x/y/Android.bp": nil,
+		// .proto files
+		"foo.proto":     nil,
+		"x/bar.proto":   nil,
+		"x/baz.proto":   nil,
+		"x/y/qux.proto": nil,
+	})
+
+	var ctx BazelConversionPathContext = &TestBazelConversionPathContext{
+		cfg: cfg,
+	}
+
+	// Root dir
+	ctx.(*TestBazelConversionPathContext).mockGlobResults = &[]string{"foo.proto", "x/bar.proto", "x/baz.proto", "x/y/qux.proto"}
+	actualLabelsFromRoot := BazelLabelForSrcPatternExcludes(ctx, ".", "**/*.proto", []string{})
+	expectedLabelsAsString := []string{"foo.proto", "//x:bar.proto", "//x:baz.proto", "//x/y:qux.proto"}
+	for i, actual := range actualLabelsFromRoot.Includes {
+		AssertStringEquals(t, "Error in finding src labels relative to root directory", expectedLabelsAsString[i], actual.Label)
+	}
+
+	// x dir
+	ctx.(*TestBazelConversionPathContext).mockGlobResults = &[]string{"x/bar.proto", "x/baz.proto", "x/y/qux.proto"}
+	actualLabelsFromRoot = BazelLabelForSrcPatternExcludes(ctx, "x", "**/*.proto", []string{})
+	expectedLabelsAsString = []string{"bar.proto", "baz.proto", "//x/y:qux.proto"}
+	for i, actual := range actualLabelsFromRoot.Includes {
+		AssertStringEquals(t, "Error in finding src labels relative to x directory", expectedLabelsAsString[i], actual.Label)
+	}
+
+	// y dir
+	ctx.(*TestBazelConversionPathContext).mockGlobResults = &[]string{"x/y/qux.proto"}
+	actualLabelsFromRoot = BazelLabelForSrcPatternExcludes(ctx, "x/y", "**/*.proto", []string{})
+	expectedLabelsAsString = []string{"qux.proto"}
+	for i, actual := range actualLabelsFromRoot.Includes {
+		AssertStringEquals(t, "Error in finding src labels relative to x/y directory", expectedLabelsAsString[i], actual.Label)
+	}
+}