fix(gradle-plugin): fix build failure when 'apply plugin: ..' syntax is used in module projects (#1274, #1620)

This commit is contained in:
Akash Yadav
2024-01-12 14:03:23 +05:30
parent 0367c63bb1
commit 2775702f2e
7 changed files with 127 additions and 80 deletions
@@ -20,6 +20,7 @@ package com.itsaky.androidide.gradle
import com.itsaky.androidide.buildinfo.BuildInfo
import com.itsaky.androidide.tooling.api.LogSenderConfig._PROPERTY_IS_TEST_ENV
import com.itsaky.androidide.tooling.api.LogSenderConfig._PROPERTY_MAVEN_LOCAL_REPOSITORY
import org.gradle.StartParameter
import org.gradle.api.Plugin
import org.gradle.api.artifacts.dsl.RepositoryHandler
import org.gradle.api.initialization.Settings
@@ -43,14 +44,17 @@ class AndroidIDEInitScriptPlugin : Plugin<Gradle> {
override fun apply(target: Gradle) {
target.settingsEvaluated { settings ->
val (isTestEnv, mavenLocalRepos) = settings.startParameter.run {
val isTestEnv = projectProperties.containsKey(_PROPERTY_IS_TEST_ENV)
&& projectProperties[_PROPERTY_IS_TEST_ENV].toString().toBoolean()
val mavenLocalRepos = projectProperties.getOrDefault(_PROPERTY_MAVEN_LOCAL_REPOSITORY, "")
isTestEnv to mavenLocalRepos
}
settings.addDependencyRepositories()
}
settings.addDependencyRepositories(isTestEnv, mavenLocalRepos)
target.rootProject { rootProject ->
rootProject.buildscript.apply {
dependencies.apply {
add("classpath", rootProject.ideDependency("gradle-plugin"))
}
repositories.addDependencyRepositories(rootProject.gradle.startParameter)
}
}
target.projectsLoaded { gradle ->
@@ -62,10 +66,6 @@ class AndroidIDEInitScriptPlugin : Plugin<Gradle> {
return@subprojects
}
sub.buildscript.dependencies.apply {
add("classpath", sub.ideDependency("gradle-plugin"))
}
sub.afterEvaluate {
logger.info("Trying to apply plugin '${BuildInfo.PACKAGE_NAME}' to project '${sub.path}'")
sub.pluginManager.apply(BuildInfo.PACKAGE_NAME)
@@ -74,9 +74,16 @@ class AndroidIDEInitScriptPlugin : Plugin<Gradle> {
}
}
private fun Settings.addDependencyRepositories() {
val (isTestEnv, mavenLocalRepos) = getTestEnvProps(startParameter)
addDependencyRepositories(isTestEnv, mavenLocalRepos)
}
@Suppress("UnstableApiUsage")
private fun Settings.addDependencyRepositories(isMavenLocalEnabled: Boolean,
mavenLocalRepo: String) {
private fun Settings.addDependencyRepositories(
isMavenLocalEnabled: Boolean,
mavenLocalRepo: String
) {
dependencyResolutionManagement.run {
repositories.configureRepositories(isMavenLocalEnabled, mavenLocalRepo)
}
@@ -86,6 +93,21 @@ class AndroidIDEInitScriptPlugin : Plugin<Gradle> {
}
}
private fun RepositoryHandler.addDependencyRepositories(startParams: StartParameter) {
val (isTestEnv, mavenLocalRepos) = getTestEnvProps(startParams)
configureRepositories(isTestEnv, mavenLocalRepos)
}
private fun getTestEnvProps(startParameter: StartParameter): Pair<Boolean, String> {
return startParameter.run {
val isTestEnv = projectProperties.containsKey(_PROPERTY_IS_TEST_ENV)
&& projectProperties[_PROPERTY_IS_TEST_ENV].toString().toBoolean()
val mavenLocalRepos = projectProperties.getOrDefault(_PROPERTY_MAVEN_LOCAL_REPOSITORY, "")
isTestEnv to mavenLocalRepos
}
}
private fun RepositoryHandler.configureRepositories(
isMavenLocalEnabled: Boolean,
mavenLocalRepos: String
@@ -17,6 +17,7 @@
package com.itsaky.androidide.gradle
import com.android.build.api.component.analytics.AnalyticsEnabledApplicationVariant
import com.android.build.api.variant.ApplicationAndroidComponentsExtension
import com.android.build.api.variant.ApplicationVariant
import com.android.build.api.variant.impl.ApplicationVariantImpl
@@ -107,7 +108,10 @@ class LogSenderPlugin : Plugin<Project> {
private fun ApplicationVariant.withRuntimeConfiguration(
action: Configuration.() -> Unit
) {
this as ApplicationVariantImpl
variantDependencies.runtimeClasspath.action()
if (this is ApplicationVariantImpl) {
variantDependencies.runtimeClasspath.action()
} else if (this is AnalyticsEnabledApplicationVariant) {
delegate.withRuntimeConfiguration(action)
}
}
}
@@ -39,6 +39,16 @@ class AndroidIDEInitScriptPluginTest {
assertBasics(result)
}
@Test
fun `test behavior with apply plugin syntax`() {
val result = buildProject(
agpVersion = BuildInfo.AGP_VERSION_MININUM,
gradleVersion = "7.5.1",
useApplyPluginGroovySyntax = true
)
assertBasics(result)
}
private fun assertBasics(result: BuildResult) {
// These plugins must be applied to the
for ((project, plugins) in mapOf(
@@ -30,10 +30,11 @@ import kotlin.io.path.pathString
internal fun buildProject(
agpVersion: String = BuildInfo.AGP_VERSION_LATEST,
gradleVersion: String = "8.2",
useApplyPluginGroovySyntax: Boolean = false,
configureArgs: (MutableList<String>) -> Unit = {},
vararg plugins: String
): BuildResult {
val projectRoot = openProject(agpVersion, *plugins)
val projectRoot = openProject(agpVersion, useApplyPluginGroovySyntax, *plugins)
val initScript = FileProvider.testHomeDir().resolve(".androidide/init/androidide.init.gradle")
val mavenLocal = FileProvider.projectRoot().resolve("gradle-plugin/build/maven-local/repos.txt").toFile()
@@ -99,6 +100,7 @@ internal fun writeInitScript(file: File, deps: List<File>) {
internal fun openProject(
agpVersion: String = BuildInfo.AGP_VERSION_LATEST,
useApplyPluginGroovySyntax: Boolean = false,
vararg plugins: String
): Path {
val projectRoot = FileProvider.projectRoot()
@@ -110,8 +112,20 @@ internal fun openProject(
}
run {
val pluginsText = plugins.joinToString(separator = "\n") { "id(\"$it\")" }
projectRoot.resolve("app/build.gradle.kts").toFile()
// remove existing build scripts
projectRoot.resolve("app")
.toFile()
.listFiles()!!
.filter { it.name.startsWith("build.gradle") && !it.name.endsWith(".in") }
.forEach { it.delete() }
val pluginsText = if (!useApplyPluginGroovySyntax) {
plugins.joinToString(separator = "\n") { "id(\"$it\")" }
} else {
plugins.joinToString(separator = "\n") { "apply plugin: \"$it\"" }
}
projectRoot.resolve("app/build.gradle" + if (useApplyPluginGroovySyntax) "" else ".kts").toFile()
.replaceAllPlaceholders(mapOf("PLUGINS" to pluginsText))
}
@@ -1,2 +1,3 @@
/build
build.gradle
build.gradle.kts
@@ -0,0 +1,58 @@
apply plugin: 'com.android.application'
@@PLUGINS@@
android {
namespace "com.example.myapplication2"
compileSdk 33
buildToolsVersion "33.0.2"
defaultConfig {
applicationId "com.example.myapplication2"
minSdk 21
targetSdk 33
versionCode 1
versionName "1.0"
vectorDrawables {
useSupportLibrary true
}
}
compileOptions {
sourceCompatibility JavaVersion.VERSION_11
targetCompatibility JavaVersion.VERSION_11
}
buildTypes {
release {
minifyEnabled true
proguardFiles(getDefaultProguardFile("proguard-android-optimize.txt"), "proguard-rules.pro")
}
}
buildFeatures {
viewBinding true
}
// LogSender must be applied to all the debuggable product flavors
flavorDimensions += "version"
productFlavors {
demo {
dimension "version"
applicationIdSuffix ".demo"
versionNameSuffix "-demo"
}
full {
dimension "version"
applicationIdSuffix ".full"
versionNameSuffix "-full"
}
}
}
dependencies {
implementation "androidx.appcompat:appcompat:1.6.1"
implementation "androidx.constraintlayout:constraintlayout:2.1.4"
implementation "com.google.android.material:material:1.9.0"
}
@@ -1,62 +0,0 @@
plugins {
id("com.android.application")
}
android {
namespace = "com.example.myapplication2"
compileSdk = 33
buildToolsVersion = "33.0.2"
defaultConfig {
applicationId = "com.example.myapplication2"
minSdk = 21
targetSdk = 33
versionCode = 1
versionName = "1.0"
vectorDrawables {
useSupportLibrary = true
}
}
compileOptions {
sourceCompatibility = JavaVersion.VERSION_11
targetCompatibility = JavaVersion.VERSION_11
}
buildTypes {
release {
isMinifyEnabled = true
proguardFiles(getDefaultProguardFile("proguard-android-optimize.txt"), "proguard-rules.pro")
}
}
buildFeatures {
viewBinding = true
}
// LogSender must be applied to all the debuggable product flavors
flavorDimensions += "version"
productFlavors {
create("demo") {
dimension = "version"
applicationIdSuffix = ".demo"
versionNameSuffix = "-demo"
}
create("full") {
dimension = "version"
applicationIdSuffix = ".full"
versionNameSuffix = "-full"
}
}
}
dependencies {
implementation("androidx.appcompat:appcompat:1.6.1")
implementation("androidx.constraintlayout:constraintlayout:2.1.4")
implementation("com.google.android.material:material:1.9.0")
}