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

Commit 574cc84a authored by Makoto Onuki's avatar Makoto Onuki Committed by Gerrit Code Review
Browse files

Merge "Merge the "big 3" metalava invocations into one"

parents e051d0d3 88b9905d
Loading
Loading
Loading
Loading
+93 −112
Original line number Diff line number Diff line
@@ -1473,46 +1473,16 @@ 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())
	}

	rule.Restat()

	zipSyncCleanupCmd(rule, srcJarDir)
	doApiLint := false
	doCheckReleased := false

	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)

		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)
		doApiLint = true

		newSince := android.OptionalPathForModuleSrc(ctx, d.properties.Check_api.Api_lint.New_since)
		if newSince.Valid() {
@@ -1521,35 +1491,39 @@ func (d *Droidstubs) GenerateAndroidBuildActions(ctx android.ModuleContext) {
			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)
		cmd.FlagWithOutput("--report-even-if-suppressed ", d.apiLintReport) // TODO:  Change to ":api-lint"

		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 {
@@ -1557,21 +1531,82 @@ 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() {

@@ -1584,7 +1619,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")
@@ -1592,8 +1627,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")
@@ -1652,60 +1687,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",