Donate to e Foundation | Murena handsets with /e/OS | Own a part of Murena! Learn more

Commit ba15f142 authored by Makoto Onuki's avatar Makoto Onuki Committed by Android (Google) Code Review
Browse files

Merge "Merge the "big 3" metalava invocations into one" into rvc-dev

parents 5c5c4d93 b850a9de
Loading
Loading
Loading
Loading
+100 −119
Original line number Diff line number Diff line
@@ -1448,44 +1448,25 @@ func (d *Droidstubs) GenerateAndroidBuildActions(ctx android.ModuleContext) {
		cmd.ImplicitOutput(android.PathForModuleGen(ctx, o))
	}

	if generateStubs {
		rule.Command().
			BuiltTool(ctx, "soong_zip").
			Flag("-write_if_changed").
			Flag("-jar").
			FlagWithOutput("-o ", d.Javadoc.stubsSrcJar).
			FlagWithArg("-C ", stubsDir.String()).
			FlagWithArg("-D ", stubsDir.String())
	}
	// Add options for the other optional tasks: API-lint and check-released.
	// We generate separate timestamp files for them.

	if Bool(d.properties.Write_sdk_values) {
		d.metadataZip = android.PathForModuleOut(ctx, ctx.ModuleName()+"-metadata.zip")
		rule.Command().
			BuiltTool(ctx, "soong_zip").
			Flag("-write_if_changed").
			Flag("-d").
			FlagWithOutput("-o ", d.metadataZip).
			FlagWithArg("-C ", d.metadataDir.String()).
			FlagWithArg("-D ", d.metadataDir.String())
	}
	doApiLint := false
	doCheckReleased := false

	rule.Restat()

	zipSyncCleanupCmd(rule, srcJarDir)

	rule.Build(pctx, ctx, "metalava", "metalava")

	// Create rule for apicheck
	// Add API lint options.

	if BoolDefault(d.properties.Check_api.Api_lint.Enabled, false) && !ctx.Config().IsPdkBuild() {
		rule := android.NewRuleBuilder()
		rule.Command().Text("( true")

		srcJarDir := android.PathForModuleOut(ctx, "api_lint", "srcjars")
		srcJarList := zipSyncCmd(ctx, rule, srcJarDir, d.Javadoc.srcJars)
		doApiLint = true

		cmd := metalavaCmd(ctx, rule, javaVersion, d.Javadoc.srcFiles, srcJarList,
			deps.bootClasspath, deps.classpath, d.Javadoc.sourcepaths)
		newSince := android.OptionalPathForModuleSrc(ctx, d.properties.Check_api.Api_lint.New_since)
		if newSince.Valid() {
			cmd.FlagWithInput("--api-lint ", newSince.Path())
		} else {
			cmd.Flag("--api-lint")
		}
		d.apiLintReport = android.PathForModuleOut(ctx, "api_lint_report.txt")
		cmd.FlagWithOutput("--report-even-if-suppressed ", d.apiLintReport) // TODO:  Change to ":api-lint"

		// TODO(b/154317059): Clean up this whitelist by baselining and/or checking in last-released.
		if d.Name() != "android.car-system-stubs-docs" &&
@@ -1496,44 +1477,37 @@ func (d *Droidstubs) GenerateAndroidBuildActions(ctx android.ModuleContext) {
			cmd.Flag("--warnings-as-errors") // Most lints are actually warnings.
		}

		cmd.Flag(d.Javadoc.args).Implicits(d.Javadoc.argFiles)

		newSince := android.OptionalPathForModuleSrc(ctx, d.properties.Check_api.Api_lint.New_since)
		if newSince.Valid() {
			cmd.FlagWithInput("--api-lint ", newSince.Path())
		} else {
			cmd.Flag("--api-lint")
		}
		d.apiLintReport = android.PathForModuleOut(ctx, "api_lint_report.txt")
		cmd.FlagWithOutput("--report-even-if-suppressed ", d.apiLintReport)

		d.inclusionAnnotationsFlags(ctx, cmd)
		d.mergeAnnoDirFlags(ctx, cmd)

		baselineFile := android.OptionalPathForModuleSrc(ctx, d.properties.Check_api.Api_lint.Baseline_file)
		updatedBaselineOutput := android.PathForModuleOut(ctx, "api_lint_baseline.txt")
		d.apiLintTimestamp = android.PathForModuleOut(ctx, "api_lint.timestamp")

		msg := `` +
		// Note this string includes a special shell quote $' ... ', which decodes the "\n"s.
		// However, because $' ... ' doesn't expand environmental variables, we can't just embed
		// $PWD, so we have to terminate $'...', use "$PWD", then start $' ... ' again,
		// which is why we have '"$PWD"$' in it.
		//
		// TODO: metalava also has a slightly different message hardcoded. Should we unify this
		// message and metalava's one?
		msg := `$'` + // Enclose with $' ... '
			`************************************************************\n` +
			`Your API changes are triggering API Lint warnings or errors.\n` +
			`To make these errors go away, fix the code according to the\n` +
			`error and/or warning messages above.\n` +
			`\n` +
			`If it's not possible to do so, there are workarounds:\n` +
			`If it is not possible to do so, there are workarounds:\n` +
			`\n` +
			`1. You can suppress the errors with @SuppressLint(\"<id>\")\n`
			`1. You can suppress the errors with @SuppressLint("<id>")\n`

		if baselineFile.Valid() {
			cmd.FlagWithInput("--baseline ", baselineFile.Path())
			cmd.FlagWithOutput("--update-baseline ", updatedBaselineOutput)
			cmd.FlagWithInput("--baseline:api-lint ", baselineFile.Path())
			cmd.FlagWithOutput("--update-baseline:api-lint ", updatedBaselineOutput)

			msg += fmt.Sprintf(``+
				`2. You can update the baseline by executing the following\n`+
				`   command:\n`+
				`       cp \\ \n`+
				`       \"$PWD/%s\" \\ \n`+
				`       \"$PWD/%s\" \n`+
				`       "'"$PWD"$'/%s" \\ \n`+
				`       "'"$PWD"$'/%s" \n`+
				`   To submit the revised baseline.txt to the main Android\n`+
				`   repository, you will need approval.\n`, updatedBaselineOutput, baselineFile.Path())
		} else {
@@ -1541,20 +1515,81 @@ func (d *Droidstubs) GenerateAndroidBuildActions(ctx android.ModuleContext) {
				`2. You can add a baseline file of existing lint failures\n`+
				`   to the build rule of %s.\n`, d.Name())
		}
		msg += `************************************************************\n`
		// Note the message ends with a ' (single quote), to close the $' ... ' .
		msg += `************************************************************\n'`

		zipSyncCleanupCmd(rule, srcJarDir)
		cmd.FlagWithArg("--error-message:api-lint ", msg)
	}

	// Add "check released" options. (Detect incompatible API changes from the last public release)

	if apiCheckEnabled(ctx, d.properties.Check_api.Last_released, "last_released") &&
		!ctx.Config().IsPdkBuild() {
		doCheckReleased = true

		if len(d.Javadoc.properties.Out) > 0 {
			ctx.PropertyErrorf("out", "out property may not be combined with check_api")
		}

		apiFile := android.PathForModuleSrc(ctx, String(d.properties.Check_api.Last_released.Api_file))
		removedApiFile := android.PathForModuleSrc(ctx, String(d.properties.Check_api.Last_released.Removed_api_file))
		baselineFile := android.OptionalPathForModuleSrc(ctx, d.properties.Check_api.Last_released.Baseline_file)
		updatedBaselineOutput := android.PathForModuleOut(ctx, "last_released_baseline.txt")

		d.checkLastReleasedApiTimestamp = android.PathForModuleOut(ctx, "check_last_released_api.timestamp")

		cmd.FlagWithInput("--check-compatibility:api:released ", apiFile)
		cmd.FlagWithInput("--check-compatibility:removed:released ", removedApiFile)

		if baselineFile.Valid() {
			cmd.FlagWithInput("--baseline:compatibility:released ", baselineFile.Path())
			cmd.FlagWithOutput("--update-baseline:compatibility:released ", updatedBaselineOutput)
		}

		// Note this string includes quote ($' ... '), which decodes the "\n"s.
		msg := `$'\n******************************\n` +
			`You have tried to change the API from what has been previously released in\n` +
			`an SDK.  Please fix the errors listed above.\n` +
			`******************************\n'`

		cmd.FlagWithArg("--error-message:compatibility:released ", msg)
	}

	if generateStubs {
		rule.Command().
			Text("touch").Output(d.apiLintTimestamp).
			Text(") || (").
			Text("echo").Flag("-e").Flag(`"` + msg + `"`).
			Text("; exit 38").
			Text(")")
			BuiltTool(ctx, "soong_zip").
			Flag("-write_if_changed").
			Flag("-jar").
			FlagWithOutput("-o ", d.Javadoc.stubsSrcJar).
			FlagWithArg("-C ", stubsDir.String()).
			FlagWithArg("-D ", stubsDir.String())
	}

		rule.Build(pctx, ctx, "metalavaApiLint", "metalava API lint")
	if Bool(d.properties.Write_sdk_values) {
		d.metadataZip = android.PathForModuleOut(ctx, ctx.ModuleName()+"-metadata.zip")
		rule.Command().
			BuiltTool(ctx, "soong_zip").
			Flag("-write_if_changed").
			Flag("-d").
			FlagWithOutput("-o ", d.metadataZip).
			FlagWithArg("-C ", d.metadataDir.String()).
			FlagWithArg("-D ", d.metadataDir.String())
	}

	// TODO: We don't really need two separate API files, but this is a reminiscence of how
	// we used to run metalava separately for API lint and the "last_released" check. Unify them.
	if doApiLint {
		rule.Command().Text("touch").Output(d.apiLintTimestamp)
	}
	if doCheckReleased {
		rule.Command().Text("touch").Output(d.checkLastReleasedApiTimestamp)
	}

	rule.Restat()

	zipSyncCleanupCmd(rule, srcJarDir)

	rule.Build(pctx, ctx, "metalava", "metalava merged")

	if apiCheckEnabled(ctx, d.properties.Check_api.Current, "current") &&
		!ctx.Config().IsPdkBuild() {
@@ -1568,7 +1603,7 @@ func (d *Droidstubs) GenerateAndroidBuildActions(ctx android.ModuleContext) {
		baselineFile := android.OptionalPathForModuleSrc(ctx, d.properties.Check_api.Current.Baseline_file)

		if baselineFile.Valid() {
			ctx.PropertyErrorf("current API check can't have a baseline file. (module %s)", ctx.ModuleName())
			ctx.PropertyErrorf("baseline_file", "current API check can't have a baseline file. (module %s)", ctx.ModuleName())
		}

		d.checkCurrentApiTimestamp = android.PathForModuleOut(ctx, "check_current_api.timestamp")
@@ -1576,8 +1611,8 @@ func (d *Droidstubs) GenerateAndroidBuildActions(ctx android.ModuleContext) {
		rule := android.NewRuleBuilder()

		// Diff command line.
		// -F matches the closest "opening" line, such as "package xxx{"
		// and "  public class Yyy {".
		// -F matches the closest "opening" line, such as "package android {"
		// and "  public class Intent {".
		diff := `diff -u -F '{ *$'`

		rule.Command().Text("( true")
@@ -1636,60 +1671,6 @@ func (d *Droidstubs) GenerateAndroidBuildActions(ctx android.ModuleContext) {
		rule.Build(pctx, ctx, "metalavaCurrentApiUpdate", "update current API")
	}

	if apiCheckEnabled(ctx, d.properties.Check_api.Last_released, "last_released") &&
		!ctx.Config().IsPdkBuild() {

		if len(d.Javadoc.properties.Out) > 0 {
			ctx.PropertyErrorf("out", "out property may not be combined with check_api")
		}

		apiFile := android.PathForModuleSrc(ctx, String(d.properties.Check_api.Last_released.Api_file))
		removedApiFile := android.PathForModuleSrc(ctx, String(d.properties.Check_api.Last_released.Removed_api_file))
		baselineFile := android.OptionalPathForModuleSrc(ctx, d.properties.Check_api.Last_released.Baseline_file)
		updatedBaselineOutput := android.PathForModuleOut(ctx, "last_released_baseline.txt")

		d.checkLastReleasedApiTimestamp = android.PathForModuleOut(ctx, "check_last_released_api.timestamp")

		rule := android.NewRuleBuilder()

		rule.Command().Text("( true")

		srcJarDir := android.PathForModuleOut(ctx, "last-apicheck", "srcjars")
		srcJarList := zipSyncCmd(ctx, rule, srcJarDir, d.Javadoc.srcJars)

		cmd := metalavaCmd(ctx, rule, javaVersion, d.Javadoc.srcFiles, srcJarList,
			deps.bootClasspath, deps.classpath, d.Javadoc.sourcepaths)

		cmd.Flag(d.Javadoc.args).Implicits(d.Javadoc.argFiles).
			FlagWithInput("--check-compatibility:api:released ", apiFile)

		d.inclusionAnnotationsFlags(ctx, cmd)

		cmd.FlagWithInput("--check-compatibility:removed:released ", removedApiFile)

		d.mergeAnnoDirFlags(ctx, cmd)

		if baselineFile.Valid() {
			cmd.FlagWithInput("--baseline ", baselineFile.Path())
			cmd.FlagWithOutput("--update-baseline ", updatedBaselineOutput)
		}

		zipSyncCleanupCmd(rule, srcJarDir)

		msg := `\n******************************\n` +
			`You have tried to change the API from what has been previously released in\n` +
			`an SDK.  Please fix the errors listed above.\n` +
			`******************************\n`
		rule.Command().
			Text("touch").Output(d.checkLastReleasedApiTimestamp).
			Text(") || (").
			Text("echo").Flag("-e").Flag(`"` + msg + `"`).
			Text("; exit 38").
			Text(")")

		rule.Build(pctx, ctx, "metalavaLastApiCheck", "metalava check last API")
	}

	if String(d.properties.Check_nullability_warnings) != "" {
		if d.nullabilityWarningsFile == nil {
			ctx.PropertyErrorf("check_nullability_warnings",