Use bazel syntax for fully qualified name in path property
A module reference to a fully qualified module in a path property looks
like:
//path:module
And with a tag:
//path:module{tag}
At the moment the checking is quite lax but some follow up changes will
make it much stricter.
Bug: 193228441
Test: m nothing
Change-Id: Ie42edcfa33ec66fda5d75b3df1da73f56f147afd
diff --git a/android/module.go b/android/module.go
index ef319a4..e9ad987 100644
--- a/android/module.go
+++ b/android/module.go
@@ -2807,30 +2807,57 @@
return m.bp
}
-// SrcIsModule decodes module references in the format ":name" into the module name, or empty string if the input
-// was not a module reference.
+// SrcIsModule decodes module references in the format ":unqualified-name" or "//namespace:name"
+// into the module name, or empty string if the input was not a module reference.
func SrcIsModule(s string) (module string) {
- if len(s) > 1 && s[0] == ':' {
- return s[1:]
+ if len(s) > 1 {
+ if s[0] == ':' {
+ module = s[1:]
+ if !isUnqualifiedModuleName(module) {
+ // The module name should be unqualified but is not so do not treat it as a module.
+ module = ""
+ }
+ } else if s[0] == '/' && s[1] == '/' {
+ module = s
+ }
}
- return ""
+ return module
}
-// SrcIsModule decodes module references in the format ":name{.tag}" into the module name and tag, ":name" into the
-// module name and an empty string for the tag, or empty strings if the input was not a module reference.
+// SrcIsModule decodes module references in the format ":unqualified-name{.tag}" or
+// "//namespace:name{.tag}" into the module name and an empty string for the tag, or empty strings
+// if the input was not a module reference.
func SrcIsModuleWithTag(s string) (module, tag string) {
- if len(s) > 1 && s[0] == ':' {
- module = s[1:]
- if tagStart := strings.IndexByte(module, '{'); tagStart > 0 {
- if module[len(module)-1] == '}' {
- tag = module[tagStart+1 : len(module)-1]
- module = module[:tagStart]
- return module, tag
+ if len(s) > 1 {
+ if s[0] == ':' {
+ module = s[1:]
+ } else if s[0] == '/' && s[1] == '/' {
+ module = s
+ }
+
+ if module != "" {
+ if tagStart := strings.IndexByte(module, '{'); tagStart > 0 {
+ if module[len(module)-1] == '}' {
+ tag = module[tagStart+1 : len(module)-1]
+ module = module[:tagStart]
+ }
+ }
+
+ if s[0] == ':' && !isUnqualifiedModuleName(module) {
+ // The module name should be unqualified but is not so do not treat it as a module.
+ module = ""
+ tag = ""
}
}
- return module, ""
}
- return "", ""
+
+ return module, tag
+}
+
+// isUnqualifiedModuleName makes sure that the supplied module is an unqualified module name, i.e.
+// does not contain any /.
+func isUnqualifiedModuleName(module string) bool {
+ return strings.IndexByte(module, '/') == -1
}
type sourceOrOutputDependencyTag struct {
diff --git a/android/module_test.go b/android/module_test.go
index 9ac9291..9e2b0ca 100644
--- a/android/module_test.go
+++ b/android/module_test.go
@@ -55,6 +55,27 @@
},
wantModule: "foo:bar",
},
+ {
+ name: "fully qualified",
+ args: args{
+ s: "//foo:bar",
+ },
+ wantModule: "//foo:bar",
+ },
+ {
+ name: "fully qualified with tag",
+ args: args{
+ s: "//foo:bar{.tag}",
+ },
+ wantModule: "//foo:bar{.tag}",
+ },
+ {
+ name: "invalid unqualified name",
+ args: args{
+ s: ":foo/bar",
+ },
+ wantModule: "",
+ },
}
for _, tt := range tests {
t.Run(tt.name, func(t *testing.T) {
@@ -128,6 +149,35 @@
},
wantModule: "foo.bar}",
},
+ {
+ name: "fully qualified",
+ args: args{
+ s: "//foo:bar",
+ },
+ wantModule: "//foo:bar",
+ },
+ {
+ name: "fully qualified with tag",
+ args: args{
+ s: "//foo:bar{.tag}",
+ },
+ wantModule: "//foo:bar",
+ wantTag: ".tag",
+ },
+ {
+ name: "invalid unqualified name",
+ args: args{
+ s: ":foo/bar",
+ },
+ wantModule: "",
+ },
+ {
+ name: "invalid unqualified name with tag",
+ args: args{
+ s: ":foo/bar{.tag}",
+ },
+ wantModule: "",
+ },
}
for _, tt := range tests {
t.Run(tt.name, func(t *testing.T) {
diff --git a/android/paths_test.go b/android/paths_test.go
index 4c18cfd..7675905 100644
--- a/android/paths_test.go
+++ b/android/paths_test.go
@@ -1351,7 +1351,6 @@
{
// This test makes sure that an unqualified module name cannot contain characters that make
// it appear as a qualified module name.
- // TODO(b/193228441): Fix broken test.
name: "output file provider, invalid fully qualified name",
bp: `
test {
@@ -1372,13 +1371,12 @@
outs: ["gen/c"],
}
`),
- errorHandler: FixtureExpectsAllErrorsToMatchAPattern([]string{
- `"foo": missing dependencies: //other:b, is the property annotated with android:"path"`,
- `"foo": missing dependency on "//other:c", is the property annotated with android:"path"`,
- }),
+ src: "foo/:/other:b",
+ rel: ":/other:b",
+ srcs: []string{"foo/:/other:c"},
+ rels: []string{":/other:c"},
},
{
- // TODO(b/193228441): Fix broken test.
name: "output file provider, missing fully qualified name",
bp: `
test {
@@ -1386,13 +1384,9 @@
src: "//other:b",
srcs: ["//other:c"],
}`,
- src: "foo",
- rel: "foo",
- srcs: []string{"foo"},
- rels: []string{"foo"},
errorHandler: FixtureExpectsAllErrorsToMatchAPattern([]string{
- `"foo": Path is outside directory: /other:b`,
- `"foo": Path is outside directory: /other:c`,
+ `"foo" depends on undefined module "//other:b"`,
+ `"foo" depends on undefined module "//other:c"`,
}),
},
{
@@ -1417,13 +1411,9 @@
outs: ["gen/c"],
}
`),
- src: "foo",
- rel: "foo",
- srcs: []string{"foo"},
- rels: []string{"foo"},
errorHandler: FixtureExpectsAllErrorsToMatchAPattern([]string{
- `"foo": Path is outside directory: /other:b`,
- `"foo": Path is outside directory: /other:c`,
+ `"foo": missing dependencies: //other:b, is the property annotated with android:"path"`,
+ `"foo": missing dependency on "//other:c", is the property annotated with android:"path"`,
}),
},
}