diff --git a/android/config.go b/android/config.go index 50e39d7e9..d64790b1c 100644 --- a/android/config.go +++ b/android/config.go @@ -127,7 +127,7 @@ type config struct { // If testAllowNonExistentPaths is true then PathForSource and PathForModuleSrc won't error // in tests when a path doesn't exist. - testAllowNonExistentPaths bool + TestAllowNonExistentPaths bool // The list of files that when changed, must invalidate soong_build to // regenerate build.ninja. @@ -254,7 +254,7 @@ func TestConfig(buildDir string, env map[string]string, bp string, fs map[string // Set testAllowNonExistentPaths so that test contexts don't need to specify every path // passed to PathForSource or PathForModuleSrc. - testAllowNonExistentPaths: true, + TestAllowNonExistentPaths: true, BazelContext: noopBazelContext{}, } diff --git a/android/paths.go b/android/paths.go index 44221be70..c9eb63303 100644 --- a/android/paths.go +++ b/android/paths.go @@ -582,7 +582,7 @@ func expandOneSrcPath(ctx ModuleWithDepsPathContext, sPath string, expandedExclu p := pathForModuleSrc(ctx, sPath) if exists, _, err := ctx.Config().fs.Exists(p.String()); err != nil { ReportPathErrorf(ctx, "%s: %s", p, err.Error()) - } else if !exists && !ctx.Config().testAllowNonExistentPaths { + } else if !exists && !ctx.Config().TestAllowNonExistentPaths { ReportPathErrorf(ctx, "module source path %q does not exist", p) } @@ -1018,7 +1018,7 @@ func PathForSource(ctx PathContext, pathComponents ...string) SourcePath { } } else if exists, _, err := ctx.Config().fs.Exists(path.String()); err != nil { ReportPathErrorf(ctx, "%s: %s", path, err.Error()) - } else if !exists && !ctx.Config().testAllowNonExistentPaths { + } else if !exists && !ctx.Config().TestAllowNonExistentPaths { ReportPathErrorf(ctx, "source path %q does not exist", path) } return path diff --git a/java/java_test.go b/java/java_test.go index e7776c35d..0ef4db680 100644 --- a/java/java_test.go +++ b/java/java_test.go @@ -127,7 +127,6 @@ func testJavaErrorWithConfig(t *testing.T, pattern string, config android.Config } t.Fatalf("missing expected error %q (0 errors are returned)", pattern) - return ctx, config } @@ -1179,6 +1178,110 @@ func TestIncludeSrcs(t *testing.T) { } } +func TestJavaLint(t *testing.T) { + ctx, _ := testJavaWithFS(t, ` + java_library { + name: "foo", + srcs: [ + "a.java", + "b.java", + "c.java", + ], + min_sdk_version: "29", + sdk_version: "system_current", + } + `, map[string][]byte{ + "lint-baseline.xml": nil, + }) + + foo := ctx.ModuleForTests("foo", "android_common") + rule := foo.Rule("lint") + + if !strings.Contains(rule.RuleParams.Command, "--baseline lint-baseline.xml") { + t.Error("did not pass --baseline flag") + } +} + +func TestJavaLintWithoutBaseline(t *testing.T) { + ctx, _ := testJavaWithFS(t, ` + java_library { + name: "foo", + srcs: [ + "a.java", + "b.java", + "c.java", + ], + min_sdk_version: "29", + sdk_version: "system_current", + } + `, map[string][]byte{}) + + foo := ctx.ModuleForTests("foo", "android_common") + rule := foo.Rule("lint") + + if strings.Contains(rule.RuleParams.Command, "--baseline") { + t.Error("passed --baseline flag for non existent file") + } +} + +func TestJavaLintRequiresCustomLintFileToExist(t *testing.T) { + config := testConfig( + nil, + ` + java_library { + name: "foo", + srcs: [ + ], + min_sdk_version: "29", + sdk_version: "system_current", + lint: { + baseline_filename: "mybaseline.xml", + }, + } + `, map[string][]byte{ + "build/soong/java/lint_defaults.txt": nil, + "prebuilts/cmdline-tools/tools/bin/lint": nil, + "prebuilts/cmdline-tools/tools/lib/lint-classpath.jar": nil, + "framework/aidl": nil, + "a.java": nil, + "AndroidManifest.xml": nil, + "build/make/target/product/security": nil, + }) + config.TestAllowNonExistentPaths = false + testJavaErrorWithConfig(t, + "source path \"mybaseline.xml\" does not exist", + config, + ) +} + +func TestJavaLintUsesCorrectBpConfig(t *testing.T) { + ctx, _ := testJavaWithFS(t, ` + java_library { + name: "foo", + srcs: [ + "a.java", + "b.java", + "c.java", + ], + min_sdk_version: "29", + sdk_version: "system_current", + lint: { + error_checks: ["SomeCheck"], + baseline_filename: "mybaseline.xml", + }, + } + `, map[string][]byte{ + "mybaseline.xml": nil, + }) + + foo := ctx.ModuleForTests("foo", "android_common") + rule := foo.Rule("lint") + + if !strings.Contains(rule.RuleParams.Command, "--baseline mybaseline.xml") { + t.Error("did not use the correct file for baseline") + } +} + func TestGeneratedSources(t *testing.T) { ctx, _ := testJavaWithFS(t, ` java_library { diff --git a/java/lint.go b/java/lint.go index cd2a904d6..a42deecdf 100644 --- a/java/lint.go +++ b/java/lint.go @@ -19,6 +19,8 @@ import ( "sort" "strings" + "github.com/google/blueprint/proptools" + "android/soong/android" ) @@ -46,6 +48,9 @@ type LintProperties struct { // Modules that provide extra lint checks Extra_check_modules []string + + // Name of the file that lint uses as the baseline. Defaults to "lint-baseline.xml". + Baseline_filename *string } } @@ -343,6 +348,19 @@ func (l *linter) lint(ctx android.ModuleContext) { cmd.FlagWithArg("--check ", checkOnly) } + if lintFilename := proptools.StringDefault(l.properties.Lint.Baseline_filename, "lint-baseline.xml"); lintFilename != "" { + var lintBaseline android.OptionalPath + if String(l.properties.Lint.Baseline_filename) != "" { + // if manually specified, we require the file to exist + lintBaseline = android.OptionalPathForPath(android.PathForModuleSrc(ctx, lintFilename)) + } else { + lintBaseline = android.ExistentPathForSource(ctx, ctx.ModuleDir(), lintFilename) + } + if lintBaseline.Valid() { + cmd.FlagWithInput("--baseline ", lintBaseline.Path()) + } + } + cmd.Text("|| (").Text("cat").Input(text).Text("; exit 7)").Text(")") rule.Command().Text("rm -rf").Flag(cacheDir.String()).Flag(homeDir.String())