Revert "Add ability to declare licenses in soong."
Revert submission 1377717-metalics Reason for revert: This has broken renderscript_mac target for aosp-master, see b/176909442 Reverted Changes: I26ac54ca9:Define the standard license_kind rules. I656486070:Export soong license data to make. If9d661dfc:Export soong license data to make. I97943de53:Add ability to declare licenses in soong. Icaff40171:Rough-in license metadata support to make. Ib8e538bd0:Add variables for notice deps, license kinds etc. Change-Id: Iddf5468e0175831ddb642011f2768f87a5e4fcf2
This commit is contained in:
@@ -30,9 +30,6 @@ bootstrap_go_package {
|
|||||||
"filegroup.go",
|
"filegroup.go",
|
||||||
"hooks.go",
|
"hooks.go",
|
||||||
"image.go",
|
"image.go",
|
||||||
"license.go",
|
|
||||||
"license_kind.go",
|
|
||||||
"licenses.go",
|
|
||||||
"makefile_goal.go",
|
"makefile_goal.go",
|
||||||
"makevars.go",
|
"makevars.go",
|
||||||
"metrics.go",
|
"metrics.go",
|
||||||
@@ -80,9 +77,6 @@ bootstrap_go_package {
|
|||||||
"depset_test.go",
|
"depset_test.go",
|
||||||
"deptag_test.go",
|
"deptag_test.go",
|
||||||
"expand_test.go",
|
"expand_test.go",
|
||||||
"license_kind_test.go",
|
|
||||||
"license_test.go",
|
|
||||||
"licenses_test.go",
|
|
||||||
"module_test.go",
|
"module_test.go",
|
||||||
"mutator_test.go",
|
"mutator_test.go",
|
||||||
"namespace_test.go",
|
"namespace_test.go",
|
||||||
|
@@ -204,9 +204,6 @@ func InitDefaultsModule(module DefaultsModule) {
|
|||||||
// its checking phase and parsing phase so add it to the list as a normal property.
|
// its checking phase and parsing phase so add it to the list as a normal property.
|
||||||
AddVisibilityProperty(module, "visibility", &commonProperties.Visibility)
|
AddVisibilityProperty(module, "visibility", &commonProperties.Visibility)
|
||||||
|
|
||||||
// The applicable licenses property for defaults is 'licenses'.
|
|
||||||
setPrimaryLicensesProperty(module, "licenses", &commonProperties.Licenses)
|
|
||||||
|
|
||||||
base.module = module
|
base.module = module
|
||||||
}
|
}
|
||||||
|
|
||||||
|
@@ -1,82 +0,0 @@
|
|||||||
// Copyright 2020 Google Inc. All rights reserved.
|
|
||||||
//
|
|
||||||
// Licensed under the Apache License, Version 2.0 (the "License");
|
|
||||||
// you may not use this file except in compliance with the License.
|
|
||||||
// You may obtain a copy of the License at
|
|
||||||
//
|
|
||||||
// http://www.apache.org/licenses/LICENSE-2.0
|
|
||||||
//
|
|
||||||
// Unless required by applicable law or agreed to in writing, software
|
|
||||||
// distributed under the License is distributed on an "AS IS" BASIS,
|
|
||||||
// WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied.
|
|
||||||
// See the License for the specific language governing permissions and
|
|
||||||
// limitations under the License.
|
|
||||||
|
|
||||||
package android
|
|
||||||
|
|
||||||
import (
|
|
||||||
"github.com/google/blueprint"
|
|
||||||
)
|
|
||||||
|
|
||||||
type licenseKindDependencyTag struct {
|
|
||||||
blueprint.BaseDependencyTag
|
|
||||||
}
|
|
||||||
|
|
||||||
var (
|
|
||||||
licenseKindTag = licenseKindDependencyTag{}
|
|
||||||
)
|
|
||||||
|
|
||||||
func init() {
|
|
||||||
RegisterLicenseBuildComponents(InitRegistrationContext)
|
|
||||||
}
|
|
||||||
|
|
||||||
// Register the license module type.
|
|
||||||
func RegisterLicenseBuildComponents(ctx RegistrationContext) {
|
|
||||||
ctx.RegisterModuleType("license", LicenseFactory)
|
|
||||||
}
|
|
||||||
|
|
||||||
type licenseProperties struct {
|
|
||||||
// Specifies the kinds of license that apply.
|
|
||||||
License_kinds []string
|
|
||||||
// Specifies a short copyright notice to use for the license.
|
|
||||||
Copyright_notice *string
|
|
||||||
// Specifies the path or label for the text of the license.
|
|
||||||
License_text []string `android:"path"`
|
|
||||||
// Specifies the package name to which the license applies.
|
|
||||||
Package_name *string
|
|
||||||
// Specifies where this license can be used
|
|
||||||
Visibility []string
|
|
||||||
}
|
|
||||||
|
|
||||||
type licenseModule struct {
|
|
||||||
ModuleBase
|
|
||||||
DefaultableModuleBase
|
|
||||||
|
|
||||||
properties licenseProperties
|
|
||||||
}
|
|
||||||
|
|
||||||
func (m *licenseModule) DepsMutator(ctx BottomUpMutatorContext) {
|
|
||||||
ctx.AddVariationDependencies(nil, licenseKindTag, m.properties.License_kinds...)
|
|
||||||
}
|
|
||||||
|
|
||||||
func (m *licenseModule) GenerateAndroidBuildActions(ctx ModuleContext) {
|
|
||||||
// Nothing to do.
|
|
||||||
}
|
|
||||||
|
|
||||||
func LicenseFactory() Module {
|
|
||||||
module := &licenseModule{}
|
|
||||||
|
|
||||||
base := module.base()
|
|
||||||
module.AddProperties(&base.nameProperties, &module.properties)
|
|
||||||
|
|
||||||
base.generalProperties = module.GetProperties()
|
|
||||||
base.customizableProperties = module.GetProperties()
|
|
||||||
|
|
||||||
// The visibility property needs to be checked and parsed by the visibility module.
|
|
||||||
setPrimaryVisibilityProperty(module, "visibility", &module.properties.Visibility)
|
|
||||||
|
|
||||||
initAndroidModuleBase(module)
|
|
||||||
InitDefaultableModule(module)
|
|
||||||
|
|
||||||
return module
|
|
||||||
}
|
|
@@ -1,66 +0,0 @@
|
|||||||
// Copyright 2020 Google Inc. All rights reserved.
|
|
||||||
//
|
|
||||||
// Licensed under the Apache License, Version 2.0 (the "License");
|
|
||||||
// you may not use this file except in compliance with the License.
|
|
||||||
// You may obtain a copy of the License at
|
|
||||||
//
|
|
||||||
// http://www.apache.org/licenses/LICENSE-2.0
|
|
||||||
//
|
|
||||||
// Unless required by applicable law or agreed to in writing, software
|
|
||||||
// distributed under the License is distributed on an "AS IS" BASIS,
|
|
||||||
// WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied.
|
|
||||||
// See the License for the specific language governing permissions and
|
|
||||||
// limitations under the License.
|
|
||||||
|
|
||||||
package android
|
|
||||||
|
|
||||||
func init() {
|
|
||||||
RegisterLicenseKindBuildComponents(InitRegistrationContext)
|
|
||||||
}
|
|
||||||
|
|
||||||
// Register the license_kind module type.
|
|
||||||
func RegisterLicenseKindBuildComponents(ctx RegistrationContext) {
|
|
||||||
ctx.RegisterModuleType("license_kind", LicenseKindFactory)
|
|
||||||
}
|
|
||||||
|
|
||||||
type licenseKindProperties struct {
|
|
||||||
// Specifies the conditions for all licenses of the kind.
|
|
||||||
Conditions []string
|
|
||||||
// Specifies the url to the canonical license definition.
|
|
||||||
Url string
|
|
||||||
// Specifies where this license can be used
|
|
||||||
Visibility []string
|
|
||||||
}
|
|
||||||
|
|
||||||
type licenseKindModule struct {
|
|
||||||
ModuleBase
|
|
||||||
DefaultableModuleBase
|
|
||||||
|
|
||||||
properties licenseKindProperties
|
|
||||||
}
|
|
||||||
|
|
||||||
func (m *licenseKindModule) DepsMutator(ctx BottomUpMutatorContext) {
|
|
||||||
// Nothing to do.
|
|
||||||
}
|
|
||||||
|
|
||||||
func (m *licenseKindModule) GenerateAndroidBuildActions(ModuleContext) {
|
|
||||||
// Nothing to do.
|
|
||||||
}
|
|
||||||
|
|
||||||
func LicenseKindFactory() Module {
|
|
||||||
module := &licenseKindModule{}
|
|
||||||
|
|
||||||
base := module.base()
|
|
||||||
module.AddProperties(&base.nameProperties, &module.properties)
|
|
||||||
|
|
||||||
base.generalProperties = module.GetProperties()
|
|
||||||
base.customizableProperties = module.GetProperties()
|
|
||||||
|
|
||||||
// The visibility property needs to be checked and parsed by the visibility module.
|
|
||||||
setPrimaryVisibilityProperty(module, "visibility", &module.properties.Visibility)
|
|
||||||
|
|
||||||
initAndroidModuleBase(module)
|
|
||||||
InitDefaultableModule(module)
|
|
||||||
|
|
||||||
return module
|
|
||||||
}
|
|
@@ -1,174 +0,0 @@
|
|||||||
package android
|
|
||||||
|
|
||||||
import (
|
|
||||||
"testing"
|
|
||||||
|
|
||||||
"github.com/google/blueprint"
|
|
||||||
)
|
|
||||||
|
|
||||||
var licenseKindTests = []struct {
|
|
||||||
name string
|
|
||||||
fs map[string][]byte
|
|
||||||
expectedErrors []string
|
|
||||||
}{
|
|
||||||
{
|
|
||||||
name: "license_kind must not accept licenses property",
|
|
||||||
fs: map[string][]byte{
|
|
||||||
"top/Blueprints": []byte(`
|
|
||||||
license_kind {
|
|
||||||
name: "top_license",
|
|
||||||
licenses: ["other_license"],
|
|
||||||
}`),
|
|
||||||
},
|
|
||||||
expectedErrors: []string{
|
|
||||||
`top/Blueprints:4:14: unrecognized property "licenses"`,
|
|
||||||
},
|
|
||||||
},
|
|
||||||
{
|
|
||||||
name: "bad license_kind",
|
|
||||||
fs: map[string][]byte{
|
|
||||||
"top/Blueprints": []byte(`
|
|
||||||
license_kind {
|
|
||||||
name: "top_notice",
|
|
||||||
conditions: ["notice"],
|
|
||||||
}`),
|
|
||||||
"other/Blueprints": []byte(`
|
|
||||||
mock_license {
|
|
||||||
name: "other_notice",
|
|
||||||
license_kinds: ["notice"],
|
|
||||||
}`),
|
|
||||||
},
|
|
||||||
expectedErrors: []string{
|
|
||||||
`other/Blueprints:2:5: "other_notice" depends on undefined module "notice"`,
|
|
||||||
},
|
|
||||||
},
|
|
||||||
{
|
|
||||||
name: "good license kind",
|
|
||||||
fs: map[string][]byte{
|
|
||||||
"top/Blueprints": []byte(`
|
|
||||||
license_kind {
|
|
||||||
name: "top_by_exception_only",
|
|
||||||
conditions: ["by_exception_only"],
|
|
||||||
}
|
|
||||||
|
|
||||||
mock_license {
|
|
||||||
name: "top_proprietary",
|
|
||||||
license_kinds: ["top_by_exception_only"],
|
|
||||||
}`),
|
|
||||||
"other/Blueprints": []byte(`
|
|
||||||
mock_license {
|
|
||||||
name: "other_proprietary",
|
|
||||||
license_kinds: ["top_proprietary"],
|
|
||||||
}`),
|
|
||||||
},
|
|
||||||
},
|
|
||||||
{
|
|
||||||
name: "multiple license kinds",
|
|
||||||
fs: map[string][]byte{
|
|
||||||
"top/Blueprints": []byte(`
|
|
||||||
license_kind {
|
|
||||||
name: "top_notice",
|
|
||||||
conditions: ["notice"],
|
|
||||||
}
|
|
||||||
|
|
||||||
license_kind {
|
|
||||||
name: "top_by_exception_only",
|
|
||||||
conditions: ["by_exception_only"],
|
|
||||||
}
|
|
||||||
|
|
||||||
mock_license {
|
|
||||||
name: "top_allowed_as_notice",
|
|
||||||
license_kinds: ["top_notice"],
|
|
||||||
}
|
|
||||||
|
|
||||||
mock_license {
|
|
||||||
name: "top_proprietary",
|
|
||||||
license_kinds: ["top_by_exception_only"],
|
|
||||||
}`),
|
|
||||||
"other/Blueprints": []byte(`
|
|
||||||
mock_license {
|
|
||||||
name: "other_rule",
|
|
||||||
license_kinds: ["top_by_exception_only"],
|
|
||||||
}`),
|
|
||||||
},
|
|
||||||
},
|
|
||||||
}
|
|
||||||
|
|
||||||
func TestLicenseKind(t *testing.T) {
|
|
||||||
for _, test := range licenseKindTests {
|
|
||||||
t.Run(test.name, func(t *testing.T) {
|
|
||||||
_, errs := testLicenseKind(test.fs)
|
|
||||||
|
|
||||||
expectedErrors := test.expectedErrors
|
|
||||||
if expectedErrors == nil {
|
|
||||||
FailIfErrored(t, errs)
|
|
||||||
} else {
|
|
||||||
for _, expectedError := range expectedErrors {
|
|
||||||
FailIfNoMatchingErrors(t, expectedError, errs)
|
|
||||||
}
|
|
||||||
if len(errs) > len(expectedErrors) {
|
|
||||||
t.Errorf("additional errors found, expected %d, found %d", len(expectedErrors), len(errs))
|
|
||||||
for i, expectedError := range expectedErrors {
|
|
||||||
t.Errorf("expectedErrors[%d] = %s", i, expectedError)
|
|
||||||
}
|
|
||||||
for i, err := range errs {
|
|
||||||
t.Errorf("errs[%d] = %s", i, err)
|
|
||||||
}
|
|
||||||
}
|
|
||||||
}
|
|
||||||
})
|
|
||||||
}
|
|
||||||
}
|
|
||||||
|
|
||||||
func testLicenseKind(fs map[string][]byte) (*TestContext, []error) {
|
|
||||||
|
|
||||||
// Create a new config per test as license_kind information is stored in the config.
|
|
||||||
config := TestArchConfig(buildDir, nil, "", fs)
|
|
||||||
|
|
||||||
ctx := NewTestArchContext(config)
|
|
||||||
RegisterLicenseKindBuildComponents(ctx)
|
|
||||||
ctx.RegisterModuleType("mock_license", newMockLicenseModule)
|
|
||||||
ctx.Register()
|
|
||||||
|
|
||||||
_, errs := ctx.ParseBlueprintsFiles(".")
|
|
||||||
if len(errs) > 0 {
|
|
||||||
return ctx, errs
|
|
||||||
}
|
|
||||||
|
|
||||||
_, errs = ctx.PrepareBuildActions(config)
|
|
||||||
return ctx, errs
|
|
||||||
}
|
|
||||||
|
|
||||||
type mockLicenseProperties struct {
|
|
||||||
License_kinds []string
|
|
||||||
}
|
|
||||||
|
|
||||||
type mockLicenseModule struct {
|
|
||||||
ModuleBase
|
|
||||||
DefaultableModuleBase
|
|
||||||
|
|
||||||
properties mockLicenseProperties
|
|
||||||
}
|
|
||||||
|
|
||||||
func newMockLicenseModule() Module {
|
|
||||||
m := &mockLicenseModule{}
|
|
||||||
m.AddProperties(&m.properties)
|
|
||||||
InitAndroidArchModule(m, HostAndDeviceSupported, MultilibCommon)
|
|
||||||
InitDefaultableModule(m)
|
|
||||||
return m
|
|
||||||
}
|
|
||||||
|
|
||||||
type licensekindTag struct {
|
|
||||||
blueprint.BaseDependencyTag
|
|
||||||
}
|
|
||||||
|
|
||||||
func (j *mockLicenseModule) DepsMutator(ctx BottomUpMutatorContext) {
|
|
||||||
m, ok := ctx.Module().(Module)
|
|
||||||
if !ok {
|
|
||||||
return
|
|
||||||
}
|
|
||||||
ctx.AddDependency(m, licensekindTag{}, j.properties.License_kinds...)
|
|
||||||
}
|
|
||||||
|
|
||||||
func (p *mockLicenseModule) GenerateAndroidBuildActions(ModuleContext) {
|
|
||||||
}
|
|
@@ -1,233 +0,0 @@
|
|||||||
package android
|
|
||||||
|
|
||||||
import (
|
|
||||||
"testing"
|
|
||||||
)
|
|
||||||
|
|
||||||
var licenseTests = []struct {
|
|
||||||
name string
|
|
||||||
fs map[string][]byte
|
|
||||||
expectedErrors []string
|
|
||||||
}{
|
|
||||||
{
|
|
||||||
name: "license must not accept licenses property",
|
|
||||||
fs: map[string][]byte{
|
|
||||||
"top/Blueprints": []byte(`
|
|
||||||
license {
|
|
||||||
name: "top_license",
|
|
||||||
visibility: ["//visibility:private"],
|
|
||||||
licenses: ["other_license"],
|
|
||||||
}`),
|
|
||||||
},
|
|
||||||
expectedErrors: []string{
|
|
||||||
`top/Blueprints:5:14: unrecognized property "licenses"`,
|
|
||||||
},
|
|
||||||
},
|
|
||||||
{
|
|
||||||
name: "private license",
|
|
||||||
fs: map[string][]byte{
|
|
||||||
"top/Blueprints": []byte(`
|
|
||||||
license_kind {
|
|
||||||
name: "top_notice",
|
|
||||||
conditions: ["notice"],
|
|
||||||
visibility: ["//visibility:private"],
|
|
||||||
}
|
|
||||||
|
|
||||||
license {
|
|
||||||
name: "top_allowed_as_notice",
|
|
||||||
license_kinds: ["top_notice"],
|
|
||||||
visibility: ["//visibility:private"],
|
|
||||||
}`),
|
|
||||||
"other/Blueprints": []byte(`
|
|
||||||
rule {
|
|
||||||
name: "arule",
|
|
||||||
licenses: ["top_allowed_as_notice"],
|
|
||||||
}`),
|
|
||||||
"yetmore/Blueprints": []byte(`
|
|
||||||
package {
|
|
||||||
default_applicable_licenses: ["top_allowed_as_notice"],
|
|
||||||
}`),
|
|
||||||
},
|
|
||||||
expectedErrors: []string{
|
|
||||||
`other/Blueprints:2:5: module "arule": depends on //top:top_allowed_as_notice `+
|
|
||||||
`which is not visible to this module`,
|
|
||||||
`yetmore/Blueprints:2:5: module "//yetmore": depends on //top:top_allowed_as_notice `+
|
|
||||||
`which is not visible to this module`,
|
|
||||||
},
|
|
||||||
},
|
|
||||||
{
|
|
||||||
name: "must reference license_kind module",
|
|
||||||
fs: map[string][]byte{
|
|
||||||
"top/Blueprints": []byte(`
|
|
||||||
rule {
|
|
||||||
name: "top_by_exception_only",
|
|
||||||
}
|
|
||||||
|
|
||||||
license {
|
|
||||||
name: "top_proprietary",
|
|
||||||
license_kinds: ["top_by_exception_only"],
|
|
||||||
visibility: ["//visibility:public"],
|
|
||||||
}`),
|
|
||||||
},
|
|
||||||
expectedErrors: []string{
|
|
||||||
`top/Blueprints:6:5: module "top_proprietary": license_kinds property `+
|
|
||||||
`"top_by_exception_only" is not a license_kind module`,
|
|
||||||
},
|
|
||||||
},
|
|
||||||
{
|
|
||||||
name: "license_kind module must exist",
|
|
||||||
fs: map[string][]byte{
|
|
||||||
"top/Blueprints": []byte(`
|
|
||||||
license {
|
|
||||||
name: "top_notice_allowed",
|
|
||||||
license_kinds: ["top_notice"],
|
|
||||||
visibility: ["//visibility:public"],
|
|
||||||
}`),
|
|
||||||
},
|
|
||||||
expectedErrors: []string{
|
|
||||||
`top/Blueprints:2:5: "top_notice_allowed" depends on undefined module "top_notice"`,
|
|
||||||
},
|
|
||||||
},
|
|
||||||
{
|
|
||||||
name: "public license",
|
|
||||||
fs: map[string][]byte{
|
|
||||||
"top/Blueprints": []byte(`
|
|
||||||
license_kind {
|
|
||||||
name: "top_by_exception_only",
|
|
||||||
conditions: ["by_exception_only"],
|
|
||||||
visibility: ["//visibility:private"],
|
|
||||||
}
|
|
||||||
|
|
||||||
license {
|
|
||||||
name: "top_proprietary",
|
|
||||||
license_kinds: ["top_by_exception_only"],
|
|
||||||
visibility: ["//visibility:public"],
|
|
||||||
}`),
|
|
||||||
"other/Blueprints": []byte(`
|
|
||||||
rule {
|
|
||||||
name: "arule",
|
|
||||||
licenses: ["top_proprietary"],
|
|
||||||
}`),
|
|
||||||
"yetmore/Blueprints": []byte(`
|
|
||||||
package {
|
|
||||||
default_applicable_licenses: ["top_proprietary"],
|
|
||||||
}`),
|
|
||||||
},
|
|
||||||
},
|
|
||||||
{
|
|
||||||
name: "multiple licenses",
|
|
||||||
fs: map[string][]byte{
|
|
||||||
"top/Blueprints": []byte(`
|
|
||||||
package {
|
|
||||||
default_applicable_licenses: ["top_proprietary"],
|
|
||||||
}
|
|
||||||
|
|
||||||
license_kind {
|
|
||||||
name: "top_notice",
|
|
||||||
conditions: ["notice"],
|
|
||||||
}
|
|
||||||
|
|
||||||
license_kind {
|
|
||||||
name: "top_by_exception_only",
|
|
||||||
conditions: ["by_exception_only"],
|
|
||||||
visibility: ["//visibility:public"],
|
|
||||||
}
|
|
||||||
|
|
||||||
license {
|
|
||||||
name: "top_allowed_as_notice",
|
|
||||||
license_kinds: ["top_notice"],
|
|
||||||
}
|
|
||||||
|
|
||||||
license {
|
|
||||||
name: "top_proprietary",
|
|
||||||
license_kinds: ["top_by_exception_only"],
|
|
||||||
visibility: ["//visibility:public"],
|
|
||||||
}
|
|
||||||
rule {
|
|
||||||
name: "myrule",
|
|
||||||
licenses: ["top_allowed_as_notice", "top_proprietary"]
|
|
||||||
}`),
|
|
||||||
"other/Blueprints": []byte(`
|
|
||||||
rule {
|
|
||||||
name: "arule",
|
|
||||||
licenses: ["top_proprietary"],
|
|
||||||
}`),
|
|
||||||
"yetmore/Blueprints": []byte(`
|
|
||||||
package {
|
|
||||||
default_applicable_licenses: ["top_proprietary"],
|
|
||||||
}`),
|
|
||||||
},
|
|
||||||
},
|
|
||||||
}
|
|
||||||
|
|
||||||
func TestLicense(t *testing.T) {
|
|
||||||
for _, test := range licenseTests {
|
|
||||||
t.Run(test.name, func(t *testing.T) {
|
|
||||||
_, errs := testLicense(test.fs)
|
|
||||||
|
|
||||||
expectedErrors := test.expectedErrors
|
|
||||||
if expectedErrors == nil {
|
|
||||||
FailIfErrored(t, errs)
|
|
||||||
} else {
|
|
||||||
for _, expectedError := range expectedErrors {
|
|
||||||
FailIfNoMatchingErrors(t, expectedError, errs)
|
|
||||||
}
|
|
||||||
if len(errs) > len(expectedErrors) {
|
|
||||||
t.Errorf("additional errors found, expected %d, found %d", len(expectedErrors), len(errs))
|
|
||||||
for i, expectedError := range expectedErrors {
|
|
||||||
t.Errorf("expectedErrors[%d] = %s", i, expectedError)
|
|
||||||
}
|
|
||||||
for i, err := range errs {
|
|
||||||
t.Errorf("errs[%d] = %s", i, err)
|
|
||||||
}
|
|
||||||
}
|
|
||||||
}
|
|
||||||
})
|
|
||||||
}
|
|
||||||
}
|
|
||||||
|
|
||||||
func testLicense(fs map[string][]byte) (*TestContext, []error) {
|
|
||||||
|
|
||||||
// Create a new config per test as visibility information is stored in the config.
|
|
||||||
env := make(map[string]string)
|
|
||||||
env["ANDROID_REQUIRE_LICENSES"] = "1"
|
|
||||||
config := TestArchConfig(buildDir, env, "", fs)
|
|
||||||
|
|
||||||
ctx := NewTestArchContext(config)
|
|
||||||
RegisterPackageBuildComponents(ctx)
|
|
||||||
registerTestPrebuiltBuildComponents(ctx)
|
|
||||||
RegisterLicenseKindBuildComponents(ctx)
|
|
||||||
RegisterLicenseBuildComponents(ctx)
|
|
||||||
ctx.RegisterModuleType("rule", newMockRuleModule)
|
|
||||||
ctx.PreArchMutators(RegisterVisibilityRuleChecker)
|
|
||||||
ctx.PreArchMutators(RegisterLicensesPackageMapper)
|
|
||||||
ctx.PreArchMutators(RegisterDefaultsPreArchMutators)
|
|
||||||
ctx.PreArchMutators(RegisterLicensesPropertyGatherer)
|
|
||||||
ctx.PreArchMutators(RegisterVisibilityRuleGatherer)
|
|
||||||
ctx.PostDepsMutators(RegisterVisibilityRuleEnforcer)
|
|
||||||
ctx.PostDepsMutators(RegisterLicensesDependencyChecker)
|
|
||||||
ctx.Register()
|
|
||||||
|
|
||||||
_, errs := ctx.ParseBlueprintsFiles(".")
|
|
||||||
if len(errs) > 0 {
|
|
||||||
return ctx, errs
|
|
||||||
}
|
|
||||||
|
|
||||||
_, errs = ctx.PrepareBuildActions(config)
|
|
||||||
return ctx, errs
|
|
||||||
}
|
|
||||||
|
|
||||||
type mockRuleModule struct {
|
|
||||||
ModuleBase
|
|
||||||
DefaultableModuleBase
|
|
||||||
}
|
|
||||||
|
|
||||||
func newMockRuleModule() Module {
|
|
||||||
m := &mockRuleModule{}
|
|
||||||
InitAndroidModule(m)
|
|
||||||
InitDefaultableModule(m)
|
|
||||||
return m
|
|
||||||
}
|
|
||||||
|
|
||||||
func (p *mockRuleModule) GenerateAndroidBuildActions(ModuleContext) {
|
|
||||||
}
|
|
@@ -1,295 +0,0 @@
|
|||||||
// Copyright 2020 Google Inc. All rights reserved.
|
|
||||||
//
|
|
||||||
// Licensed under the Apache License, Version 2.0 (the "License");
|
|
||||||
// you may not use this file except in compliance with the License.
|
|
||||||
// You may obtain a copy of the License at
|
|
||||||
//
|
|
||||||
// http://www.apache.org/licenses/LICENSE-2.0
|
|
||||||
//
|
|
||||||
// Unless required by applicable law or agreed to in writing, software
|
|
||||||
// distributed under the License is distributed on an "AS IS" BASIS,
|
|
||||||
// WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied.
|
|
||||||
// See the License for the specific language governing permissions and
|
|
||||||
// limitations under the License.
|
|
||||||
|
|
||||||
package android
|
|
||||||
|
|
||||||
import (
|
|
||||||
"reflect"
|
|
||||||
"sync"
|
|
||||||
|
|
||||||
"github.com/google/blueprint"
|
|
||||||
)
|
|
||||||
|
|
||||||
// Adds cross-cutting licenses dependency to propagate license metadata through the build system.
|
|
||||||
//
|
|
||||||
// Stage 1 - bottom-up records package-level default_applicable_licenses property mapped by package name.
|
|
||||||
// Stage 2 - bottom-up converts licenses property or package default_applicable_licenses to dependencies.
|
|
||||||
// Stage 3 - bottom-up type-checks every added applicable license dependency and license_kind dependency.
|
|
||||||
// Stage 4 - GenerateBuildActions calculates properties for the union of license kinds, conditions and texts.
|
|
||||||
|
|
||||||
type licensesDependencyTag struct {
|
|
||||||
blueprint.BaseDependencyTag
|
|
||||||
}
|
|
||||||
|
|
||||||
var (
|
|
||||||
licensesTag = licensesDependencyTag{}
|
|
||||||
)
|
|
||||||
|
|
||||||
// Describes the property provided by a module to reference applicable licenses.
|
|
||||||
type applicableLicensesProperty interface {
|
|
||||||
// The name of the property. e.g. default_applicable_licenses or licenses
|
|
||||||
getName() string
|
|
||||||
// The values assigned to the property. (Must reference license modules.)
|
|
||||||
getStrings() []string
|
|
||||||
}
|
|
||||||
|
|
||||||
type applicableLicensesPropertyImpl struct {
|
|
||||||
name string
|
|
||||||
licensesProperty *[]string
|
|
||||||
}
|
|
||||||
|
|
||||||
func newApplicableLicensesProperty(name string, licensesProperty *[]string) applicableLicensesProperty {
|
|
||||||
return applicableLicensesPropertyImpl{
|
|
||||||
name: name,
|
|
||||||
licensesProperty: licensesProperty,
|
|
||||||
}
|
|
||||||
}
|
|
||||||
|
|
||||||
func (p applicableLicensesPropertyImpl) getName() string {
|
|
||||||
return p.name
|
|
||||||
}
|
|
||||||
|
|
||||||
func (p applicableLicensesPropertyImpl) getStrings() []string {
|
|
||||||
return *p.licensesProperty
|
|
||||||
}
|
|
||||||
|
|
||||||
// Set the primary applicable licenses property for a module.
|
|
||||||
func setPrimaryLicensesProperty(module Module, name string, licensesProperty *[]string) {
|
|
||||||
module.base().primaryLicensesProperty = newApplicableLicensesProperty(name, licensesProperty)
|
|
||||||
}
|
|
||||||
|
|
||||||
// Storage blob for a package's default_applicable_licenses mapped by package directory.
|
|
||||||
type licensesContainer struct {
|
|
||||||
licenses []string
|
|
||||||
}
|
|
||||||
|
|
||||||
func (r licensesContainer) getLicenses() []string {
|
|
||||||
return r.licenses
|
|
||||||
}
|
|
||||||
|
|
||||||
var packageDefaultLicensesMap = NewOnceKey("packageDefaultLicensesMap")
|
|
||||||
|
|
||||||
// The map from package dir name to default applicable licenses as a licensesContainer.
|
|
||||||
func moduleToPackageDefaultLicensesMap(config Config) *sync.Map {
|
|
||||||
return config.Once(packageDefaultLicensesMap, func() interface{} {
|
|
||||||
return &sync.Map{}
|
|
||||||
}).(*sync.Map)
|
|
||||||
}
|
|
||||||
|
|
||||||
// Registers the function that maps each package to its default_applicable_licenses.
|
|
||||||
//
|
|
||||||
// This goes before defaults expansion so the defaults can pick up the package default.
|
|
||||||
func RegisterLicensesPackageMapper(ctx RegisterMutatorsContext) {
|
|
||||||
ctx.BottomUp("licensesPackageMapper", licensesPackageMapper).Parallel()
|
|
||||||
}
|
|
||||||
|
|
||||||
// Registers the function that gathers the license dependencies for each module.
|
|
||||||
//
|
|
||||||
// This goes after defaults expansion so that it can pick up default licenses and before visibility enforcement.
|
|
||||||
func RegisterLicensesPropertyGatherer(ctx RegisterMutatorsContext) {
|
|
||||||
ctx.BottomUp("licensesPropertyGatherer", licensesPropertyGatherer).Parallel()
|
|
||||||
}
|
|
||||||
|
|
||||||
// Registers the function that verifies the licenses and license_kinds dependency types for each module.
|
|
||||||
func RegisterLicensesDependencyChecker(ctx RegisterMutatorsContext) {
|
|
||||||
ctx.BottomUp("licensesPropertyChecker", licensesDependencyChecker).Parallel()
|
|
||||||
}
|
|
||||||
|
|
||||||
// Maps each package to its default applicable licenses.
|
|
||||||
func licensesPackageMapper(ctx BottomUpMutatorContext) {
|
|
||||||
p, ok := ctx.Module().(*packageModule)
|
|
||||||
if !ok {
|
|
||||||
return
|
|
||||||
}
|
|
||||||
|
|
||||||
licenses := getLicenses(ctx, p)
|
|
||||||
|
|
||||||
dir := ctx.ModuleDir()
|
|
||||||
c := makeLicensesContainer(licenses)
|
|
||||||
moduleToPackageDefaultLicensesMap(ctx.Config()).Store(dir, c)
|
|
||||||
}
|
|
||||||
|
|
||||||
// Copies the default_applicable_licenses property values for mapping by package directory.
|
|
||||||
func makeLicensesContainer(propVals []string) licensesContainer {
|
|
||||||
licenses := make([]string, 0, len(propVals))
|
|
||||||
licenses = append(licenses, propVals...)
|
|
||||||
|
|
||||||
return licensesContainer{licenses}
|
|
||||||
}
|
|
||||||
|
|
||||||
// Gathers the applicable licenses into dependency references after defaults expansion.
|
|
||||||
func licensesPropertyGatherer(ctx BottomUpMutatorContext) {
|
|
||||||
m, ok := ctx.Module().(Module)
|
|
||||||
if !ok {
|
|
||||||
return
|
|
||||||
}
|
|
||||||
|
|
||||||
if exemptFromRequiredApplicableLicensesProperty(m) {
|
|
||||||
return
|
|
||||||
}
|
|
||||||
|
|
||||||
licenses := getLicenses(ctx, m)
|
|
||||||
|
|
||||||
ctx.AddVariationDependencies(nil, licensesTag, licenses...)
|
|
||||||
}
|
|
||||||
|
|
||||||
// Verifies the license and license_kind dependencies are each the correct kind of module.
|
|
||||||
func licensesDependencyChecker(ctx BottomUpMutatorContext) {
|
|
||||||
m, ok := ctx.Module().(Module)
|
|
||||||
if !ok {
|
|
||||||
return
|
|
||||||
}
|
|
||||||
|
|
||||||
// license modules have no licenses, but license_kinds must refer to license_kind modules
|
|
||||||
if _, ok := m.(*licenseModule); ok {
|
|
||||||
for _, module := range ctx.GetDirectDepsWithTag(licenseKindTag) {
|
|
||||||
if _, ok := module.(*licenseKindModule); !ok {
|
|
||||||
ctx.ModuleErrorf("license_kinds property %q is not a license_kind module", ctx.OtherModuleName(module))
|
|
||||||
}
|
|
||||||
}
|
|
||||||
return
|
|
||||||
}
|
|
||||||
|
|
||||||
if exemptFromRequiredApplicableLicensesProperty(m) {
|
|
||||||
return
|
|
||||||
}
|
|
||||||
|
|
||||||
for _, module := range ctx.GetDirectDepsWithTag(licensesTag) {
|
|
||||||
if _, ok := module.(*licenseModule); !ok {
|
|
||||||
propertyName := "licenses"
|
|
||||||
primaryProperty := m.base().primaryLicensesProperty
|
|
||||||
if primaryProperty != nil {
|
|
||||||
propertyName = primaryProperty.getName()
|
|
||||||
}
|
|
||||||
ctx.ModuleErrorf("%s property %q is not a license module", propertyName, ctx.OtherModuleName(module))
|
|
||||||
}
|
|
||||||
}
|
|
||||||
}
|
|
||||||
|
|
||||||
// Flattens license and license_kind dependencies into calculated properties.
|
|
||||||
//
|
|
||||||
// Re-validates applicable licenses properties refer only to license modules and license_kinds properties refer
|
|
||||||
// only to license_kind modules.
|
|
||||||
func licensesPropertyFlattener(ctx ModuleContext) {
|
|
||||||
m, ok := ctx.Module().(Module)
|
|
||||||
if !ok {
|
|
||||||
return
|
|
||||||
}
|
|
||||||
|
|
||||||
// license modules have no licenses, but license_kinds must refer to license_kind modules
|
|
||||||
if l, ok := m.(*licenseModule); ok {
|
|
||||||
mergeProps(&m.base().commonProperties.Effective_licenses, ctx.ModuleName())
|
|
||||||
mergeProps(&m.base().commonProperties.Effective_license_text, PathsForModuleSrc(ctx, l.properties.License_text).Strings()...)
|
|
||||||
for _, module := range ctx.GetDirectDepsWithTag(licenseKindTag) {
|
|
||||||
if lk, ok := module.(*licenseKindModule); ok {
|
|
||||||
mergeProps(&m.base().commonProperties.Effective_license_conditions, lk.properties.Conditions...)
|
|
||||||
mergeProps(&m.base().commonProperties.Effective_license_kinds, ctx.OtherModuleName(module))
|
|
||||||
} else {
|
|
||||||
ctx.ModuleErrorf("license_kinds property %q is not a license_kind module", ctx.OtherModuleName(module))
|
|
||||||
}
|
|
||||||
}
|
|
||||||
return
|
|
||||||
}
|
|
||||||
|
|
||||||
if exemptFromRequiredApplicableLicensesProperty(m) {
|
|
||||||
return
|
|
||||||
}
|
|
||||||
|
|
||||||
for _, module := range ctx.GetDirectDepsWithTag(licensesTag) {
|
|
||||||
if l, ok := module.(*licenseModule); ok {
|
|
||||||
if m.base().commonProperties.Effective_package_name == nil && l.properties.Package_name != nil {
|
|
||||||
m.base().commonProperties.Effective_package_name = l.properties.Package_name
|
|
||||||
}
|
|
||||||
mergeProps(&m.base().commonProperties.Effective_licenses, module.base().commonProperties.Effective_licenses...)
|
|
||||||
mergeProps(&m.base().commonProperties.Effective_license_text, module.base().commonProperties.Effective_license_text...)
|
|
||||||
mergeProps(&m.base().commonProperties.Effective_license_kinds, module.base().commonProperties.Effective_license_kinds...)
|
|
||||||
mergeProps(&m.base().commonProperties.Effective_license_conditions, module.base().commonProperties.Effective_license_conditions...)
|
|
||||||
} else {
|
|
||||||
propertyName := "licenses"
|
|
||||||
primaryProperty := m.base().primaryLicensesProperty
|
|
||||||
if primaryProperty != nil {
|
|
||||||
propertyName = primaryProperty.getName()
|
|
||||||
}
|
|
||||||
ctx.ModuleErrorf("%s property %q is not a license module", propertyName, ctx.OtherModuleName(module))
|
|
||||||
}
|
|
||||||
}
|
|
||||||
}
|
|
||||||
|
|
||||||
// Update a property string array with a distinct union of its values and a list of new values.
|
|
||||||
func mergeProps(prop *[]string, values ...string) {
|
|
||||||
s := make(map[string]bool)
|
|
||||||
for _, v := range *prop {
|
|
||||||
s[v] = true
|
|
||||||
}
|
|
||||||
for _, v := range values {
|
|
||||||
s[v] = true
|
|
||||||
}
|
|
||||||
*prop = []string{}
|
|
||||||
*prop = append(*prop, SortedStringKeys(s)...)
|
|
||||||
}
|
|
||||||
|
|
||||||
// Get the licenses property falling back to the package default.
|
|
||||||
func getLicenses(ctx BaseModuleContext, module Module) []string {
|
|
||||||
if exemptFromRequiredApplicableLicensesProperty(module) {
|
|
||||||
return nil
|
|
||||||
}
|
|
||||||
|
|
||||||
primaryProperty := module.base().primaryLicensesProperty
|
|
||||||
if primaryProperty == nil {
|
|
||||||
if ctx.Config().IsEnvTrue("ANDROID_REQUIRE_LICENSES") {
|
|
||||||
ctx.ModuleErrorf("module type %q must have an applicable licenses property", ctx.OtherModuleType(module))
|
|
||||||
}
|
|
||||||
return nil
|
|
||||||
}
|
|
||||||
|
|
||||||
licenses := primaryProperty.getStrings()
|
|
||||||
if len(licenses) > 0 {
|
|
||||||
s := make(map[string]bool)
|
|
||||||
for _, l := range licenses {
|
|
||||||
if _, ok := s[l]; ok {
|
|
||||||
ctx.ModuleErrorf("duplicate %q %s", l, primaryProperty.getName())
|
|
||||||
}
|
|
||||||
s[l] = true
|
|
||||||
}
|
|
||||||
return licenses
|
|
||||||
}
|
|
||||||
|
|
||||||
dir := ctx.OtherModuleDir(module)
|
|
||||||
|
|
||||||
moduleToApplicableLicenses := moduleToPackageDefaultLicensesMap(ctx.Config())
|
|
||||||
value, ok := moduleToApplicableLicenses.Load(dir)
|
|
||||||
var c licensesContainer
|
|
||||||
if ok {
|
|
||||||
c = value.(licensesContainer)
|
|
||||||
} else {
|
|
||||||
c = licensesContainer{}
|
|
||||||
}
|
|
||||||
return c.getLicenses()
|
|
||||||
}
|
|
||||||
|
|
||||||
// Returns whether a module is an allowed list of modules that do not have or need applicable licenses.
|
|
||||||
func exemptFromRequiredApplicableLicensesProperty(module Module) bool {
|
|
||||||
switch reflect.TypeOf(module).String() {
|
|
||||||
case "*android.licenseModule": // is a license, doesn't need one
|
|
||||||
case "*android.licenseKindModule": // is a license, doesn't need one
|
|
||||||
case "*android.NamespaceModule": // just partitions things, doesn't add anything
|
|
||||||
case "*android.soongConfigModuleTypeModule": // creates aliases for modules with licenses
|
|
||||||
case "*android.soongConfigModuleTypeImport": // creates aliases for modules with licenses
|
|
||||||
case "*android.soongConfigStringVariableDummyModule": // used for creating aliases
|
|
||||||
case "*android.SoongConfigBoolVariableDummyModule": // used for creating aliases
|
|
||||||
default:
|
|
||||||
return false
|
|
||||||
}
|
|
||||||
return true
|
|
||||||
}
|
|
@@ -1,863 +0,0 @@
|
|||||||
package android
|
|
||||||
|
|
||||||
import (
|
|
||||||
"testing"
|
|
||||||
|
|
||||||
"github.com/google/blueprint"
|
|
||||||
)
|
|
||||||
|
|
||||||
var licensesTests = []struct {
|
|
||||||
name string
|
|
||||||
fs map[string][]byte
|
|
||||||
expectedErrors []string
|
|
||||||
effectiveLicenses map[string][]string
|
|
||||||
effectiveInheritedLicenses map[string][]string
|
|
||||||
effectivePackage map[string]string
|
|
||||||
effectiveNotices map[string][]string
|
|
||||||
effectiveKinds map[string][]string
|
|
||||||
effectiveConditions map[string][]string
|
|
||||||
}{
|
|
||||||
{
|
|
||||||
name: "invalid module type without licenses property",
|
|
||||||
fs: map[string][]byte{
|
|
||||||
"top/Blueprints": []byte(`
|
|
||||||
mock_bad_module {
|
|
||||||
name: "libexample",
|
|
||||||
}`),
|
|
||||||
},
|
|
||||||
expectedErrors: []string{`module type "mock_bad_module" must have an applicable licenses property`},
|
|
||||||
},
|
|
||||||
{
|
|
||||||
name: "license must exist",
|
|
||||||
fs: map[string][]byte{
|
|
||||||
"top/Blueprints": []byte(`
|
|
||||||
mock_library {
|
|
||||||
name: "libexample",
|
|
||||||
licenses: ["notice"],
|
|
||||||
}`),
|
|
||||||
},
|
|
||||||
expectedErrors: []string{`"libexample" depends on undefined module "notice"`},
|
|
||||||
},
|
|
||||||
{
|
|
||||||
name: "all good",
|
|
||||||
fs: map[string][]byte{
|
|
||||||
"top/Blueprints": []byte(`
|
|
||||||
license_kind {
|
|
||||||
name: "notice",
|
|
||||||
conditions: ["shownotice"],
|
|
||||||
}
|
|
||||||
|
|
||||||
license {
|
|
||||||
name: "top_Apache2",
|
|
||||||
license_kinds: ["notice"],
|
|
||||||
package_name: "topDog",
|
|
||||||
license_text: ["LICENSE", "NOTICE"],
|
|
||||||
}
|
|
||||||
|
|
||||||
mock_library {
|
|
||||||
name: "libexample1",
|
|
||||||
licenses: ["top_Apache2"],
|
|
||||||
}`),
|
|
||||||
"top/nested/Blueprints": []byte(`
|
|
||||||
mock_library {
|
|
||||||
name: "libnested",
|
|
||||||
licenses: ["top_Apache2"],
|
|
||||||
}`),
|
|
||||||
"other/Blueprints": []byte(`
|
|
||||||
mock_library {
|
|
||||||
name: "libother",
|
|
||||||
licenses: ["top_Apache2"],
|
|
||||||
}`),
|
|
||||||
},
|
|
||||||
effectiveLicenses: map[string][]string{
|
|
||||||
"libexample1": []string{"top_Apache2"},
|
|
||||||
"libnested": []string{"top_Apache2"},
|
|
||||||
"libother": []string{"top_Apache2"},
|
|
||||||
},
|
|
||||||
effectiveKinds: map[string][]string{
|
|
||||||
"libexample1": []string{"notice"},
|
|
||||||
"libnested": []string{"notice"},
|
|
||||||
"libother": []string{"notice"},
|
|
||||||
},
|
|
||||||
effectivePackage: map[string]string{
|
|
||||||
"libexample1": "topDog",
|
|
||||||
"libnested": "topDog",
|
|
||||||
"libother": "topDog",
|
|
||||||
},
|
|
||||||
effectiveConditions: map[string][]string{
|
|
||||||
"libexample1": []string{"shownotice"},
|
|
||||||
"libnested": []string{"shownotice"},
|
|
||||||
"libother": []string{"shownotice"},
|
|
||||||
},
|
|
||||||
effectiveNotices: map[string][]string{
|
|
||||||
"libexample1": []string{"top/LICENSE", "top/NOTICE"},
|
|
||||||
"libnested": []string{"top/LICENSE", "top/NOTICE"},
|
|
||||||
"libother": []string{"top/LICENSE", "top/NOTICE"},
|
|
||||||
},
|
|
||||||
},
|
|
||||||
|
|
||||||
// Defaults propagation tests
|
|
||||||
{
|
|
||||||
// Check that licenses is the union of the defaults modules.
|
|
||||||
name: "defaults union, basic",
|
|
||||||
fs: map[string][]byte{
|
|
||||||
"top/Blueprints": []byte(`
|
|
||||||
license_kind {
|
|
||||||
name: "top_notice",
|
|
||||||
conditions: ["notice"],
|
|
||||||
}
|
|
||||||
|
|
||||||
license {
|
|
||||||
name: "top_other",
|
|
||||||
license_kinds: ["top_notice"],
|
|
||||||
}
|
|
||||||
|
|
||||||
mock_defaults {
|
|
||||||
name: "libexample_defaults",
|
|
||||||
licenses: ["top_other"],
|
|
||||||
}
|
|
||||||
mock_library {
|
|
||||||
name: "libexample",
|
|
||||||
licenses: ["nested_other"],
|
|
||||||
defaults: ["libexample_defaults"],
|
|
||||||
}
|
|
||||||
mock_library {
|
|
||||||
name: "libsamepackage",
|
|
||||||
deps: ["libexample"],
|
|
||||||
}`),
|
|
||||||
"top/nested/Blueprints": []byte(`
|
|
||||||
license_kind {
|
|
||||||
name: "nested_notice",
|
|
||||||
conditions: ["notice"],
|
|
||||||
}
|
|
||||||
|
|
||||||
license {
|
|
||||||
name: "nested_other",
|
|
||||||
license_kinds: ["nested_notice"],
|
|
||||||
}
|
|
||||||
|
|
||||||
mock_library {
|
|
||||||
name: "libnested",
|
|
||||||
deps: ["libexample"],
|
|
||||||
}`),
|
|
||||||
"other/Blueprints": []byte(`
|
|
||||||
mock_library {
|
|
||||||
name: "libother",
|
|
||||||
deps: ["libexample"],
|
|
||||||
}`),
|
|
||||||
},
|
|
||||||
effectiveLicenses: map[string][]string{
|
|
||||||
"libexample": []string{"nested_other", "top_other"},
|
|
||||||
"libsamepackage": []string{},
|
|
||||||
"libnested": []string{},
|
|
||||||
"libother": []string{},
|
|
||||||
},
|
|
||||||
effectiveInheritedLicenses: map[string][]string{
|
|
||||||
"libexample": []string{"nested_other", "top_other"},
|
|
||||||
"libsamepackage": []string{"nested_other", "top_other"},
|
|
||||||
"libnested": []string{"nested_other", "top_other"},
|
|
||||||
"libother": []string{"nested_other", "top_other"},
|
|
||||||
},
|
|
||||||
effectiveKinds: map[string][]string{
|
|
||||||
"libexample": []string{"nested_notice", "top_notice"},
|
|
||||||
"libsamepackage": []string{},
|
|
||||||
"libnested": []string{},
|
|
||||||
"libother": []string{},
|
|
||||||
},
|
|
||||||
effectiveConditions: map[string][]string{
|
|
||||||
"libexample": []string{"notice"},
|
|
||||||
"libsamepackage": []string{},
|
|
||||||
"libnested": []string{},
|
|
||||||
"libother": []string{},
|
|
||||||
},
|
|
||||||
},
|
|
||||||
{
|
|
||||||
name: "defaults union, multiple defaults",
|
|
||||||
fs: map[string][]byte{
|
|
||||||
"top/Blueprints": []byte(`
|
|
||||||
license {
|
|
||||||
name: "top",
|
|
||||||
}
|
|
||||||
mock_defaults {
|
|
||||||
name: "libexample_defaults_1",
|
|
||||||
licenses: ["other"],
|
|
||||||
}
|
|
||||||
mock_defaults {
|
|
||||||
name: "libexample_defaults_2",
|
|
||||||
licenses: ["top_nested"],
|
|
||||||
}
|
|
||||||
mock_library {
|
|
||||||
name: "libexample",
|
|
||||||
defaults: ["libexample_defaults_1", "libexample_defaults_2"],
|
|
||||||
}
|
|
||||||
mock_library {
|
|
||||||
name: "libsamepackage",
|
|
||||||
deps: ["libexample"],
|
|
||||||
}`),
|
|
||||||
"top/nested/Blueprints": []byte(`
|
|
||||||
license {
|
|
||||||
name: "top_nested",
|
|
||||||
license_text: ["LICENSE.txt"],
|
|
||||||
}
|
|
||||||
mock_library {
|
|
||||||
name: "libnested",
|
|
||||||
deps: ["libexample"],
|
|
||||||
}`),
|
|
||||||
"other/Blueprints": []byte(`
|
|
||||||
license {
|
|
||||||
name: "other",
|
|
||||||
}
|
|
||||||
mock_library {
|
|
||||||
name: "libother",
|
|
||||||
deps: ["libexample"],
|
|
||||||
}`),
|
|
||||||
"outsider/Blueprints": []byte(`
|
|
||||||
mock_library {
|
|
||||||
name: "liboutsider",
|
|
||||||
deps: ["libexample"],
|
|
||||||
}`),
|
|
||||||
},
|
|
||||||
effectiveLicenses: map[string][]string{
|
|
||||||
"libexample": []string{"other", "top_nested"},
|
|
||||||
"libsamepackage": []string{},
|
|
||||||
"libnested": []string{},
|
|
||||||
"libother": []string{},
|
|
||||||
"liboutsider": []string{},
|
|
||||||
},
|
|
||||||
effectiveInheritedLicenses: map[string][]string{
|
|
||||||
"libexample": []string{"other", "top_nested"},
|
|
||||||
"libsamepackage": []string{"other", "top_nested"},
|
|
||||||
"libnested": []string{"other", "top_nested"},
|
|
||||||
"libother": []string{"other", "top_nested"},
|
|
||||||
"liboutsider": []string{"other", "top_nested"},
|
|
||||||
},
|
|
||||||
effectiveKinds: map[string][]string{
|
|
||||||
"libexample": []string{},
|
|
||||||
"libsamepackage": []string{},
|
|
||||||
"libnested": []string{},
|
|
||||||
"libother": []string{},
|
|
||||||
"liboutsider": []string{},
|
|
||||||
},
|
|
||||||
effectiveNotices: map[string][]string{
|
|
||||||
"libexample": []string{"top/nested/LICENSE.txt"},
|
|
||||||
"libsamepackage": []string{},
|
|
||||||
"libnested": []string{},
|
|
||||||
"libother": []string{},
|
|
||||||
"liboutsider": []string{},
|
|
||||||
},
|
|
||||||
},
|
|
||||||
|
|
||||||
// Defaults module's defaults_licenses tests
|
|
||||||
{
|
|
||||||
name: "defaults_licenses invalid",
|
|
||||||
fs: map[string][]byte{
|
|
||||||
"top/Blueprints": []byte(`
|
|
||||||
mock_defaults {
|
|
||||||
name: "top_defaults",
|
|
||||||
licenses: ["notice"],
|
|
||||||
}`),
|
|
||||||
},
|
|
||||||
expectedErrors: []string{`"top_defaults" depends on undefined module "notice"`},
|
|
||||||
},
|
|
||||||
{
|
|
||||||
name: "defaults_licenses overrides package default",
|
|
||||||
fs: map[string][]byte{
|
|
||||||
"top/Blueprints": []byte(`
|
|
||||||
package {
|
|
||||||
default_applicable_licenses: ["by_exception_only"],
|
|
||||||
}
|
|
||||||
license {
|
|
||||||
name: "by_exception_only",
|
|
||||||
}
|
|
||||||
license {
|
|
||||||
name: "notice",
|
|
||||||
}
|
|
||||||
mock_defaults {
|
|
||||||
name: "top_defaults",
|
|
||||||
licenses: ["notice"],
|
|
||||||
}
|
|
||||||
mock_library {
|
|
||||||
name: "libexample",
|
|
||||||
}
|
|
||||||
mock_library {
|
|
||||||
name: "libdefaults",
|
|
||||||
defaults: ["top_defaults"],
|
|
||||||
}`),
|
|
||||||
},
|
|
||||||
effectiveLicenses: map[string][]string{
|
|
||||||
"libexample": []string{"by_exception_only"},
|
|
||||||
"libdefaults": []string{"notice"},
|
|
||||||
},
|
|
||||||
effectiveInheritedLicenses: map[string][]string{
|
|
||||||
"libexample": []string{"by_exception_only"},
|
|
||||||
"libdefaults": []string{"notice"},
|
|
||||||
},
|
|
||||||
},
|
|
||||||
|
|
||||||
// Package default_applicable_licenses tests
|
|
||||||
{
|
|
||||||
name: "package default_applicable_licenses must exist",
|
|
||||||
fs: map[string][]byte{
|
|
||||||
"top/Blueprints": []byte(`
|
|
||||||
package {
|
|
||||||
default_applicable_licenses: ["notice"],
|
|
||||||
}`),
|
|
||||||
},
|
|
||||||
expectedErrors: []string{`"//top" depends on undefined module "notice"`},
|
|
||||||
},
|
|
||||||
{
|
|
||||||
// This test relies on the default licenses being legacy_public.
|
|
||||||
name: "package default_applicable_licenses property used when no licenses specified",
|
|
||||||
fs: map[string][]byte{
|
|
||||||
"top/Blueprints": []byte(`
|
|
||||||
package {
|
|
||||||
default_applicable_licenses: ["top_notice"],
|
|
||||||
}
|
|
||||||
|
|
||||||
license {
|
|
||||||
name: "top_notice",
|
|
||||||
}
|
|
||||||
mock_library {
|
|
||||||
name: "libexample",
|
|
||||||
}`),
|
|
||||||
"outsider/Blueprints": []byte(`
|
|
||||||
mock_library {
|
|
||||||
name: "liboutsider",
|
|
||||||
deps: ["libexample"],
|
|
||||||
}`),
|
|
||||||
},
|
|
||||||
effectiveLicenses: map[string][]string{
|
|
||||||
"libexample": []string{"top_notice"},
|
|
||||||
"liboutsider": []string{},
|
|
||||||
},
|
|
||||||
effectiveInheritedLicenses: map[string][]string{
|
|
||||||
"libexample": []string{"top_notice"},
|
|
||||||
"liboutsider": []string{"top_notice"},
|
|
||||||
},
|
|
||||||
},
|
|
||||||
{
|
|
||||||
name: "package default_applicable_licenses not inherited to subpackages",
|
|
||||||
fs: map[string][]byte{
|
|
||||||
"top/Blueprints": []byte(`
|
|
||||||
package {
|
|
||||||
default_applicable_licenses: ["top_notice"],
|
|
||||||
}
|
|
||||||
license {
|
|
||||||
name: "top_notice",
|
|
||||||
}
|
|
||||||
mock_library {
|
|
||||||
name: "libexample",
|
|
||||||
}`),
|
|
||||||
"top/nested/Blueprints": []byte(`
|
|
||||||
package {
|
|
||||||
default_applicable_licenses: ["outsider"],
|
|
||||||
}
|
|
||||||
|
|
||||||
mock_library {
|
|
||||||
name: "libnested",
|
|
||||||
}`),
|
|
||||||
"top/other/Blueprints": []byte(`
|
|
||||||
mock_library {
|
|
||||||
name: "libother",
|
|
||||||
}`),
|
|
||||||
"outsider/Blueprints": []byte(`
|
|
||||||
license {
|
|
||||||
name: "outsider",
|
|
||||||
}
|
|
||||||
mock_library {
|
|
||||||
name: "liboutsider",
|
|
||||||
deps: ["libexample", "libother", "libnested"],
|
|
||||||
}`),
|
|
||||||
},
|
|
||||||
effectiveLicenses: map[string][]string{
|
|
||||||
"libexample": []string{"top_notice"},
|
|
||||||
"libnested": []string{"outsider"},
|
|
||||||
"libother": []string{},
|
|
||||||
"liboutsider": []string{},
|
|
||||||
},
|
|
||||||
effectiveInheritedLicenses: map[string][]string{
|
|
||||||
"libexample": []string{"top_notice"},
|
|
||||||
"libnested": []string{"outsider"},
|
|
||||||
"libother": []string{},
|
|
||||||
"liboutsider": []string{"top_notice", "outsider"},
|
|
||||||
},
|
|
||||||
},
|
|
||||||
{
|
|
||||||
name: "verify that prebuilt dependencies are included",
|
|
||||||
fs: map[string][]byte{
|
|
||||||
"prebuilts/Blueprints": []byte(`
|
|
||||||
license {
|
|
||||||
name: "prebuilt"
|
|
||||||
}
|
|
||||||
prebuilt {
|
|
||||||
name: "module",
|
|
||||||
licenses: ["prebuilt"],
|
|
||||||
}`),
|
|
||||||
"top/sources/source_file": nil,
|
|
||||||
"top/sources/Blueprints": []byte(`
|
|
||||||
license {
|
|
||||||
name: "top_sources"
|
|
||||||
}
|
|
||||||
source {
|
|
||||||
name: "module",
|
|
||||||
licenses: ["top_sources"],
|
|
||||||
}`),
|
|
||||||
"top/other/source_file": nil,
|
|
||||||
"top/other/Blueprints": []byte(`
|
|
||||||
source {
|
|
||||||
name: "other",
|
|
||||||
deps: [":module"],
|
|
||||||
}`),
|
|
||||||
},
|
|
||||||
effectiveLicenses: map[string][]string{
|
|
||||||
"other": []string{},
|
|
||||||
},
|
|
||||||
effectiveInheritedLicenses: map[string][]string{
|
|
||||||
"other": []string{"prebuilt", "top_sources"},
|
|
||||||
},
|
|
||||||
},
|
|
||||||
{
|
|
||||||
name: "verify that prebuilt dependencies are ignored for licenses reasons (preferred)",
|
|
||||||
fs: map[string][]byte{
|
|
||||||
"prebuilts/Blueprints": []byte(`
|
|
||||||
license {
|
|
||||||
name: "prebuilt"
|
|
||||||
}
|
|
||||||
prebuilt {
|
|
||||||
name: "module",
|
|
||||||
licenses: ["prebuilt"],
|
|
||||||
prefer: true,
|
|
||||||
}`),
|
|
||||||
"top/sources/source_file": nil,
|
|
||||||
"top/sources/Blueprints": []byte(`
|
|
||||||
license {
|
|
||||||
name: "top_sources"
|
|
||||||
}
|
|
||||||
source {
|
|
||||||
name: "module",
|
|
||||||
licenses: ["top_sources"],
|
|
||||||
}`),
|
|
||||||
"top/other/source_file": nil,
|
|
||||||
"top/other/Blueprints": []byte(`
|
|
||||||
source {
|
|
||||||
name: "other",
|
|
||||||
deps: [":module"],
|
|
||||||
}`),
|
|
||||||
},
|
|
||||||
effectiveLicenses: map[string][]string{
|
|
||||||
"other": []string{},
|
|
||||||
},
|
|
||||||
effectiveInheritedLicenses: map[string][]string{
|
|
||||||
"module": []string{"prebuilt", "top_sources"},
|
|
||||||
"other": []string{"prebuilt", "top_sources"},
|
|
||||||
},
|
|
||||||
},
|
|
||||||
}
|
|
||||||
|
|
||||||
func TestLicenses(t *testing.T) {
|
|
||||||
for _, test := range licensesTests {
|
|
||||||
t.Run(test.name, func(t *testing.T) {
|
|
||||||
ctx, errs := testLicenses(buildDir, test.fs)
|
|
||||||
|
|
||||||
CheckErrorsAgainstExpectations(t, errs, test.expectedErrors)
|
|
||||||
|
|
||||||
if test.effectiveLicenses != nil {
|
|
||||||
checkEffectiveLicenses(t, ctx, test.effectiveLicenses)
|
|
||||||
}
|
|
||||||
|
|
||||||
if test.effectivePackage != nil {
|
|
||||||
checkEffectivePackage(t, ctx, test.effectivePackage)
|
|
||||||
}
|
|
||||||
|
|
||||||
if test.effectiveNotices != nil {
|
|
||||||
checkEffectiveNotices(t, ctx, test.effectiveNotices)
|
|
||||||
}
|
|
||||||
|
|
||||||
if test.effectiveKinds != nil {
|
|
||||||
checkEffectiveKinds(t, ctx, test.effectiveKinds)
|
|
||||||
}
|
|
||||||
|
|
||||||
if test.effectiveConditions != nil {
|
|
||||||
checkEffectiveConditions(t, ctx, test.effectiveConditions)
|
|
||||||
}
|
|
||||||
|
|
||||||
if test.effectiveInheritedLicenses != nil {
|
|
||||||
checkEffectiveInheritedLicenses(t, ctx, test.effectiveInheritedLicenses)
|
|
||||||
}
|
|
||||||
})
|
|
||||||
}
|
|
||||||
}
|
|
||||||
|
|
||||||
func checkEffectiveLicenses(t *testing.T, ctx *TestContext, effectiveLicenses map[string][]string) {
|
|
||||||
actualLicenses := make(map[string][]string)
|
|
||||||
ctx.Context.Context.VisitAllModules(func(m blueprint.Module) {
|
|
||||||
if _, ok := m.(*licenseModule); ok {
|
|
||||||
return
|
|
||||||
}
|
|
||||||
if _, ok := m.(*licenseKindModule); ok {
|
|
||||||
return
|
|
||||||
}
|
|
||||||
if _, ok := m.(*packageModule); ok {
|
|
||||||
return
|
|
||||||
}
|
|
||||||
module, ok := m.(Module)
|
|
||||||
if !ok {
|
|
||||||
t.Errorf("%q not a module", m.Name())
|
|
||||||
return
|
|
||||||
}
|
|
||||||
base := module.base()
|
|
||||||
if base == nil {
|
|
||||||
return
|
|
||||||
}
|
|
||||||
actualLicenses[m.Name()] = base.commonProperties.Effective_licenses
|
|
||||||
})
|
|
||||||
|
|
||||||
for moduleName, expectedLicenses := range effectiveLicenses {
|
|
||||||
licenses, ok := actualLicenses[moduleName]
|
|
||||||
if !ok {
|
|
||||||
licenses = []string{}
|
|
||||||
}
|
|
||||||
if !compareUnorderedStringArrays(expectedLicenses, licenses) {
|
|
||||||
t.Errorf("effective licenses mismatch for module %q: expected %q, found %q", moduleName, expectedLicenses, licenses)
|
|
||||||
}
|
|
||||||
}
|
|
||||||
}
|
|
||||||
|
|
||||||
func checkEffectiveInheritedLicenses(t *testing.T, ctx *TestContext, effectiveInheritedLicenses map[string][]string) {
|
|
||||||
actualLicenses := make(map[string][]string)
|
|
||||||
ctx.Context.Context.VisitAllModules(func(m blueprint.Module) {
|
|
||||||
if _, ok := m.(*licenseModule); ok {
|
|
||||||
return
|
|
||||||
}
|
|
||||||
if _, ok := m.(*licenseKindModule); ok {
|
|
||||||
return
|
|
||||||
}
|
|
||||||
if _, ok := m.(*packageModule); ok {
|
|
||||||
return
|
|
||||||
}
|
|
||||||
module, ok := m.(Module)
|
|
||||||
if !ok {
|
|
||||||
t.Errorf("%q not a module", m.Name())
|
|
||||||
return
|
|
||||||
}
|
|
||||||
base := module.base()
|
|
||||||
if base == nil {
|
|
||||||
return
|
|
||||||
}
|
|
||||||
inherited := make(map[string]bool)
|
|
||||||
for _, l := range base.commonProperties.Effective_licenses {
|
|
||||||
inherited[l] = true
|
|
||||||
}
|
|
||||||
ctx.Context.Context.VisitDepsDepthFirst(m, func(c blueprint.Module) {
|
|
||||||
if _, ok := c.(*licenseModule); ok {
|
|
||||||
return
|
|
||||||
}
|
|
||||||
if _, ok := c.(*licenseKindModule); ok {
|
|
||||||
return
|
|
||||||
}
|
|
||||||
if _, ok := c.(*packageModule); ok {
|
|
||||||
return
|
|
||||||
}
|
|
||||||
cmodule, ok := c.(Module)
|
|
||||||
if !ok {
|
|
||||||
t.Errorf("%q not a module", c.Name())
|
|
||||||
return
|
|
||||||
}
|
|
||||||
cbase := cmodule.base()
|
|
||||||
if cbase == nil {
|
|
||||||
return
|
|
||||||
}
|
|
||||||
for _, l := range cbase.commonProperties.Effective_licenses {
|
|
||||||
inherited[l] = true
|
|
||||||
}
|
|
||||||
})
|
|
||||||
actualLicenses[m.Name()] = []string{}
|
|
||||||
for l := range inherited {
|
|
||||||
actualLicenses[m.Name()] = append(actualLicenses[m.Name()], l)
|
|
||||||
}
|
|
||||||
})
|
|
||||||
|
|
||||||
for moduleName, expectedInheritedLicenses := range effectiveInheritedLicenses {
|
|
||||||
licenses, ok := actualLicenses[moduleName]
|
|
||||||
if !ok {
|
|
||||||
licenses = []string{}
|
|
||||||
}
|
|
||||||
if !compareUnorderedStringArrays(expectedInheritedLicenses, licenses) {
|
|
||||||
t.Errorf("effective inherited licenses mismatch for module %q: expected %q, found %q", moduleName, expectedInheritedLicenses, licenses)
|
|
||||||
}
|
|
||||||
}
|
|
||||||
}
|
|
||||||
|
|
||||||
func checkEffectivePackage(t *testing.T, ctx *TestContext, effectivePackage map[string]string) {
|
|
||||||
actualPackage := make(map[string]string)
|
|
||||||
ctx.Context.Context.VisitAllModules(func(m blueprint.Module) {
|
|
||||||
if _, ok := m.(*licenseModule); ok {
|
|
||||||
return
|
|
||||||
}
|
|
||||||
if _, ok := m.(*licenseKindModule); ok {
|
|
||||||
return
|
|
||||||
}
|
|
||||||
if _, ok := m.(*packageModule); ok {
|
|
||||||
return
|
|
||||||
}
|
|
||||||
module, ok := m.(Module)
|
|
||||||
if !ok {
|
|
||||||
t.Errorf("%q not a module", m.Name())
|
|
||||||
return
|
|
||||||
}
|
|
||||||
base := module.base()
|
|
||||||
if base == nil {
|
|
||||||
return
|
|
||||||
}
|
|
||||||
|
|
||||||
if base.commonProperties.Effective_package_name == nil {
|
|
||||||
actualPackage[m.Name()] = ""
|
|
||||||
} else {
|
|
||||||
actualPackage[m.Name()] = *base.commonProperties.Effective_package_name
|
|
||||||
}
|
|
||||||
})
|
|
||||||
|
|
||||||
for moduleName, expectedPackage := range effectivePackage {
|
|
||||||
packageName, ok := actualPackage[moduleName]
|
|
||||||
if !ok {
|
|
||||||
packageName = ""
|
|
||||||
}
|
|
||||||
if expectedPackage != packageName {
|
|
||||||
t.Errorf("effective package mismatch for module %q: expected %q, found %q", moduleName, expectedPackage, packageName)
|
|
||||||
}
|
|
||||||
}
|
|
||||||
}
|
|
||||||
|
|
||||||
func checkEffectiveNotices(t *testing.T, ctx *TestContext, effectiveNotices map[string][]string) {
|
|
||||||
actualNotices := make(map[string][]string)
|
|
||||||
ctx.Context.Context.VisitAllModules(func(m blueprint.Module) {
|
|
||||||
if _, ok := m.(*licenseModule); ok {
|
|
||||||
return
|
|
||||||
}
|
|
||||||
if _, ok := m.(*licenseKindModule); ok {
|
|
||||||
return
|
|
||||||
}
|
|
||||||
if _, ok := m.(*packageModule); ok {
|
|
||||||
return
|
|
||||||
}
|
|
||||||
module, ok := m.(Module)
|
|
||||||
if !ok {
|
|
||||||
t.Errorf("%q not a module", m.Name())
|
|
||||||
return
|
|
||||||
}
|
|
||||||
base := module.base()
|
|
||||||
if base == nil {
|
|
||||||
return
|
|
||||||
}
|
|
||||||
actualNotices[m.Name()] = base.commonProperties.Effective_license_text
|
|
||||||
})
|
|
||||||
|
|
||||||
for moduleName, expectedNotices := range effectiveNotices {
|
|
||||||
notices, ok := actualNotices[moduleName]
|
|
||||||
if !ok {
|
|
||||||
notices = []string{}
|
|
||||||
}
|
|
||||||
if !compareUnorderedStringArrays(expectedNotices, notices) {
|
|
||||||
t.Errorf("effective notice files mismatch for module %q: expected %q, found %q", moduleName, expectedNotices, notices)
|
|
||||||
}
|
|
||||||
}
|
|
||||||
}
|
|
||||||
|
|
||||||
func checkEffectiveKinds(t *testing.T, ctx *TestContext, effectiveKinds map[string][]string) {
|
|
||||||
actualKinds := make(map[string][]string)
|
|
||||||
ctx.Context.Context.VisitAllModules(func(m blueprint.Module) {
|
|
||||||
if _, ok := m.(*licenseModule); ok {
|
|
||||||
return
|
|
||||||
}
|
|
||||||
if _, ok := m.(*licenseKindModule); ok {
|
|
||||||
return
|
|
||||||
}
|
|
||||||
if _, ok := m.(*packageModule); ok {
|
|
||||||
return
|
|
||||||
}
|
|
||||||
module, ok := m.(Module)
|
|
||||||
if !ok {
|
|
||||||
t.Errorf("%q not a module", m.Name())
|
|
||||||
return
|
|
||||||
}
|
|
||||||
base := module.base()
|
|
||||||
if base == nil {
|
|
||||||
return
|
|
||||||
}
|
|
||||||
actualKinds[m.Name()] = base.commonProperties.Effective_license_kinds
|
|
||||||
})
|
|
||||||
|
|
||||||
for moduleName, expectedKinds := range effectiveKinds {
|
|
||||||
kinds, ok := actualKinds[moduleName]
|
|
||||||
if !ok {
|
|
||||||
kinds = []string{}
|
|
||||||
}
|
|
||||||
if !compareUnorderedStringArrays(expectedKinds, kinds) {
|
|
||||||
t.Errorf("effective license kinds mismatch for module %q: expected %q, found %q", moduleName, expectedKinds, kinds)
|
|
||||||
}
|
|
||||||
}
|
|
||||||
}
|
|
||||||
|
|
||||||
func checkEffectiveConditions(t *testing.T, ctx *TestContext, effectiveConditions map[string][]string) {
|
|
||||||
actualConditions := make(map[string][]string)
|
|
||||||
ctx.Context.Context.VisitAllModules(func(m blueprint.Module) {
|
|
||||||
if _, ok := m.(*licenseModule); ok {
|
|
||||||
return
|
|
||||||
}
|
|
||||||
if _, ok := m.(*licenseKindModule); ok {
|
|
||||||
return
|
|
||||||
}
|
|
||||||
if _, ok := m.(*packageModule); ok {
|
|
||||||
return
|
|
||||||
}
|
|
||||||
module, ok := m.(Module)
|
|
||||||
if !ok {
|
|
||||||
t.Errorf("%q not a module", m.Name())
|
|
||||||
return
|
|
||||||
}
|
|
||||||
base := module.base()
|
|
||||||
if base == nil {
|
|
||||||
return
|
|
||||||
}
|
|
||||||
actualConditions[m.Name()] = base.commonProperties.Effective_license_conditions
|
|
||||||
})
|
|
||||||
|
|
||||||
for moduleName, expectedConditions := range effectiveConditions {
|
|
||||||
conditions, ok := actualConditions[moduleName]
|
|
||||||
if !ok {
|
|
||||||
conditions = []string{}
|
|
||||||
}
|
|
||||||
if !compareUnorderedStringArrays(expectedConditions, conditions) {
|
|
||||||
t.Errorf("effective license conditions mismatch for module %q: expected %q, found %q", moduleName, expectedConditions, conditions)
|
|
||||||
}
|
|
||||||
}
|
|
||||||
}
|
|
||||||
|
|
||||||
func compareUnorderedStringArrays(expected, actual []string) bool {
|
|
||||||
if len(expected) != len(actual) {
|
|
||||||
return false
|
|
||||||
}
|
|
||||||
s := make(map[string]int)
|
|
||||||
for _, v := range expected {
|
|
||||||
s[v] += 1
|
|
||||||
}
|
|
||||||
for _, v := range actual {
|
|
||||||
c, ok := s[v]
|
|
||||||
if !ok {
|
|
||||||
return false
|
|
||||||
}
|
|
||||||
if c < 1 {
|
|
||||||
return false
|
|
||||||
}
|
|
||||||
s[v] -= 1
|
|
||||||
}
|
|
||||||
return true
|
|
||||||
}
|
|
||||||
|
|
||||||
func testLicenses(buildDir string, fs map[string][]byte) (*TestContext, []error) {
|
|
||||||
|
|
||||||
// Create a new config per test as licenses information is stored in the config.
|
|
||||||
env := make(map[string]string)
|
|
||||||
env["ANDROID_REQUIRE_LICENSES"] = "1"
|
|
||||||
config := TestArchConfig(buildDir, env, "", fs)
|
|
||||||
|
|
||||||
ctx := NewTestArchContext(config)
|
|
||||||
ctx.RegisterModuleType("mock_bad_module", newMockLicensesBadModule)
|
|
||||||
ctx.RegisterModuleType("mock_library", newMockLicensesLibraryModule)
|
|
||||||
ctx.RegisterModuleType("mock_defaults", defaultsLicensesFactory)
|
|
||||||
|
|
||||||
// Order of the following method calls is significant.
|
|
||||||
RegisterPackageBuildComponents(ctx)
|
|
||||||
registerTestPrebuiltBuildComponents(ctx)
|
|
||||||
RegisterLicenseKindBuildComponents(ctx)
|
|
||||||
RegisterLicenseBuildComponents(ctx)
|
|
||||||
ctx.PreArchMutators(RegisterVisibilityRuleChecker)
|
|
||||||
ctx.PreArchMutators(RegisterLicensesPackageMapper)
|
|
||||||
ctx.PreArchMutators(RegisterDefaultsPreArchMutators)
|
|
||||||
ctx.PreArchMutators(RegisterLicensesPropertyGatherer)
|
|
||||||
ctx.PreArchMutators(RegisterVisibilityRuleGatherer)
|
|
||||||
ctx.PostDepsMutators(RegisterVisibilityRuleEnforcer)
|
|
||||||
ctx.PostDepsMutators(RegisterLicensesDependencyChecker)
|
|
||||||
ctx.Register()
|
|
||||||
|
|
||||||
_, errs := ctx.ParseBlueprintsFiles(".")
|
|
||||||
if len(errs) > 0 {
|
|
||||||
return ctx, errs
|
|
||||||
}
|
|
||||||
|
|
||||||
_, errs = ctx.PrepareBuildActions(config)
|
|
||||||
return ctx, errs
|
|
||||||
}
|
|
||||||
|
|
||||||
type mockLicensesBadProperties struct {
|
|
||||||
Visibility []string
|
|
||||||
}
|
|
||||||
|
|
||||||
type mockLicensesBadModule struct {
|
|
||||||
ModuleBase
|
|
||||||
DefaultableModuleBase
|
|
||||||
properties mockLicensesBadProperties
|
|
||||||
}
|
|
||||||
|
|
||||||
func newMockLicensesBadModule() Module {
|
|
||||||
m := &mockLicensesBadModule{}
|
|
||||||
|
|
||||||
base := m.base()
|
|
||||||
m.AddProperties(&base.nameProperties, &m.properties)
|
|
||||||
|
|
||||||
base.generalProperties = m.GetProperties()
|
|
||||||
base.customizableProperties = m.GetProperties()
|
|
||||||
|
|
||||||
// The default_visibility property needs to be checked and parsed by the visibility module during
|
|
||||||
// its checking and parsing phases so make it the primary visibility property.
|
|
||||||
setPrimaryVisibilityProperty(m, "visibility", &m.properties.Visibility)
|
|
||||||
|
|
||||||
initAndroidModuleBase(m)
|
|
||||||
InitDefaultableModule(m)
|
|
||||||
|
|
||||||
return m
|
|
||||||
}
|
|
||||||
|
|
||||||
func (m *mockLicensesBadModule) GenerateAndroidBuildActions(ModuleContext) {
|
|
||||||
}
|
|
||||||
|
|
||||||
type mockLicensesLibraryProperties struct {
|
|
||||||
Deps []string
|
|
||||||
}
|
|
||||||
|
|
||||||
type mockLicensesLibraryModule struct {
|
|
||||||
ModuleBase
|
|
||||||
DefaultableModuleBase
|
|
||||||
properties mockLicensesLibraryProperties
|
|
||||||
}
|
|
||||||
|
|
||||||
func newMockLicensesLibraryModule() Module {
|
|
||||||
m := &mockLicensesLibraryModule{}
|
|
||||||
m.AddProperties(&m.properties)
|
|
||||||
InitAndroidArchModule(m, HostAndDeviceSupported, MultilibCommon)
|
|
||||||
InitDefaultableModule(m)
|
|
||||||
return m
|
|
||||||
}
|
|
||||||
|
|
||||||
type dependencyLicensesTag struct {
|
|
||||||
blueprint.BaseDependencyTag
|
|
||||||
name string
|
|
||||||
}
|
|
||||||
|
|
||||||
func (j *mockLicensesLibraryModule) DepsMutator(ctx BottomUpMutatorContext) {
|
|
||||||
ctx.AddVariationDependencies(nil, dependencyLicensesTag{name: "mockdeps"}, j.properties.Deps...)
|
|
||||||
}
|
|
||||||
|
|
||||||
func (p *mockLicensesLibraryModule) GenerateAndroidBuildActions(ModuleContext) {
|
|
||||||
}
|
|
||||||
|
|
||||||
type mockLicensesDefaults struct {
|
|
||||||
ModuleBase
|
|
||||||
DefaultsModuleBase
|
|
||||||
}
|
|
||||||
|
|
||||||
func defaultsLicensesFactory() Module {
|
|
||||||
m := &mockLicensesDefaults{}
|
|
||||||
InitDefaultsModule(m)
|
|
||||||
return m
|
|
||||||
}
|
|
@@ -619,20 +619,6 @@ type commonProperties struct {
|
|||||||
// more details.
|
// more details.
|
||||||
Visibility []string
|
Visibility []string
|
||||||
|
|
||||||
// Describes the licenses applicable to this module. Must reference license modules.
|
|
||||||
Licenses []string
|
|
||||||
|
|
||||||
// Flattened from direct license dependencies. Equal to Licenses unless particular module adds more.
|
|
||||||
Effective_licenses []string `blueprint:"mutated"`
|
|
||||||
// Override of module name when reporting licenses
|
|
||||||
Effective_package_name *string `blueprint:"mutated"`
|
|
||||||
// Notice files
|
|
||||||
Effective_license_text []string `blueprint:"mutated"`
|
|
||||||
// License names
|
|
||||||
Effective_license_kinds []string `blueprint:"mutated"`
|
|
||||||
// License conditions
|
|
||||||
Effective_license_conditions []string `blueprint:"mutated"`
|
|
||||||
|
|
||||||
// control whether this module compiles for 32-bit, 64-bit, or both. Possible values
|
// control whether this module compiles for 32-bit, 64-bit, or both. Possible values
|
||||||
// are "32" (compile for 32-bit only), "64" (compile for 64-bit only), "both" (compile for both
|
// are "32" (compile for 32-bit only), "64" (compile for 64-bit only), "both" (compile for both
|
||||||
// architectures), or "first" (compile for 64-bit on a 64-bit platform, and 32-bit on a 32-bit
|
// architectures), or "first" (compile for 64-bit on a 64-bit platform, and 32-bit on a 32-bit
|
||||||
@@ -954,10 +940,6 @@ func InitAndroidModule(m Module) {
|
|||||||
// The default_visibility property needs to be checked and parsed by the visibility module during
|
// The default_visibility property needs to be checked and parsed by the visibility module during
|
||||||
// its checking and parsing phases so make it the primary visibility property.
|
// its checking and parsing phases so make it the primary visibility property.
|
||||||
setPrimaryVisibilityProperty(m, "visibility", &base.commonProperties.Visibility)
|
setPrimaryVisibilityProperty(m, "visibility", &base.commonProperties.Visibility)
|
||||||
|
|
||||||
// The default_applicable_licenses property needs to be checked and parsed by the licenses module during
|
|
||||||
// its checking and parsing phases so make it the primary licenses property.
|
|
||||||
setPrimaryLicensesProperty(m, "licenses", &base.commonProperties.Licenses)
|
|
||||||
}
|
}
|
||||||
|
|
||||||
// InitAndroidArchModule initializes the Module as an Android module that is architecture-specific.
|
// InitAndroidArchModule initializes the Module as an Android module that is architecture-specific.
|
||||||
@@ -1075,9 +1057,6 @@ type ModuleBase struct {
|
|||||||
// The primary visibility property, may be nil, that controls access to the module.
|
// The primary visibility property, may be nil, that controls access to the module.
|
||||||
primaryVisibilityProperty visibilityProperty
|
primaryVisibilityProperty visibilityProperty
|
||||||
|
|
||||||
// The primary licenses property, may be nil, records license metadata for the module.
|
|
||||||
primaryLicensesProperty applicableLicensesProperty
|
|
||||||
|
|
||||||
noAddressSanitizer bool
|
noAddressSanitizer bool
|
||||||
installFiles InstallPaths
|
installFiles InstallPaths
|
||||||
installFilesDepSet *installPathsDepSet
|
installFilesDepSet *installPathsDepSet
|
||||||
@@ -1753,11 +1732,6 @@ func (m *ModuleBase) GenerateBuildActions(blueprintCtx blueprint.ModuleContext)
|
|||||||
}
|
}
|
||||||
}
|
}
|
||||||
|
|
||||||
licensesPropertyFlattener(ctx)
|
|
||||||
if ctx.Failed() {
|
|
||||||
return
|
|
||||||
}
|
|
||||||
|
|
||||||
m.module.GenerateAndroidBuildActions(ctx)
|
m.module.GenerateAndroidBuildActions(ctx)
|
||||||
if ctx.Failed() {
|
if ctx.Failed() {
|
||||||
return
|
return
|
||||||
|
@@ -115,11 +115,6 @@ var preArch = []RegisterMutatorFunc{
|
|||||||
//
|
//
|
||||||
RegisterVisibilityRuleChecker,
|
RegisterVisibilityRuleChecker,
|
||||||
|
|
||||||
// Record the default_applicable_licenses for each package.
|
|
||||||
//
|
|
||||||
// This must run before the defaults so that defaults modules can pick up the package default.
|
|
||||||
RegisterLicensesPackageMapper,
|
|
||||||
|
|
||||||
// Apply properties from defaults modules to the referencing modules.
|
// Apply properties from defaults modules to the referencing modules.
|
||||||
//
|
//
|
||||||
// Any mutators that are added before this will not see any modules created by
|
// Any mutators that are added before this will not see any modules created by
|
||||||
@@ -146,12 +141,6 @@ var preArch = []RegisterMutatorFunc{
|
|||||||
// prebuilt.
|
// prebuilt.
|
||||||
RegisterPrebuiltsPreArchMutators,
|
RegisterPrebuiltsPreArchMutators,
|
||||||
|
|
||||||
// Gather the licenses properties for all modules for use during expansion and enforcement.
|
|
||||||
//
|
|
||||||
// This must come after the defaults mutators to ensure that any licenses supplied
|
|
||||||
// in a defaults module has been successfully applied before the rules are gathered.
|
|
||||||
RegisterLicensesPropertyGatherer,
|
|
||||||
|
|
||||||
// Gather the visibility rules for all modules for us during visibility enforcement.
|
// Gather the visibility rules for all modules for us during visibility enforcement.
|
||||||
//
|
//
|
||||||
// This must come after the defaults mutators to ensure that any visibility supplied
|
// This must come after the defaults mutators to ensure that any visibility supplied
|
||||||
@@ -173,7 +162,6 @@ var postDeps = []RegisterMutatorFunc{
|
|||||||
registerPathDepsMutator,
|
registerPathDepsMutator,
|
||||||
RegisterPrebuiltsPostDepsMutators,
|
RegisterPrebuiltsPostDepsMutators,
|
||||||
RegisterVisibilityRuleEnforcer,
|
RegisterVisibilityRuleEnforcer,
|
||||||
RegisterLicensesDependencyChecker,
|
|
||||||
RegisterNeverallowMutator,
|
RegisterNeverallowMutator,
|
||||||
RegisterOverridePostDepsMutators,
|
RegisterOverridePostDepsMutators,
|
||||||
}
|
}
|
||||||
|
@@ -31,8 +31,6 @@ func RegisterPackageBuildComponents(ctx RegistrationContext) {
|
|||||||
type packageProperties struct {
|
type packageProperties struct {
|
||||||
// Specifies the default visibility for all modules defined in this package.
|
// Specifies the default visibility for all modules defined in this package.
|
||||||
Default_visibility []string
|
Default_visibility []string
|
||||||
// Specifies the default license terms for all modules defined in this package.
|
|
||||||
Default_applicable_licenses []string
|
|
||||||
}
|
}
|
||||||
|
|
||||||
type packageModule struct {
|
type packageModule struct {
|
||||||
@@ -70,9 +68,5 @@ func PackageFactory() Module {
|
|||||||
// its checking and parsing phases so make it the primary visibility property.
|
// its checking and parsing phases so make it the primary visibility property.
|
||||||
setPrimaryVisibilityProperty(module, "default_visibility", &module.properties.Default_visibility)
|
setPrimaryVisibilityProperty(module, "default_visibility", &module.properties.Default_visibility)
|
||||||
|
|
||||||
// The default_applicable_licenses property needs to be checked and parsed by the licenses module during
|
|
||||||
// its checking and parsing phases so make it the primary licenses property.
|
|
||||||
setPrimaryLicensesProperty(module, "default_applicable_licenses", &module.properties.Default_applicable_licenses)
|
|
||||||
|
|
||||||
return module
|
return module
|
||||||
}
|
}
|
||||||
|
@@ -17,11 +17,9 @@ var packageTests = []struct {
|
|||||||
package {
|
package {
|
||||||
name: "package",
|
name: "package",
|
||||||
visibility: ["//visibility:private"],
|
visibility: ["//visibility:private"],
|
||||||
licenses: ["license"],
|
|
||||||
}`),
|
}`),
|
||||||
},
|
},
|
||||||
expectedErrors: []string{
|
expectedErrors: []string{
|
||||||
`top/Blueprints:5:14: unrecognized property "licenses"`,
|
|
||||||
`top/Blueprints:3:10: unrecognized property "name"`,
|
`top/Blueprints:3:10: unrecognized property "name"`,
|
||||||
`top/Blueprints:4:16: unrecognized property "visibility"`,
|
`top/Blueprints:4:16: unrecognized property "visibility"`,
|
||||||
},
|
},
|
||||||
@@ -46,10 +44,9 @@ var packageTests = []struct {
|
|||||||
"top/Blueprints": []byte(`
|
"top/Blueprints": []byte(`
|
||||||
package {
|
package {
|
||||||
default_visibility: ["//visibility:private"],
|
default_visibility: ["//visibility:private"],
|
||||||
default_applicable_licenses: ["license"],
|
|
||||||
}
|
}
|
||||||
|
|
||||||
package {
|
package {
|
||||||
}`),
|
}`),
|
||||||
},
|
},
|
||||||
expectedErrors: []string{
|
expectedErrors: []string{
|
||||||
|
Reference in New Issue
Block a user