Merge "apex: apex_available with prefix" into main
This commit is contained in:
@@ -280,6 +280,7 @@ type ApexProperties struct {
|
|||||||
//
|
//
|
||||||
// "//apex_available:anyapex" is a pseudo APEX name that matches to any APEX.
|
// "//apex_available:anyapex" is a pseudo APEX name that matches to any APEX.
|
||||||
// "//apex_available:platform" refers to non-APEX partitions like "system.img".
|
// "//apex_available:platform" refers to non-APEX partitions like "system.img".
|
||||||
|
// Prefix pattern (com.foo.*) can be used to match with any APEX name with the prefix(com.foo.).
|
||||||
// Default is ["//apex_available:platform"].
|
// Default is ["//apex_available:platform"].
|
||||||
Apex_available []string
|
Apex_available []string
|
||||||
|
|
||||||
@@ -491,10 +492,27 @@ func CheckAvailableForApex(what string, apex_available []string) bool {
|
|||||||
if len(apex_available) == 0 {
|
if len(apex_available) == 0 {
|
||||||
return what == AvailableToPlatform
|
return what == AvailableToPlatform
|
||||||
}
|
}
|
||||||
return InList(what, apex_available) ||
|
|
||||||
(what != AvailableToPlatform && InList(AvailableToAnyApex, apex_available)) ||
|
// TODO b/248601389
|
||||||
(what == "com.google.mainline.primary.libs") || // TODO b/248601389
|
if what == "com.google.mainline.primary.libs" || what == "com.google.mainline.go.primary.libs" {
|
||||||
(what == "com.google.mainline.go.primary.libs") // TODO b/248601389
|
return true
|
||||||
|
}
|
||||||
|
|
||||||
|
for _, apex_name := range apex_available {
|
||||||
|
// exact match.
|
||||||
|
if apex_name == what {
|
||||||
|
return true
|
||||||
|
}
|
||||||
|
// //apex_available:anyapex matches with any apex name, but not //apex_available:platform
|
||||||
|
if apex_name == AvailableToAnyApex && what != AvailableToPlatform {
|
||||||
|
return true
|
||||||
|
}
|
||||||
|
// prefix match.
|
||||||
|
if strings.HasSuffix(apex_name, ".*") && strings.HasPrefix(what, strings.TrimSuffix(apex_name, "*")) {
|
||||||
|
return true
|
||||||
|
}
|
||||||
|
}
|
||||||
|
return false
|
||||||
}
|
}
|
||||||
|
|
||||||
// Implements ApexModule
|
// Implements ApexModule
|
||||||
@@ -523,6 +541,19 @@ func (m *ApexModuleBase) checkApexAvailableProperty(mctx BaseModuleContext) {
|
|||||||
if n == AvailableToPlatform || n == AvailableToAnyApex {
|
if n == AvailableToPlatform || n == AvailableToAnyApex {
|
||||||
continue
|
continue
|
||||||
}
|
}
|
||||||
|
// Prefix pattern should end with .* and has at least two components.
|
||||||
|
if strings.Contains(n, "*") {
|
||||||
|
if !strings.HasSuffix(n, ".*") {
|
||||||
|
mctx.PropertyErrorf("apex_available", "Wildcard should end with .* like com.foo.*")
|
||||||
|
}
|
||||||
|
if strings.Count(n, ".") < 2 {
|
||||||
|
mctx.PropertyErrorf("apex_available", "Wildcard requires two or more components like com.foo.*")
|
||||||
|
}
|
||||||
|
if strings.Count(n, "*") != 1 {
|
||||||
|
mctx.PropertyErrorf("apex_available", "Wildcard is not allowed in the middle.")
|
||||||
|
}
|
||||||
|
continue
|
||||||
|
}
|
||||||
if !mctx.OtherModuleExists(n) && !mctx.Config().AllowMissingDependencies() {
|
if !mctx.OtherModuleExists(n) && !mctx.Config().AllowMissingDependencies() {
|
||||||
mctx.PropertyErrorf("apex_available", "%q is not a valid module name", n)
|
mctx.PropertyErrorf("apex_available", "%q is not a valid module name", n)
|
||||||
}
|
}
|
||||||
|
15
apex/apex.go
15
apex/apex.go
@@ -2767,10 +2767,21 @@ func (a *apexBundle) checkApexAvailability(ctx android.ModuleContext) {
|
|||||||
if to.AvailableFor(apexName) || baselineApexAvailable(apexName, toName) {
|
if to.AvailableFor(apexName) || baselineApexAvailable(apexName, toName) {
|
||||||
return true
|
return true
|
||||||
}
|
}
|
||||||
|
|
||||||
|
// Let's give some hint for apex_available
|
||||||
|
hint := fmt.Sprintf("%q", apexName)
|
||||||
|
|
||||||
|
if strings.HasPrefix(apexName, "com.") && !strings.HasPrefix(apexName, "com.android.") && strings.Count(apexName, ".") >= 2 {
|
||||||
|
// In case of a partner APEX, prefix format might be an option.
|
||||||
|
components := strings.Split(apexName, ".")
|
||||||
|
components[len(components)-1] = "*"
|
||||||
|
hint += fmt.Sprintf(" or %q", strings.Join(components, "."))
|
||||||
|
}
|
||||||
|
|
||||||
ctx.ModuleErrorf("%q requires %q that doesn't list the APEX under 'apex_available'."+
|
ctx.ModuleErrorf("%q requires %q that doesn't list the APEX under 'apex_available'."+
|
||||||
"\n\nDependency path:%s\n\n"+
|
"\n\nDependency path:%s\n\n"+
|
||||||
"Consider adding %q to 'apex_available' property of %q",
|
"Consider adding %s to 'apex_available' property of %q",
|
||||||
fromName, toName, ctx.GetPathString(true), apexName, toName)
|
fromName, toName, ctx.GetPathString(true), hint, toName)
|
||||||
// Visit this module's dependencies to check and report any issues with their availability.
|
// Visit this module's dependencies to check and report any issues with their availability.
|
||||||
return true
|
return true
|
||||||
})
|
})
|
||||||
|
@@ -6722,6 +6722,99 @@ func TestApexAvailable_CreatedForApex(t *testing.T) {
|
|||||||
}
|
}
|
||||||
}
|
}
|
||||||
|
|
||||||
|
func TestApexAvailable_PrefixMatch(t *testing.T) {
|
||||||
|
|
||||||
|
for _, tc := range []struct {
|
||||||
|
name string
|
||||||
|
apexAvailable string
|
||||||
|
expectedError string
|
||||||
|
}{
|
||||||
|
{
|
||||||
|
name: "prefix matches correctly",
|
||||||
|
apexAvailable: "com.foo.*",
|
||||||
|
},
|
||||||
|
{
|
||||||
|
name: "prefix doesn't match",
|
||||||
|
apexAvailable: "com.bar.*",
|
||||||
|
expectedError: `Consider .* "com.foo\.\*"`,
|
||||||
|
},
|
||||||
|
{
|
||||||
|
name: "short prefix",
|
||||||
|
apexAvailable: "com.*",
|
||||||
|
expectedError: "requires two or more components",
|
||||||
|
},
|
||||||
|
{
|
||||||
|
name: "wildcard not in the end",
|
||||||
|
apexAvailable: "com.*.foo",
|
||||||
|
expectedError: "should end with .*",
|
||||||
|
},
|
||||||
|
{
|
||||||
|
name: "wildcard in the middle",
|
||||||
|
apexAvailable: "com.foo*.*",
|
||||||
|
expectedError: "not allowed in the middle",
|
||||||
|
},
|
||||||
|
{
|
||||||
|
name: "hint with prefix pattern",
|
||||||
|
apexAvailable: "//apex_available:platform",
|
||||||
|
expectedError: "Consider adding \"com.foo.bar\" or \"com.foo.*\"",
|
||||||
|
},
|
||||||
|
} {
|
||||||
|
t.Run(tc.name, func(t *testing.T) {
|
||||||
|
errorHandler := android.FixtureExpectsNoErrors
|
||||||
|
if tc.expectedError != "" {
|
||||||
|
errorHandler = android.FixtureExpectsAtLeastOneErrorMatchingPattern(tc.expectedError)
|
||||||
|
}
|
||||||
|
context := android.GroupFixturePreparers(
|
||||||
|
prepareForApexTest,
|
||||||
|
android.FixtureMergeMockFs(android.MockFS{
|
||||||
|
"system/sepolicy/apex/com.foo.bar-file_contexts": nil,
|
||||||
|
}),
|
||||||
|
).ExtendWithErrorHandler(errorHandler)
|
||||||
|
|
||||||
|
context.RunTestWithBp(t, `
|
||||||
|
apex {
|
||||||
|
name: "com.foo.bar",
|
||||||
|
key: "myapex.key",
|
||||||
|
native_shared_libs: ["libfoo"],
|
||||||
|
updatable: false,
|
||||||
|
}
|
||||||
|
|
||||||
|
apex_key {
|
||||||
|
name: "myapex.key",
|
||||||
|
public_key: "testkey.avbpubkey",
|
||||||
|
private_key: "testkey.pem",
|
||||||
|
}
|
||||||
|
|
||||||
|
cc_library {
|
||||||
|
name: "libfoo",
|
||||||
|
stl: "none",
|
||||||
|
system_shared_libs: [],
|
||||||
|
apex_available: ["`+tc.apexAvailable+`"],
|
||||||
|
}`)
|
||||||
|
})
|
||||||
|
}
|
||||||
|
testApexError(t, `Consider adding "com.foo" to`, `
|
||||||
|
apex {
|
||||||
|
name: "com.foo", // too short for a partner apex
|
||||||
|
key: "myapex.key",
|
||||||
|
native_shared_libs: ["libfoo"],
|
||||||
|
updatable: false,
|
||||||
|
}
|
||||||
|
|
||||||
|
apex_key {
|
||||||
|
name: "myapex.key",
|
||||||
|
public_key: "testkey.avbpubkey",
|
||||||
|
private_key: "testkey.pem",
|
||||||
|
}
|
||||||
|
|
||||||
|
cc_library {
|
||||||
|
name: "libfoo",
|
||||||
|
stl: "none",
|
||||||
|
system_shared_libs: [],
|
||||||
|
}
|
||||||
|
`)
|
||||||
|
}
|
||||||
|
|
||||||
func TestOverrideApex(t *testing.T) {
|
func TestOverrideApex(t *testing.T) {
|
||||||
ctx := testApex(t, `
|
ctx := testApex(t, `
|
||||||
apex {
|
apex {
|
||||||
|
Reference in New Issue
Block a user