1 /* 2 * Copyright (C) 2024 The Android Open Source Project 3 * 4 * Licensed under the Apache License, Version 2.0 (the "License"); 5 * you may not use this file except in compliance with the License. 6 * You may obtain a copy of the License at 7 * 8 * http://www.apache.org/licenses/LICENSE-2.0 9 * 10 * Unless required by applicable law or agreed to in writing, software 11 * distributed under the License is distributed on an "AS IS" BASIS, 12 * WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied. 13 * See the License for the specific language governing permissions and 14 * limitations under the License. 15 */ 16 17 package com.android.tools.metalava.cli.lint 18 19 import com.android.tools.metalava.cli.common.BaselineOptionsMixin 20 import com.android.tools.metalava.cli.common.CommonBaselineOptions 21 import com.android.tools.metalava.cli.common.ExecutionEnvironment 22 import com.android.tools.metalava.cli.common.PreviouslyReleasedApi 23 import com.android.tools.metalava.cli.common.allowStructuredOptionName 24 import com.android.tools.metalava.cli.common.existingFile 25 import com.android.tools.metalava.lint.DefaultLintErrorMessage 26 import com.github.ajalt.clikt.parameters.groups.OptionGroup 27 import com.github.ajalt.clikt.parameters.options.default 28 import com.github.ajalt.clikt.parameters.options.flag 29 import com.github.ajalt.clikt.parameters.options.multiple 30 import com.github.ajalt.clikt.parameters.options.option 31 32 const val ARG_API_LINT = "--api-lint" 33 const val ARG_API_LINT_PREVIOUS_API = "--api-lint-previous-api" 34 const val ARG_ERROR_MESSAGE_API_LINT = "--error-message:api-lint" 35 36 const val ARG_BASELINE_API_LINT = "--baseline:api-lint" 37 const val ARG_UPDATE_BASELINE_API_LINT = "--update-baseline:api-lint" 38 39 const val ARG_ALLOWED_ACRONYM = "--api-lint-allowed-acronym" 40 41 /** The name of the group, can be used in help text to refer to the options in this group. */ 42 const val API_LINT_GROUP = "Api Lint" 43 44 class ApiLintOptions( 45 executionEnvironment: ExecutionEnvironment = ExecutionEnvironment(), 46 commonBaselineOptions: CommonBaselineOptions = CommonBaselineOptions(), 47 ) : 48 OptionGroup( 49 name = API_LINT_GROUP, 50 help = 51 """ 52 Options controlling API linting. 53 """ 54 .trimIndent(), 55 ) { 56 57 internal val apiLintEnabled: Boolean by 58 option( 59 ARG_API_LINT, 60 help = 61 """ 62 Check API for Android API best practices. 63 """ 64 .trimIndent(), 65 ) 66 .flag() 67 68 internal val apiLintPreviousApis by 69 option( 70 ARG_API_LINT_PREVIOUS_API, 71 help = 72 """ 73 An API signature file that defines, albeit maybe only partially, a 74 previously released API. 75 76 If the API surface extends another API surface then this must include all 77 the corresponding signature files in order from the outermost API surface 78 that does not extend any API surface to the innermost one that represents 79 the API surface being generated. 80 81 API Lint issues found in the previously released API will be ignored. 82 """ 83 .trimIndent(), 84 ) 85 .existingFile() 86 .multiple() 87 88 /** 89 * The optional [PreviouslyReleasedApi]. If provided then only API lint issues which are new 90 * since that API was released will be reported. 91 */ 92 internal val previouslyReleasedApi by <lambda>null93 lazy(LazyThreadSafetyMode.NONE) { 94 PreviouslyReleasedApi.optionalPreviouslyReleasedApi( 95 ARG_API_LINT_PREVIOUS_API, 96 apiLintPreviousApis 97 ) 98 } 99 100 /** 101 * If set, metalava will show this error message when "API lint" (i.e. [ARG_API_LINT]) fails. 102 */ 103 internal val errorMessage: String? by 104 option( 105 ARG_ERROR_MESSAGE_API_LINT, 106 help = 107 """ 108 If set, this is output when errors are detected in $ARG_API_LINT. 109 """ 110 .trimIndent(), 111 metavar = "<message>", 112 ) 113 .default(DefaultLintErrorMessage, defaultForHelp = "") 114 .allowStructuredOptionName() 115 116 internal val allowedAcronyms: List<String> by 117 option( 118 ARG_ALLOWED_ACRONYM, 119 help = 120 """ 121 An acronym that should be allowed by API lint. Can be specified multiple times. 122 """ 123 .trimIndent(), 124 metavar = "<acronym>" 125 ) 126 .multiple() 127 128 private val baselineOptionsMixin = 129 BaselineOptionsMixin( 130 containingGroup = this, 131 executionEnvironment, 132 baselineOptionName = ARG_BASELINE_API_LINT, 133 updateBaselineOptionName = ARG_UPDATE_BASELINE_API_LINT, 134 issueType = "API lint", 135 description = "api-lint", 136 commonBaselineOptions = commonBaselineOptions, 137 ) 138 139 internal val baseline by baselineOptionsMixin::baseline 140 } 141