mirror of
https://gitee.com/zhangsken/AndroidIDE.git
synced 2026-10-16 07:49:44 +08:00
feat(tooling-api): fetch project sync issues from the Android Gradle Plugin
This commit is contained in:
@@ -61,6 +61,8 @@ import com.itsaky.androidide.utils.resolveAttr
|
||||
import com.itsaky.androidide.utils.showOnUiThread
|
||||
import com.itsaky.androidide.utils.withIcon
|
||||
import com.itsaky.androidide.viewmodel.BuildVariantsViewModel
|
||||
import kotlinx.coroutines.Dispatchers
|
||||
import kotlinx.coroutines.launch
|
||||
import java.io.File
|
||||
import java.util.concurrent.CompletableFuture
|
||||
import java.util.regex.Pattern
|
||||
@@ -457,11 +459,13 @@ abstract class ProjectHandlerActivity : BaseEditorActivity() {
|
||||
}
|
||||
|
||||
manager.cachedInitResult = result
|
||||
manager.setupProject()
|
||||
manager.notifyProjectUpdate()
|
||||
updateBuildVariants(manager.androidBuildVariants)
|
||||
activityBackroundScope.launch(Dispatchers.IO) {
|
||||
manager.setupProject()
|
||||
manager.notifyProjectUpdate()
|
||||
updateBuildVariants(manager.androidBuildVariants)
|
||||
|
||||
ThreadUtils.runOnUiThread { postProjectInit(true) }
|
||||
com.itsaky.androidide.tasks.runOnUiThread { postProjectInit(true) }
|
||||
}
|
||||
}
|
||||
|
||||
protected open fun preProjectInit() {
|
||||
|
||||
@@ -43,6 +43,7 @@ import com.itsaky.androidide.utils.ILogger
|
||||
import io.github.rosemoe.sora.text.Content
|
||||
import io.mockk.every
|
||||
import io.mockk.mockkStatic
|
||||
import kotlinx.coroutines.runBlocking
|
||||
import org.greenrobot.eventbus.EventBus
|
||||
import org.junit.Before
|
||||
import org.junit.runner.RunWith
|
||||
@@ -102,7 +103,7 @@ abstract class LSPTest {
|
||||
|
||||
val projectManager = ProjectManagerImpl.getInstance()
|
||||
projectManager.register()
|
||||
projectManager.setupProject(project)
|
||||
runBlocking { projectManager.setupProject(project) }
|
||||
|
||||
// We need to manually setup the language server with the project here
|
||||
// ProjectManager.notifyProjectUpdate()
|
||||
|
||||
+792
@@ -0,0 +1,792 @@
|
||||
/*
|
||||
* This file is part of AndroidIDE.
|
||||
*
|
||||
* AndroidIDE is free software: you can redistribute it and/or modify
|
||||
* it under the terms of the GNU General Public License as published by
|
||||
* the Free Software Foundation, either version 3 of the License, or
|
||||
* (at your option) any later version.
|
||||
*
|
||||
* AndroidIDE is distributed in the hope that it will be useful,
|
||||
* but WITHOUT ANY WARRANTY; without even the implied warranty of
|
||||
* MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the
|
||||
* GNU General Public License for more details.
|
||||
*
|
||||
* You should have received a copy of the GNU General Public License
|
||||
* along with AndroidIDE. If not, see <https://www.gnu.org/licenses/>.
|
||||
*/
|
||||
|
||||
/*
|
||||
* Copyright (C) 2017 The Android Open Source Project
|
||||
*
|
||||
* Licensed under the Apache License, Version 2.0 (the "License");
|
||||
* you may not use this file except in compliance with the License.
|
||||
* You may obtain a copy of the License at
|
||||
*
|
||||
* http://www.apache.org/licenses/LICENSE-2.0
|
||||
*
|
||||
* Unless required by applicable law or agreed to in writing, software
|
||||
* distributed under the License is distributed on an "AS IS" BASIS,
|
||||
* WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied.
|
||||
* See the License for the specific language governing permissions and
|
||||
* limitations under the License.
|
||||
*/
|
||||
|
||||
package com.android.build.gradle.options
|
||||
|
||||
import com.android.build.gradle.options.DeprecationTarget.BUILD_CONFIG_GLOBAL_PROPERTY
|
||||
import com.android.build.gradle.options.DeprecationTarget.VERSION_9_0
|
||||
import com.android.build.gradle.options.Version.VERSION_3_5
|
||||
import com.android.build.gradle.options.Version.VERSION_3_6
|
||||
import com.android.build.gradle.options.Version.VERSION_4_0
|
||||
import com.android.build.gradle.options.Version.VERSION_4_1
|
||||
import com.android.build.gradle.options.Version.VERSION_4_2
|
||||
import com.android.build.gradle.options.Version.VERSION_7_0
|
||||
import com.android.build.gradle.options.Version.VERSION_7_2
|
||||
import com.android.build.gradle.options.Version.VERSION_7_3
|
||||
import com.android.build.gradle.options.Version.VERSION_BEFORE_4_0
|
||||
import com.android.builder.model.AndroidProject
|
||||
import com.android.builder.model.AndroidProject.PROPERTY_BUILD_MODEL_ONLY
|
||||
import com.android.builder.model.PROPERTY_BUILD_MODEL_V2_ONLY
|
||||
import com.android.builder.model.PROPERTY_BUILD_WITH_STABLE_IDS
|
||||
import com.android.builder.model.PROPERTY_DEPLOY_AS_INSTANT_APP
|
||||
import com.android.builder.model.PROPERTY_EXTRACT_INSTANT_APK
|
||||
import com.android.builder.model.PROPERTY_INVOKED_FROM_IDE
|
||||
import com.android.builder.model.PROPERTY_REFRESH_EXTERNAL_NATIVE_MODEL
|
||||
|
||||
enum class BooleanOption(
|
||||
override val propertyName: String,
|
||||
override val defaultValue: Boolean,
|
||||
val stage: Stage
|
||||
) : Option<Boolean> {
|
||||
|
||||
/* ----------
|
||||
* STABLE API
|
||||
*/
|
||||
|
||||
// IDE properties
|
||||
IDE_INVOKED_FROM_IDE(PROPERTY_INVOKED_FROM_IDE, false, ApiStage.Stable),
|
||||
IDE_BUILD_MODEL_ONLY_V2(PROPERTY_BUILD_MODEL_V2_ONLY, false, ApiStage.Stable),
|
||||
@Deprecated("This is for model v1 only. Please also use IDE_BUILD_MODEL_ONLY_V2")
|
||||
IDE_BUILD_MODEL_ONLY(PROPERTY_BUILD_MODEL_ONLY, false, ApiStage.Stable),
|
||||
@Deprecated("Use IDE_BUILD_MODEL_ONLY_V2")
|
||||
IDE_BUILD_MODEL_ONLY_ADVANCED(AndroidProject.PROPERTY_BUILD_MODEL_ONLY_ADVANCED, false, ApiStage.Stable),
|
||||
@Deprecated("Use IDE_BUILD_MODEL_ONLY_V2")
|
||||
IDE_BUILD_MODEL_FEATURE_FULL_DEPENDENCIES(AndroidProject.PROPERTY_BUILD_MODEL_FEATURE_FULL_DEPENDENCIES, false, ApiStage.Stable),
|
||||
IDE_REFRESH_EXTERNAL_NATIVE_MODEL(PROPERTY_REFRESH_EXTERNAL_NATIVE_MODEL, false, ApiStage.Stable),
|
||||
//IDE_GENERATE_SOURCES_ONLY(AndroidProject.PROPERTY_GENERATE_SOURCES_ONLY, false, ApiStage.Stable),
|
||||
|
||||
// tell bundletool to only extract instant APKs.
|
||||
IDE_EXTRACT_INSTANT(PROPERTY_EXTRACT_INSTANT_APK, false, ApiStage.Stable),
|
||||
|
||||
// Flag used to indicate a "deploy as instant" run configuration.
|
||||
IDE_DEPLOY_AS_INSTANT_APP(PROPERTY_DEPLOY_AS_INSTANT_APP, false, ApiStage.Stable),
|
||||
|
||||
ENABLE_STUDIO_VERSION_CHECK("android.injected.studio.version.check", true, ApiStage.Stable),
|
||||
ENABLE_STABLE_IDS(PROPERTY_BUILD_WITH_STABLE_IDS, false, ApiStage.Stable),
|
||||
|
||||
// Features' default values
|
||||
BUILD_FEATURE_DATABINDING("android.defaults.buildfeatures.databinding", false, ApiStage.Stable),
|
||||
BUILD_FEATURE_RESVALUES("android.defaults.buildfeatures.resvalues", true, ApiStage.Stable),
|
||||
BUILD_FEATURE_SHADERS("android.defaults.buildfeatures.shaders", true, ApiStage.Stable),
|
||||
BUILD_FEATURE_VIEWBINDING("android.defaults.buildfeatures.viewbinding", false, ApiStage.Stable),
|
||||
BUILD_FEATURE_ANDROID_RESOURCES("android.library.defaults.buildfeatures.androidresources", true, ApiStage.Stable),
|
||||
|
||||
// DSLs default values
|
||||
ENABLE_DATABINDING_KTX("android.defaults.databinding.addKtx", true, ApiStage.Stable),
|
||||
|
||||
// AndroidX & Jetifier
|
||||
USE_ANDROID_X("android.useAndroidX", false, ApiStage.Stable),
|
||||
ENABLE_JETIFIER("android.enableJetifier", false, ApiStage.Stable),
|
||||
|
||||
DEBUG_OBSOLETE_API("android.debug.obsoleteApi", false, ApiStage.Stable),
|
||||
|
||||
// Disabled by default due to low usage.
|
||||
GENERATE_MANIFEST_CLASS("android.generateManifestClass", false, ApiStage.Stable),
|
||||
|
||||
USE_NON_FINAL_RES_IDS("android.nonFinalResIds", true, ApiStage.Stable),
|
||||
NON_TRANSITIVE_R_CLASS("android.nonTransitiveRClass", true, ApiStage.Stable),
|
||||
|
||||
/**
|
||||
* Setting this field to false indicates that in the current
|
||||
* project, all the APKs installed during test will be uninstalled
|
||||
* after test finishes. Setting it to true means that the AGP
|
||||
* will leave the test APKs untouched after test.
|
||||
*
|
||||
* Default is false
|
||||
*/
|
||||
ANDROID_TEST_LEAVE_APKS_INSTALLED_AFTER_RUN("android.injected.androidTest.leaveApksInstalledAfterRun", false, ApiStage.Stable),
|
||||
|
||||
/**
|
||||
* When this option is enabled, dexing transforms will use the full classpath (if desugaring
|
||||
* requires a classpath). This classpath consists of all external artifacts
|
||||
* ([com.android.build.gradle.internal.publishing.AndroidArtifacts.ArtifactScope.EXTERNAL])
|
||||
* in addition to the input artifact's dependencies provided by Gradle through
|
||||
* [org.gradle.api.artifacts.transform.InputArtifactDependencies].
|
||||
*
|
||||
* This option is useful when some dependencies are missing from the input artifact's
|
||||
* dependencies (see bug 230454566), so the full classpath is needed.
|
||||
*
|
||||
* If dexing transforms do not require a classpath, this option is not used.
|
||||
*/
|
||||
USE_FULL_CLASSPATH_FOR_DEXING_TRANSFORM(
|
||||
"android.useFullClasspathForDexingTransform",
|
||||
false,
|
||||
ApiStage.Stable
|
||||
),
|
||||
|
||||
/* ------------------
|
||||
* SUPPORTED FEATURES
|
||||
*/
|
||||
|
||||
// Used by Studio as workaround for b/71054106, b/75955471
|
||||
ENABLE_SDK_DOWNLOAD("android.builder.sdkDownload", true, FeatureStage.Supported),
|
||||
|
||||
ENFORCE_UNIQUE_PACKAGE_NAMES("android.uniquePackageNames", false, FeatureStage.Supported),
|
||||
|
||||
// Flag added to work around b/130596259.
|
||||
FORCE_JACOCO_OUT_OF_PROCESS("android.forceJacocoOutOfProcess", false, FeatureStage.Supported),
|
||||
|
||||
PRECOMPILE_DEPENDENCIES_RESOURCES("android.precompileDependenciesResources", true, FeatureStage.Supported),
|
||||
|
||||
INCLUDE_DEPENDENCY_INFO_IN_APKS("android.includeDependencyInfoInApks", true, FeatureStage.Supported),
|
||||
|
||||
// FIXME switch to false once we know we don't use these getters internally.
|
||||
ENABLE_LEGACY_API("android.compatibility.enableLegacyApi", true, FeatureStage.Supported),
|
||||
FULL_R8("android.enableR8.fullMode", true, FeatureStage.Supported),
|
||||
|
||||
/* ---------------------
|
||||
* EXPERIMENTAL FEATURES
|
||||
*/
|
||||
|
||||
BUILD_FEATURE_MLMODELBINDING("android.defaults.buildfeatures.mlmodelbinding", false, ApiStage.Experimental),
|
||||
ENABLE_DEFAULT_DEBUG_SIGNING_CONFIG("android.experimental.useDefaultDebugSigningConfigForProfileableBuildtypes", false, ApiStage.Experimental),
|
||||
ENABLE_PROFILE_JSON("android.enableProfileJson", false, FeatureStage.Experimental),
|
||||
DISALLOW_DEPENDENCY_RESOLUTION_AT_CONFIGURATION("android.dependencyResolutionAtConfigurationTime.disallow", false, FeatureStage.Experimental),
|
||||
VERSION_CHECK_OVERRIDE_PROPERTY("android.overrideVersionCheck", false, FeatureStage.Experimental),
|
||||
OVERRIDE_PATH_CHECK_PROPERTY("android.overridePathCheck", false, FeatureStage.Experimental),
|
||||
DISABLE_RESOURCE_VALIDATION("android.disableResourceValidation", false, FeatureStage.Experimental),
|
||||
CONSUME_DEPENDENCIES_AS_SHARED_LIBRARIES("android.consumeDependenciesAsSharedLibraries", false, FeatureStage.Experimental),
|
||||
DISABLE_EARLY_MANIFEST_PARSING("android.disableEarlyManifestParsing", false, FeatureStage.Experimental),
|
||||
ENABLE_RESOURCE_NAMESPACING_DEFAULT("android.enableResourceNamespacingDefault", false, FeatureStage.Experimental),
|
||||
CONDITIONAL_KEEP_RULES("android.useConditionalKeepRules", false, FeatureStage.Experimental),
|
||||
KEEP_SERVICES_BETWEEN_BUILDS("android.keepWorkerActionServicesBetweenBuilds", false, FeatureStage.Experimental),
|
||||
ENABLE_PARTIAL_R_INCREMENTAL_BUILDS("android.enablePartialRIncrementalBuilds", false, FeatureStage.Experimental),
|
||||
ENABLE_NEW_RESOURCE_SHRINKER_PRECISE("android.experimental.enableNewResourceShrinker.preciseShrinking", false, FeatureStage.Experimental),
|
||||
ENABLE_LOCAL_TESTING("android.bundletool.enableLocalTesting", false, FeatureStage.Experimental),
|
||||
DISABLE_MINSDKLIBRARY_CHECK("android.unsafe.disable.minSdkLibraryCheck", false, FeatureStage.Experimental),
|
||||
ENABLE_INSTRUMENTATION_TEST_DESUGARING("android.experimental.library.desugarAndroidTest", false, FeatureStage.Experimental),
|
||||
ENABLE_EMULATOR_CONTROL("android.experimental.androidTest.enableEmulatorControl", false, FeatureStage.Experimental),
|
||||
ENABLE_SCREENSHOT_TEST("android.experimental.enableScreenshotTest", false, FeatureStage.Experimental),
|
||||
/**
|
||||
* When enabled, incompatible APKs installed on a testing device will be uninstalled automatically
|
||||
* during an instrumentation test run (e.g. When INSTALL_FAILED_UPDATE_INCOMPATIBLE error happens
|
||||
* after attempting to install APKs for testing).
|
||||
*/
|
||||
UNINSTALL_INCOMPATIBLE_APKS("android.experimental.testOptions.uninstallIncompatibleApks", false, FeatureStage.Experimental),
|
||||
|
||||
/**
|
||||
* When enabled, "-show-kernel" and "-verbose" flags are used when running an Android emulator
|
||||
* for Gradle Managed devices.
|
||||
*/
|
||||
GRADLE_MANAGED_DEVICE_EMULATOR_SHOW_KERNEL_LOGGING("android.experimental.testOptions.managedDevices.emulator.showKernelLogging", false, FeatureStage.Experimental),
|
||||
|
||||
/**
|
||||
* Gradle Managed devices officially supports Android devices on API level 27 and higher because
|
||||
* using the API level 26 and lower devices increase instability. When a user tries to use those
|
||||
* old API devices, GMD task throws an exception and task fails by default.
|
||||
*
|
||||
* When this flag is enabled, it allows a user to use any old API level devices regardless of
|
||||
* its instability.
|
||||
*/
|
||||
GRADLE_MANAGED_DEVICE_ALLOW_OLD_API_LEVEL_DEVICES("android.experimental.testOptions.managedDevices.allowOldApiLevelDevices", false, FeatureStage.Experimental),
|
||||
|
||||
/**
|
||||
* When enabled, Gradle Managed Device allows a custom managed device type that can be provided
|
||||
* by a plugin by implementing ManagedDeviceTestRunner APIs.
|
||||
*/
|
||||
GRADLE_MANAGED_DEVICE_CUSTOM_DEVICE("android.experimental.testOptions.managedDevices.customDevice", false, FeatureStage.Experimental),
|
||||
|
||||
/** When set R classes are treated as compilation classpath in libraries, rather than runtime classpath, with values set to 0. */
|
||||
ENABLE_ADDITIONAL_ANDROID_TEST_OUTPUT("android.enableAdditionalTestOutput", true, FeatureStage.Experimental),
|
||||
|
||||
ENABLE_APP_COMPILE_TIME_R_CLASS("android.enableAppCompileTimeRClass", false, FeatureStage.Experimental),
|
||||
ENABLE_EXTRACT_ANNOTATIONS("android.enableExtractAnnotations", true, FeatureStage.Experimental),
|
||||
|
||||
// Marked as stable to avoid reporting deprecation twice.
|
||||
CONVERT_NON_NAMESPACED_DEPENDENCIES("android.convertNonNamespacedDependencies", true, FeatureStage.Experimental),
|
||||
|
||||
/** Set to true to build native .so libraries only for the device it will be run on. */
|
||||
BUILD_ONLY_TARGET_ABI("android.buildOnlyTargetAbi", true, FeatureStage.Experimental),
|
||||
|
||||
ENABLE_PARALLEL_NATIVE_JSON_GEN("android.enableParallelJsonGen", false, FeatureStage.Experimental),
|
||||
ENABLE_SIDE_BY_SIDE_CMAKE("android.enableSideBySideCmake", true, FeatureStage.Experimental),
|
||||
ENABLE_NATIVE_COMPILER_SETTINGS_CACHE("android.enableNativeCompilerSettingsCache", false, FeatureStage.Experimental),
|
||||
ENABLE_CMAKE_BUILD_COHABITATION("android.enableCmakeBuildCohabitation", false, FeatureStage.Experimental),
|
||||
ENABLE_PROGUARD_RULES_EXTRACTION("android.proguard.enableRulesExtraction", true, FeatureStage.Experimental),
|
||||
USE_DEPENDENCY_CONSTRAINTS("android.dependency.useConstraints", true, FeatureStage.Experimental),
|
||||
EXCLUDE_LIBRARY_COMPONENTS_FROM_CONSTRAINTS("android.experimental.dependency.excludeLibraryComponentsFromConstraints", false, FeatureStage.Experimental),
|
||||
ENABLE_DUPLICATE_CLASSES_CHECK("android.enableDuplicateClassesCheck", true, FeatureStage.Experimental),
|
||||
MINIMAL_KEEP_RULES("android.useMinimalKeepRules", true, FeatureStage.Experimental),
|
||||
EXCLUDE_RES_SOURCES_FOR_RELEASE_BUNDLES("android.bundle.excludeResSourcesForRelease", true, FeatureStage.Experimental),
|
||||
ENABLE_BUILD_CONFIG_AS_BYTECODE("android.enableBuildConfigAsBytecode", false, FeatureStage.Experimental),
|
||||
/** Whether lint should be run in process; the default is true. */
|
||||
RUN_LINT_IN_PROCESS("android.experimental.runLintInProcess", true, FeatureStage.Experimental),
|
||||
|
||||
ENABLE_TEST_FIXTURES("android.experimental.enableTestFixtures", false, FeatureStage.Experimental),
|
||||
|
||||
USE_NEW_DSL_INTERFACES("android.experimental.newDslInterfaces", false, FeatureStage.Experimental),
|
||||
|
||||
/** Whether to force the APK to be deterministic. */
|
||||
FORCE_DETERMINISTIC_APK("android.experimental.forceDeterministicApk", false, FeatureStage.Experimental),
|
||||
|
||||
MISSING_LINT_BASELINE_IS_EMPTY_BASELINE(
|
||||
"android.experimental.lint.missingBaselineIsEmptyBaseline",
|
||||
false,
|
||||
FeatureStage.Experimental,
|
||||
),
|
||||
|
||||
LEGACY_TRANSFORM_TASK_FORCE_NON_INCREMENTAL(
|
||||
"android.experimental.legacyTransform.forceNonIncremental",
|
||||
false,
|
||||
FeatureStage.Experimental
|
||||
),
|
||||
|
||||
PRIVACY_SANDBOX_SDK_SUPPORT("android.experimental.privacysandboxsdk.enable", false, FeatureStage.Experimental),
|
||||
PRIVACY_SANDBOX_SDK_REQUIRE_SERVICES(
|
||||
"android.experimental.privacysandboxsdk.requireServices", true, FeatureStage.Experimental),
|
||||
|
||||
PRINT_LINT_STACK_TRACE("android.lint.printStackTrace", false, FeatureStage.Experimental),
|
||||
|
||||
VERIFY_AAR_CLASSES("android.experimental.verifyLibraryClasses", false, FeatureStage.Experimental),
|
||||
DISABLE_COMPILE_SDK_CHECKS("android.experimental.disableCompileSdkChecks", false, FeatureStage.Experimental),
|
||||
ADDITIONAL_ARTIFACTS_IN_MODEL("android.experimental.additionalArtifactsInModel", false, FeatureStage.Experimental),
|
||||
|
||||
// Whether to suppress warnings about android:extractNativeLibs set to true in dependencies
|
||||
SUPPRESS_EXTRACT_NATIVE_LIBS_WARNINGS(
|
||||
"android.experimental.suppressExtractNativeLibsWarnings",
|
||||
false,
|
||||
FeatureStage.Experimental
|
||||
),
|
||||
|
||||
FUSED_LIBRARY_SUPPORT("android.experimental.fusedLibrarySupport", false, FeatureStage.Experimental),
|
||||
SUPPORT_PAST_STUDIO_VERSIONS("android.experimental.support.past.studio.versions", false, FeatureStage.Experimental),
|
||||
|
||||
/**
|
||||
* Enables task to add version control info to APKs/Bundle
|
||||
*/
|
||||
ENABLE_VCS_INFO("android.enableVcsInfo", false, FeatureStage.Experimental),
|
||||
|
||||
/**
|
||||
* Whether to omit line numbers when writing lint baselines
|
||||
*/
|
||||
LINT_BASELINE_OMIT_LINE_NUMBERS(
|
||||
"android.lint.baselineOmitLineNumbers",
|
||||
false,
|
||||
FeatureStage.Experimental
|
||||
),
|
||||
|
||||
/**
|
||||
* Whether to use K2 UAST when running lint
|
||||
*/
|
||||
LINT_USE_K2_UAST(
|
||||
"android.lint.useK2Uast",
|
||||
false,
|
||||
FeatureStage.Experimental
|
||||
),
|
||||
|
||||
/* ------------------------
|
||||
* SOFTLY-ENFORCED FEATURES
|
||||
*/
|
||||
ENABLE_RESOURCE_OPTIMIZATIONS(
|
||||
"android.enableResourceOptimizations",
|
||||
true,
|
||||
FeatureStage.SoftlyEnforced(VERSION_9_0)
|
||||
),
|
||||
|
||||
ANDROID_TEST_USES_UNIFIED_TEST_PLATFORM(
|
||||
"android.experimental.androidTest.useUnifiedTestPlatform",
|
||||
true,
|
||||
FeatureStage.SoftlyEnforced(VERSION_9_0)
|
||||
),
|
||||
|
||||
/**
|
||||
* Whether to do lint analysis per component (instead of analysing the main variant and the test
|
||||
* components in the same lint invocation).
|
||||
*/
|
||||
LINT_ANALYSIS_PER_COMPONENT(
|
||||
"android.experimental.lint.analysisPerComponent",
|
||||
true,
|
||||
FeatureStage.SoftlyEnforced(VERSION_9_0)
|
||||
),
|
||||
|
||||
/* -------------------
|
||||
* DEPRECATED FEATURES
|
||||
*/
|
||||
|
||||
BUILD_FEATURE_AIDL(
|
||||
"android.defaults.buildfeatures.aidl",
|
||||
false,
|
||||
ApiStage.Deprecated(VERSION_9_0)
|
||||
),
|
||||
|
||||
BUILD_FEATURE_RENDERSCRIPT(
|
||||
"android.defaults.buildfeatures.renderscript",
|
||||
false,
|
||||
ApiStage.Deprecated(VERSION_9_0)
|
||||
),
|
||||
|
||||
BUILD_FEATURE_BUILDCONFIG(
|
||||
"android.defaults.buildfeatures.buildconfig",
|
||||
false,
|
||||
ApiStage.Deprecated(BUILD_CONFIG_GLOBAL_PROPERTY))
|
||||
,
|
||||
|
||||
/* -----------------
|
||||
* ENFORCED FEATURES
|
||||
*/
|
||||
@Suppress("unused")
|
||||
PREFER_CMAKE_FILE_API(
|
||||
"android.preferCmakeFileApi",
|
||||
true, FeatureStage.Enforced(VERSION_7_0)),
|
||||
|
||||
@Suppress("unused")
|
||||
ENABLE_NATIVE_CONFIGURATION_FOLDING(
|
||||
"android.enableNativeConfigurationFolding",
|
||||
true,
|
||||
FeatureStage.Enforced(VERSION_7_0)),
|
||||
|
||||
@Suppress("unused")
|
||||
ENABLE_SIDE_BY_SIDE_NDK(
|
||||
"android.enableSideBySideNdk",
|
||||
true,
|
||||
FeatureStage.Enforced(
|
||||
VERSION_4_1,
|
||||
"The android.enableSideBySideNdk property does not have any effect. " +
|
||||
"Side-by-side NDK is always enabled."
|
||||
)
|
||||
),
|
||||
|
||||
@Suppress("unused")
|
||||
ENABLE_IMPROVED_DEPENDENCY_RESOLUTION(
|
||||
"android.enableImprovedDependenciesResolution",
|
||||
true,
|
||||
FeatureStage.Enforced(
|
||||
VERSION_BEFORE_4_0,
|
||||
"The android.enableImprovedDependenciesResolution property does not have any effect. "
|
||||
+ "Dependency resolution is only performed during task execution phase."
|
||||
)
|
||||
),
|
||||
|
||||
@Suppress("unused")
|
||||
ENABLE_NEW_RESOURCE_PROCESSING(
|
||||
"android.enableNewResourceProcessing",
|
||||
true,
|
||||
FeatureStage.Enforced(
|
||||
VERSION_BEFORE_4_0,
|
||||
"New resource processing is now always enabled."
|
||||
)
|
||||
),
|
||||
|
||||
@Suppress("unused")
|
||||
DISABLE_RES_MERGE_IN_LIBRARY(
|
||||
"android.disable.res.merge",
|
||||
true,
|
||||
FeatureStage.Enforced(
|
||||
VERSION_BEFORE_4_0,
|
||||
"Resources from dependencies are never merged in libraries."
|
||||
)
|
||||
),
|
||||
|
||||
@Suppress("unused")
|
||||
ENABLE_DAEMON_MODE_AAPT2(
|
||||
"android.enableAapt2DaemonMode",
|
||||
true,
|
||||
FeatureStage.Enforced(VERSION_BEFORE_4_0, "AAPT2 daemon mode is now always enabled.")
|
||||
),
|
||||
|
||||
@Suppress("unused")
|
||||
ENABLE_INCREMENTAL_DESUGARING(
|
||||
"android.enableIncrementalDesugaring",
|
||||
true,
|
||||
FeatureStage.Enforced(
|
||||
VERSION_BEFORE_4_0,
|
||||
"This property has no effect, incremental desugaring is always enabled."
|
||||
)
|
||||
),
|
||||
|
||||
@Suppress("unused")
|
||||
ENABLE_CORE_LAMBDA_STUBS(
|
||||
"android.enableCoreLambdaStubs",
|
||||
true,
|
||||
FeatureStage.Enforced(
|
||||
VERSION_BEFORE_4_0,
|
||||
"This property has no effect, core-lambda-stubs.jar is always in the bootclasspath."
|
||||
)
|
||||
),
|
||||
|
||||
@Suppress("unused")
|
||||
ENABLE_DEX_ARCHIVE(
|
||||
"android.useDexArchive",
|
||||
true,
|
||||
FeatureStage.Enforced(
|
||||
VERSION_BEFORE_4_0,
|
||||
"This property has no effect, incremental dexing is always used."
|
||||
)
|
||||
),
|
||||
|
||||
@Suppress("unused")
|
||||
ENABLE_AAPT2(
|
||||
"android.enableAapt2",
|
||||
true,
|
||||
FeatureStage.Enforced(
|
||||
VERSION_BEFORE_4_0,
|
||||
"This property has no effect, AAPT2 is now always used."
|
||||
)
|
||||
),
|
||||
|
||||
@Suppress("unused")
|
||||
USE_AAPT2_FROM_MAVEN(
|
||||
"android.useAapt2FromMaven",
|
||||
true,
|
||||
FeatureStage.Enforced(
|
||||
VERSION_BEFORE_4_0,
|
||||
"This property has no effect and AAPT2 from maven.google.com is now always used. "
|
||||
+ "If you wish to use a local executable of AAPT2 please use the "
|
||||
+ "'android.aapt2FromMavenOverride' option."
|
||||
)
|
||||
),
|
||||
|
||||
@Suppress("unused")
|
||||
ENABLE_D8_MAIN_DEX_LIST(
|
||||
"android.enableD8MainDexList",
|
||||
true,
|
||||
FeatureStage.Enforced(
|
||||
VERSION_BEFORE_4_0,
|
||||
"This property has no effect, D8 is always used to compute the main dex list."
|
||||
)
|
||||
),
|
||||
|
||||
@Suppress("unused")
|
||||
ENABLE_DATA_BINDING_V2(
|
||||
"android.databinding.enableV2",
|
||||
true,
|
||||
FeatureStage.Enforced(VERSION_BEFORE_4_0, "Databinding v1 is removed.")
|
||||
),
|
||||
|
||||
ENABLE_SEPARATE_R_CLASS_COMPILATION(
|
||||
"android.enableSeparateRClassCompilation",
|
||||
true,
|
||||
FeatureStage.Enforced(
|
||||
VERSION_BEFORE_4_0,
|
||||
"Separate R class compilation has been enabled and can no longer be disabled."
|
||||
)
|
||||
),
|
||||
|
||||
@Suppress("unused")
|
||||
ENABLE_GRADLE_WORKERS(
|
||||
"android.enableGradleWorkers",
|
||||
true,
|
||||
FeatureStage.Enforced(
|
||||
VERSION_4_2,
|
||||
"Gradle workers are always used."
|
||||
)
|
||||
),
|
||||
|
||||
@Suppress("unused")
|
||||
ENABLE_D8(
|
||||
"android.enableD8",
|
||||
true,
|
||||
FeatureStage.Enforced(
|
||||
VERSION_7_0,
|
||||
"For more details, see https://d.android.com/r/studio-ui/d8-overview.html."
|
||||
)
|
||||
),
|
||||
|
||||
@Suppress("unused")
|
||||
ENABLE_D8_DESUGARING(
|
||||
"android.enableD8.desugaring",
|
||||
true,
|
||||
FeatureStage.Enforced(
|
||||
VERSION_7_0,
|
||||
"D8 desugaring is used by default, when applicable."
|
||||
)
|
||||
),
|
||||
|
||||
@Suppress("unused")
|
||||
ENABLE_R8_DESUGARING(
|
||||
"android.enableR8.desugaring",
|
||||
true,
|
||||
FeatureStage.Enforced(
|
||||
VERSION_7_0,
|
||||
"R8 desugaring is used by default, when applicable."
|
||||
)
|
||||
),
|
||||
|
||||
USE_NEW_LINT_MODEL("android.experimental.useNewLintModel", true, FeatureStage.Enforced(VERSION_7_0)),
|
||||
|
||||
/** Whether Jetifier will skip libraries that already support AndroidX. */
|
||||
JETIFIER_SKIP_IF_POSSIBLE("android.jetifier.skipIfPossible", true, FeatureStage.Enforced(VERSION_7_0)),
|
||||
|
||||
@Suppress("unused")
|
||||
NON_TRANSITIVE_APP_R_CLASS(
|
||||
"android.experimental.nonTransitiveAppRClass",
|
||||
true,
|
||||
FeatureStage.Enforced(
|
||||
VERSION_7_0,
|
||||
"Non-transitive R classes are now enabled in app modules with the " +
|
||||
"${NON_TRANSITIVE_R_CLASS.propertyName} option.")),
|
||||
|
||||
/** Incremental dexing task using D8's new API for desugaring graph computation. */
|
||||
ENABLE_INCREMENTAL_DEXING_TASK_V2("android.enableIncrementalDexingTaskV2", true, FeatureStage.Enforced(VERSION_7_0)),
|
||||
|
||||
/** Incremental dexing transform. */
|
||||
ENABLE_INCREMENTAL_DEXING_TRANSFORM("android.enableIncrementalDexingTransform", true, FeatureStage.Enforced(VERSION_7_0)),
|
||||
|
||||
ENABLE_R8_LIBRARIES("android.enableR8.libraries", true, FeatureStage.Enforced(VERSION_7_0)),
|
||||
|
||||
ENABLE_SYMBOL_TABLE_CACHING("android.enableSymbolTableCaching", true, FeatureStage.Enforced(VERSION_7_0)),
|
||||
|
||||
ENABLE_JVM_RESOURCE_COMPILER("android.enableJvmResourceCompiler", true, FeatureStage.Enforced(VERSION_7_0)),
|
||||
|
||||
/** Whether to use lint's partial analysis functionality. */
|
||||
USE_LINT_PARTIAL_ANALYSIS("android.enableParallelLint", true, FeatureStage.Enforced(VERSION_7_2)),
|
||||
|
||||
ENABLE_AAPT2_WORKER_ACTIONS(
|
||||
"android.enableAapt2WorkerActions",
|
||||
true,
|
||||
FeatureStage.Enforced(
|
||||
VERSION_7_3,
|
||||
"AAPT2 worker actions have been used unconditionally since Android Gradle Plugin 3.3"
|
||||
)
|
||||
),
|
||||
ENABLE_JACOCO_TRANSFORM_INSTRUMENTATION(
|
||||
"android.enableJacocoTransformInstrumentation",
|
||||
true,
|
||||
FeatureStage.Enforced(VERSION_7_3)
|
||||
),
|
||||
|
||||
@Suppress("unused")
|
||||
ENABLE_SOURCE_SET_PATHS_MAP(
|
||||
"android.enableSourceSetPathsMap",
|
||||
true,
|
||||
FeatureStage.Enforced(Version.VERSION_8_0)
|
||||
),
|
||||
|
||||
@Suppress("unused")
|
||||
RELATIVE_COMPILE_LIB_RESOURCES(
|
||||
"android.cacheCompileLibResources",
|
||||
true,
|
||||
FeatureStage.Enforced(Version.VERSION_8_0)
|
||||
),
|
||||
|
||||
@Suppress("unused")
|
||||
R8_FAIL_ON_MISSING_CLASSES(
|
||||
"android.r8.failOnMissingClasses",
|
||||
true,
|
||||
FeatureStage.Enforced(Version.VERSION_8_0)
|
||||
),
|
||||
|
||||
USE_NEW_JAR_CREATOR(
|
||||
"android.useNewJarCreator",
|
||||
true,
|
||||
FeatureStage.Enforced(Version.VERSION_8_0)
|
||||
),
|
||||
|
||||
USE_NEW_APK_CREATOR(
|
||||
"android.useNewApkCreator",
|
||||
true,
|
||||
FeatureStage.Enforced(Version.VERSION_8_0)
|
||||
),
|
||||
|
||||
WARN_ABOUT_DEPENDENCY_RESOLUTION_AT_CONFIGURATION(
|
||||
"android.dependencyResolutionAtConfigurationTime.warn",
|
||||
true,
|
||||
FeatureStage.Enforced(Version.VERSION_8_0)
|
||||
),
|
||||
|
||||
ENABLE_ART_PROFILES(
|
||||
"android.enableArtProfiles",
|
||||
true,
|
||||
FeatureStage.Enforced(Version.VERSION_8_0)
|
||||
),
|
||||
|
||||
USE_RELATIVE_PATH_IN_TEST_CONFIG(
|
||||
"android.testConfig.useRelativePath",
|
||||
true,
|
||||
FeatureStage.Enforced(Version.VERSION_8_0)
|
||||
),
|
||||
|
||||
INCLUDE_REPOSITORIES_IN_DEPENDENCY_REPORT(
|
||||
"android.bundletool.includeRepositoriesInDependencyReport",
|
||||
true,
|
||||
FeatureStage.Enforced(Version.VERSION_8_0)
|
||||
),
|
||||
|
||||
ENABLE_INCREMENTAL_DATA_BINDING(
|
||||
"android.databinding.incremental",
|
||||
true,
|
||||
FeatureStage.Enforced(Version.VERSION_8_1)
|
||||
),
|
||||
|
||||
ENABLE_NEW_RESOURCE_SHRINKER("android.enableNewResourceShrinker",
|
||||
true,
|
||||
FeatureStage.Enforced(Version.VERSION_8_0)),
|
||||
|
||||
@Suppress("unused")
|
||||
ENABLE_R_TXT_RESOURCE_SHRINKING(
|
||||
"android.enableRTxtResourceShrinking",
|
||||
true,
|
||||
FeatureStage.Enforced(Version.VERSION_8_1)
|
||||
),
|
||||
|
||||
@Suppress("unused")
|
||||
COMPILE_CLASSPATH_LIBRARY_R_CLASSES(
|
||||
"android.useCompileClasspathLibraryRClasses",
|
||||
true,
|
||||
FeatureStage.Enforced(Version.VERSION_8_1)
|
||||
),
|
||||
|
||||
ENABLE_UNCOMPRESSED_NATIVE_LIBS_IN_BUNDLE(
|
||||
"android.bundle.enableUncompressedNativeLibs",
|
||||
true,
|
||||
FeatureStage.Enforced(Version.VERSION_8_1)
|
||||
),
|
||||
|
||||
ENABLE_GLOBAL_SYNTHETICS(
|
||||
"android.enableGlobalSyntheticsGeneration",
|
||||
true,
|
||||
FeatureStage.Enforced(Version.VERSION_8_1)
|
||||
),
|
||||
|
||||
ENABLE_DEXING_DESUGARING_ARTIFACT_TRANSFORM(
|
||||
"android.enableDexingArtifactTransform.desugaring",
|
||||
true,
|
||||
FeatureStage.Enforced(
|
||||
Version.VERSION_8_2,
|
||||
"If you run into issues with dexing transforms, try setting `${USE_FULL_CLASSPATH_FOR_DEXING_TRANSFORM.propertyName} = true` instead."
|
||||
)
|
||||
),
|
||||
|
||||
ENABLE_DEXING_ARTIFACT_TRANSFORM_FOR_EXTERNAL_LIBS(
|
||||
"android.enableDexingArtifactTransformForExternalLibs",
|
||||
true,
|
||||
FeatureStage.Enforced(Version.VERSION_8_2)
|
||||
),
|
||||
|
||||
ENABLE_DEXING_ARTIFACT_TRANSFORM(
|
||||
"android.enableDexingArtifactTransform",
|
||||
true,
|
||||
FeatureStage.Enforced(
|
||||
Version.VERSION_8_3,
|
||||
"If you run into issues with dexing transforms, try setting `${USE_FULL_CLASSPATH_FOR_DEXING_TRANSFORM.propertyName} = true` instead."
|
||||
)
|
||||
),
|
||||
|
||||
/* ----------------
|
||||
* REMOVED FEATURES
|
||||
*/
|
||||
|
||||
@Suppress("unused")
|
||||
ENABLE_IN_PROCESS_AAPT2(
|
||||
"android.enableAapt2jni",
|
||||
false,
|
||||
FeatureStage.Removed(VERSION_BEFORE_4_0, "AAPT2 JNI has been removed.")
|
||||
),
|
||||
|
||||
@Suppress("unused")
|
||||
ENABLE_DEPRECATED_NDK(
|
||||
"android.useDeprecatedNdk",
|
||||
false,
|
||||
FeatureStage.Removed(VERSION_BEFORE_4_0, "NdkCompile is no longer supported")
|
||||
),
|
||||
|
||||
@Suppress("unused")
|
||||
INJECT_SDK_MAVEN_REPOS(
|
||||
"android.injectSdkMavenRepos",
|
||||
false,
|
||||
FeatureStage.Removed(
|
||||
VERSION_3_5,
|
||||
"The ability to inject the Android SDK maven repos is removed in AGP 3.5"
|
||||
)
|
||||
),
|
||||
|
||||
@Suppress("unused")
|
||||
ENABLE_UNIT_TEST_BINARY_RESOURCES(
|
||||
"android.enableUnitTestBinaryResources",
|
||||
false,
|
||||
FeatureStage.Removed(
|
||||
VERSION_BEFORE_4_0,
|
||||
"The raw resource for unit test functionality is removed."
|
||||
)
|
||||
),
|
||||
|
||||
@Suppress("unused")
|
||||
ENABLE_EXPERIMENTAL_FEATURE_DATABINDING(
|
||||
"android.enableExperimentalFeatureDatabinding",
|
||||
false,
|
||||
FeatureStage.Removed(
|
||||
VERSION_4_0,
|
||||
"This property has no effect. The features plugin was removed in AGP 4.0.")
|
||||
),
|
||||
|
||||
@Suppress("unused")
|
||||
ENABLE_SEPARATE_APK_RESOURCES(
|
||||
"android.enableSeparateApkRes",
|
||||
false,
|
||||
FeatureStage.Removed(VERSION_BEFORE_4_0, "Instant run is replaced by apply changes.")
|
||||
),
|
||||
|
||||
@Suppress("unused")
|
||||
KEEP_TIMESTAMPS_IN_APK(
|
||||
"android.keepTimestampsInApk",
|
||||
false,
|
||||
FeatureStage.Removed(
|
||||
VERSION_3_6,
|
||||
"The ability to keep timestamps in the APK is removed in AGP 3.6"
|
||||
)
|
||||
),
|
||||
|
||||
@Suppress("unused")
|
||||
ENABLE_SEPARATE_ANNOTATION_PROCESSING(
|
||||
"android.enableSeparateAnnotationProcessing",
|
||||
false,
|
||||
FeatureStage.Removed(VERSION_4_0, "This feature was removed in AGP 4.0")
|
||||
),
|
||||
|
||||
@Suppress("unused")
|
||||
GENERATE_R_JAVA(
|
||||
"android.generateRJava",
|
||||
false,
|
||||
FeatureStage.Removed(VERSION_4_1, "This feature was removed in AGP 4.1")),
|
||||
|
||||
@Suppress("unused")
|
||||
ENABLE_BUILD_CACHE(
|
||||
"android.enableBuildCache",
|
||||
false,
|
||||
FeatureStage.Removed(VERSION_7_0, "The Android-specific build caches were superseded by the Gradle build cache (https://docs.gradle.org/current/userguide/build_cache.html).")
|
||||
),
|
||||
|
||||
@Suppress("unused")
|
||||
ENABLE_INTERMEDIATE_ARTIFACTS_CACHE(
|
||||
"android.enableIntermediateArtifactsCache",
|
||||
false,
|
||||
FeatureStage.Removed(VERSION_7_0, "The Android-specific build caches were superseded by the Gradle build cache (https://docs.gradle.org/current/userguide/build_cache.html).")
|
||||
),
|
||||
|
||||
@Suppress("unused")
|
||||
ENABLE_DESUGAR(
|
||||
"android.enableDesugar",
|
||||
false,
|
||||
FeatureStage.Removed(VERSION_7_0, "Desugar tool has been removed from AGP.")
|
||||
),
|
||||
|
||||
@Suppress("unused")
|
||||
ENABLE_TEST_SHARDING("android.androidTest.shardBetweenDevices", false, FeatureStage.Removed(Version.VERSION_8_2, "Cross device sharding is no longer supported.")),
|
||||
; // end of enums
|
||||
|
||||
override val status = stage.status
|
||||
|
||||
override fun parse(value: Any): Boolean {
|
||||
return parseBoolean(propertyName, value)
|
||||
}
|
||||
}
|
||||
+100
@@ -0,0 +1,100 @@
|
||||
/*
|
||||
* Copyright (C) 2017 The Android Open Source Project
|
||||
*
|
||||
* Licensed under the Apache License, Version 2.0 (the "License");
|
||||
* you may not use this file except in compliance with the License.
|
||||
* You may obtain a copy of the License at
|
||||
*
|
||||
* http://www.apache.org/licenses/LICENSE-2.0
|
||||
*
|
||||
* Unless required by applicable law or agreed to in writing, software
|
||||
* distributed under the License is distributed on an "AS IS" BASIS,
|
||||
* WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied.
|
||||
* See the License for the specific language governing permissions and
|
||||
* limitations under the License.
|
||||
*/
|
||||
|
||||
package com.android.build.gradle.options
|
||||
/** Enum for deprecated element removal target. */
|
||||
enum class DeprecationTarget constructor(
|
||||
|
||||
/**
|
||||
* The target version when a deprecated element will be removed.
|
||||
*
|
||||
* Usage note: Do not use this field to construct a deprecation message, use
|
||||
* getDeprecationTargetMessage() instead to ensure consistent message format.
|
||||
*/
|
||||
val removalTarget: Version,
|
||||
|
||||
/**
|
||||
* Additional message to be shown below the pre-formatted error/warning message.
|
||||
*
|
||||
* Note that this additional message should be constructed such that it fits well in the
|
||||
* overall message:
|
||||
*
|
||||
* "This feature will be removed in version X.Y of the Android Gradle plugin.\n
|
||||
* $additionalMessage"
|
||||
*
|
||||
* For example, avoid writing additional messages that say "This feature is planned for
|
||||
* removal", as it will be duplicated.
|
||||
*/
|
||||
private val additionalMessage: String? = null
|
||||
) {
|
||||
VERSION_9_0(Version.VERSION_9_0),
|
||||
|
||||
VERSION_8_3(Version.VERSION_8_3),
|
||||
|
||||
VERSION_8_0(Version.VERSION_8_0),
|
||||
|
||||
// Obsolete dx Dex Options
|
||||
DEX_OPTIONS(Version.VERSION_8_0, "Using it has no effect, and the Android" +
|
||||
"Gradle plugin optimizes dexing automatically."),
|
||||
|
||||
// Deprecation of Task Access in the variant API
|
||||
TASK_ACCESS_VIA_VARIANT(Version.VERSION_9_0),
|
||||
|
||||
USE_PROPERTIES(
|
||||
Version.VERSION_8_0,
|
||||
"Gradle Properties must be used to change Variant information."
|
||||
),
|
||||
|
||||
LINT_CHECK_ONLY(
|
||||
Version.VERSION_8_0,
|
||||
"`check` has been renamed to `checkOnly` to make it clear that it " +
|
||||
"will turn off all other checks than those explicitly listed. If that is " +
|
||||
"what you actually intended, use `checkOnly`; otherwise switch to `enable`."
|
||||
),
|
||||
|
||||
DEFAULT_PUBLISH_CONFIG(
|
||||
Version.VERSION_8_0,
|
||||
"The support for publishing artifacts with Maven Plugin is removed, " +
|
||||
"please migrate Maven Publish Plugin. See " +
|
||||
"https://developer.android.com/studio/build/maven-publish-plugin for more information."
|
||||
),
|
||||
|
||||
TRANSFORM_API(
|
||||
Version.VERSION_8_0,
|
||||
"""
|
||||
The Transform API support has been removed in AGP 8.0.
|
||||
""".trimIndent()
|
||||
),
|
||||
|
||||
DENSITY_SPLIT_API(
|
||||
Version.VERSION_9_0,
|
||||
"Density-based apk split feature is deprecated and will be removed in AGP 9.0. " +
|
||||
"Use Android App Bundle (https://developer.android.com/guide/app-bundle) " +
|
||||
"to generate optimized APKs."
|
||||
),
|
||||
|
||||
BUILD_CONFIG_GLOBAL_PROPERTY(
|
||||
Version.VERSION_9_0,
|
||||
"You can resolve this warning in Android Studio via `Refactor` > `Migrate " +
|
||||
"BuildConfig to Gradle Build Files`"
|
||||
)
|
||||
;
|
||||
|
||||
fun getDeprecationTargetMessage(): String {
|
||||
return removalTarget.getDeprecationTargetMessage() +
|
||||
(additionalMessage?.let { "\n$it" } ?: "")
|
||||
}
|
||||
}
|
||||
+147
@@ -0,0 +1,147 @@
|
||||
/*
|
||||
* Copyright (C) 2017 The Android Open Source Project
|
||||
*
|
||||
* Licensed under the Apache License, Version 2.0 (the "License");
|
||||
* you may not use this file except in compliance with the License.
|
||||
* You may obtain a copy of the License at
|
||||
*
|
||||
* http://www.apache.org/licenses/LICENSE-2.0
|
||||
*
|
||||
* Unless required by applicable law or agreed to in writing, software
|
||||
* distributed under the License is distributed on an "AS IS" BASIS,
|
||||
* WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied.
|
||||
* See the License for the specific language governing permissions and
|
||||
* limitations under the License.
|
||||
*/
|
||||
|
||||
package com.android.build.gradle.options
|
||||
|
||||
import com.android.build.gradle.options.Version.VERSION_8_2
|
||||
import com.android.builder.model.AndroidProject
|
||||
import com.android.build.gradle.options.Version.VERSION_BEFORE_4_0
|
||||
import com.android.builder.model.PROPERTY_BUILD_API
|
||||
|
||||
enum class IntegerOption(
|
||||
override val propertyName: String,
|
||||
stage: ApiStage
|
||||
) : Option<Int> {
|
||||
ANDROID_TEST_SHARD_COUNT("android.androidTest.numShards", ApiStage.Removed(VERSION_8_2, "Cross device sharding is no longer supported.")),
|
||||
ANDROID_SDK_CHANNEL("android.sdk.channel", ApiStage.Experimental),
|
||||
|
||||
/**
|
||||
* Returns the level of model-only mode.
|
||||
*
|
||||
* The model-only mode is triggered when the IDE does a sync, and therefore we do things a
|
||||
* bit differently (don't throw exceptions for instance). Things evolved a bit over versions and
|
||||
* the behavior changes. This reflects the mode to use.
|
||||
*
|
||||
* @see AndroidProject#MODEL_LEVEL_0_ORIGINAL
|
||||
* @see AndroidProject#MODEL_LEVEL_1_SYNC_ISSUE
|
||||
* @see AndroidProject#MODEL_LEVEL_3_VARIANT_OUTPUT_POST_BUILD
|
||||
* @see AndroidProject#MODEL_LEVEL_4_NEW_DEP_MODEL
|
||||
*/
|
||||
IDE_BUILD_MODEL_ONLY_VERSION(AndroidProject.PROPERTY_BUILD_MODEL_ONLY_VERSIONED, ApiStage.Stable),
|
||||
|
||||
/**
|
||||
* The api level for the target device.
|
||||
*
|
||||
* <p>For preview versions that is the last stable version, and the {@link
|
||||
* StringOption#IDE_TARGET_DEVICE_CODENAME} will also be set.
|
||||
*/
|
||||
IDE_TARGET_DEVICE_API(PROPERTY_BUILD_API, ApiStage.Stable),
|
||||
|
||||
/**
|
||||
* Size of the buffers in kilobytes used to read .class files and storage for writing .dex files
|
||||
* translations into.
|
||||
*/
|
||||
DEXING_READ_BUFFER_SIZE("android.dexingReadBuffer.size", ApiStage.Experimental),
|
||||
DEXING_WRITE_BUFFER_SIZE("android.dexingWriteBuffer.size", ApiStage.Experimental),
|
||||
|
||||
/** Number of buckets used by `DexArchiveBuilderTask` and `DexMergingTask`. */
|
||||
DEXING_NUMBER_OF_BUCKETS("android.dexingNumberOfBuckets", ApiStage.Experimental),
|
||||
|
||||
/**
|
||||
* Maximum number of dynamic features that can be allocated before Oreo platforms.
|
||||
*/
|
||||
PRE_O_MAX_NUMBER_OF_FEATURES("android.maxNumberOfFeaturesBeforeOreo", ApiStage.Experimental),
|
||||
|
||||
/**
|
||||
* Override the thread pool size dedicated to AAPT2 work units when not running with WorkerAPI.
|
||||
*/
|
||||
AAPT2_THREAD_POOL_SIZE("android.aapt2ThreadPoolSize", ApiStage.Experimental),
|
||||
|
||||
/**
|
||||
* Max number of R8 workers to run at once
|
||||
*/
|
||||
R8_MAX_WORKERS("android.r8.maxWorkers", ApiStage.Experimental),
|
||||
|
||||
/**
|
||||
* Flags for Android Test Retention
|
||||
* >=1: enable Android Test Retention and set it as maximum number of snapshots.
|
||||
* 0: disable Android Test Retention.
|
||||
* <0: enable Android Test Retention with unlimited number of snapshots.
|
||||
*/
|
||||
TEST_FAILURE_RETENTION("android.experimental.testOptions.emulatorSnapshots.maxSnapshotsForTestFailures", ApiStage.Experimental),
|
||||
|
||||
/**
|
||||
* The number of shards ran on Managed Devices during testing.
|
||||
*/
|
||||
MANAGED_DEVICE_SHARD_POOL_SIZE("android.experimental.androidTest.numManagedDeviceShards", ApiStage.Experimental),
|
||||
|
||||
/**
|
||||
* The timeout duration in minute for Gradle Managed Device setup steps (booting AVD and creating snapshot image)
|
||||
* If the value is 0 or negative value, it will never time out.
|
||||
*/
|
||||
GRADLE_MANAGED_DEVICE_SETUP_TIMEOUT_MINUTES("android.experimental.testOptions.managedDevices.setupTimeoutMinutes", ApiStage.Experimental),
|
||||
|
||||
/**
|
||||
* Maximum number of concurrent Gradle Managed Devices (AVDs) to be active at any one point in time.
|
||||
*
|
||||
* If the value is 0 or negative value, there is no maximum devices.
|
||||
*/
|
||||
GRADLE_MANAGED_DEVICE_MAX_CONCURRENT_DEVICES("android.experimental.testOptions.managedDevices.maxConcurrentDevices", ApiStage.Experimental),
|
||||
|
||||
/**
|
||||
* The timeout duration in seconds for install apk
|
||||
* If the value is 0 or negative value, it will be set to a default value by UTP.
|
||||
*/
|
||||
INSTALL_APK_TIMEOUT("android.experimental.testOptions.installApkTimeout", ApiStage.Experimental),
|
||||
/* ------------
|
||||
* REMOVED APIS
|
||||
*/
|
||||
|
||||
THREAD_POOL_SIZE(
|
||||
"android.threadPoolSize",
|
||||
ApiStage.Removed(
|
||||
VERSION_BEFORE_4_0,
|
||||
"The android.threadPoolSize property has no effect"
|
||||
)
|
||||
),
|
||||
|
||||
;
|
||||
|
||||
override val status = stage.status
|
||||
|
||||
override fun parse(value: Any): Int {
|
||||
if (value is CharSequence) {
|
||||
try {
|
||||
return Integer.parseInt(value.toString())
|
||||
} catch (ignored: NumberFormatException) {
|
||||
// Throws below.
|
||||
}
|
||||
|
||||
}
|
||||
if (value is Number) {
|
||||
return value.toInt()
|
||||
}
|
||||
throw IllegalArgumentException(
|
||||
"Cannot parse project property "
|
||||
+ this.propertyName
|
||||
+ "='"
|
||||
+ value
|
||||
+ "' of type '"
|
||||
+ value.javaClass
|
||||
+ "' as integer."
|
||||
)
|
||||
}
|
||||
}
|
||||
+93
@@ -0,0 +1,93 @@
|
||||
/*
|
||||
* This file is part of AndroidIDE.
|
||||
*
|
||||
* AndroidIDE is free software: you can redistribute it and/or modify
|
||||
* it under the terms of the GNU General Public License as published by
|
||||
* the Free Software Foundation, either version 3 of the License, or
|
||||
* (at your option) any later version.
|
||||
*
|
||||
* AndroidIDE is distributed in the hope that it will be useful,
|
||||
* but WITHOUT ANY WARRANTY; without even the implied warranty of
|
||||
* MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the
|
||||
* GNU General Public License for more details.
|
||||
*
|
||||
* You should have received a copy of the GNU General Public License
|
||||
* along with AndroidIDE. If not, see <https://www.gnu.org/licenses/>.
|
||||
*/
|
||||
|
||||
/*
|
||||
* Copyright (C) 2017 The Android Open Source Project
|
||||
*
|
||||
* Licensed under the Apache License, Version 2.0 (the "License");
|
||||
* you may not use this file except in compliance with the License.
|
||||
* You may obtain a copy of the License at
|
||||
*
|
||||
* http://www.apache.org/licenses/LICENSE-2.0
|
||||
*
|
||||
* Unless required by applicable law or agreed to in writing, software
|
||||
* distributed under the License is distributed on an "AS IS" BASIS,
|
||||
* WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied.
|
||||
* See the License for the specific language governing permissions and
|
||||
* limitations under the License.
|
||||
*/
|
||||
|
||||
package com.android.build.gradle.options
|
||||
|
||||
interface Option<out T> {
|
||||
|
||||
sealed class Status {
|
||||
|
||||
data object EXPERIMENTAL : Status()
|
||||
|
||||
data object STABLE : Status()
|
||||
|
||||
class Deprecated(val deprecationTarget: DeprecationTarget) :
|
||||
Status() {
|
||||
|
||||
fun getDeprecationTargetMessage(): String {
|
||||
return deprecationTarget.getDeprecationTargetMessage()
|
||||
}
|
||||
}
|
||||
|
||||
class Removed(
|
||||
|
||||
/**
|
||||
* The version when an element was removed.
|
||||
*
|
||||
* Usage note: Do not use this field to construct a removal message, use
|
||||
* getRemovedVersionMessage() instead to ensure consistent message format.
|
||||
*/
|
||||
val removedVersion: Version,
|
||||
|
||||
/**
|
||||
* Additional message to be shown below the pre-formatted error/warning message.
|
||||
*
|
||||
* Note that this additional message should be constructed such that it fits well in the
|
||||
* overall message:
|
||||
*
|
||||
* "This feature was removed in version X.Y of the Android Gradle plugin.\n
|
||||
* $additionalMessage"
|
||||
*
|
||||
* For example, avoid writing additional messages that say "This feature has been
|
||||
* removed", as it will be duplicated.
|
||||
*/
|
||||
private val additionalMessage: String? = null
|
||||
|
||||
) : Status() {
|
||||
|
||||
fun getRemovedVersionMessage(): String {
|
||||
return removedVersion.getRemovedVersionMessage() +
|
||||
(additionalMessage?.let { "\n$it" } ?: "")
|
||||
}
|
||||
}
|
||||
}
|
||||
|
||||
val propertyName: String
|
||||
|
||||
val defaultValue: T?
|
||||
get() = null
|
||||
|
||||
val status: Status
|
||||
|
||||
fun parse(value: Any): T
|
||||
}
|
||||
+53
@@ -0,0 +1,53 @@
|
||||
/*
|
||||
* Copyright (C) 2018 The Android Open Source Project
|
||||
*
|
||||
* Licensed under the Apache License, Version 2.0 (the "License");
|
||||
* you may not use this file except in compliance with the License.
|
||||
* You may obtain a copy of the License at
|
||||
*
|
||||
* http://www.apache.org/licenses/LICENSE-2.0
|
||||
*
|
||||
* Unless required by applicable law or agreed to in writing, software
|
||||
* distributed under the License is distributed on an "AS IS" BASIS,
|
||||
* WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied.
|
||||
* See the License for the specific language governing permissions and
|
||||
* limitations under the License.
|
||||
*/
|
||||
@file:JvmName("OptionParsers")
|
||||
|
||||
package com.android.build.gradle.options
|
||||
|
||||
import java.util.Locale
|
||||
|
||||
fun parseBoolean(propertyName: String, value: Any, propertyKind: String = "project"): Boolean {
|
||||
return when (value) {
|
||||
is Boolean -> value
|
||||
is CharSequence ->
|
||||
when (value.toString().lowercase(Locale.US)) {
|
||||
"true" -> true
|
||||
"false" -> false
|
||||
else -> parseBooleanFailure(propertyName, value, propertyKind)
|
||||
}
|
||||
is Number ->
|
||||
when (value.toInt()) {
|
||||
0 -> false
|
||||
1 -> true
|
||||
else -> parseBooleanFailure(propertyName, value, propertyKind)
|
||||
}
|
||||
else -> parseBooleanFailure(propertyName, value, propertyKind)
|
||||
}
|
||||
}
|
||||
|
||||
private fun parseBooleanFailure(propertyName: String, value: Any, propertyKind: String): Nothing {
|
||||
throw IllegalArgumentException(
|
||||
"Cannot parse "
|
||||
+ propertyKind
|
||||
+ " property "
|
||||
+ propertyName
|
||||
+ "='"
|
||||
+ value
|
||||
+ "' of type '"
|
||||
+ value.javaClass
|
||||
+ "' as boolean. Expected 'true' or 'false'."
|
||||
)
|
||||
}
|
||||
+86
@@ -0,0 +1,86 @@
|
||||
/*
|
||||
* Copyright (C) 2017 The Android Open Source Project
|
||||
*
|
||||
* Licensed under the Apache License, Version 2.0 (the "License");
|
||||
* you may not use this file except in compliance with the License.
|
||||
* You may obtain a copy of the License at
|
||||
*
|
||||
* http://www.apache.org/licenses/LICENSE-2.0
|
||||
*
|
||||
* Unless required by applicable law or agreed to in writing, software
|
||||
* distributed under the License is distributed on an "AS IS" BASIS,
|
||||
* WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied.
|
||||
* See the License for the specific language governing permissions and
|
||||
* limitations under the License.
|
||||
*/
|
||||
|
||||
package com.android.build.gradle.options
|
||||
|
||||
import com.android.build.gradle.options.Version.VERSION_7_0
|
||||
import com.android.build.gradle.options.Version.VERSION_8_0
|
||||
import com.android.build.gradle.options.Version.VERSION_BEFORE_4_0
|
||||
import com.android.builder.model.PROPERTY_SIGNING_V1_ENABLED
|
||||
import com.android.builder.model.PROPERTY_SIGNING_V2_ENABLED
|
||||
import com.android.builder.model.PROPERTY_TEST_ONLY
|
||||
|
||||
enum class OptionalBooleanOption(
|
||||
override val propertyName: String,
|
||||
val stage: Stage,
|
||||
val recommendedValue: Boolean? = null
|
||||
) : Option<Boolean> {
|
||||
SIGNING_V1_ENABLED(PROPERTY_SIGNING_V1_ENABLED, ApiStage.Stable),
|
||||
SIGNING_V2_ENABLED(PROPERTY_SIGNING_V2_ENABLED, ApiStage.Stable),
|
||||
IDE_TEST_ONLY(PROPERTY_TEST_ONLY, ApiStage.Stable),
|
||||
|
||||
/**
|
||||
* This project property is read by the firebase plugin, and has no direct impact on AGP behavior.
|
||||
*
|
||||
* It is included as an OptionalBooleanOption in order that its value, if set, is recorded in the AGP analytics.
|
||||
*/
|
||||
FIREBASE_PERF_PLUGIN_ENABLE_FLAG("firebasePerformanceInstrumentationEnabled", ApiStage.Stable),
|
||||
|
||||
// Flags for Android Test Retention
|
||||
ENABLE_TEST_FAILURE_RETENTION_COMPRESS_SNAPSHOT("android.experimental.testOptions.emulatorSnapshots.compressSnapshots", ApiStage.Experimental),
|
||||
|
||||
ENABLE_API_MODELING_AND_GLOBAL_SYNTHETICS("android.enableApiModelingAndGlobalSynthetics", ApiStage.Experimental),
|
||||
|
||||
/* ----------------
|
||||
* SOFTLY ENFORCED FEATURES
|
||||
*/
|
||||
|
||||
/* ----------------
|
||||
* ENFORCED FEATURES
|
||||
*/
|
||||
@Suppress("unused")
|
||||
ENABLE_R8(
|
||||
"android.enableR8",
|
||||
FeatureStage.Enforced(VERSION_7_0, "Please remove it from `gradle.properties`.")
|
||||
),
|
||||
|
||||
@Suppress("unused")
|
||||
DISABLE_AUTOMATIC_COMPONENT_CREATION(
|
||||
"android.disableAutomaticComponentCreation",
|
||||
FeatureStage.Enforced(VERSION_8_0, "Please remove it from `gradle.properties`.")
|
||||
),
|
||||
|
||||
/* ----------------
|
||||
* REMOVED FEATURES
|
||||
*/
|
||||
|
||||
@Suppress("unused")
|
||||
SERIAL_AAPT2(
|
||||
"android.injected.aapt2.serial",
|
||||
FeatureStage.Removed(
|
||||
VERSION_BEFORE_4_0,
|
||||
"Invoking AAPT2 serially is no longer supported."
|
||||
)
|
||||
),
|
||||
|
||||
;
|
||||
|
||||
override val status = stage.status
|
||||
|
||||
override fun parse(value: Any): Boolean {
|
||||
return parseBoolean(propertyName, value)
|
||||
}
|
||||
}
|
||||
+171
@@ -0,0 +1,171 @@
|
||||
/*
|
||||
* Copyright (C) 2017 The Android Open Source Project
|
||||
*
|
||||
* Licensed under the Apache License, Version 2.0 (the "License");
|
||||
* you may not use this file except in compliance with the License.
|
||||
* You may obtain a copy of the License at
|
||||
*
|
||||
* http://www.apache.org/licenses/LICENSE-2.0
|
||||
*
|
||||
* Unless required by applicable law or agreed to in writing, software
|
||||
* distributed under the License is distributed on an "AS IS" BASIS,
|
||||
* WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied.
|
||||
* See the License for the specific language governing permissions and
|
||||
* limitations under the License.
|
||||
*/
|
||||
|
||||
package com.android.build.gradle.options
|
||||
|
||||
import com.android.build.gradle.options.Version.VERSION_4_0
|
||||
import com.android.build.gradle.options.Version.VERSION_4_1
|
||||
import com.android.build.gradle.options.Version.VERSION_7_0
|
||||
import com.android.build.gradle.options.Version.VERSION_BEFORE_4_0
|
||||
|
||||
/**
|
||||
* [Option] that has been replaced by something else (e.g., another option or the DSL).
|
||||
*
|
||||
* Note that replaced options are different from removed options. Removed options belong to the
|
||||
* [Option] subclass where they were first introduced, and should not be put in this class.
|
||||
*/
|
||||
enum class ReplacedOption(
|
||||
override val propertyName: String,
|
||||
private val replacedVersion: Version,
|
||||
private val additionalMessage: String
|
||||
) : Option<String> {
|
||||
|
||||
@Suppress("unused")
|
||||
INCREMENTAL_JAVA_COMPILE(
|
||||
"android.incrementalJavaCompile",
|
||||
VERSION_BEFORE_4_0,
|
||||
"The android.incrementalJavaCompile property has been replaced by a DSL property. "
|
||||
+ "Please add the following to your build.gradle instead:\n"
|
||||
+ "android {\n"
|
||||
+ " compileOptions.incremental = false\n"
|
||||
+ "}"
|
||||
),
|
||||
|
||||
@Suppress("unused")
|
||||
THREAD_POOL_SIZE_OLD(
|
||||
"com.android.build.threadPoolSize",
|
||||
VERSION_BEFORE_4_0,
|
||||
"This property has been replaced by ${IntegerOption.THREAD_POOL_SIZE.propertyName}"
|
||||
),
|
||||
|
||||
@Suppress("unused")
|
||||
VERSION_CHECK_OVERRIDE_PROPERTY_OLD(
|
||||
"com.android.build.gradle.overrideVersionCheck",
|
||||
VERSION_BEFORE_4_0,
|
||||
"This property has been replaced by ${BooleanOption.VERSION_CHECK_OVERRIDE_PROPERTY.propertyName}"
|
||||
),
|
||||
|
||||
@Suppress("unused")
|
||||
OVERRIDE_PATH_CHECK_PROPERTY_OLD(
|
||||
"com.android.build.gradle.overridePathCheck",
|
||||
VERSION_BEFORE_4_0,
|
||||
"This property has been replaced by ${BooleanOption.OVERRIDE_PATH_CHECK_PROPERTY.propertyName}"
|
||||
),
|
||||
|
||||
@Suppress("unused")
|
||||
AAPT_NAMESPACING(
|
||||
"android.aaptNamespacing",
|
||||
VERSION_BEFORE_4_0,
|
||||
"This property has been replaced by android.aaptOptions.namespaced (DSL)"
|
||||
),
|
||||
|
||||
@Suppress("unused")
|
||||
EXCLUDE_R_AND_MANIFEST_DOT_JAVA_FROM_GENERATED_SOURCES(
|
||||
"android.excludeRAndManifestDotJavaFromGeneratedSources",
|
||||
VERSION_BEFORE_4_0,
|
||||
"Subsumed by ${BooleanOption.ENABLE_SEPARATE_R_CLASS_COMPILATION.propertyName}"
|
||||
),
|
||||
|
||||
// This option should belong to the LongOption class, but that class has been removed so we put
|
||||
// it here.
|
||||
@Suppress("unused")
|
||||
DEPRECATED_NDK_COMPILE_LEASE(
|
||||
"android.deprecatedNdkCompileLease",
|
||||
VERSION_BEFORE_4_0,
|
||||
"NdkCompile is no longer supported"
|
||||
),
|
||||
|
||||
@Suppress("unused")
|
||||
USE_NON_FINAL_RES_IDS_IN_TESTS(
|
||||
"android.androidTest.nonFinalResIds",
|
||||
VERSION_BEFORE_4_0,
|
||||
"This property has been replaced by ${BooleanOption.USE_NON_FINAL_RES_IDS.propertyName}"
|
||||
),
|
||||
|
||||
@Suppress("unused")
|
||||
ENABLE_INCREMENTAL_DESUGARING_V2(
|
||||
"android.enableIncrementalDesugaringV2",
|
||||
VERSION_4_0,
|
||||
"This property has been replaced by ${BooleanOption.ENABLE_INCREMENTAL_DEXING_TASK_V2.propertyName}"
|
||||
),
|
||||
|
||||
@Suppress("unused")
|
||||
ENABLE_INCREMENTAL_DEXING_V2(
|
||||
"android.enableIncrementalDexingV2",
|
||||
VERSION_4_1,
|
||||
"This property has been replaced by ${BooleanOption.ENABLE_INCREMENTAL_DEXING_TASK_V2.propertyName}"
|
||||
),
|
||||
|
||||
@Suppress("unused")
|
||||
NAMESPACED_R_CLASS(
|
||||
"android.namespacedRClass",
|
||||
VERSION_4_1,
|
||||
"This property has been replaced by ${BooleanOption.NON_TRANSITIVE_R_CLASS.propertyName}"
|
||||
),
|
||||
|
||||
@Suppress("unused")
|
||||
ENABLE_PREFAB(
|
||||
"android.enablePrefab",
|
||||
VERSION_4_1,
|
||||
"This property has been replaced by android.buildFeatures.prefab (DSL)"
|
||||
),
|
||||
|
||||
// The flag was renamed.
|
||||
@Suppress("unused")
|
||||
ENABLE_STABLE_IDS(
|
||||
"android.experimental.enableStableIds",
|
||||
VERSION_4_1,
|
||||
"This property has been replaced by ${BooleanOption.ENABLE_STABLE_IDS.propertyName}"
|
||||
),
|
||||
|
||||
@Suppress("unused")
|
||||
TEST_FAILURE_RETENTION_0(
|
||||
"android.experimental.testOptions.emulatorSnapshots",
|
||||
VERSION_7_0,
|
||||
"This property has been replaced by ${IntegerOption.TEST_FAILURE_RETENTION.propertyName}"
|
||||
),
|
||||
|
||||
@Suppress("unused")
|
||||
TEST_FAILURE_RETENTION_1(
|
||||
"android.testOptions.failureRetention",
|
||||
VERSION_7_0,
|
||||
"This property has been replaced by ${IntegerOption.TEST_FAILURE_RETENTION.propertyName}"
|
||||
),
|
||||
|
||||
@Suppress("unused")
|
||||
ENABLE_TEST_FAILURE_RETENTION_COMPRESS_SNAPSHOT(
|
||||
"android.testOptions.failureRetention.compressSnapshots",
|
||||
VERSION_7_0,
|
||||
"This property has been replaced by ${OptionalBooleanOption.ENABLE_TEST_FAILURE_RETENTION_COMPRESS_SNAPSHOT.propertyName}"
|
||||
),
|
||||
|
||||
// Jetifier: List of regular expressions for libraries that should not be jetified
|
||||
@Suppress("unused", "WrongTerminology")
|
||||
JETIFIER_BLACKLIST(
|
||||
"android.jetifier.blacklist",
|
||||
VERSION_7_0,
|
||||
"This property has been replaced by ${StringOption.JETIFIER_IGNORE_LIST.propertyName}"
|
||||
)
|
||||
|
||||
;
|
||||
|
||||
override val status: Option.Status
|
||||
get() = Option.Status.Removed(replacedVersion, additionalMessage)
|
||||
|
||||
override fun parse(value: Any): String {
|
||||
return value.toString()
|
||||
}
|
||||
}
|
||||
+167
@@ -0,0 +1,167 @@
|
||||
/*
|
||||
* This file is part of AndroidIDE.
|
||||
*
|
||||
* AndroidIDE is free software: you can redistribute it and/or modify
|
||||
* it under the terms of the GNU General Public License as published by
|
||||
* the Free Software Foundation, either version 3 of the License, or
|
||||
* (at your option) any later version.
|
||||
*
|
||||
* AndroidIDE is distributed in the hope that it will be useful,
|
||||
* but WITHOUT ANY WARRANTY; without even the implied warranty of
|
||||
* MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the
|
||||
* GNU General Public License for more details.
|
||||
*
|
||||
* You should have received a copy of the GNU General Public License
|
||||
* along with AndroidIDE. If not, see <https://www.gnu.org/licenses/>.
|
||||
*/
|
||||
|
||||
/*
|
||||
* Copyright (C) 2019 The Android Open Source Project
|
||||
*
|
||||
* Licensed under the Apache License, Version 2.0 (the "License");
|
||||
* you may not use this file except in compliance with the License.
|
||||
* You may obtain a copy of the License at
|
||||
*
|
||||
* http://www.apache.org/licenses/LICENSE-2.0
|
||||
*
|
||||
* Unless required by applicable law or agreed to in writing, software
|
||||
* distributed under the License is distributed on an "AS IS" BASIS,
|
||||
* WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied.
|
||||
* See the License for the specific language governing permissions and
|
||||
* limitations under the License.
|
||||
*/
|
||||
|
||||
package com.android.build.gradle.options
|
||||
|
||||
/**
|
||||
* The stage of an API or feature in its life cycle.
|
||||
*
|
||||
* An API or feature has an associated [Option] to allow the users to change the behavior of the
|
||||
* Android Gradle plugin. The difference between them is that:
|
||||
* - The [Option] associated with an API is intended to be used in the long term. For example, if
|
||||
* it is a [BooleanOption] (or [OptionalBooleanOption]), one value of the option may be
|
||||
* experimental at first, but eventually both values of the option will be supported.
|
||||
* - The [Option] associated with a feature is intended to be used only in the short term. It can
|
||||
* only be a [BooleanOption] (or [OptionalBooleanOption]). One value of the [BooleanOption] may
|
||||
* be experimental at first to enable the new behavior, but eventually the option will be
|
||||
* removed, either because the feature is fully supported and now enforced, or because the
|
||||
* feature was not / is no longer useful and now removed.
|
||||
*/
|
||||
open class Stage(
|
||||
|
||||
/**
|
||||
* Status of the [Option] which represents an API or feature. It is related but not the same as
|
||||
* the [Stage] of the API of feature.
|
||||
*/
|
||||
val status: Option.Status
|
||||
)
|
||||
|
||||
/**
|
||||
* The stage of an API in its life cycle.
|
||||
*
|
||||
* See [Stage] for the difference between an API and a feature.
|
||||
*/
|
||||
sealed class ApiStage(status: Option.Status) : Stage(status) {
|
||||
|
||||
/**
|
||||
* Indicates that the API is experimental.
|
||||
*
|
||||
* It may become stable or may be removed in a future release (see stage [Stable] and
|
||||
* [Removed]).
|
||||
*/
|
||||
object Experimental : ApiStage(Option.Status.EXPERIMENTAL)
|
||||
|
||||
/**
|
||||
* Indicates that the API is stable.
|
||||
*/
|
||||
object Stable : ApiStage(Option.Status.STABLE)
|
||||
|
||||
/**
|
||||
* Indicates that the API will be removed soon because it was not / is no longer useful (see
|
||||
* stage [Removed]).
|
||||
*
|
||||
* @param removalTarget a target when the API and the corresponding [Option] will be removed
|
||||
*/
|
||||
class Deprecated(removalTarget: DeprecationTarget) :
|
||||
ApiStage(Option.Status.Deprecated(removalTarget))
|
||||
|
||||
/**
|
||||
* Indicates that the API and the corresponding [Option] have been removed.
|
||||
*
|
||||
* @param removedVersion the version when the API and the corresponding [Option] were removed
|
||||
* @param additionalMessage the additional message to be shown if the [Option] is used
|
||||
*/
|
||||
class Removed(removedVersion: Version, additionalMessage: String? = null) :
|
||||
ApiStage(Option.Status.Removed(removedVersion, additionalMessage))
|
||||
}
|
||||
|
||||
/**
|
||||
* The stage of a feature in its life cycle.
|
||||
*
|
||||
* See [Stage] for the difference between an API and a feature.
|
||||
*/
|
||||
sealed class FeatureStage(status: Option.Status) : Stage(status) {
|
||||
|
||||
/**
|
||||
* Indicates that the feature is experimental.
|
||||
*
|
||||
* It may be enforced or removed in a future release (see stage [Enforced] and [Removed]).
|
||||
*/
|
||||
object Experimental : FeatureStage(Option.Status.EXPERIMENTAL)
|
||||
|
||||
/**
|
||||
* Indicates that the feature is fully supported.
|
||||
*
|
||||
* It may or may not be enabled by default. If it is not yet enabled by default, it will likely
|
||||
* be enabled by default in a future release.
|
||||
*
|
||||
* Eventually, the feature will likely be enforced (see stage [SoftlyEnforced] and [Enforced]).
|
||||
* In some cases, it may be removed (see stage [Deprecated] and [Removed]).
|
||||
*
|
||||
* DISCOURAGED USAGE: The use of this stage is actually discouraged as it doesn't specify a
|
||||
* clear timeline and features may stay in this stage for too long, thus increasing maintenance
|
||||
* cost to AGP and users. Consider using [SoftlyEnforced] or [Deprecated] instead.
|
||||
*/
|
||||
object Supported : FeatureStage(Option.Status.STABLE)
|
||||
|
||||
/**
|
||||
* Indicates that the feature will be enforced soon (see stage [Enforced]).
|
||||
*
|
||||
* @param enforcementTarget a target when the feature will be enforced, at which point the
|
||||
* corresponding [Option] will be removed (hence this parameter has type
|
||||
* `DeprecationTarget`)
|
||||
*/
|
||||
class SoftlyEnforced(enforcementTarget: DeprecationTarget) :
|
||||
FeatureStage(Option.Status.Deprecated(enforcementTarget))
|
||||
|
||||
/**
|
||||
* Indicates that the feature is enforced (always enabled), and the corresponding [Option] has
|
||||
* been removed.
|
||||
*
|
||||
* @param enforcedVersion the version when the feature is enforced and the corresponding
|
||||
* [Option] was removed
|
||||
* @param additionalMessage the additional message to be shown if the [Option] is used
|
||||
*/
|
||||
class Enforced(enforcedVersion: Version, additionalMessage: String? = null) :
|
||||
FeatureStage(Option.Status.Removed(enforcedVersion, additionalMessage))
|
||||
|
||||
/**
|
||||
* Indicates that the feature will be removed soon because it was not / is no longer useful (see
|
||||
* stage [Removed]).
|
||||
*
|
||||
* @param removalTarget a target when the feature and the corresponding [Option] will be removed
|
||||
*/
|
||||
class Deprecated(removalTarget: DeprecationTarget) :
|
||||
FeatureStage(Option.Status.Deprecated(removalTarget))
|
||||
|
||||
/**
|
||||
* Indicates that the feature has been removed (always disabled), and the corresponding [Option]
|
||||
* has been removed.
|
||||
*
|
||||
* @param removedVersion the version when the feature and the corresponding [Option] were
|
||||
* removed
|
||||
* @param additionalMessage the additional message to be shown if the [Option] is used
|
||||
*/
|
||||
class Removed(removedVersion: Version, additionalMessage: String? = null) :
|
||||
FeatureStage(Option.Status.Removed(removedVersion, additionalMessage))
|
||||
}
|
||||
+181
@@ -0,0 +1,181 @@
|
||||
/*
|
||||
* Copyright (C) 2017 The Android Open Source Project
|
||||
*
|
||||
* Licensed under the Apache License, Version 2.0 (the "License");
|
||||
* you may not use this file except in compliance with the License.
|
||||
* You may obtain a copy of the License at
|
||||
*
|
||||
* http://www.apache.org/licenses/LICENSE-2.0
|
||||
*
|
||||
* Unless required by applicable law or agreed to in writing, software
|
||||
* distributed under the License is distributed on an "AS IS" BASIS,
|
||||
* WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied.
|
||||
* See the License for the specific language governing permissions and
|
||||
* limitations under the License.
|
||||
*/
|
||||
|
||||
package com.android.build.gradle.options
|
||||
|
||||
import com.android.builder.model.AndroidProject
|
||||
import com.android.builder.model.PROPERTY_APK_LOCATION
|
||||
import com.android.builder.model.PROPERTY_APK_SELECT_CONFIG
|
||||
import com.android.builder.model.PROPERTY_ATTRIBUTION_FILE_LOCATION
|
||||
import com.android.builder.model.PROPERTY_BUILD_ABI
|
||||
import com.android.builder.model.PROPERTY_BUILD_API_CODENAME
|
||||
import com.android.builder.model.PROPERTY_BUILD_DENSITY
|
||||
import com.android.builder.model.PROPERTY_CHECK_JETIFIER_RESULT_FILE
|
||||
import com.android.builder.model.PROPERTY_INJECTED_DYNAMIC_MODULES_LIST
|
||||
import com.android.builder.model.PROPERTY_NATIVE_BUILD_OUTPUT_LEVEL
|
||||
import com.android.builder.model.PROPERTY_SIGNING_KEY_ALIAS
|
||||
import com.android.builder.model.PROPERTY_SIGNING_KEY_PASSWORD
|
||||
import com.android.builder.model.PROPERTY_SIGNING_STORE_FILE
|
||||
import com.android.builder.model.PROPERTY_SIGNING_STORE_PASSWORD
|
||||
import com.android.builder.model.PROPERTY_SIGNING_STORE_TYPE
|
||||
|
||||
enum class StringOption(
|
||||
override val propertyName: String,
|
||||
stage: ApiStage
|
||||
) : Option<String> {
|
||||
|
||||
/* -----------
|
||||
* STABLE APIs
|
||||
*/
|
||||
|
||||
IDE_BUILD_TARGET_ABI(PROPERTY_BUILD_ABI, ApiStage.Stable),
|
||||
|
||||
IDE_ATTRIBUTION_FILE_LOCATION(PROPERTY_ATTRIBUTION_FILE_LOCATION, ApiStage.Stable),
|
||||
|
||||
/** Absolute path to a file containing the result of the `CheckJetifier` task. */
|
||||
IDE_CHECK_JETIFIER_RESULT_FILE(PROPERTY_CHECK_JETIFIER_RESULT_FILE, ApiStage.Stable),
|
||||
|
||||
// Signing options
|
||||
IDE_SIGNING_STORE_TYPE(PROPERTY_SIGNING_STORE_TYPE, ApiStage.Stable),
|
||||
IDE_SIGNING_STORE_FILE(PROPERTY_SIGNING_STORE_FILE, ApiStage.Stable),
|
||||
IDE_SIGNING_STORE_PASSWORD(PROPERTY_SIGNING_STORE_PASSWORD, ApiStage.Stable),
|
||||
IDE_SIGNING_KEY_ALIAS(PROPERTY_SIGNING_KEY_ALIAS, ApiStage.Stable),
|
||||
IDE_SIGNING_KEY_PASSWORD(PROPERTY_SIGNING_KEY_PASSWORD, ApiStage.Stable),
|
||||
|
||||
// device config for ApkSelect
|
||||
IDE_APK_SELECT_CONFIG(PROPERTY_APK_SELECT_CONFIG, ApiStage.Stable),
|
||||
|
||||
// location where to write the APK/BUNDLE
|
||||
IDE_APK_LOCATION(PROPERTY_APK_LOCATION, ApiStage.Stable),
|
||||
|
||||
IDE_TARGET_DEVICE_CODENAME(PROPERTY_BUILD_API_CODENAME, ApiStage.Stable),
|
||||
|
||||
// Profiler plugin
|
||||
IDE_ANDROID_CUSTOM_CLASS_TRANSFORMS("android.advanced.profiling.transforms", ApiStage.Stable),
|
||||
|
||||
// The exact version of Android Support plugin used, e.g. 2.4.0.6
|
||||
IDE_ANDROID_STUDIO_VERSION(AndroidProject.PROPERTY_ANDROID_SUPPORT_VERSION, ApiStage.Stable),
|
||||
|
||||
// The version of Android Game Development Extension used to orchestrate the build
|
||||
IDE_AGDE_VERSION("agde.version", ApiStage.Stable),
|
||||
|
||||
// Native
|
||||
NATIVE_BUILD_OUTPUT_LEVEL(PROPERTY_NATIVE_BUILD_OUTPUT_LEVEL, ApiStage.Stable),
|
||||
|
||||
// AGP suggests it should be upgraded if the compile sdk is newer than the version it was tested
|
||||
// with. This option allows developers to suppress that warning.
|
||||
// e.g. android.suppressUnsupportedCompileSdk=S,31,32
|
||||
SUPPRESS_UNSUPPORTED_COMPILE_SDK("android.suppressUnsupportedCompileSdk", ApiStage.Stable),
|
||||
|
||||
// User-specified flag for using a profileable or debuggable build,
|
||||
// if the flag is not set, the debuggable value will fallback to using the DSL 'debuggable'.
|
||||
PROFILING_MODE("android.profilingMode", ApiStage.Stable),
|
||||
|
||||
// Override for the default execution profile in the settings plugin.
|
||||
EXECUTION_PROFILE_SELECTION("android.settings.executionProfile", ApiStage.Stable),
|
||||
|
||||
/* -----------------
|
||||
* EXPERIMENTAL APIs
|
||||
*/
|
||||
|
||||
// Installation related options
|
||||
IDE_INSTALL_DYNAMIC_MODULES_LIST(PROPERTY_INJECTED_DYNAMIC_MODULES_LIST, ApiStage.Experimental),
|
||||
|
||||
// Testing
|
||||
DEVICE_POOL_SERIAL("com.android.test.devicepool.serial", ApiStage.Experimental),
|
||||
PROFILE_OUTPUT_DIR("android.advanced.profileOutputDir", ApiStage.Experimental),
|
||||
|
||||
BUILD_ARTIFACT_REPORT_FILE("android.buildartifact.reportfile", ApiStage.Experimental),
|
||||
|
||||
AAPT2_FROM_MAVEN_OVERRIDE("android.aapt2FromMavenOverride", ApiStage.Experimental),
|
||||
|
||||
AAPT2_FROM_MAVEN_VERSION_OVERRIDE("android.aapt2Version", ApiStage.Experimental),
|
||||
|
||||
AAPT2_FROM_MAVEN_PLATFORM_OVERRIDE("android.aapt2Platform", ApiStage.Experimental),
|
||||
|
||||
SUPPRESS_UNSUPPORTED_OPTION_WARNINGS("android.suppressUnsupportedOptionWarnings", ApiStage.Experimental),
|
||||
|
||||
// User-specified path to Prefab jar to return from getPrefabFromMaven.
|
||||
PREFAB_CLASSPATH("android.prefabClassPath", ApiStage.Experimental),
|
||||
|
||||
// User-specified Prefab version to pull from Maven in getPrefabFromMaven.
|
||||
PREFAB_VERSION("android.prefabVersion", ApiStage.Experimental),
|
||||
|
||||
// Jetifier: List of regular expressions for libraries that should not be jetified
|
||||
JETIFIER_IGNORE_LIST("android.jetifier.ignorelist", ApiStage.Experimental),
|
||||
|
||||
// Lint: Allow customization of the heap size of the process started to run lint
|
||||
LINT_HEAP_SIZE("android.experimental.lint.heapSize", ApiStage.Experimental),
|
||||
|
||||
// Lint: Allow customization of the amount of memory earmarked for each lint task (when lint
|
||||
// runs in process)
|
||||
LINT_RESERVED_MEMORY_PER_TASK("android.experimental.lint.reservedMemoryPerTask", ApiStage.Experimental),
|
||||
|
||||
// Lint: Allow override of the version. Note that lint versions are generally 23 higher than
|
||||
// the version of Android Gradle Plugin. So AGP 7.0.0-beta02 defaults to using lint
|
||||
// 30.0.0-beta02
|
||||
LINT_VERSION_OVERRIDE("android.experimental.lint.version", ApiStage.Experimental),
|
||||
|
||||
// User-specified flag to override the emulator gpu mode for Gradle Managed Devices,
|
||||
// If the flag is not set, the emulator gpu mode will default to auto-no-window.
|
||||
// Supported values are "auto", "auto-no-window", "host", "swiftshader_indirect",
|
||||
// "angle_indirect"
|
||||
GRADLE_MANAGED_DEVICE_EMULATOR_GPU_MODE("android.testoptions.manageddevices.emulator.gpu", ApiStage.Experimental),
|
||||
|
||||
ANDROID_PRIVACY_SANDBOX_SDK_API_GENERATOR("android.privacySandboxSdk.apiGenerator", ApiStage.Experimental),
|
||||
|
||||
ANDROID_PRIVACY_SANDBOX_SDK_API_GENERATOR_GENERATED_RUNTIME_DEPENDENCIES("android.privacySandboxSdk.apiGenerator.generatedRuntimeDependencies", ApiStage.Experimental),
|
||||
|
||||
ANDROID_PRIVACY_SANDBOX_SDK_API_PACKAGER("android.privacySandboxSdk.apiPackager", ApiStage.Experimental),
|
||||
/* ---------------
|
||||
* DEPRECATED APIs
|
||||
*/
|
||||
|
||||
/* ------------
|
||||
* REMOVED APIs
|
||||
*/
|
||||
|
||||
@Suppress("unused")
|
||||
BUILD_CACHE_DIR(
|
||||
"android.buildCacheDir",
|
||||
ApiStage.Removed(Version.VERSION_7_0, "The Android-specific build caches were superseded by the Gradle build cache (https://docs.gradle.org/current/userguide/build_cache.html).")
|
||||
),
|
||||
|
||||
@Suppress("unused")
|
||||
IDE_BUILD_TARGET_DENSITY(
|
||||
PROPERTY_BUILD_DENSITY,
|
||||
ApiStage.Removed(Version.VERSION_8_0, "Density property injection from Android Studio has been removed.")
|
||||
),
|
||||
|
||||
;
|
||||
|
||||
override val status = stage.status
|
||||
|
||||
override fun parse(value: Any): String {
|
||||
if (value is CharSequence || value is Number) {
|
||||
return value.toString()
|
||||
}
|
||||
throw IllegalArgumentException(
|
||||
"Cannot parse project property "
|
||||
+ this.propertyName
|
||||
+ "='"
|
||||
+ value
|
||||
+ "' of type '"
|
||||
+ value.javaClass
|
||||
+ "' as string."
|
||||
)
|
||||
}
|
||||
}
|
||||
+62
@@ -0,0 +1,62 @@
|
||||
/*
|
||||
* Copyright (C) 2020 The Android Open Source Project
|
||||
*
|
||||
* Licensed under the Apache License, Version 2.0 (the "License");
|
||||
* you may not use this file except in compliance with the License.
|
||||
* You may obtain a copy of the License at
|
||||
*
|
||||
* http://www.apache.org/licenses/LICENSE-2.0
|
||||
*
|
||||
* Unless required by applicable law or agreed to in writing, software
|
||||
* distributed under the License is distributed on an "AS IS" BASIS,
|
||||
* WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied.
|
||||
* See the License for the specific language governing permissions and
|
||||
* limitations under the License.
|
||||
*/
|
||||
|
||||
package com.android.build.gradle.options
|
||||
|
||||
/**
|
||||
* A list of standard instrumentation test runner keys.
|
||||
*
|
||||
* Details: https://developer.android.com/studio/test/command-line#AMOptionsSyntax
|
||||
*/
|
||||
enum class TestRunnerArguments(
|
||||
private val key: String
|
||||
) {
|
||||
@Suppress("unused")
|
||||
PACKAGE("package"),
|
||||
|
||||
@Suppress("unused")
|
||||
CLASS("class"),
|
||||
|
||||
@Suppress("unused")
|
||||
FUNC("func"),
|
||||
|
||||
@Suppress("unused")
|
||||
SIZE("size"),
|
||||
|
||||
@Suppress("unused")
|
||||
PERF("perf"),
|
||||
|
||||
@Suppress("unused")
|
||||
DEBUG("debug"),
|
||||
|
||||
@Suppress("unused")
|
||||
LOG("log"),
|
||||
|
||||
@Suppress("unused")
|
||||
EMMA("emma"),
|
||||
|
||||
@Suppress("unused")
|
||||
COVERAGE_FILE("coverageFile"),
|
||||
;
|
||||
|
||||
fun getFullKey() : String = "$TEST_RUNNER_ARGS_PREFIX$key"
|
||||
|
||||
fun getShortKey() : String = key
|
||||
|
||||
companion object {
|
||||
const val TEST_RUNNER_ARGS_PREFIX = "android.testInstrumentationRunnerArguments."
|
||||
}
|
||||
}
|
||||
+66
@@ -0,0 +1,66 @@
|
||||
/*
|
||||
* Copyright (C) 2020 The Android Open Source Project
|
||||
*
|
||||
* Licensed under the Apache License, Version 2.0 (the "License");
|
||||
* you may not use this file except in compliance with the License.
|
||||
* You may obtain a copy of the License at
|
||||
*
|
||||
* http://www.apache.org/licenses/LICENSE-2.0
|
||||
*
|
||||
* Unless required by applicable law or agreed to in writing, software
|
||||
* distributed under the License is distributed on an "AS IS" BASIS,
|
||||
* WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied.
|
||||
* See the License for the specific language governing permissions and
|
||||
* limitations under the License.
|
||||
*/
|
||||
|
||||
package com.android.build.gradle.options
|
||||
|
||||
/** An Android Gradle plugin version. */
|
||||
enum class Version(
|
||||
|
||||
/**
|
||||
* String value of the version, or `null` if it is not known (e.g., [VERSION_BEFORE_4_0]).
|
||||
*
|
||||
* Usage note: Do not use this field to construct a deprecation/removal message, use
|
||||
* getDeprecationTargetMessage()/getRemovedVersionMessage() instead to ensure consistent message
|
||||
* format.
|
||||
*/
|
||||
val versionString: String?
|
||||
) {
|
||||
|
||||
/**
|
||||
* A version before version 4.0, used when the exact version is not known, except that it's
|
||||
* guaranteed to be before 4.0.
|
||||
*/
|
||||
VERSION_BEFORE_4_0(null),
|
||||
|
||||
VERSION_3_5("3.5"),
|
||||
VERSION_3_6("3.6"),
|
||||
VERSION_4_0("4.0"),
|
||||
VERSION_4_1("4.1"),
|
||||
VERSION_4_2("4.2"),
|
||||
VERSION_7_0("7.0"),
|
||||
VERSION_7_2("7.2"),
|
||||
VERSION_7_3("7.3"),
|
||||
VERSION_8_0("8.0"),
|
||||
VERSION_8_1("8.1"),
|
||||
VERSION_8_2("8.2"),
|
||||
VERSION_8_3("8.3"),
|
||||
VERSION_9_0("9.0"),
|
||||
|
||||
; // end of enums
|
||||
|
||||
fun getDeprecationTargetMessage(): String {
|
||||
check(this != VERSION_BEFORE_4_0)
|
||||
return "It will be removed in version $versionString of the Android Gradle plugin."
|
||||
}
|
||||
|
||||
fun getRemovedVersionMessage(): String {
|
||||
return if (this == VERSION_BEFORE_4_0) {
|
||||
"It has been removed from the current version of the Android Gradle plugin."
|
||||
} else {
|
||||
"It was removed in version $versionString of the Android Gradle plugin."
|
||||
}
|
||||
}
|
||||
}
|
||||
+1
-1
@@ -20,7 +20,7 @@ import com.android.builder.model.v2.models.ProjectSyncIssues
|
||||
import java.io.Serializable
|
||||
|
||||
/** @author Akash Yadav */
|
||||
class DefaultProjectSyncIssues(override val syncIssues: Collection<DefaultSyncIssue>) :
|
||||
data class DefaultProjectSyncIssues(override val syncIssues: Collection<DefaultSyncIssue>) :
|
||||
ProjectSyncIssues, Serializable {
|
||||
private val serialVersionUID = 1L
|
||||
}
|
||||
|
||||
+3
-3
@@ -17,16 +17,16 @@
|
||||
|
||||
package com.itsaky.androidide.builder.model
|
||||
|
||||
import com.android.builder.model.v2.ide.SyncIssue
|
||||
import java.io.Serializable
|
||||
|
||||
/** @author Akash Yadav */
|
||||
class DefaultSyncIssue(
|
||||
data class DefaultSyncIssue(
|
||||
override val data: String?,
|
||||
override val message: String,
|
||||
override val multiLineMessage: List<String?>?,
|
||||
override val severity: Int,
|
||||
override val type: Int
|
||||
) : SyncIssue, Serializable {
|
||||
) : IDESyncIssue, Serializable {
|
||||
|
||||
private val serialVersionUID = 1L
|
||||
}
|
||||
|
||||
+57
@@ -0,0 +1,57 @@
|
||||
/*
|
||||
* This file is part of AndroidIDE.
|
||||
*
|
||||
* AndroidIDE is free software: you can redistribute it and/or modify
|
||||
* it under the terms of the GNU General Public License as published by
|
||||
* the Free Software Foundation, either version 3 of the License, or
|
||||
* (at your option) any later version.
|
||||
*
|
||||
* AndroidIDE is distributed in the hope that it will be useful,
|
||||
* but WITHOUT ANY WARRANTY; without even the implied warranty of
|
||||
* MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the
|
||||
* GNU General Public License for more details.
|
||||
*
|
||||
* You should have received a copy of the GNU General Public License
|
||||
* along with AndroidIDE. If not, see <https://www.gnu.org/licenses/>.
|
||||
*/
|
||||
|
||||
package com.itsaky.androidide.builder.model
|
||||
|
||||
import com.android.build.gradle.options.StringOption
|
||||
import com.android.build.gradle.options.StringOption.AAPT2_FROM_MAVEN_OVERRIDE
|
||||
import com.android.builder.model.v2.ide.SyncIssue
|
||||
|
||||
/**
|
||||
* Sync issue model for AndroidIDE.
|
||||
*
|
||||
* @author Akash Yadav
|
||||
*/
|
||||
interface IDESyncIssue : SyncIssue {
|
||||
companion object {
|
||||
|
||||
/**
|
||||
* Indicates that the Android Gradle Plugin that is being used by the project
|
||||
* is too new for AndroidIDE. Data is `projectAgpVersion:maxAgpVersion`.
|
||||
*/
|
||||
const val TYPE_AGP_VERSION_TOO_NEW = -1
|
||||
|
||||
// Note: When adding new types, decrement the version by 1
|
||||
// The types that are defined in SyncIssue class have their values starting at 0 and incremented
|
||||
// by 1 when new types are added. So, we could never know what is the latest type's value
|
||||
}
|
||||
}
|
||||
|
||||
/**
|
||||
* Checks whether this [SyncIssue] should be ignored and not reported to the user.
|
||||
*
|
||||
* @return Whether the issue can be ignored.
|
||||
*/
|
||||
fun SyncIssue.shouldBeIgnored() : Boolean {
|
||||
if (this.type != SyncIssue.TYPE_UNSUPPORTED_PROJECT_OPTION_USE) {
|
||||
return false
|
||||
}
|
||||
|
||||
// AndroidIDE sets android.aapt2FromMavenOverride in order to use a custom AAPT2 that is
|
||||
// compatible with Android
|
||||
return AAPT2_FROM_MAVEN_OVERRIDE.propertyName == this.data
|
||||
}
|
||||
+10
-10
@@ -42,7 +42,7 @@ open class CachingProject(val project: IProject) : IProject {
|
||||
private val log = ILogger.newInstance(javaClass.simpleName)
|
||||
|
||||
private val projects = mutableListOf<BasicProjectMetadata>()
|
||||
private val syncIssues = mutableMapOf<String, DefaultProjectSyncIssues>()
|
||||
private var syncIssues: DefaultProjectSyncIssues? = null
|
||||
|
||||
override fun getProjects(): CompletableFuture<List<BasicProjectMetadata>> {
|
||||
return if (this.projects.isNotEmpty()) {
|
||||
@@ -64,23 +64,23 @@ open class CachingProject(val project: IProject) : IProject {
|
||||
}
|
||||
}
|
||||
|
||||
override fun getProjectSyncIssues(): CompletableFuture<Map<String, DefaultProjectSyncIssues>> {
|
||||
return if (this.syncIssues.isNotEmpty()) {
|
||||
log.info("Using cached sync issues...")
|
||||
CompletableFuture.completedFuture(this.syncIssues)
|
||||
} else this.project.getProjectSyncIssues().whenComplete { syncIssues, err ->
|
||||
if (err != null || syncIssues == null) {
|
||||
override fun getProjectSyncIssues(): CompletableFuture<DefaultProjectSyncIssues> {
|
||||
this.syncIssues?.also {
|
||||
return CompletableFuture.completedFuture(it)
|
||||
}
|
||||
|
||||
return this.project.getProjectSyncIssues().whenComplete { projectSyncIssues, err ->
|
||||
if (err != null || projectSyncIssues == null) {
|
||||
log.debug("Unable to fetch project sync issues from tooling server", err)
|
||||
return@whenComplete
|
||||
}
|
||||
|
||||
if (syncIssues.isEmpty()) {
|
||||
if (projectSyncIssues.syncIssues.isEmpty()) {
|
||||
log.debug("No sync issues.")
|
||||
return@whenComplete
|
||||
}
|
||||
|
||||
this.syncIssues.clear()
|
||||
this.syncIssues.putAll(syncIssues)
|
||||
this.syncIssues = projectSyncIssues
|
||||
}
|
||||
}
|
||||
|
||||
|
||||
+7
-1
@@ -18,6 +18,7 @@
|
||||
package com.itsaky.androidide.projects
|
||||
|
||||
import androidx.annotation.RestrictTo
|
||||
import com.android.builder.model.v2.models.ProjectSyncIssues
|
||||
import com.itsaky.androidide.lookup.Lookup
|
||||
import com.itsaky.androidide.projects.api.AndroidModule
|
||||
import com.itsaky.androidide.projects.api.ModuleProject
|
||||
@@ -68,6 +69,11 @@ interface IProjectManager {
|
||||
val projectDir: File
|
||||
get() = File(projectDirPath)
|
||||
|
||||
/**
|
||||
* Issues that were encountered during project synchronization.
|
||||
*/
|
||||
val projectSyncIssues: ProjectSyncIssues?
|
||||
|
||||
/**
|
||||
* Build variant information about Android modules in the project.
|
||||
*
|
||||
@@ -81,7 +87,7 @@ interface IProjectManager {
|
||||
* @param project The project proxy.
|
||||
*/
|
||||
@RestrictTo(RestrictTo.Scope.LIBRARY_GROUP_PREFIX)
|
||||
fun setupProject(
|
||||
suspend fun setupProject(
|
||||
project: IProject = Lookup.getDefault().lookup(BuildService.KEY_PROJECT_PROXY)!!
|
||||
)
|
||||
|
||||
|
||||
+14
-2
@@ -18,6 +18,7 @@
|
||||
package com.itsaky.androidide.projects
|
||||
|
||||
import androidx.annotation.RestrictTo
|
||||
import com.android.builder.model.v2.models.ProjectSyncIssues
|
||||
import com.google.auto.service.AutoService
|
||||
import com.google.common.collect.ImmutableList
|
||||
import com.itsaky.androidide.eventbus.events.EventReceiver
|
||||
@@ -51,6 +52,7 @@ import kotlinx.coroutines.flow.flow
|
||||
import kotlinx.coroutines.flow.map
|
||||
import kotlinx.coroutines.flow.toList
|
||||
import kotlinx.coroutines.runBlocking
|
||||
import kotlinx.coroutines.withContext
|
||||
import org.greenrobot.eventbus.EventBus
|
||||
import org.greenrobot.eventbus.Subscribe
|
||||
import org.greenrobot.eventbus.ThreadMode
|
||||
@@ -84,6 +86,9 @@ class ProjectManagerImpl : IProjectManager, EventReceiver {
|
||||
override val projectDirPath: String
|
||||
get() = projectPath
|
||||
|
||||
override val projectSyncIssues: ProjectSyncIssues?
|
||||
get() = rootProject?.projectSyncIssues
|
||||
|
||||
companion object {
|
||||
|
||||
private val log = ILogger.newInstance("ProjectManagerImpl")
|
||||
@@ -95,8 +100,13 @@ class ProjectManagerImpl : IProjectManager, EventReceiver {
|
||||
}
|
||||
}
|
||||
|
||||
override fun setupProject(project: IProject) {
|
||||
this.rootProject = ProjectTransformer().transform(CachingProject(project))
|
||||
override suspend fun setupProject(project: IProject) {
|
||||
this.rootProject = withStopWatch("Transform project proxy") {
|
||||
withContext(Dispatchers.IO) {
|
||||
ProjectTransformer().transform(CachingProject(project))
|
||||
}
|
||||
}
|
||||
|
||||
val rootProject = this.rootProject ?: return
|
||||
|
||||
// build variants must be updated before the sources and classpaths are indexed
|
||||
@@ -104,6 +114,8 @@ class ProjectManagerImpl : IProjectManager, EventReceiver {
|
||||
androidBuildVariants = buildVariants
|
||||
}
|
||||
|
||||
log.info("Found ${rootProject.projectSyncIssues.syncIssues.size} project sync issues: ${rootProject.projectSyncIssues.syncIssues}")
|
||||
|
||||
withStopWatch("Setup project") {
|
||||
val indexerScope = CoroutineScope(Dispatchers.Default)
|
||||
val modulesFlow = flow {
|
||||
|
||||
@@ -18,7 +18,7 @@
|
||||
package com.itsaky.androidide.projects.api
|
||||
|
||||
import com.android.builder.model.v2.ide.ProjectType
|
||||
import com.itsaky.androidide.builder.model.DefaultProjectSyncIssues
|
||||
import com.android.builder.model.v2.models.ProjectSyncIssues
|
||||
import java.io.File
|
||||
import java.nio.file.Path
|
||||
|
||||
@@ -27,11 +27,14 @@ import java.nio.file.Path
|
||||
*
|
||||
* @property rootProject The root Gradle project.
|
||||
* @property subProjects List of all project that are included the project.
|
||||
* @property syncIssues The issues that occurred while syncing the project.
|
||||
* @property projectSyncIssues The issues that occurred while syncing the project.
|
||||
* @author Akash Yadav
|
||||
*/
|
||||
data class Project(val rootProject: GradleProject, val subProjects: List<GradleProject>,
|
||||
val syncIssues: Map<String, DefaultProjectSyncIssues>) {
|
||||
data class Project(
|
||||
val rootProject: GradleProject,
|
||||
val subProjects: List<GradleProject>,
|
||||
val projectSyncIssues: ProjectSyncIssues
|
||||
) {
|
||||
|
||||
/**
|
||||
* Finds the project by the given path.
|
||||
|
||||
+5
-2
@@ -57,8 +57,11 @@ class ProjectTransformer {
|
||||
"Root project must be either an Android project or a Gradle project")
|
||||
}
|
||||
|
||||
return Project(rootProject, CopyOnWriteArrayList(transform(allProjects, project)),
|
||||
project.getProjectSyncIssues().get())
|
||||
return Project(
|
||||
rootProject,
|
||||
CopyOnWriteArrayList(transform(allProjects, project)),
|
||||
project.getProjectSyncIssues().get()
|
||||
)
|
||||
} catch (error: Throwable) {
|
||||
log.error("Unable to transform project", error)
|
||||
return null
|
||||
|
||||
+2
-1
@@ -30,6 +30,7 @@ import com.itsaky.androidide.tooling.api.messages.InitializeProjectParams
|
||||
import com.itsaky.androidide.tooling.testing.ToolingApiTestLauncher
|
||||
import com.itsaky.androidide.utils.FileProvider
|
||||
import com.itsaky.androidide.utils.SourceClassTrie.SourceNode
|
||||
import kotlinx.coroutines.runBlocking
|
||||
import java.io.File
|
||||
import java.nio.file.Files
|
||||
import kotlin.io.path.pathString
|
||||
@@ -205,7 +206,7 @@ class ModuleProjectTest {
|
||||
}
|
||||
|
||||
val projectManager = ProjectManagerImpl.getInstance()
|
||||
projectManager.setupProject()
|
||||
runBlocking { projectManager.setupProject() }
|
||||
|
||||
val rootProject = IProjectManager.getInstance().rootProject
|
||||
assertThat(rootProject).isNotNull()
|
||||
|
||||
+1
-2
@@ -159,8 +159,7 @@ internal class ToolingApiServerImpl(private val project: ProjectImpl) :
|
||||
stopWatch.lapFromLast("Project read successful")
|
||||
stopWatch.log()
|
||||
|
||||
this.project.rootProject = project.rootProject
|
||||
this.project.projects = project.projects
|
||||
this.project.setFrom(project)
|
||||
this.isInitialized = true
|
||||
|
||||
notifyBuildSuccess(emptyList())
|
||||
|
||||
+13
-4
@@ -33,11 +33,11 @@ import java.util.concurrent.CompletableFuture
|
||||
/**
|
||||
* @author Akash Yadav
|
||||
*/
|
||||
@Suppress("JoinDeclarationAndAssignment")
|
||||
internal class ProjectImpl(
|
||||
var rootProject: IGradleProject? = null,
|
||||
var rootProjectPath: String? = null,
|
||||
var projects: List<IGradleProject> = emptyList()
|
||||
var projects: List<IGradleProject> = emptyList(),
|
||||
var projectSyncIssues: DefaultProjectSyncIssues = DefaultProjectSyncIssues(emptyList())
|
||||
) : IProject, Serializable {
|
||||
|
||||
private val serialVersionUID = 1L
|
||||
@@ -57,6 +57,13 @@ internal class ProjectImpl(
|
||||
this.selectedProject = ForwardingProject()
|
||||
}
|
||||
|
||||
fun setFrom(other: ProjectImpl) {
|
||||
this.rootProject = other.rootProject
|
||||
this.rootProjectPath = other.rootProjectPath
|
||||
this.projects = other.projects
|
||||
this.projectSyncIssues = other.projectSyncIssues
|
||||
}
|
||||
|
||||
private fun getProject(path: String): IGradleProject? {
|
||||
return if (path.isBlank()) rootProject else projects.find {
|
||||
it.getMetadata().get().projectPath == path
|
||||
@@ -69,8 +76,10 @@ internal class ProjectImpl(
|
||||
}
|
||||
}
|
||||
|
||||
override fun getProjectSyncIssues(): CompletableFuture<Map<String, DefaultProjectSyncIssues>> {
|
||||
return CompletableFuture.completedFuture(emptyMap())
|
||||
override fun getProjectSyncIssues(): CompletableFuture<DefaultProjectSyncIssues> {
|
||||
return CompletableFuture.completedFuture(
|
||||
this.projectSyncIssues ?: DefaultProjectSyncIssues(emptyList())
|
||||
)
|
||||
}
|
||||
|
||||
override fun selectProject(param: StringParameter): CompletableFuture<SelectProjectResult> {
|
||||
|
||||
+16
-9
@@ -16,7 +16,10 @@
|
||||
*/
|
||||
package com.itsaky.androidide.tooling.impl.sync
|
||||
|
||||
import com.android.builder.model.v2.ide.SyncIssue
|
||||
import com.android.builder.model.v2.models.Versions
|
||||
import com.itsaky.androidide.builder.model.DefaultSyncIssue
|
||||
import com.itsaky.androidide.builder.model.IDESyncIssue
|
||||
import com.itsaky.androidide.tooling.api.messages.InitializeProjectParams
|
||||
import com.itsaky.androidide.tooling.impl.util.StopWatch
|
||||
import com.itsaky.androidide.utils.AndroidPluginVersion
|
||||
@@ -54,9 +57,13 @@ abstract class AbstractModelBuilder<P, R>(
|
||||
* [AndroidPluginVersion.LATEST_TESTED], warns the user.
|
||||
*
|
||||
* @param versions The [Versions] model.
|
||||
* @param syncIssueReporter [ISyncIssueReporter] for reporting issues with the Android Gradle Plugin version.
|
||||
*/
|
||||
@JvmStatic
|
||||
protected fun checkAgpVersion(versions: Versions) {
|
||||
protected fun checkAgpVersion(
|
||||
versions: Versions,
|
||||
syncIssueReporter: ISyncIssueReporter
|
||||
) {
|
||||
|
||||
val agpVersion = AndroidPluginVersion.parse(versions.agp)
|
||||
|
||||
@@ -72,14 +79,14 @@ abstract class AbstractModelBuilder<P, R>(
|
||||
|
||||
// Warn the user if the project is using a newer AGP version
|
||||
if (!newerAgpWarned.get() && agpVersion > LATEST_TESTED) {
|
||||
log()
|
||||
log("!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!")
|
||||
log("You are using Android Gradle Plugin version that has not been tested with AndroidIDE.")
|
||||
log("Newer versions may not work properly!")
|
||||
log("Current version : ${agpVersion.toStringSimple()}")
|
||||
log("Latest tested : ${LATEST_TESTED.toStringSimple()}")
|
||||
log("!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!")
|
||||
log()
|
||||
val syncIssue = DefaultSyncIssue(
|
||||
data = "${agpVersion.toStringSimple()}:${LATEST_TESTED.toStringSimple()}",
|
||||
message = "You are using Android Gradle Plugin version that has not been tested with AndroidIDE.",
|
||||
multiLineMessage = null,
|
||||
severity = SyncIssue.SEVERITY_WARNING,
|
||||
type = IDESyncIssue.TYPE_AGP_VERSION_TOO_NEW
|
||||
)
|
||||
syncIssueReporter.report(syncIssue)
|
||||
newerAgpWarned.set(true)
|
||||
}
|
||||
}
|
||||
|
||||
+8
-2
@@ -19,6 +19,7 @@ package com.itsaky.androidide.tooling.impl.sync
|
||||
import com.android.builder.model.v2.models.AndroidProject
|
||||
import com.android.builder.model.v2.models.BasicAndroidProject
|
||||
import com.android.builder.model.v2.models.ModelBuilderParameter
|
||||
import com.android.builder.model.v2.models.ProjectSyncIssues
|
||||
import com.android.builder.model.v2.models.VariantDependencies
|
||||
import com.itsaky.androidide.tooling.api.IAndroidProject
|
||||
import com.itsaky.androidide.tooling.api.messages.InitializeProjectParams
|
||||
@@ -33,7 +34,7 @@ class AndroidProjectModelBuilder(initializationParams: InitializeProjectParams)
|
||||
AbstractModelBuilder<AndroidProjectModelBuilderParams, IAndroidProject>(initializationParams) {
|
||||
|
||||
override fun build(param: AndroidProjectModelBuilderParams): IAndroidProject {
|
||||
val (controller, module, versions) = param
|
||||
val (controller, module, versions, syncIssueReporter) = param
|
||||
|
||||
val androidParams = initializationParams.androidParams
|
||||
val projectPath = module.gradleProject.path
|
||||
@@ -47,7 +48,8 @@ class AndroidProjectModelBuilder(initializationParams: InitializeProjectParams)
|
||||
var androidVariant = androidParams.variantSelections[projectPath]
|
||||
|
||||
if (androidVariant != null && !variantNames.contains(androidVariant)) {
|
||||
log("Configured variant '$androidVariant' not found for project '$projectPath'. Falling back to default variant.")
|
||||
log(
|
||||
"Configured variant '$androidVariant' not found for project '$projectPath'. Falling back to default variant.")
|
||||
androidVariant = null
|
||||
}
|
||||
|
||||
@@ -65,6 +67,10 @@ class AndroidProjectModelBuilder(initializationParams: InitializeProjectParams)
|
||||
it.dontBuildRuntimeClasspath = false
|
||||
}
|
||||
|
||||
controller.findModel(module, ProjectSyncIssues::class.java)?.also { syncIssues ->
|
||||
syncIssueReporter.reportAll(syncIssues)
|
||||
}
|
||||
|
||||
return AndroidProjectImpl(
|
||||
module.gradleProject,
|
||||
configurationVariant,
|
||||
|
||||
+48
@@ -0,0 +1,48 @@
|
||||
/*
|
||||
* This file is part of AndroidIDE.
|
||||
*
|
||||
* AndroidIDE is free software: you can redistribute it and/or modify
|
||||
* it under the terms of the GNU General Public License as published by
|
||||
* the Free Software Foundation, either version 3 of the License, or
|
||||
* (at your option) any later version.
|
||||
*
|
||||
* AndroidIDE is distributed in the hope that it will be useful,
|
||||
* but WITHOUT ANY WARRANTY; without even the implied warranty of
|
||||
* MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the
|
||||
* GNU General Public License for more details.
|
||||
*
|
||||
* You should have received a copy of the GNU General Public License
|
||||
* along with AndroidIDE. If not, see <https://www.gnu.org/licenses/>.
|
||||
*/
|
||||
|
||||
package com.itsaky.androidide.tooling.impl.sync
|
||||
|
||||
import com.android.builder.model.v2.ide.SyncIssue
|
||||
import com.android.builder.model.v2.models.ProjectSyncIssues
|
||||
|
||||
/**
|
||||
* A sync issue reporter reports project synchronization issues.
|
||||
*
|
||||
* @author Akash Yadav
|
||||
*/
|
||||
fun interface ISyncIssueReporter {
|
||||
|
||||
/**
|
||||
* Report all sync issues from the given [ProjectSyncIssues].
|
||||
*/
|
||||
fun reportAll(issues: ProjectSyncIssues) {
|
||||
reportAll(issues.syncIssues)
|
||||
}
|
||||
|
||||
/**
|
||||
* Report all the given [sync issues][issues].
|
||||
*/
|
||||
fun reportAll(issues: Collection<SyncIssue>) {
|
||||
issues.forEach(this::report)
|
||||
}
|
||||
|
||||
/**
|
||||
* Report the give [sync issue][issue].
|
||||
*/
|
||||
fun report(issue: SyncIssue)
|
||||
}
|
||||
+7
-2
@@ -31,9 +31,14 @@ class ModuleProjectModelBuilder(initializationParams: InitializeProjectParams) :
|
||||
override fun build(param: ModuleProjectModelBuilderParams): IModuleProject {
|
||||
val versions = getAndroidVersions(param.module, param.controller)
|
||||
return if (versions != null) {
|
||||
checkAgpVersion(versions)
|
||||
checkAgpVersion(versions, param.syncIssueReporter)
|
||||
AndroidProjectModelBuilder(initializationParams)
|
||||
.build(Triple(param.controller, param.module, versions))
|
||||
.build(AndroidProjectModelBuilderParams(
|
||||
param.controller,
|
||||
param.module,
|
||||
versions,
|
||||
param.syncIssueReporter
|
||||
))
|
||||
} else {
|
||||
JavaProjectModelBuilder(initializationParams).build(
|
||||
JavaProjectModelBuilderParams(param))
|
||||
|
||||
+36
-4
@@ -17,9 +17,13 @@
|
||||
|
||||
package com.itsaky.androidide.tooling.impl.sync
|
||||
|
||||
import com.itsaky.androidide.builder.model.DefaultProjectSyncIssues
|
||||
import com.itsaky.androidide.builder.model.DefaultSyncIssue
|
||||
import com.itsaky.androidide.builder.model.shouldBeIgnored
|
||||
import com.itsaky.androidide.tooling.api.IAndroidProject
|
||||
import com.itsaky.androidide.tooling.api.IProject
|
||||
import com.itsaky.androidide.tooling.api.messages.InitializeProjectParams
|
||||
import com.itsaky.androidide.tooling.api.util.AndroidModulePropertyCopier
|
||||
import com.itsaky.androidide.tooling.impl.Main
|
||||
import com.itsaky.androidide.tooling.impl.Main.finalizeLauncher
|
||||
import com.itsaky.androidide.tooling.impl.internal.ProjectImpl
|
||||
@@ -55,20 +59,48 @@ class RootModelBuilder(initializationParams: InitializeProjectParams) :
|
||||
|
||||
val rootProjectVersions = getAndroidVersions(rootModule, controller)
|
||||
|
||||
val syncIssues = hashSetOf<DefaultSyncIssue>()
|
||||
val syncIssueReporter = ISyncIssueReporter {
|
||||
if (it.shouldBeIgnored()) {
|
||||
// this SyncIssue should not be shown to the user
|
||||
return@ISyncIssueReporter
|
||||
}
|
||||
|
||||
val issue = it as? DefaultSyncIssue ?: AndroidModulePropertyCopier.copy(it)
|
||||
syncIssues.add(issue)
|
||||
}
|
||||
|
||||
val rootProject = if (rootProjectVersions != null) {
|
||||
// Root project is an Android project
|
||||
checkAgpVersion(rootProjectVersions)
|
||||
AndroidProjectModelBuilder(initializationParams).build(Triple(controller, rootModule, rootProjectVersions))
|
||||
checkAgpVersion(rootProjectVersions, syncIssueReporter)
|
||||
AndroidProjectModelBuilder(initializationParams)
|
||||
.build(AndroidProjectModelBuilderParams(
|
||||
controller,
|
||||
rootModule,
|
||||
rootProjectVersions,
|
||||
syncIssueReporter
|
||||
))
|
||||
} else {
|
||||
GradleProjectModelBuilder(initializationParams).build(rootModule.gradleProject)
|
||||
}
|
||||
|
||||
val projects = ideaModules.map { ideaModule ->
|
||||
ModuleProjectModelBuilder(initializationParams).build(
|
||||
ModuleProjectModelBuilderParams(controller, ideaProject, ideaModule, modulePaths))
|
||||
ModuleProjectModelBuilderParams(
|
||||
controller,
|
||||
ideaProject,
|
||||
ideaModule,
|
||||
modulePaths,
|
||||
syncIssueReporter
|
||||
))
|
||||
}
|
||||
|
||||
return@action ProjectImpl(rootProject, rootModule.gradleProject.path, projects)
|
||||
return@action ProjectImpl(
|
||||
rootProject,
|
||||
rootModule.gradleProject.path,
|
||||
projects,
|
||||
DefaultProjectSyncIssues(syncIssues)
|
||||
)
|
||||
}
|
||||
|
||||
finalizeLauncher(executor)
|
||||
|
||||
+21
-3
@@ -22,10 +22,28 @@ import org.gradle.tooling.BuildController
|
||||
import org.gradle.tooling.model.idea.IdeaModule
|
||||
import org.gradle.tooling.model.idea.IdeaProject
|
||||
|
||||
typealias AndroidProjectModelBuilderParams = Triple<BuildController, IdeaModule, Versions>
|
||||
/**
|
||||
* Parameters for building model for an Android project.
|
||||
*
|
||||
* @property controller The build controller that will be used to fetch project models.
|
||||
* @property module The [IdeaModule] to fetch the models from.
|
||||
* @property versions The Android Gradle Plugin version information.
|
||||
* @property syncIssueReporter [ISyncIssueReporter] to report project synchronization issues.
|
||||
*/
|
||||
data class AndroidProjectModelBuilderParams(
|
||||
val controller: BuildController,
|
||||
val module: IdeaModule,
|
||||
val versions: Versions,
|
||||
val syncIssueReporter: ISyncIssueReporter
|
||||
)
|
||||
|
||||
class ModuleProjectModelBuilderParams(val controller: BuildController, project: IdeaProject,
|
||||
module: IdeaModule, modulePaths: Map<String, String>) : JavaProjectModelBuilderParams(
|
||||
class ModuleProjectModelBuilderParams(
|
||||
val controller: BuildController,
|
||||
project: IdeaProject,
|
||||
module: IdeaModule,
|
||||
modulePaths: Map<String, String>,
|
||||
val syncIssueReporter: ISyncIssueReporter
|
||||
) : JavaProjectModelBuilderParams(
|
||||
project, module, modulePaths)
|
||||
|
||||
open class JavaProjectModelBuilderParams(val project: IdeaProject, val module: IdeaModule,
|
||||
|
||||
+1
-1
@@ -43,7 +43,7 @@ interface IProject : IProjectQueries {
|
||||
* Get the project sync issues.
|
||||
*/
|
||||
@JsonRequest
|
||||
fun getProjectSyncIssues(): CompletableFuture<Map<String, DefaultProjectSyncIssues>>
|
||||
fun getProjectSyncIssues(): CompletableFuture<DefaultProjectSyncIssues>
|
||||
|
||||
companion object {
|
||||
|
||||
|
||||
+1
-1
@@ -306,5 +306,5 @@ object AndroidModulePropertyCopier {
|
||||
}
|
||||
|
||||
fun copy(issue: SyncIssue) =
|
||||
DefaultSyncIssue(issue.data, issue.message, issue.multiLineMessage, issue.severity, issue.type)
|
||||
DefaultSyncIssue(issue.data, issue.message, issue.multiLineMessage?.toTypedArray()?.let { listOf(*it) }, issue.severity, issue.type)
|
||||
}
|
||||
@@ -27,6 +27,7 @@ import com.itsaky.androidide.projects.api.AndroidModule
|
||||
import com.itsaky.androidide.projects.builder.BuildService
|
||||
import com.itsaky.androidide.projects.util.findAppModule
|
||||
import com.itsaky.androidide.tooling.testing.ToolingApiTestLauncher
|
||||
import kotlinx.coroutines.runBlocking
|
||||
import org.junit.Ignore
|
||||
import org.robolectric.Robolectric
|
||||
import java.util.concurrent.atomic.AtomicBoolean
|
||||
@@ -47,7 +48,7 @@ object XmlInflaterTest {
|
||||
assertThat(result?.isSuccessful).isTrue()
|
||||
|
||||
Lookup.getDefault().register(BuildService.KEY_PROJECT_PROXY, project)
|
||||
IProjectManager.getInstance().setupProject(project)
|
||||
runBlocking { IProjectManager.getInstance().setupProject(project) }
|
||||
init.set(true)
|
||||
}
|
||||
}
|
||||
|
||||
Reference in New Issue
Block a user