diff --git a/build.gradle b/build.gradle index 1fb56b1b6507ea6b2384e4893c5240c44b04ade8..ad5e88029928872ad5b64e5718e7e519d90df19f 100644 --- a/build.gradle +++ b/build.gradle @@ -109,7 +109,7 @@ configurations { } dependencies { - ktlint "com.github.shyiko:ktlint:0.29.0" + ktlint "com.github.shyiko:ktlint:0.30.0" } task ktlint(type: JavaExec, group: "verification") { diff --git a/src/main/java/com/android/tools/metalava/Options.kt b/src/main/java/com/android/tools/metalava/Options.kt index 8afb8cb5fd51ca34fb911a6fab223f35851b8f6f..7b9698d7c5a9ca74dcee3da7e296a3ae2ac0e767 100644 --- a/src/main/java/com/android/tools/metalava/Options.kt +++ b/src/main/java/com/android/tools/metalava/Options.kt @@ -136,7 +136,8 @@ const val ARG_INCLUDE_ANNOTATION_CLASSES = "--include-annotation-classes" const val ARG_REWRITE_ANNOTATIONS = "--rewrite-annotations" const val ARG_INCLUDE_SOURCE_RETENTION = "--include-source-retention" const val ARG_INCLUDE_SIG_VERSION = "--include-signature-version" -const val ARG_UPDATE_API = "--update-api" +const val ARG_UPDATE_API = "--only-update-api" +const val ARG_CHECK_API = "--only-check-api" const val ARG_PASS_BASELINE_UPDATES = "--pass-baseline-updates" const val ARG_DEX_API_MAPPING = "--dex-api-mapping" const val ARG_GENERATE_DOCUMENTATION = "--generate-documentation" @@ -241,7 +242,20 @@ class Options( * signature files. This avoids having duplicate metalava invocation logic where potentially newly * added flags are missing in one of the invocations etc. */ - var updateApi = false + var onlyUpdateApi = false + + /** + * Whether metalava is invoked as part of running the checkapi target. When this is true, metalava + * should *cancel* various other flags that are also being passed in, such as updating signature + * files. + * + * This is there to ease integration in the build system: for a given target, the build system will + * pass all the applicable flags (--stubs, --api, --check-compatibility, --generate-documentation, etc), + * and this integration is re-used for the checkapi facility where we *only* want to run compatibility + * checks. This avoids having duplicate metalava invocation logic where potentially newly + * added flags are missing in one of the invocations etc. + */ + var onlyCheckApi = false /** * Whether signature files should emit in "compat" mode, preserving the various @@ -420,7 +434,7 @@ class Options( var migrateNullsFrom: File? = null /** Private backing list for [compatibilityChecks]] */ - private var mutableCompatibilityChecks: MutableList<CheckRequest> = mutableListOf() + private val mutableCompatibilityChecks: MutableList<CheckRequest> = mutableListOf() /** The list of compatibility checks to run */ val compatibilityChecks: List<CheckRequest> = mutableCompatibilityChecks @@ -986,7 +1000,8 @@ class Options( ARG_NO_DOCS, "-nodocs" -> noDocs = true - ARG_UPDATE_API -> updateApi = true + ARG_UPDATE_API, "--update-api" -> onlyUpdateApi = true + ARG_CHECK_API -> onlyCheckApi = true ARG_GENERATE_DOCUMENTATION -> { // Digest all the remaining arguments. @@ -1350,7 +1365,10 @@ class Options( generateAnnotations = false } - if (updateApi) { + if (onlyUpdateApi) { + if (onlyCheckApi) { + throw DriverException(stderr = "Cannot supply both $ARG_UPDATE_API and $ARG_CHECK_API at the same time") + } // We're running in update API mode: cancel other "action" flags; only signature file generation // flags count annotationCoverageClassReport = null @@ -1373,6 +1391,46 @@ class Options( mutableCompatibilityChecks.clear() mutableAnnotationCoverageOf.clear() artifactRegistrations.clear() + mutableConvertToXmlFiles.clear() + nullabilityAnnotationsValidator = null + nullabilityWarningsTxt = null + validateNullabilityFromMergedStubs = false + validateNullabilityFromMergedStubs = false + validateNullabilityFromList = null + } else if (onlyCheckApi) { + annotationCoverageClassReport = null + annotationCoverageMemberReport = null + dumpAnnotationStatistics = false + apiLevelJars = null + generateApiLevelXml = null + applyApiLevelsXml = null + androidJarSignatureFiles = null + stubsDir = null + docStubsDir = null + stubsSourceList = null + docStubsSourceList = null + sdkValueDir = null + externalAnnotations = null + proguard = null + noDocs = true + invokeDocumentationToolArguments = emptyArray() + checkKotlinInterop = false + mutableAnnotationCoverageOf.clear() + artifactRegistrations.clear() + mutableConvertToXmlFiles.clear() + nullabilityAnnotationsValidator = null + nullabilityWarningsTxt = null + validateNullabilityFromMergedStubs = false + validateNullabilityFromMergedStubs = false + validateNullabilityFromList = null + apiFile = null + apiXmlFile = null + privateApiFile = null + dexApiFile = null + dexApiMappingFile = null + privateDexApiFile = null + removedApiFile = null + removedDexApiFile = null } if (baselineFile == null) { @@ -1790,6 +1848,8 @@ class Options( "to make it easier customize build system tasks.", ARG_UPDATE_API, "Cancel any other \"action\" flags other than generating signature files. This is here " + "to make it easier customize build system tasks, particularly for the \"make update-api\" task.", + ARG_CHECK_API, "Cancel any other \"action\" flags other than checking signature files. This is here " + + "to make it easier customize build system tasks, particularly for the \"make checkapi\" task.", "", "\nAPI sources:", "$ARG_SOURCE_FILES <files>", "A comma separated list of source files to be parsed. Can also be " + diff --git a/src/test/java/com/android/tools/metalava/OptionsTest.kt b/src/test/java/com/android/tools/metalava/OptionsTest.kt index 36d02bf03f2735ac1277cb4e3293ab13f91f6a2f..c405942eb5e2c475ea16dfe556dfa09c04471be5 100644 --- a/src/test/java/com/android/tools/metalava/OptionsTest.kt +++ b/src/test/java/com/android/tools/metalava/OptionsTest.kt @@ -42,10 +42,14 @@ General: --no-docs Cancel any other documentation flags supplied to metalava. This is here to make it easier customize build system tasks. ---update-api Cancel any other "action" flags other than +--only-update-api Cancel any other "action" flags other than generating signature files. This is here to make it easier customize build system tasks, particularly for the "make update-api" task. +--only-check-api Cancel any other "action" flags other than + checking signature files. This is here to make + it easier customize build system tasks, + particularly for the "make checkapi" task. API sources: --source-files <files> A comma separated list of source files to be diff --git a/src/test/java/com/android/tools/metalava/StubsTest.kt b/src/test/java/com/android/tools/metalava/StubsTest.kt index 3143036218d450022a35bf0d0422b7127c7df4c0..d0eb814955e9acf2dd4591a4d8998228bebc49f7 100644 --- a/src/test/java/com/android/tools/metalava/StubsTest.kt +++ b/src/test/java/com/android/tools/metalava/StubsTest.kt @@ -3715,6 +3715,41 @@ class StubsTest : DriverTest() { ) } + @Test(expected = AssertionError::class) + fun `Test check-api should not generate stubs or API files`() { + check( + extraArguments = arrayOf( + ARG_CHECK_API, + ARG_EXCLUDE_ANNOTATIONS + ), + compatibilityMode = false, + sourceFiles = *arrayOf( + java( + """ + package test.pkg; + public class Foo { + /** + * @deprecated Use checkPermission instead. + */ + @Deprecated + protected boolean inClass(String name) { + return false; + } + } + """ + ) + ), + api = """ + package test.pkg { + public class Foo { + ctor public Foo(); + method @Deprecated protected boolean inClass(String); + } + } + """ + ) + } + @Test fun `Include package private classes referenced from public API`() { // Real world example: android.net.http.Connection in apache-http referenced from RequestHandle