1 /*
<lambda>null2  * Copyright 2020 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 androidx.build
18 
19 import androidx.build.dependencyTracker.AffectedModuleDetector
20 import org.gradle.api.GradleException
21 import org.gradle.api.Project
22 import org.gradle.api.provider.Provider
23 
24 /**
25  * Whether to enable constraints for projects in same-version groups
26  *
27  * This is default true.
28  */
29 const val ADD_GROUP_CONSTRAINTS = "androidx.constraints"
30 
31 /**
32  * Setting this property makes Test tasks succeed even if there are some failing tests. Useful when
33  * running tests in CI where build passes test results as XML to test reporter.
34  */
35 const val TEST_FAILURES_DO_NOT_FAIL_TEST_TASK = "androidx.ignoreTestFailures"
36 
37 /** Setting this property to false makes test tasks not display detailed output to stdout. */
38 const val DISPLAY_TEST_OUTPUT = "androidx.displayTestOutput"
39 
40 /** Setting this property changes "url" property in publishing maven artifact metadata */
41 const val ALTERNATIVE_PROJECT_URL = "androidx.alternativeProjectUrl"
42 
43 /** Validate the project structure against Jetpack guidelines */
44 const val VALIDATE_PROJECT_STRUCTURE = "androidx.validateProjectStructure"
45 
46 /**
47  * Setting this property enables Compose Compiler metrics - see
48  * compose/compiler/design/compiler-metrics.md
49  */
50 const val ENABLE_COMPOSE_COMPILER_METRICS = "androidx.enableComposeCompilerMetrics"
51 
52 /**
53  * Setting this property enables Compose Compiler reports - see
54  * compose/compiler/design/compiler-metrics.md
55  */
56 const val ENABLE_COMPOSE_COMPILER_REPORTS = "androidx.enableComposeCompilerReports"
57 
58 /** Returns whether the project should generate documentation. */
59 const val ENABLE_DOCUMENTATION = "androidx.enableDocumentation"
60 
61 /** Setting this property puts a summary of the relevant failure messages into standard error */
62 const val SUMMARIZE_STANDARD_ERROR = "androidx.summarizeStderr"
63 
64 /**
65  * Setting this property indicates that a build is being performed to check for forward
66  * compatibility.
67  */
68 const val USE_MAX_DEP_VERSIONS = "androidx.useMaxDepVersions"
69 
70 /** Setting this property enables writing versioned API files */
71 const val WRITE_VERSIONED_API_FILES = "androidx.writeVersionedApiFiles"
72 
73 /**
74  * Build id used to pull SNAPSHOT versions to substitute project dependencies in Playground projects
75  */
76 const val PLAYGROUND_SNAPSHOT_BUILD_ID = "androidx.playground.snapshotBuildId"
77 
78 /** Build Id used to pull SNAPSHOT version of Metalava for Playground projects */
79 const val PLAYGROUND_METALAVA_BUILD_ID = "androidx.playground.metalavaBuildId"
80 
81 /** Specifies to prepend the current time to each Gradle log message */
82 const val PRINT_TIMESTAMPS = "androidx.printTimestamps"
83 
84 /**
85  * Filepath to the java agent of YourKit for profiling If this value is set, profiling via YourKit
86  * will automatically be enabled
87  */
88 const val PROFILE_YOURKIT_AGENT_PATH = "androidx.profile.yourkitAgentPath"
89 
90 /**
91  * Specifies to validate that the build doesn't generate any unrecognized messages This prevents
92  * developers from inadvertently adding new warnings to the build output
93  */
94 const val VALIDATE_NO_UNRECOGNIZED_MESSAGES = "androidx.validateNoUnrecognizedMessages"
95 
96 /**
97  * Specifies to run the build twice and validate that the second build doesn't run more tasks than
98  * expected.
99  */
100 const val VERIFY_UP_TO_DATE = "androidx.verifyUpToDate"
101 
102 /**
103  * If true, we are building in GitHub and should enable build features related to KMP. If false, we
104  * are in AOSP, where not all KMP features are enabled.
105  */
106 const val KMP_GITHUB_BUILD = "androidx.github.build"
107 
108 /** Specifies to give as much memory to Gradle as in a typical CI run */
109 const val HIGH_MEMORY = "androidx.highMemory"
110 
111 /** Negates the HIGH_MEMORY flag */
112 const val LOW_MEMORY = "androidx.lowMemory"
113 
114 /**
115  * If true, don't require lint-checks project to exist. This should only be set in integration
116  * tests, to allow them to save time by not configuring extra projects.
117  */
118 const val ALLOW_MISSING_LINT_CHECKS_PROJECT = "androidx.allow.missing.lint"
119 
120 /**
121  * If set to a uri, this is the location that will be used to download `xcodegen` when running
122  * Darwin benchmarks.
123  */
124 const val XCODEGEN_DOWNLOAD_URI = "androidx.benchmark.darwin.xcodeGenDownloadUri"
125 
126 /** If true, don't restrict usage of compileSdk property. */
127 const val ALLOW_CUSTOM_COMPILE_SDK = "androidx.allowCustomCompileSdk"
128 
129 /** If true, yarn dependencies are fetched from an offline mirror */
130 const val YARN_OFFLINE_MODE = "androidx.yarnOfflineMode"
131 
132 const val FORCE_KOTLIN_2_0_TARGET = "androidx.forceKotlin20Target"
133 
134 /** Defined by AndroidX Benchmark Plugin, may be used for local experiments with compilation */
135 const val FORCE_BENCHMARK_AOT_COMPILATION = "androidx.benchmark.forceaotcompilation"
136 
137 val ALL_ANDROIDX_PROPERTIES =
138     setOf(
139         ADD_GROUP_CONSTRAINTS,
140         ALTERNATIVE_PROJECT_URL,
141         VALIDATE_PROJECT_STRUCTURE,
142         ENABLE_COMPOSE_COMPILER_METRICS,
143         ENABLE_COMPOSE_COMPILER_REPORTS,
144         DISPLAY_TEST_OUTPUT,
145         ENABLE_DOCUMENTATION,
146         HIGH_MEMORY,
147         LOW_MEMORY,
148         STUDIO_TYPE,
149         SUMMARIZE_STANDARD_ERROR,
150         USE_MAX_DEP_VERSIONS,
151         TEST_FAILURES_DO_NOT_FAIL_TEST_TASK,
152         VALIDATE_NO_UNRECOGNIZED_MESSAGES,
153         VERIFY_UP_TO_DATE,
154         WRITE_VERSIONED_API_FILES,
155         AffectedModuleDetector.ENABLE_ARG,
156         AffectedModuleDetector.BASE_COMMIT_ARG,
157         PLAYGROUND_SNAPSHOT_BUILD_ID,
158         PLAYGROUND_METALAVA_BUILD_ID,
159         PRINT_TIMESTAMPS,
160         PROFILE_YOURKIT_AGENT_PATH,
161         KMP_GITHUB_BUILD,
162         ENABLED_KMP_TARGET_PLATFORMS,
163         ALLOW_MISSING_LINT_CHECKS_PROJECT,
164         XCODEGEN_DOWNLOAD_URI,
165         ALLOW_CUSTOM_COMPILE_SDK,
166         FilteredAnchorTask.PROP_TASK_NAME,
167         FilteredAnchorTask.PROP_PATH_PREFIX,
168         YARN_OFFLINE_MODE,
169         FORCE_KOTLIN_2_0_TARGET,
170         FORCE_BENCHMARK_AOT_COMPILATION,
171     ) + AndroidConfigImpl.GRADLE_PROPERTIES
172 
173 fun Project.shouldForceKotlin20Target() =
174     project.providers.gradleProperty(FORCE_KOTLIN_2_0_TARGET).map { it.toBoolean() }.orElse(false)
175 
176 /**
177  * Whether to enable constraints for projects in same-version groups See the property definition for
178  * more details
179  */
Projectnull180 fun Project.shouldAddGroupConstraints() =
181     project.providers.gradleProperty(ADD_GROUP_CONSTRAINTS).map { s -> s.toBoolean() }.orElse(true)
182 
183 /**
184  * Returns alternative project url that will be used as "url" property in publishing maven artifact
185  * metadata.
186  *
187  * Returns null if there is no alternative project url.
188  */
Projectnull189 fun Project.getAlternativeProjectUrl(): String? =
190     project.providers.gradleProperty(ALTERNATIVE_PROJECT_URL).getOrNull()
191 
192 /** Validate the project structure against Jetpack guidelines */
193 fun Project.isValidateProjectStructureEnabled(): Boolean =
194     findBooleanProperty(VALIDATE_PROJECT_STRUCTURE) ?: true
195 
196 /**
197  * Validates that all properties passed by the user of the form "-Pandroidx.*" are not misspelled
198  */
199 fun Project.validateAllAndroidxArgumentsAreRecognized() {
200     for (propertyName in project.properties.keys) {
201         if (propertyName.startsWith("androidx")) {
202             if (!ALL_ANDROIDX_PROPERTIES.contains(propertyName)) {
203                 val message =
204                     "Unrecognized Androidx property '$propertyName'.\n" +
205                         "\n" +
206                         "Is this a misspelling? All recognized Androidx properties:\n" +
207                         ALL_ANDROIDX_PROPERTIES.joinToString("\n") +
208                         "\n" +
209                         "\n" +
210                         "See AndroidXGradleProperties.kt if you need to add this property to " +
211                         "the list of known properties."
212                 throw GradleException(message)
213             }
214         }
215     }
216 }
217 
218 /**
219  * Returns whether tests in the project should display output. Build server scripts generally set
220  * displayTestOutput to false so that their failing test results aren't considered build failures,
221  * and instead pass their test failures on via build artifacts to be tracked and displayed on test
222  * dashboards in a different format
223  */
Projectnull224 fun Project.isDisplayTestOutput(): Boolean = findBooleanProperty(DISPLAY_TEST_OUTPUT) ?: true
225 
226 /**
227  * Returns whether the project should write versioned API files, e.g. `1.1.0-alpha01.txt`.
228  *
229  * <p>
230  * When set to `true`, the `updateApi` task will write the current API surface to both `current.txt`
231  * and `<version>.txt`. When set to `false`, only `current.txt` will be written. The default value
232  * is `true`.
233  */
234 fun Project.isWriteVersionedApiFilesEnabled(): Boolean =
235     findBooleanProperty(WRITE_VERSIONED_API_FILES) ?: true
236 
237 /** Returns whether the build is for checking forward compatibility across projects */
238 fun Project.usingMaxDepVersions(): Provider<Boolean> {
239     return project.providers.gradleProperty(USE_MAX_DEP_VERSIONS).map { true }.orElse(false)
240 }
241 
242 /** Returns whether we export compose compiler metrics */
Projectnull243 fun Project.enableComposeCompilerMetrics() =
244     findBooleanProperty(ENABLE_COMPOSE_COMPILER_METRICS) ?: false
245 
246 /** Returns whether we export compose compiler reports */
247 fun Project.enableComposeCompilerReports() =
248     findBooleanProperty(ENABLE_COMPOSE_COMPILER_REPORTS) ?: false
249 
250 /** Returns whether we should use the offline mirror for dependencies */
251 fun Project.useYarnOffline() = findBooleanProperty(YARN_OFFLINE_MODE) ?: false
252 
253 /**
254  * Returns whether this is an integration test that is allowing lint checks to be skipped to save
255  * configuration time.
256  */
257 fun Project.allowMissingLintProject() =
258     findBooleanProperty(ALLOW_MISSING_LINT_CHECKS_PROJECT) ?: false
259 
260 /** Whether libraries are allowed to customize the value of the compileSdk property. */
261 fun Project.isCustomCompileSdkAllowed(): Boolean =
262     findBooleanProperty(ALLOW_CUSTOM_COMPILE_SDK) ?: true
263 
264 fun Project.findBooleanProperty(propName: String): Boolean? =
265     project.providers.gradleProperty(propName).map { it.toBoolean() }.getOrNull()
266