diff options
-rw-r--r-- | apex/apex.go | 24 | ||||
-rw-r--r-- | apex/apex_test.go | 114 | ||||
-rw-r--r-- | apex/builder.go | 13 | ||||
-rw-r--r-- | java/java.go | 14 | ||||
-rw-r--r-- | java/lint.go | 162 | ||||
-rw-r--r-- | java/lint_test.go | 19 | ||||
-rw-r--r-- | java/sdk_library.go | 15 | ||||
-rw-r--r-- | java/testing.go | 1 | ||||
-rw-r--r-- | scripts/Android.bp | 17 | ||||
-rwxr-xr-x | scripts/lint_project_xml.py | 24 | ||||
-rwxr-xr-x | scripts/lint_strict_updatability_checks.py | 81 | ||||
-rwxr-xr-x[-rw-r--r--] | scripts/lint_strict_updatability_checks_test.py (renamed from scripts/lint_project_xml_test.py) | 6 |
12 files changed, 267 insertions, 223 deletions
diff --git a/apex/apex.go b/apex/apex.go index aff69c12f..79f1ad610 100644 --- a/apex/apex.go +++ b/apex/apex.go @@ -68,8 +68,6 @@ func RegisterPostDepsMutators(ctx android.RegisterMutatorsContext) { ctx.Transition("apex", &apexTransitionMutator{}) ctx.BottomUp("apex_directly_in_any", apexDirectlyInAnyMutator).Parallel() ctx.BottomUp("apex_dcla_deps", apexDCLADepsMutator).Parallel() - // Register after apex_info mutator so that it can use ApexVariationName - ctx.TopDown("apex_strict_updatability_lint", apexStrictUpdatibilityLintMutator).Parallel() } type apexBundleProperties struct { @@ -1115,26 +1113,6 @@ func apexInfoMutator(mctx android.TopDownMutatorContext) { enforceAppUpdatability(mctx) } -// apexStrictUpdatibilityLintMutator propagates strict_updatability_linting to transitive deps of a mainline module -// This check is enforced for updatable modules -func apexStrictUpdatibilityLintMutator(mctx android.TopDownMutatorContext) { - if !mctx.Module().Enabled(mctx) { - return - } - if apex, ok := mctx.Module().(*apexBundle); ok && apex.checkStrictUpdatabilityLinting(mctx) { - apex.WalkPayloadDeps(mctx, func(mctx android.BaseModuleContext, from blueprint.Module, to android.ApexModule, externalDep bool) bool { - if externalDep { - return false - } - if lintable, ok := to.(java.LintDepSetsIntf); ok { - lintable.SetStrictUpdatabilityLinting(true) - } - // visit transitive deps - return true - }) - } -} - // enforceAppUpdatability propagates updatable=true to apps of updatable apexes func enforceAppUpdatability(mctx android.TopDownMutatorContext) { if !mctx.Module().Enabled(mctx) { @@ -1197,7 +1175,7 @@ var ( } ) -func (a *apexBundle) checkStrictUpdatabilityLinting(mctx android.TopDownMutatorContext) bool { +func (a *apexBundle) checkStrictUpdatabilityLinting(mctx android.ModuleContext) bool { // The allowlist contains the base apex name, so use that instead of the ApexVariationName return a.Updatable() && !android.InList(mctx.ModuleName(), skipStrictUpdatabilityLintAllowlist) } diff --git a/apex/apex_test.go b/apex/apex_test.go index 8cb8a9132..c3c9b7c35 100644 --- a/apex/apex_test.go +++ b/apex/apex_test.go @@ -9693,59 +9693,84 @@ func TestApexStrictUpdtabilityLint(t *testing.T) { } testCases := []struct { - testCaseName string - apexUpdatable bool - javaStrictUpdtabilityLint bool - lintFileExists bool - disallowedFlagExpected bool + testCaseName string + apexUpdatable bool + javaStrictUpdtabilityLint bool + lintFileExists bool + disallowedFlagExpectedOnApex bool + disallowedFlagExpectedOnJavalib bool }{ { - testCaseName: "lint-baseline.xml does not exist, no disallowed flag necessary in lint cmd", - apexUpdatable: true, - javaStrictUpdtabilityLint: true, - lintFileExists: false, - disallowedFlagExpected: false, + testCaseName: "lint-baseline.xml does not exist, no disallowed flag necessary in lint cmd", + apexUpdatable: true, + javaStrictUpdtabilityLint: true, + lintFileExists: false, + disallowedFlagExpectedOnApex: false, + disallowedFlagExpectedOnJavalib: false, }, { - testCaseName: "non-updatable apex respects strict_updatability of javalib", - apexUpdatable: false, - javaStrictUpdtabilityLint: false, - lintFileExists: true, - disallowedFlagExpected: false, + testCaseName: "non-updatable apex respects strict_updatability of javalib", + apexUpdatable: false, + javaStrictUpdtabilityLint: false, + lintFileExists: true, + disallowedFlagExpectedOnApex: false, + disallowedFlagExpectedOnJavalib: false, }, { - testCaseName: "non-updatable apex respects strict updatability of javalib", - apexUpdatable: false, - javaStrictUpdtabilityLint: true, - lintFileExists: true, - disallowedFlagExpected: true, + testCaseName: "non-updatable apex respects strict updatability of javalib", + apexUpdatable: false, + javaStrictUpdtabilityLint: true, + lintFileExists: true, + disallowedFlagExpectedOnApex: false, + disallowedFlagExpectedOnJavalib: true, }, { - testCaseName: "updatable apex sets strict updatability of javalib to true", - apexUpdatable: true, - javaStrictUpdtabilityLint: false, // will be set to true by mutator - lintFileExists: true, - disallowedFlagExpected: true, + testCaseName: "updatable apex checks strict updatability of javalib", + apexUpdatable: true, + javaStrictUpdtabilityLint: false, + lintFileExists: true, + disallowedFlagExpectedOnApex: true, + disallowedFlagExpectedOnJavalib: false, }, } for _, testCase := range testCases { - fixtures := []android.FixturePreparer{} - baselineProperty := "" - if testCase.lintFileExists { - fixtures = append(fixtures, fs.AddToFixture()) - baselineProperty = "baseline_filename: \"lint-baseline.xml\"" - } - bp := fmt.Sprintf(bpTemplate, testCase.apexUpdatable, testCase.javaStrictUpdtabilityLint, baselineProperty) + t.Run(testCase.testCaseName, func(t *testing.T) { + fixtures := []android.FixturePreparer{} + baselineProperty := "" + if testCase.lintFileExists { + fixtures = append(fixtures, fs.AddToFixture()) + baselineProperty = "baseline_filename: \"lint-baseline.xml\"" + } + bp := fmt.Sprintf(bpTemplate, testCase.apexUpdatable, testCase.javaStrictUpdtabilityLint, baselineProperty) - result := testApex(t, bp, fixtures...) - myjavalib := result.ModuleForTests("myjavalib", "android_common_apex29") - sboxProto := android.RuleBuilderSboxProtoForTests(t, result, myjavalib.Output("lint.sbox.textproto")) - disallowedFlagActual := strings.Contains(*sboxProto.Commands[0].Command, "--baseline lint-baseline.xml --disallowed_issues NewApi") + result := testApex(t, bp, fixtures...) - if disallowedFlagActual != testCase.disallowedFlagExpected { - t.Errorf("Failed testcase: %v \nActual lint cmd: %v", testCase.testCaseName, *sboxProto.Commands[0].Command) - } + checkModule := func(m android.TestingBuildParams, name string, expectStrictUpdatability bool) { + if expectStrictUpdatability { + if m.Rule == nil { + t.Errorf("expected strict updatability check rule on %s", name) + } else { + android.AssertStringDoesContain(t, fmt.Sprintf("strict updatability check rule for %s", name), + m.RuleParams.Command, "--disallowed_issues NewApi") + android.AssertStringListContains(t, fmt.Sprintf("strict updatability check baselines for %s", name), + m.Inputs.Strings(), "lint-baseline.xml") + } + } else { + if m.Rule != nil { + t.Errorf("expected no strict updatability check rule on %s", name) + } + } + } + + myjavalib := result.ModuleForTests("myjavalib", "android_common_apex29") + apex := result.ModuleForTests("myapex", "android_common_myapex") + apexStrictUpdatabilityCheck := apex.MaybeOutput("lint_strict_updatability_check.stamp") + javalibStrictUpdatabilityCheck := myjavalib.MaybeOutput("lint_strict_updatability_check.stamp") + + checkModule(apexStrictUpdatabilityCheck, "myapex", testCase.disallowedFlagExpectedOnApex) + checkModule(javalibStrictUpdatabilityCheck, "myjavalib", testCase.disallowedFlagExpectedOnJavalib) + }) } } @@ -9787,11 +9812,12 @@ func TestApexStrictUpdtabilityLintBcpFragmentDeps(t *testing.T) { } result := testApex(t, bp, dexpreopt.FixtureSetApexBootJars("myapex:myjavalib"), fs.AddToFixture()) - myjavalib := result.ModuleForTests("myjavalib", "android_common_apex29") - sboxProto := android.RuleBuilderSboxProtoForTests(t, result, myjavalib.Output("lint.sbox.textproto")) - if !strings.Contains(*sboxProto.Commands[0].Command, "--baseline lint-baseline.xml --disallowed_issues NewApi") { - t.Errorf("Strict updabality lint missing in myjavalib coming from bootclasspath_fragment mybootclasspath-fragment\nActual lint cmd: %v", *sboxProto.Commands[0].Command) - } + apex := result.ModuleForTests("myapex", "android_common_myapex") + apexStrictUpdatabilityCheck := apex.Output("lint_strict_updatability_check.stamp") + android.AssertStringDoesContain(t, "strict updatability check rule for myapex", + apexStrictUpdatabilityCheck.RuleParams.Command, "--disallowed_issues NewApi") + android.AssertStringListContains(t, "strict updatability check baselines for myapex", + apexStrictUpdatabilityCheck.Inputs.Strings(), "lint-baseline.xml") } func TestApexLintBcpFragmentSdkLibDeps(t *testing.T) { diff --git a/apex/builder.go b/apex/builder.go index 244119bdd..bf3ba9f99 100644 --- a/apex/builder.go +++ b/apex/builder.go @@ -1164,7 +1164,18 @@ func (a *apexBundle) buildLintReports(ctx android.ModuleContext) { } } - a.lintReports = java.BuildModuleLintReportZips(ctx, depSetsBuilder.Build()) + depSets := depSetsBuilder.Build() + var validations android.Paths + + if a.checkStrictUpdatabilityLinting(ctx) { + baselines := depSets.Baseline.ToList() + if len(baselines) > 0 { + outputFile := java.VerifyStrictUpdatabilityChecks(ctx, baselines) + validations = append(validations, outputFile) + } + } + + a.lintReports = java.BuildModuleLintReportZips(ctx, depSets, validations) } func (a *apexBundle) buildCannedFsConfig(ctx android.ModuleContext) android.OutputPath { diff --git a/java/java.go b/java/java.go index c6fa663ff..f0f70a1b3 100644 --- a/java/java.go +++ b/java/java.go @@ -2612,13 +2612,6 @@ func (a *Import) JacocoReportClassesFile() android.Path { return nil } -func (j *Import) getStrictUpdatabilityLinting() bool { - return false -} - -func (j *Import) setStrictUpdatabilityLinting(bool) { -} - func (j *Import) DepsMutator(ctx android.BottomUpMutatorContext) { ctx.AddVariationDependencies(nil, libTag, j.properties.Libs...) ctx.AddVariationDependencies(nil, staticLibTag, j.properties.Static_libs.GetOrDefault(ctx, nil)...) @@ -3098,13 +3091,6 @@ func (j *DexImport) IsInstallable() bool { return true } -func (j *DexImport) getStrictUpdatabilityLinting() bool { - return false -} - -func (j *DexImport) setStrictUpdatabilityLinting(bool) { -} - func (j *DexImport) GenerateAndroidBuildActions(ctx android.ModuleContext) { if len(j.properties.Jars) != 1 { ctx.PropertyErrorf("jars", "exactly one jar must be provided") diff --git a/java/lint.go b/java/lint.go index 5cd49a8b7..2cbefc3bb 100644 --- a/java/lint.go +++ b/java/lint.go @@ -100,32 +100,30 @@ type linter struct { buildModuleReportZip bool } -type LintDepSetsIntf interface { - // Methods used to propagate strict_updatability_linting values. - GetStrictUpdatabilityLinting() bool - SetStrictUpdatabilityLinting(bool) -} - type LintDepSets struct { - HTML, Text, XML *android.DepSet[android.Path] + HTML, Text, XML, Baseline *android.DepSet[android.Path] } type LintDepSetsBuilder struct { - HTML, Text, XML *android.DepSetBuilder[android.Path] + HTML, Text, XML, Baseline *android.DepSetBuilder[android.Path] } func NewLintDepSetBuilder() LintDepSetsBuilder { return LintDepSetsBuilder{ - HTML: android.NewDepSetBuilder[android.Path](android.POSTORDER), - Text: android.NewDepSetBuilder[android.Path](android.POSTORDER), - XML: android.NewDepSetBuilder[android.Path](android.POSTORDER), + HTML: android.NewDepSetBuilder[android.Path](android.POSTORDER), + Text: android.NewDepSetBuilder[android.Path](android.POSTORDER), + XML: android.NewDepSetBuilder[android.Path](android.POSTORDER), + Baseline: android.NewDepSetBuilder[android.Path](android.POSTORDER), } } -func (l LintDepSetsBuilder) Direct(html, text, xml android.Path) LintDepSetsBuilder { +func (l LintDepSetsBuilder) Direct(html, text, xml android.Path, baseline android.OptionalPath) LintDepSetsBuilder { l.HTML.Direct(html) l.Text.Direct(text) l.XML.Direct(xml) + if baseline.Valid() { + l.Baseline.Direct(baseline.Path()) + } return l } @@ -139,14 +137,18 @@ func (l LintDepSetsBuilder) Transitive(info *LintInfo) LintDepSetsBuilder { if info.TransitiveXML != nil { l.XML.Transitive(info.TransitiveXML) } + if info.TransitiveBaseline != nil { + l.Baseline.Transitive(info.TransitiveBaseline) + } return l } func (l LintDepSetsBuilder) Build() LintDepSets { return LintDepSets{ - HTML: l.HTML.Build(), - Text: l.Text.Build(), - XML: l.XML.Build(), + HTML: l.HTML.Build(), + Text: l.Text.Build(), + XML: l.XML.Build(), + Baseline: l.Baseline.Build(), } } @@ -194,16 +196,6 @@ var allLintDatabasefiles = map[android.SdkKind]lintDatabaseFiles{ }, } -func (l *linter) GetStrictUpdatabilityLinting() bool { - return BoolDefault(l.properties.Lint.Strict_updatability_linting, false) -} - -func (l *linter) SetStrictUpdatabilityLinting(strictLinting bool) { - l.properties.Lint.Strict_updatability_linting = &strictLinting -} - -var _ LintDepSetsIntf = (*linter)(nil) - var LintProvider = blueprint.NewProvider[*LintInfo]() type LintInfo struct { @@ -212,9 +204,10 @@ type LintInfo struct { XML android.Path ReferenceBaseline android.Path - TransitiveHTML *android.DepSet[android.Path] - TransitiveText *android.DepSet[android.Path] - TransitiveXML *android.DepSet[android.Path] + TransitiveHTML *android.DepSet[android.Path] + TransitiveText *android.DepSet[android.Path] + TransitiveXML *android.DepSet[android.Path] + TransitiveBaseline *android.DepSet[android.Path] } func (l *linter) enabled() bool { @@ -250,7 +243,9 @@ func lintRBEExecStrategy(ctx android.ModuleContext) string { return ctx.Config().GetenvWithDefault("RBE_LINT_EXEC_STRATEGY", remoteexec.LocalExecStrategy) } -func (l *linter) writeLintProjectXML(ctx android.ModuleContext, rule *android.RuleBuilder, srcsList android.Path) lintPaths { +func (l *linter) writeLintProjectXML(ctx android.ModuleContext, rule *android.RuleBuilder, srcsList android.Path, + baselines android.Paths) lintPaths { + projectXMLPath := android.PathForModuleOut(ctx, "lint", "project.xml") // Lint looks for a lint.xml file next to the project.xml file, give it one. configXMLPath := android.PathForModuleOut(ctx, "lint", "lint.xml") @@ -313,12 +308,10 @@ func (l *linter) writeLintProjectXML(ctx android.ModuleContext, rule *android.Ru cmd.FlagForEachArg("--error_check ", l.properties.Lint.Error_checks) cmd.FlagForEachArg("--fatal_check ", l.properties.Lint.Fatal_checks) - if l.GetStrictUpdatabilityLinting() { + if Bool(l.properties.Lint.Strict_updatability_linting) && len(baselines) > 0 { // Verify the module does not baseline issues that endanger safe updatability. - if l.properties.Lint.Baseline_filename != nil { - cmd.FlagWithInput("--baseline ", android.PathForModuleSrc(ctx, *l.properties.Lint.Baseline_filename)) - cmd.FlagForEachArg("--disallowed_issues ", updatabilityChecks) - } + strictUpdatabilityChecksOutputFile := VerifyStrictUpdatabilityChecks(ctx, baselines) + cmd.Validation(strictUpdatabilityChecksOutputFile) } return lintPaths{ @@ -330,6 +323,22 @@ func (l *linter) writeLintProjectXML(ctx android.ModuleContext, rule *android.Ru } +func VerifyStrictUpdatabilityChecks(ctx android.ModuleContext, baselines android.Paths) android.Path { + rule := android.NewRuleBuilder(pctx, ctx) + baselineRspFile := android.PathForModuleOut(ctx, "lint_strict_updatability_check_baselines.rsp") + outputFile := android.PathForModuleOut(ctx, "lint_strict_updatability_check.stamp") + rule.Command().Text("rm -f").Output(outputFile) + rule.Command(). + BuiltTool("lint_strict_updatability_checks"). + FlagWithArg("--name ", ctx.ModuleName()). + FlagWithRspFileInputList("--baselines ", baselineRspFile, baselines). + FlagForEachArg("--disallowed_issues ", updatabilityChecks) + rule.Command().Text("touch").Output(outputFile) + rule.Build("lint_strict_updatability_checks", "lint strict updatability checks") + + return outputFile +} + // generateManifest adds a command to the rule to write a simple manifest that contains the // minSdkVersion and targetSdkVersion for modules (like java_library) that don't have a manifest. func (l *linter) generateManifest(ctx android.ModuleContext, rule *android.RuleBuilder) android.WritablePath { @@ -399,6 +408,26 @@ func (l *linter) lint(ctx android.ModuleContext) { l.extraLintCheckJars = append(l.extraLintCheckJars, android.PathForSource(ctx, "prebuilts/cmdline-tools/AndroidGlobalLintChecker.jar")) + var baseline android.OptionalPath + if l.properties.Lint.Baseline_filename != nil { + baseline = android.OptionalPathForPath(android.PathForModuleSrc(ctx, *l.properties.Lint.Baseline_filename)) + } + + html := android.PathForModuleOut(ctx, "lint", "lint-report.html") + text := android.PathForModuleOut(ctx, "lint", "lint-report.txt") + xml := android.PathForModuleOut(ctx, "lint", "lint-report.xml") + referenceBaseline := android.PathForModuleOut(ctx, "lint", "lint-baseline.xml") + + depSetsBuilder := NewLintDepSetBuilder().Direct(html, text, xml, baseline) + + ctx.VisitDirectDepsWithTag(staticLibTag, func(dep android.Module) { + if info, ok := android.OtherModuleProvider(ctx, dep, LintProvider); ok { + depSetsBuilder.Transitive(info) + } + }) + + depSets := depSetsBuilder.Build() + rule := android.NewRuleBuilder(pctx, ctx). Sbox(android.PathForModuleOut(ctx, "lint"), android.PathForModuleOut(ctx, "lint.sbox.textproto")). @@ -425,22 +454,9 @@ func (l *linter) lint(ctx android.ModuleContext) { srcsListRsp := android.PathForModuleOut(ctx, "lint-srcs.list.rsp") rule.Command().Text("cp").FlagWithRspFileInputList("", srcsListRsp, l.srcs).Output(srcsList).Implicits(l.compile_data) - lintPaths := l.writeLintProjectXML(ctx, rule, srcsList) - - html := android.PathForModuleOut(ctx, "lint", "lint-report.html") - text := android.PathForModuleOut(ctx, "lint", "lint-report.txt") - xml := android.PathForModuleOut(ctx, "lint", "lint-report.xml") - referenceBaseline := android.PathForModuleOut(ctx, "lint", "lint-baseline.xml") + baselines := depSets.Baseline.ToList() - depSetsBuilder := NewLintDepSetBuilder().Direct(html, text, xml) - - ctx.VisitDirectDepsWithTag(staticLibTag, func(dep android.Module) { - if info, ok := android.OtherModuleProvider(ctx, dep, LintProvider); ok { - depSetsBuilder.Transitive(info) - } - }) - - depSets := depSetsBuilder.Build() + lintPaths := l.writeLintProjectXML(ctx, rule, srcsList, baselines) rule.Command().Text("rm -rf").Flag(lintPaths.cacheDir.String()).Flag(lintPaths.homeDir.String()) rule.Command().Text("mkdir -p").Flag(lintPaths.cacheDir.String()).Flag(lintPaths.homeDir.String()) @@ -495,8 +511,8 @@ func (l *linter) lint(ctx android.ModuleContext) { cmd.FlagWithArg("--check ", checkOnly) } - if l.properties.Lint.Baseline_filename != nil { - cmd.FlagWithInput("--baseline ", android.PathForModuleSrc(ctx, *l.properties.Lint.Baseline_filename)) + if baseline.Valid() { + cmd.FlagWithInput("--baseline ", baseline.Path()) } cmd.FlagWithOutput("--write-reference-baseline ", referenceBaseline) @@ -526,13 +542,14 @@ func (l *linter) lint(ctx android.ModuleContext) { XML: xml, ReferenceBaseline: referenceBaseline, - TransitiveHTML: depSets.HTML, - TransitiveText: depSets.Text, - TransitiveXML: depSets.XML, + TransitiveHTML: depSets.HTML, + TransitiveText: depSets.Text, + TransitiveXML: depSets.XML, + TransitiveBaseline: depSets.Baseline, }) if l.buildModuleReportZip { - l.reports = BuildModuleLintReportZips(ctx, depSets) + l.reports = BuildModuleLintReportZips(ctx, depSets, nil) } // Create a per-module phony target to run the lint check. @@ -542,7 +559,7 @@ func (l *linter) lint(ctx android.ModuleContext) { ctx.SetOutputFiles(android.Paths{xml}, ".lint") } -func BuildModuleLintReportZips(ctx android.ModuleContext, depSets LintDepSets) android.Paths { +func BuildModuleLintReportZips(ctx android.ModuleContext, depSets LintDepSets, validations android.Paths) android.Paths { htmlList := android.SortedUniquePaths(depSets.HTML.ToList()) textList := android.SortedUniquePaths(depSets.Text.ToList()) xmlList := android.SortedUniquePaths(depSets.XML.ToList()) @@ -552,13 +569,13 @@ func BuildModuleLintReportZips(ctx android.ModuleContext, depSets LintDepSets) a } htmlZip := android.PathForModuleOut(ctx, "lint-report-html.zip") - lintZip(ctx, htmlList, htmlZip) + lintZip(ctx, htmlList, htmlZip, validations) textZip := android.PathForModuleOut(ctx, "lint-report-text.zip") - lintZip(ctx, textList, textZip) + lintZip(ctx, textList, textZip, validations) xmlZip := android.PathForModuleOut(ctx, "lint-report-xml.zip") - lintZip(ctx, xmlList, xmlZip) + lintZip(ctx, xmlList, xmlZip, validations) return android.Paths{htmlZip, textZip, xmlZip} } @@ -668,7 +685,7 @@ func (l *lintSingleton) generateLintReportZips(ctx android.SingletonContext) { } } - lintZip(ctx, paths, outputPath) + lintZip(ctx, paths, outputPath, nil) } l.htmlZip = android.PathForOutput(ctx, "lint-report-html.zip") @@ -697,17 +714,9 @@ var _ android.SingletonMakeVarsProvider = (*lintSingleton)(nil) func init() { android.RegisterParallelSingletonType("lint", func() android.Singleton { return &lintSingleton{} }) - - registerLintBuildComponents(android.InitRegistrationContext) } -func registerLintBuildComponents(ctx android.RegistrationContext) { - ctx.PostDepsMutators(func(ctx android.RegisterMutatorsContext) { - ctx.TopDown("enforce_strict_updatability_linting", enforceStrictUpdatabilityLintingMutator).Parallel() - }) -} - -func lintZip(ctx android.BuilderContext, paths android.Paths, outputPath android.WritablePath) { +func lintZip(ctx android.BuilderContext, paths android.Paths, outputPath android.WritablePath, validations android.Paths) { paths = android.SortedUniquePaths(android.CopyOfPaths(paths)) sort.Slice(paths, func(i, j int) bool { @@ -719,19 +728,8 @@ func lintZip(ctx android.BuilderContext, paths android.Paths, outputPath android rule.Command().BuiltTool("soong_zip"). FlagWithOutput("-o ", outputPath). FlagWithArg("-C ", android.PathForIntermediates(ctx).String()). - FlagWithRspFileInputList("-r ", outputPath.ReplaceExtension(ctx, "rsp"), paths) + FlagWithRspFileInputList("-r ", outputPath.ReplaceExtension(ctx, "rsp"), paths). + Validations(validations) rule.Build(outputPath.Base(), outputPath.Base()) } - -// Enforce the strict updatability linting to all applicable transitive dependencies. -func enforceStrictUpdatabilityLintingMutator(ctx android.TopDownMutatorContext) { - m := ctx.Module() - if d, ok := m.(LintDepSetsIntf); ok && d.GetStrictUpdatabilityLinting() { - ctx.VisitDirectDepsWithTag(staticLibTag, func(d android.Module) { - if a, ok := d.(LintDepSetsIntf); ok { - a.SetStrictUpdatabilityLinting(true) - } - }) - } -} diff --git a/java/lint_test.go b/java/lint_test.go index b51753f71..afe3914ff 100644 --- a/java/lint_test.go +++ b/java/lint_test.go @@ -164,7 +164,7 @@ func TestJavaLintStrictUpdatabilityLinting(t *testing.T) { sdk_version: "current", lint: { strict_updatability_linting: true, - baseline_filename: "lint-baseline.xml", + baseline_filename: "foo_lint_baseline.xml", }, } @@ -176,7 +176,7 @@ func TestJavaLintStrictUpdatabilityLinting(t *testing.T) { min_sdk_version: "29", sdk_version: "current", lint: { - baseline_filename: "lint-baseline.xml", + baseline_filename: "bar_lint_baseline.xml", } } ` @@ -188,18 +188,13 @@ func TestJavaLintStrictUpdatabilityLinting(t *testing.T) { RunTestWithBp(t, bp) foo := result.ModuleForTests("foo", "android_common") - sboxProto := android.RuleBuilderSboxProtoForTests(t, result.TestContext, foo.Output("lint.sbox.textproto")) - if !strings.Contains(*sboxProto.Commands[0].Command, - "--baseline lint-baseline.xml --disallowed_issues NewApi") { - t.Error("did not restrict baselining NewApi") - } - - bar := result.ModuleForTests("bar", "android_common") - sboxProto = android.RuleBuilderSboxProtoForTests(t, result.TestContext, bar.Output("lint.sbox.textproto")) - if !strings.Contains(*sboxProto.Commands[0].Command, - "--baseline lint-baseline.xml --disallowed_issues NewApi") { + strictUpdatabilityCheck := foo.Output("lint_strict_updatability_check.stamp") + if !strings.Contains(strictUpdatabilityCheck.RuleParams.Command, + "--disallowed_issues NewApi") { t.Error("did not restrict baselining NewApi") } + android.AssertStringListContains(t, "strict updatability check baseline inputs", strictUpdatabilityCheck.Inputs.Strings(), "foo_lint_baseline.xml") + android.AssertStringListContains(t, "strict updatability check baseline inputs", strictUpdatabilityCheck.Inputs.Strings(), "bar_lint_baseline.xml") } func TestJavaLintDatabaseSelectionFull(t *testing.T) { diff --git a/java/sdk_library.go b/java/sdk_library.go index eb9fa5f58..c7a129210 100644 --- a/java/sdk_library.go +++ b/java/sdk_library.go @@ -2257,21 +2257,6 @@ func (module *SdkLibraryImport) JacocoReportClassesFile() android.Path { } // to satisfy apex.javaDependency interface -func (module *SdkLibraryImport) GetStrictUpdatabilityLinting() bool { - if module.implLibraryModule == nil { - return false - } else { - return module.implLibraryModule.GetStrictUpdatabilityLinting() - } -} - -func (module *SdkLibraryImport) SetStrictUpdatabilityLinting(strictLinting bool) { - if module.implLibraryModule != nil { - module.implLibraryModule.SetStrictUpdatabilityLinting(strictLinting) - } -} - -// to satisfy apex.javaDependency interface func (module *SdkLibraryImport) Stem() string { return module.BaseModuleName() } diff --git a/java/testing.go b/java/testing.go index 6cc9fd125..d5a19e9d2 100644 --- a/java/testing.go +++ b/java/testing.go @@ -388,7 +388,6 @@ func registerRequiredBuildComponentsForTest(ctx android.RegistrationContext) { RegisterStubsBuildComponents(ctx) RegisterSystemModulesBuildComponents(ctx) registerSystemserverClasspathBuildComponents(ctx) - registerLintBuildComponents(ctx) android.RegisterApexContributionsBuildComponents(ctx) } diff --git a/scripts/Android.bp b/scripts/Android.bp index 3d81b83c2..00b3ca591 100644 --- a/scripts/Android.bp +++ b/scripts/Android.bp @@ -184,12 +184,21 @@ python_binary_host { libs: ["ninja_rsp"], } +python_binary_host { + name: "lint_strict_updatability_checks", + main: "lint_strict_updatability_checks.py", + srcs: [ + "lint_strict_updatability_checks.py", + ], + libs: ["ninja_rsp"], +} + python_test_host { - name: "lint_project_xml_test", - main: "lint_project_xml_test.py", + name: "lint_strict_updatability_checks_test", + main: "lint_strict_updatability_checks_test.py", srcs: [ - "lint_project_xml_test.py", - "lint_project_xml.py", + "lint_strict_updatability_checks_test.py", + "lint_strict_updatability_checks.py", ], libs: ["ninja_rsp"], test_suites: ["general-tests"], diff --git a/scripts/lint_project_xml.py b/scripts/lint_project_xml.py index c40b07d38..ce6aa21a2 100755 --- a/scripts/lint_project_xml.py +++ b/scripts/lint_project_xml.py @@ -75,8 +75,6 @@ def parse_args(): help='file containing the module\'s manifest.') parser.add_argument('--merged_manifest', dest='merged_manifest', help='file containing merged manifest for the module and its dependencies.') - parser.add_argument('--baseline', dest='baseline_path', - help='file containing baseline lint issues.') parser.add_argument('--library', dest='library', action='store_true', help='mark the module as a library.') parser.add_argument('--test', dest='test', action='store_true', @@ -94,8 +92,6 @@ def parse_args(): help='treat a lint issue as a warning.') group.add_argument('--disable_check', dest='checks', action=check_action('ignore'), default=[], help='disable a lint issue.') - group.add_argument('--disallowed_issues', dest='disallowed_issues', default=[], - help='lint issues disallowed in the baseline file') return parser.parse_args() @@ -140,30 +136,10 @@ def write_config_xml(f, args): f.write("</lint>\n") -def check_baseline_for_disallowed_issues(baseline, forced_checks): - issues_element = baseline.documentElement - if issues_element.tagName != 'issues': - raise RuntimeError('expected issues tag at root') - issues = issues_element.getElementsByTagName('issue') - disallowed = set() - for issue in issues: - id = issue.getAttribute('id') - if id in forced_checks: - disallowed.add(id) - return disallowed - - def main(): """Program entry point.""" args = parse_args() - if args.baseline_path: - baseline = minidom.parse(args.baseline_path) - disallowed_issues = check_baseline_for_disallowed_issues(baseline, args.disallowed_issues) - if disallowed_issues: - sys.exit('disallowed issues %s found in lint baseline file %s for module %s' - % (disallowed_issues, args.baseline_path, args.name)) - if args.project_out: with open(args.project_out, 'w') as f: write_project_xml(f, args) diff --git a/scripts/lint_strict_updatability_checks.py b/scripts/lint_strict_updatability_checks.py new file mode 100755 index 000000000..5b5dfd81a --- /dev/null +++ b/scripts/lint_strict_updatability_checks.py @@ -0,0 +1,81 @@ +#!/usr/bin/env python3 +# +# Copyright (C) 2018 The Android Open Source Project +# +# 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. +# + +"""This file checks baselines passed to Android Lint for checks that must not be baselined.""" + +import argparse +import sys +from xml.dom import minidom + +from ninja_rsp import NinjaRspFileReader + + +def parse_args(): + """Parse commandline arguments.""" + + def convert_arg_line_to_args(arg_line): + for arg in arg_line.split(): + if arg.startswith('#'): + return + if not arg.strip(): + continue + yield arg + + parser = argparse.ArgumentParser(fromfile_prefix_chars='@') + parser.convert_arg_line_to_args = convert_arg_line_to_args + parser.add_argument('--name', dest='name', + help='name of the module.') + parser.add_argument('--baselines', dest='baselines', action='append', default=[], + help='file containing whitespace separated list of baseline files.') + parser.add_argument('--disallowed_issues', dest='disallowed_issues', default=[], + help='lint issues disallowed in the baseline file') + return parser.parse_args() + + +def check_baseline_for_disallowed_issues(baseline, forced_checks): + issues_element = baseline.documentElement + if issues_element.tagName != 'issues': + raise RuntimeError('expected issues tag at root') + issues = issues_element.getElementsByTagName('issue') + disallowed = set() + for issue in issues: + id = issue.getAttribute('id') + if id in forced_checks: + disallowed.add(id) + return disallowed + + +def main(): + """Program entry point.""" + args = parse_args() + + error = False + for baseline_rsp_file in args.baselines: + for baseline_path in NinjaRspFileReader(baseline_rsp_file): + baseline = minidom.parse(baseline_path) + disallowed_issues = check_baseline_for_disallowed_issues(baseline, args.disallowed_issues) + if disallowed_issues: + print('disallowed issues %s found in lint baseline file %s for module %s' + % (disallowed_issues, baseline_path, args.name)) + error = True + + if error: + sys.exit(1) + + +if __name__ == '__main__': + main() diff --git a/scripts/lint_project_xml_test.py b/scripts/lint_strict_updatability_checks_test.py index 344691d00..fd8610f3a 100644..100755 --- a/scripts/lint_project_xml_test.py +++ b/scripts/lint_strict_updatability_checks_test.py @@ -15,12 +15,12 @@ # limitations under the License. # -"""Unit tests for lint_project_xml.py.""" +"""Unit tests for lint_strict_updatability_checks.py.""" import unittest from xml.dom import minidom -import lint_project_xml +import lint_strict_updatability_checks class CheckBaselineForDisallowedIssuesTest(unittest.TestCase): @@ -44,7 +44,7 @@ class CheckBaselineForDisallowedIssuesTest(unittest.TestCase): '</issues>\n') def test_check_baseline_for_disallowed_issues(self): - disallowed_issues = lint_project_xml.check_baseline_for_disallowed_issues(self.baseline_xml, ["foo", "bar", "qux"]) + disallowed_issues = lint_strict_updatability_checks.check_baseline_for_disallowed_issues(self.baseline_xml, ["foo", "bar", "qux"]) self.assertEqual({"foo", "bar"}, disallowed_issues) |