diff --git a/android-library-no-tests/build.gradle.kts b/android-library-no-tests/build.gradle.kts index b71a13a8..76dda11f 100644 --- a/android-library-no-tests/build.gradle.kts +++ b/android-library-no-tests/build.gradle.kts @@ -1,6 +1,5 @@ plugins { id("com.android.library") - kotlin("android") } android { diff --git a/build.gradle b/build.gradle index b62a872a..165b5226 100644 --- a/build.gradle +++ b/build.gradle @@ -7,7 +7,6 @@ buildscript { plugins { alias(libs.plugins.agp) apply false - alias(libs.plugins.kgp) apply false alias(libs.plugins.ben.manes.versions) id "com.osacky.fulladle" alias(libs.plugins.kotlinter) @@ -22,7 +21,7 @@ fladle { } tasks.wrapper.configure { - gradleVersion = '8.14.4' + gradleVersion = '9.1.0' } def isNonStable = { String version -> diff --git a/docs/changelog.md b/docs/changelog.md index d76b820c..08f2d165 100644 --- a/docs/changelog.md +++ b/docs/changelog.md @@ -1,6 +1,8 @@ # Changelog ## Unreleased +* Minimum required Gradle version is now 9.1 +* Fixed support for Android Gradle Plugin version 9.0.1 ## 0.19.0 * Minimum required JVM version is now 17. diff --git a/fladle-plugin/build.gradle.kts b/fladle-plugin/build.gradle.kts index b0fe4eb1..29d4e847 100644 --- a/fladle-plugin/build.gradle.kts +++ b/fladle-plugin/build.gradle.kts @@ -18,18 +18,18 @@ plugins { alias(libs.plugins.vanniktech.publish) } -// See https://github.com/slackhq/keeper/pull/11#issuecomment-579544375 for context -val isReleaseMode : Boolean = hasProperty("fladle.releaseMode") - dependencies { compileOnly(gradleApi()) - if (isReleaseMode) { - compileOnly(libs.agp) - } else { - implementation(libs.agp) + compileOnly(libs.agp) { + exclude(group = "org.jetbrains.kotlin", module = "kotlin-compiler-embeddable") + exclude(group = "org.jetbrains.kotlin", module = "kotlin-compiler-runner") } compileOnly(libs.gradle.enterprise) + // AGP must be on the runtime classpath so GradleTestKit's withPluginClasspath() + // can resolve the com.android.application and com.android.library plugins. + runtimeOnly(libs.agp) + testImplementation(gradleTestKit()) testImplementation(libs.junit) testImplementation(libs.truth) @@ -106,8 +106,8 @@ tasks.withType(ValidatePlugins::class.java).configureEach { tasks.withType(org.jetbrains.kotlin.gradle.tasks.KotlinCompile::class.java).configureEach { compilerOptions { jvmTarget.set(org.jetbrains.kotlin.gradle.dsl.JvmTarget.JVM_17) - languageVersion.set(org.jetbrains.kotlin.gradle.dsl.KotlinVersion.KOTLIN_1_7) - apiVersion.set(org.jetbrains.kotlin.gradle.dsl.KotlinVersion.KOTLIN_1_7) + languageVersion.set(org.jetbrains.kotlin.gradle.dsl.KotlinVersion.KOTLIN_2_0) + apiVersion.set(org.jetbrains.kotlin.gradle.dsl.KotlinVersion.KOTLIN_2_0) } } diff --git a/fladle-plugin/settings.gradle.kts b/fladle-plugin/settings.gradle.kts index 528a0fa6..09608f5d 100644 --- a/fladle-plugin/settings.gradle.kts +++ b/fladle-plugin/settings.gradle.kts @@ -1,5 +1,9 @@ rootProject.name = "fladle" +plugins { + id("org.gradle.toolchains.foojay-resolver-convention") version "1.0.0" +} + dependencyResolutionManagement { versionCatalogs { create("libs") { diff --git a/fladle-plugin/src/main/java/com/osacky/flank/gradle/FladlePluginDelegate.kt b/fladle-plugin/src/main/java/com/osacky/flank/gradle/FladlePluginDelegate.kt index 61a9732f..44873cd9 100644 --- a/fladle-plugin/src/main/java/com/osacky/flank/gradle/FladlePluginDelegate.kt +++ b/fladle-plugin/src/main/java/com/osacky/flank/gradle/FladlePluginDelegate.kt @@ -1,14 +1,15 @@ package com.osacky.flank.gradle -import com.android.build.gradle.AppExtension -import com.android.build.gradle.TestedExtension -import com.android.build.gradle.internal.tasks.factory.dependsOn -import com.android.builder.model.TestOptions +import com.android.build.api.dsl.ApplicationExtension +import com.android.build.api.variant.ApplicationAndroidComponentsExtension +import com.android.build.api.variant.FilterConfiguration +import com.android.build.api.variant.HasAndroidTest import com.osacky.flank.gradle.validation.checkForExclusionUsage import com.osacky.flank.gradle.validation.validateOptionsUsed import org.gradle.api.GradleException import org.gradle.api.Project import org.gradle.api.artifacts.Configuration +import org.gradle.api.plugins.BasePluginExtension import org.gradle.api.tasks.TaskContainer import org.gradle.kotlin.dsl.create import org.gradle.util.GradleVersion @@ -46,24 +47,22 @@ class FladlePluginDelegate { project: Project, base: FlankGradleExtension, ) { - if (GradleVersion.current() > GradleVersion.version("6.1")) { - base.flankVersion.finalizeValueOnRead() - base.flankCoordinates.finalizeValueOnRead() - base.serviceAccountCredentials.finalizeValueOnRead() + base.flankVersion.finalizeValueOnRead() + base.flankCoordinates.finalizeValueOnRead() + base.serviceAccountCredentials.finalizeValueOnRead() + + // Register onVariants callbacks before afterEvaluate for APK path detection + project.pluginManager.withPlugin("com.android.application") { + if (!base.debugApk.isPresent || !base.instrumentationApk.isPresent) { + findDebugAndInstrumentationApk(project, base) + } } + project.afterEvaluate { // Add Flank dependency to Fladle Configuration // Must be done afterEvaluate otherwise extension values will not be set. project.dependencies.add(FLADLE_CONFIG, "${base.flankCoordinates.get()}:${base.flankVersion.get()}") - // Only use automatic apk path detection for 'com.android.application' projects. - project.pluginManager.withPlugin("com.android.application") { - // This doesn't work properly for multiple configs since they likely are inheriting the config from root already. See #60 https://github.com/runningcode/fladle/issues/60 - if (!base.debugApk.isPresent || !base.instrumentationApk.isPresent) { - findDebugAndInstrumentationApk(project, base) - } - } - tasks.apply { createTasksForConfig(base, base, project, "") @@ -97,7 +96,7 @@ class FladlePluginDelegate { val writeConfigProps = register("writeConfigProps$name", YamlConfigWriterTask::class.java, base, config, name) - writeConfigProps.dependsOn(validateFladle) + writeConfigProps.configure { dependsOn(validateFladle) } register("printYml$name") { description = "Print the flank.yml file to the console." @@ -174,17 +173,15 @@ class FladlePluginDelegate { } dependsOn(writeConfigProps) if (config.dependOnAssemble.isPresent && config.dependOnAssemble.get()) { - val testedExtension = - requireNotNull(project.extensions.findByType(TestedExtension::class.java)) { "Could not find TestedExtension in ${project.name}" } - testedExtension.testVariants.configureEach { - if (testedVariant.isExpectedVariant(config)) { - if (testedVariant.assembleProvider.isPresent) { - dependsOn(testedVariant.assembleProvider) - } - if (assembleProvider.isPresent) { - dependsOn(assembleProvider) - } - } + // Find assemble tasks by convention name pattern + val variantName = config.variant.orNull + if (variantName != null) { + val capitalizedVariant = variantName.capitalize() + dependsOn("assemble$capitalizedVariant") + dependsOn("assemble${capitalizedVariant}AndroidTest") + } else { + dependsOn("assembleDebug") + dependsOn("assembleDebugAndroidTest") } } if (config.localResultsDir.hasValue) { @@ -210,16 +207,17 @@ class FladlePluginDelegate { private fun automaticallyConfigureTestOrchestrator( project: Project, config: FladleConfig, - androidExtension: AppExtension, + androidExtension: ApplicationExtension, ) { project.afterEvaluate { + val execution = androidExtension.testOptions.execution.uppercase() val useOrchestrator = - androidExtension.testOptions.getExecutionEnum() == TestOptions.Execution.ANDROIDX_TEST_ORCHESTRATOR || - androidExtension.testOptions.getExecutionEnum() == TestOptions.Execution.ANDROID_TEST_ORCHESTRATOR + execution == "ANDROIDX_TEST_ORCHESTRATOR" || + execution == "ANDROID_TEST_ORCHESTRATOR" if (useOrchestrator) { log("Automatically detected the use of Android Test Orchestrator") + config.useOrchestrator.set(true) } - config.useOrchestrator.set(useOrchestrator) } } @@ -227,28 +225,77 @@ class FladlePluginDelegate { project: Project, config: FladleConfig, ) { - val baseExtension = - requireNotNull(project.extensions.findByType(AppExtension::class.java)) { "Could not find AppExtension in ${project.name}" } - automaticallyConfigureTestOrchestrator(project, config, baseExtension) - baseExtension.testVariants.configureEach { - val appVariant = testedVariant - outputs.configureEach test@{ - appVariant.outputs - .matching { it.isExpectedAbiOutput(config) } - .configureEach app@{ - if (appVariant.isExpectedVariant(config)) { - if (!config.debugApk.isPresent) { - // Don't set debug apk if not already set. #172 - project.log("Configuring fladle.debugApk from variant ${this@app.name}") - config.debugApk.set(this@app.outputFile.absolutePath) - } - if (!config.roboScript.isPresent && !config.instrumentationApk.isPresent && !config.sanityRobo.get()) { - // Don't set instrumentation apk if not already set. #172 - project.log("Configuring fladle.instrumentationApk from variant ${this@test.name}") - config.instrumentationApk.set(this@test.outputFile.absolutePath) - } - } + val androidExtension = + requireNotNull( + project.extensions.findByType(ApplicationExtension::class.java), + ) { "Could not find ApplicationExtension in ${project.name}" } + automaticallyConfigureTestOrchestrator(project, config, androidExtension) + + val androidComponents = + requireNotNull(project.extensions.findByType(ApplicationAndroidComponentsExtension::class.java)) { + "Could not find ApplicationAndroidComponentsExtension in ${project.name}" + } + + androidComponents.onVariants { variant -> + if (!variant.isExpectedVariant(config)) return@onVariants + val androidTest = (variant as? HasAndroidTest)?.androidTest ?: return@onVariants + + val buildType = variant.buildType ?: return@onVariants + val flavorName = variant.productFlavors.joinToString("") { it.second } + val flavorPath = variant.productFlavors.joinToString("/") { it.second } + val archivesName = + project.extensions + .getByType(BasePluginExtension::class.java) + .archivesName + .get() + val buildDir = project.layout.buildDirectory + + // Test APK path + val testApkDirPath = if (flavorPath.isNotEmpty()) "androidTest/$flavorPath/$buildType" else "androidTest/$buildType" + val testApkFileName = + if (flavorName.isNotEmpty()) { + "$archivesName-$flavorName-$buildType-androidTest.apk" + } else { + "$archivesName-$buildType-androidTest.apk" + } + val testApkPath = + buildDir + .file("outputs/apk/$testApkDirPath/$testApkFileName") + .get() + .asFile + .absolutePath + + variant.outputs.forEach { output -> + if (!output.isExpectedAbiOutput(config)) return@forEach + + val abiFilter = output.filters.firstOrNull { it.filterType == FilterConfiguration.FilterType.ABI } + val abiName = abiFilter?.identifier + + val appApkDirPath = if (flavorPath.isNotEmpty()) "$flavorPath/$buildType" else buildType + val appApkFileName = + buildString { + append(archivesName) + if (flavorName.isNotEmpty()) append("-$flavorName") + if (abiName != null) append("-$abiName") + append("-$buildType.apk") } + val appApkPath = + buildDir + .file("outputs/apk/$appApkDirPath/$appApkFileName") + .get() + .asFile + .absolutePath + + if (!config.debugApk.isPresent) { + // Don't set debug apk if not already set. #172 + project.log("Configuring fladle.debugApk from variant ${variant.name}") + config.debugApk.set(appApkPath) + } + if (!config.roboScript.isPresent && !config.instrumentationApk.isPresent && !config.sanityRobo.get()) { + // Don't set instrumentation apk if not already set. #172 + project.log("Configuring fladle.instrumentationApk from variant ${variant.name}") + config.instrumentationApk.set(testApkPath) + } } } } @@ -257,7 +304,7 @@ class FladlePluginDelegate { get() = configurations.getByName(FLADLE_CONFIG) companion object { - val GRADLE_MIN_VERSION: GradleVersion = GradleVersion.version("7.3") + val GRADLE_MIN_VERSION: GradleVersion = GradleVersion.version("9.1") const val TASK_GROUP = "fladle" const val FLADLE_CONFIG = "fladle" diff --git a/fladle-plugin/src/main/java/com/osacky/flank/gradle/FlankExecutionTask.kt b/fladle-plugin/src/main/java/com/osacky/flank/gradle/FlankExecutionTask.kt index c4605747..2518ff9d 100644 --- a/fladle-plugin/src/main/java/com/osacky/flank/gradle/FlankExecutionTask.kt +++ b/fladle-plugin/src/main/java/com/osacky/flank/gradle/FlankExecutionTask.kt @@ -8,7 +8,7 @@ import javax.inject.Inject @DisableCachingByDefault( because = "Flank executions are dependent on resources such as network connection and server and therefore cannot be cached.", ) -open class FlankExecutionTask +abstract class FlankExecutionTask @Inject constructor( projectLayout: ProjectLayout, diff --git a/fladle-plugin/src/main/java/com/osacky/flank/gradle/FlankJavaExec.kt b/fladle-plugin/src/main/java/com/osacky/flank/gradle/FlankJavaExec.kt index e515f15d..21bb73aa 100644 --- a/fladle-plugin/src/main/java/com/osacky/flank/gradle/FlankJavaExec.kt +++ b/fladle-plugin/src/main/java/com/osacky/flank/gradle/FlankJavaExec.kt @@ -8,7 +8,7 @@ import javax.inject.Inject @DisableCachingByDefault( because = "Flank executions are dependent on resources such as network connection and server and therefore cannot be cached.", ) -open class FlankJavaExec +abstract class FlankJavaExec @Inject constructor( projectLayout: ProjectLayout, diff --git a/fladle-plugin/src/main/java/com/osacky/flank/gradle/FulladleModuleExtension.kt b/fladle-plugin/src/main/java/com/osacky/flank/gradle/FulladleModuleExtension.kt index a9c23b99..e6637bd1 100644 --- a/fladle-plugin/src/main/java/com/osacky/flank/gradle/FulladleModuleExtension.kt +++ b/fladle-plugin/src/main/java/com/osacky/flank/gradle/FulladleModuleExtension.kt @@ -48,4 +48,10 @@ open class FulladleModuleExtension * can be a match. */ val variant: Property = objects.property().convention(null as String?) + + /** + * Variant APK info collected during configuration via onVariants callbacks. + * Used by FulladlePlugin at execution time to build YAML entries. + */ + internal val variantApks: MutableList = mutableListOf() } diff --git a/fladle-plugin/src/main/java/com/osacky/flank/gradle/FulladlePlugin.kt b/fladle-plugin/src/main/java/com/osacky/flank/gradle/FulladlePlugin.kt index c3901046..59be14be 100644 --- a/fladle-plugin/src/main/java/com/osacky/flank/gradle/FulladlePlugin.kt +++ b/fladle-plugin/src/main/java/com/osacky/flank/gradle/FulladlePlugin.kt @@ -1,8 +1,12 @@ package com.osacky.flank.gradle -import com.android.build.gradle.TestedExtension +import com.android.build.api.variant.ApplicationAndroidComponentsExtension +import com.android.build.api.variant.FilterConfiguration +import com.android.build.api.variant.HasAndroidTest +import com.android.build.api.variant.LibraryAndroidComponentsExtension import org.gradle.api.Plugin import org.gradle.api.Project +import org.gradle.api.plugins.BasePluginExtension import org.gradle.kotlin.dsl.getByType /** @@ -18,6 +22,96 @@ class FulladlePlugin : Plugin { root.subprojects { // Yuck, cross project configuration extensions.create("fulladleModuleConfig", FulladleModuleExtension::class.java) + + // Register onVariants callbacks to capture APK info during configuration + pluginManager.withPlugin("com.android.application") { + val androidComponents = extensions.getByType(ApplicationAndroidComponentsExtension::class.java) + val ext = extensions.findByType(FulladleModuleExtension::class.java) ?: return@withPlugin + androidComponents.onVariants { variant -> + val androidTest = (variant as? HasAndroidTest)?.androidTest ?: return@onVariants + val buildType = variant.buildType ?: return@onVariants + val flavorName = variant.productFlavors.joinToString("") { it.second } + val flavorPath = variant.productFlavors.joinToString("/") { it.second } + val archivesName = extensions.getByType(BasePluginExtension::class.java).archivesName.get() + + variant.outputs.forEach { output -> + val abiFilter = output.filters.firstOrNull { it.filterType == FilterConfiguration.FilterType.ABI } + val abiName = abiFilter?.identifier + + val appApkDirPath = if (flavorPath.isNotEmpty()) "$flavorPath/$buildType" else buildType + val appApkFileName = + buildString { + append(archivesName) + if (flavorName.isNotEmpty()) append("-$flavorName") + if (abiName != null) append("-$abiName") + append("-$buildType.apk") + } + val appApkPath = + layout.buildDirectory + .file("outputs/apk/$appApkDirPath/$appApkFileName") + .get() + .asFile.absolutePath + + val testApkDirPath = + if (flavorPath.isNotEmpty()) "androidTest/$flavorPath/$buildType" else "androidTest/$buildType" + val testApkFileName = + if (flavorName.isNotEmpty()) { + "$archivesName-$flavorName-$buildType-androidTest.apk" + } else { + "$archivesName-$buildType-androidTest.apk" + } + val testApkPath = + layout.buildDirectory + .file("outputs/apk/$testApkDirPath/$testApkFileName") + .get() + .asFile.absolutePath + + ext.variantApks.add( + VariantApkInfo( + variantName = variant.name, + appApkPath = appApkPath, + testApkPath = testApkPath, + abiName = abiName, + ), + ) + } + } + } + + pluginManager.withPlugin("com.android.library") { + val androidComponents = extensions.getByType(LibraryAndroidComponentsExtension::class.java) + val ext = extensions.findByType(FulladleModuleExtension::class.java) ?: return@withPlugin + androidComponents.onVariants { variant -> + val androidTest = (variant as? HasAndroidTest)?.androidTest ?: return@onVariants + val buildType = variant.buildType ?: return@onVariants + val flavorName = variant.productFlavors.joinToString("") { it.second } + val flavorPath = variant.productFlavors.joinToString("/") { it.second } + val archivesName = extensions.getByType(BasePluginExtension::class.java).archivesName.get() + + val testApkDirPath = + if (flavorPath.isNotEmpty()) "androidTest/$flavorPath/$buildType" else "androidTest/$buildType" + val testApkFileName = + if (flavorName.isNotEmpty()) { + "$archivesName-$flavorName-$buildType-androidTest.apk" + } else { + "$archivesName-$buildType-androidTest.apk" + } + val testApkPath = + layout.buildDirectory + .file("outputs/apk/$testApkDirPath/$testApkFileName") + .get() + .asFile.absolutePath + + ext.variantApks.add( + VariantApkInfo( + variantName = variant.name, + appApkPath = null, + testApkPath = testApkPath, + abiName = null, + ), + ) + } + } } val fulladleConfigureTask = @@ -80,82 +174,80 @@ fun configureModule( return } - val testedExtension = extensions.findByType(TestedExtension::class.java) ?: return // Only configure the first test variant per module. // Does anyone test more than one variant per module? var addedTestsForModule = false - testedExtension.testVariants.configureEach testVariant@{ - if (this.isExpectedVariantInModule(fulladleModuleExtension)) { - testedVariant.outputs - .matching { it.isExpectedAbiOutput(flankGradleExtension) } - .configureEach app@{ - if (addedTestsForModule) { - return@app - } - this@testVariant.outputs.configureEach test@{ - val yml = StringBuilder() - // If the debugApk isn't yet set, let's use this one. - if (!flankGradleExtension.debugApk.isPresent) { - if (project.isAndroidAppModule) { - // app modules produce app apks that we can consume - flankGradleExtension.debugApk.set(rootProject.provider { this@app.outputFile.absolutePath }) - } else if (project.isAndroidLibraryModule) { - // library modules do not produce an app apk and we'll use the one specified in fulladleModuleConfig block - // we need library modules to specify the app apk to test against, even if it's a dummy one - check(fulladleModuleExtension.debugApk.isPresent && fulladleModuleExtension.debugApk.orNull != null) { - "Library module ${project.path} did not specify a debug apk. Library modules do not " + - "generate a debug apk and one needs to be specified in the fulladleModuleConfig block\n" + - "This is a required parameter in FTL which remains unused for library modules under test, " + - "and you can use a dummy apk here" - } - flankGradleExtension.debugApk.set(rootProject.provider { fulladleModuleExtension.debugApk.get() }) - } - } else { - // Otherwise, let's just add it to the list. - if (project.isAndroidAppModule) { - yml.appendLine("- app: ${this@app.outputFile}") - } else if (project.isAndroidLibraryModule) { - // app apk is not required for library modules so only use if it's explicitly specified - if (fulladleModuleExtension.debugApk.orNull != null) { - yml.appendLine("- app: ${fulladleModuleExtension.debugApk.get()}") - } - } - } + for (variantInfo in fulladleModuleExtension.variantApks) { + if (addedTestsForModule) break - // If the instrumentation apk isn't yet set, let's use this one. - if (!flankGradleExtension.instrumentationApk.isPresent) { - flankGradleExtension.instrumentationApk.set(rootProject.provider { this@test.outputFile.absolutePath }) - } else { - // Otherwise, let's just add it to the list. - if (yml.isBlank()) { - // The first item in the list needs to start with a ` - `. - yml.appendLine("- test: ${this@test.outputFile}") - } else { - yml.appendLine(" test: ${this@test.outputFile}") - } - } + if (!variantInfo.isExpectedVariantInModule(fulladleModuleExtension)) continue - if (yml.isEmpty()) { - // this is the root module - // should not be added as additional test apk - overrideRootLevelConfigs(flankGradleExtension, fulladleModuleExtension) - } else { - yml.appendProperty(fulladleModuleExtension.maxTestShards, " max-test-shards") - yml.appendMapProperty( - fulladleModuleExtension.clientDetails, - " client-details", - ) { appendLine(" ${it.key}: ${it.value}") } - yml.appendMapProperty( - fulladleModuleExtension.environmentVariables, - " environment-variables", - ) { appendLine(" ${it.key}: ${it.value}") } - flankGradleExtension.additionalTestApks.add(yml.toString()) - } - addedTestsForModule = true - } + // Check ABI filter against the extension + if (flankGradleExtension.abi.isPresent && variantInfo.abiName != null && variantInfo.abiName != flankGradleExtension.abi.get()) continue + if (flankGradleExtension.abi.isPresent && variantInfo.abiName == null) { + // No ABI filter on this output - it's a match (universal) + } + + val yml = StringBuilder() + // If the debugApk isn't yet set, let's use this one. + if (!flankGradleExtension.debugApk.isPresent) { + if (project.isAndroidAppModule && variantInfo.appApkPath != null) { + // app modules produce app apks that we can consume + flankGradleExtension.debugApk.set(rootProject.provider { variantInfo.appApkPath }) + } else if (project.isAndroidLibraryModule) { + // library modules do not produce an app apk and we'll use the one specified in fulladleModuleConfig block + // we need library modules to specify the app apk to test against, even if it's a dummy one + check(fulladleModuleExtension.debugApk.isPresent && fulladleModuleExtension.debugApk.orNull != null) { + "Library module ${project.path} did not specify a debug apk. Library modules do not " + + "generate a debug apk and one needs to be specified in the fulladleModuleConfig block\n" + + "This is a required parameter in FTL which remains unused for library modules under test, " + + "and you can use a dummy apk here" } + flankGradleExtension.debugApk.set(rootProject.provider { fulladleModuleExtension.debugApk.get() }) + } + } else { + // Otherwise, let's just add it to the list. + if (project.isAndroidAppModule && variantInfo.appApkPath != null) { + yml.appendLine("- app: ${variantInfo.appApkPath}") + } else if (project.isAndroidLibraryModule) { + // app apk is not required for library modules so only use if it's explicitly specified + if (fulladleModuleExtension.debugApk.orNull != null) { + yml.appendLine("- app: ${fulladleModuleExtension.debugApk.get()}") + } + } + } + + // If the instrumentation apk isn't yet set, let's use this one. + if (!flankGradleExtension.instrumentationApk.isPresent) { + flankGradleExtension.instrumentationApk.set(rootProject.provider { variantInfo.testApkPath }) + } else { + // Otherwise, let's just add it to the list. + if (yml.isBlank()) { + // The first item in the list needs to start with a ` - `. + yml.appendLine("- test: ${variantInfo.testApkPath}") + } else { + yml.appendLine(" test: ${variantInfo.testApkPath}") + } + } + + if (yml.isEmpty()) { + // this is the root module + // should not be added as additional test apk + overrideRootLevelConfigs(flankGradleExtension, fulladleModuleExtension) + } else { + yml.appendProperty(fulladleModuleExtension.maxTestShards, " max-test-shards") + yml.appendMapProperty( + fulladleModuleExtension.clientDetails, + " client-details", + ) { appendLine(" ${it.key}: ${it.value}") } + yml.appendMapProperty( + fulladleModuleExtension.environmentVariables, + " environment-variables", + ) { appendLine(" ${it.key}: ${it.value}") } + flankGradleExtension.additionalTestApks.add(yml.toString()) } + addedTestsForModule = true } } @@ -174,16 +266,11 @@ val Project.hasAndroidTest: Boolean if (!fulladleModuleExtension.enabled.get()) { return false } - val testedExtension = extensions.findByType(TestedExtension::class.java) ?: return false - var testsFound = true - testedExtension.testVariants.configureEach testVariant@{ - if (!file("$projectDir/src/androidTest").exists()) { - println("Ignoring $name test variant in $path: No tests in $projectDir/src/androidTest") - testsFound = false - } - return@testVariant + if (!file("$projectDir/src/androidTest").exists()) { + println("Ignoring test variants in $path: No tests in $projectDir/src/androidTest") + return false } - return testsFound + return true } fun overrideRootLevelConfigs( diff --git a/fladle-plugin/src/main/java/com/osacky/flank/gradle/SanityConfigValidation.kt b/fladle-plugin/src/main/java/com/osacky/flank/gradle/SanityConfigValidation.kt index 10b51018..b26bcd5f 100644 --- a/fladle-plugin/src/main/java/com/osacky/flank/gradle/SanityConfigValidation.kt +++ b/fladle-plugin/src/main/java/com/osacky/flank/gradle/SanityConfigValidation.kt @@ -41,5 +41,5 @@ private fun FladleConfig.checkAndValidateConfig( val Property.hasValue get() = orNull.isNullOrBlank().not() -private val ListProperty.hasValue +private val ListProperty.hasValue get() = getOrElse(emptyList()).isNotEmpty() diff --git a/fladle-plugin/src/main/java/com/osacky/flank/gradle/VariantApkInfo.kt b/fladle-plugin/src/main/java/com/osacky/flank/gradle/VariantApkInfo.kt new file mode 100644 index 00000000..b69db0fa --- /dev/null +++ b/fladle-plugin/src/main/java/com/osacky/flank/gradle/VariantApkInfo.kt @@ -0,0 +1,11 @@ +package com.osacky.flank.gradle + +data class VariantApkInfo( + val variantName: String, + val appApkPath: String?, + val testApkPath: String, + val abiName: String?, +) { + fun isExpectedVariantInModule(config: FulladleModuleExtension): Boolean = + !config.variant.isPresent || (config.variant.isPresent && variantName.contains(config.variant.get())) +} diff --git a/fladle-plugin/src/main/java/com/osacky/flank/gradle/Variants.kt b/fladle-plugin/src/main/java/com/osacky/flank/gradle/Variants.kt index 630ed2ab..df732443 100644 --- a/fladle-plugin/src/main/java/com/osacky/flank/gradle/Variants.kt +++ b/fladle-plugin/src/main/java/com/osacky/flank/gradle/Variants.kt @@ -1,33 +1,34 @@ package com.osacky.flank.gradle -import com.android.build.VariantOutput -import com.android.build.gradle.api.BaseVariant -import com.android.build.gradle.api.BaseVariantOutput +import com.android.build.api.variant.FilterConfiguration +import com.android.build.api.variant.Variant +import com.android.build.api.variant.VariantOutput /** - * Returns true if this [BaseVariant] matches the variant specified in the [config]. + * Returns true if this [Variant] matches the variant specified in the [config]. * * If no variant is specified, all variants are considered a match. */ -fun BaseVariant.isExpectedVariant(config: FladleConfig) = +fun Variant.isExpectedVariant(config: FladleConfig) = !config.variant.isPresent || (config.variant.isPresent && config.variant.get() == this.name) /** - * Returns true if this [BaseVariantOutput] matches the ABI specified in the [config]. + * Returns true if this [VariantOutput] matches the ABI specified in the [config]. * - * If the config does not specify an ABI, or if the config specifies an ABI but the [BaseVariantOutput] + * If the config does not specify an ABI, or if the config specifies an ABI but the [VariantOutput] * is not filtered by ABI, it is considered a match. */ -fun BaseVariantOutput.isExpectedAbiOutput(config: FladleConfig): Boolean { +fun VariantOutput.isExpectedAbiOutput(config: FladleConfig): Boolean { + val abiFilters = filters.filter { it.filterType == FilterConfiguration.FilterType.ABI } return !config.abi.isPresent || - !filterTypes.contains(VariantOutput.FilterType.ABI.name) || - filters.single { it.filterType == VariantOutput.FilterType.ABI.name }.identifier == config.abi.get() + abiFilters.isEmpty() || + abiFilters.any { it.identifier == config.abi.get() } } /** - * Returns true if this [BaseVariant] matches the variant specified in the [config]. + * Returns true if this [Variant] matches the variant specified in the [config]. * * If no variant is specified, all variants are considered a match. */ -fun BaseVariant.isExpectedVariantInModule(config: FulladleModuleExtension) = +fun Variant.isExpectedVariantInModule(config: FulladleModuleExtension) = !config.variant.isPresent || (config.variant.isPresent && this.name.contains(config.variant.get())) diff --git a/fladle-plugin/src/main/java/com/osacky/flank/gradle/YamlExtensions.kt b/fladle-plugin/src/main/java/com/osacky/flank/gradle/YamlExtensions.kt index d0fc43af..a80543bc 100644 --- a/fladle-plugin/src/main/java/com/osacky/flank/gradle/YamlExtensions.kt +++ b/fladle-plugin/src/main/java/com/osacky/flank/gradle/YamlExtensions.kt @@ -4,14 +4,14 @@ import org.gradle.api.provider.ListProperty import org.gradle.api.provider.MapProperty import org.gradle.api.provider.Property -fun StringBuilder.appendProperty( +fun StringBuilder.appendProperty( prop: Property, name: String, ) { if (prop.isPresent) appendLine(" $name: ${prop.get()}") } -fun StringBuilder.appendMapProperty( +fun StringBuilder.appendMapProperty( prop: MapProperty, name: String, custom: StringBuilder.(Map.Entry) -> Unit, @@ -22,7 +22,7 @@ fun StringBuilder.appendMapProperty( } } -fun StringBuilder.appendListProperty( +fun StringBuilder.appendListProperty( prop: ListProperty, name: String, custom: StringBuilder.(T) -> Unit, @@ -43,8 +43,8 @@ fun StringBuilder.appendAdditionalProperty(property: Property) { } } -val ListProperty.isPresentAndNotEmpty +val ListProperty.isPresentAndNotEmpty get() = isPresent && get().isNotEmpty() -val MapProperty.isPresentAndNotEmpty +val MapProperty.isPresentAndNotEmpty get() = isPresent && get().isNotEmpty() diff --git a/fladle-plugin/src/test/java/com/osacky/flank/gradle/MultipleConfigsTest.kt b/fladle-plugin/src/test/java/com/osacky/flank/gradle/MultipleConfigsTest.kt index 8b7a732f..dcb28cd3 100644 --- a/fladle-plugin/src/test/java/com/osacky/flank/gradle/MultipleConfigsTest.kt +++ b/fladle-plugin/src/test/java/com/osacky/flank/gradle/MultipleConfigsTest.kt @@ -38,7 +38,8 @@ class MultipleConfigsTest { testProjectRoot.newFile("flank-gradle-service.json").writeText("{}") val result = - GradleRunner.create() + GradleRunner + .create() .withPluginClasspath() .withArguments("writeConfigPropsOrange", "--stacktrace") .forwardOutput() @@ -76,7 +77,8 @@ class MultipleConfigsTest { ) val regularConfig = - GradleRunner.create() + GradleRunner + .create() .withPluginClasspath() .withArguments("writeConfigProps") .forwardOutput() diff --git a/fladle-plugin/src/test/java/com/osacky/flank/gradle/integration/AutoConfigureFladleTest.kt b/fladle-plugin/src/test/java/com/osacky/flank/gradle/integration/AutoConfigureFladleTest.kt index a4c870ae..848eb540 100644 --- a/fladle-plugin/src/test/java/com/osacky/flank/gradle/integration/AutoConfigureFladleTest.kt +++ b/fladle-plugin/src/test/java/com/osacky/flank/gradle/integration/AutoConfigureFladleTest.kt @@ -39,7 +39,8 @@ class AutoConfigureFladleTest { testProjectRoot.setupFixture(fixtureName) val result = - GradleRunner.create() + GradleRunner + .create() .withProjectDir(testProjectRoot.root) .withPluginClasspath() .withArguments("assembleDebug", "assembleDebugAndroidTest", "printYml", "--stacktrace") diff --git a/fladle-plugin/src/test/java/com/osacky/flank/gradle/integration/ConfigurationCacheTest.kt b/fladle-plugin/src/test/java/com/osacky/flank/gradle/integration/ConfigurationCacheTest.kt index 2f9b5582..83cbf547 100644 --- a/fladle-plugin/src/test/java/com/osacky/flank/gradle/integration/ConfigurationCacheTest.kt +++ b/fladle-plugin/src/test/java/com/osacky/flank/gradle/integration/ConfigurationCacheTest.kt @@ -115,7 +115,7 @@ class ConfigurationCacheTest { settings.writeText( """ plugins { - id 'com.gradle.enterprise' version '3.7' + id 'com.gradle.develocity' version '4.3' } """.trimIndent(), ) @@ -131,11 +131,11 @@ class ConfigurationCacheTest { assertThat(secondResult.output).contains("Reusing configuration cache.") } - private fun configCachingRunner(arg: String): GradleRunner { - return GradleRunner.create() + private fun configCachingRunner(arg: String): GradleRunner = + GradleRunner + .create() .withProjectDir(testProjectRoot.root) .withPluginClasspath() .forwardOutput() .withArguments(arg, "--configuration-cache") - } } diff --git a/fladle-plugin/src/test/java/com/osacky/flank/gradle/integration/FlankGradlePluginIntegrationTest.kt b/fladle-plugin/src/test/java/com/osacky/flank/gradle/integration/FlankGradlePluginIntegrationTest.kt index 1a1ff22d..d95df33f 100644 --- a/fladle-plugin/src/test/java/com/osacky/flank/gradle/integration/FlankGradlePluginIntegrationTest.kt +++ b/fladle-plugin/src/test/java/com/osacky/flank/gradle/integration/FlankGradlePluginIntegrationTest.kt @@ -11,8 +11,8 @@ class FlankGradlePluginIntegrationTest { @get:Rule var testProjectRoot = TemporaryFolder() - val minSupportGradleVersion = "7.3" - val oldVersion = "7.2" + val minSupportGradleVersion = "9.1.0" + val oldVersion = "9.0.0" fun writeBuildGradle(build: String) { testProjectRoot.writeBuildDotGradle(build) @@ -27,16 +27,17 @@ class FlankGradlePluginIntegrationTest { """.trimMargin(), ) val result = - GradleRunner.create() + GradleRunner + .create() .withProjectDir(testProjectRoot.root) .withPluginClasspath() .withGradleVersion(oldVersion) .buildAndFail() - assertThat(result.output).contains("Fladle requires at minimum version Gradle 7.3. Detected version Gradle 7.2") + assertThat(result.output).contains("Fladle requires at minimum version Gradle 9.1. Detected version Gradle 9.0.0") } @Test - fun testGradleEightOh() { + fun testGradleNineOne() { writeBuildGradle( """plugins { | id "com.osacky.fladle" @@ -44,10 +45,11 @@ class FlankGradlePluginIntegrationTest { """.trimMargin(), ) val result = - GradleRunner.create() + GradleRunner + .create() .withProjectDir(testProjectRoot.root) .withPluginClasspath() - .withGradleVersion("8.0") + .withGradleVersion("9.1.0") .build() assertThat(result.output).contains("SUCCESS") @@ -61,7 +63,8 @@ class FlankGradlePluginIntegrationTest { |} """.trimMargin(), ) - GradleRunner.create() + GradleRunner + .create() .withProjectDir(testProjectRoot.root) .withPluginClasspath() .withGradleVersion(minSupportGradleVersion) @@ -82,7 +85,8 @@ class FlankGradlePluginIntegrationTest { |} """.trimMargin(), ) - GradleRunner.create() + GradleRunner + .create() .withProjectDir(testProjectRoot.root) .withPluginClasspath() .withGradleVersion(minSupportGradleVersion) @@ -103,7 +107,8 @@ class FlankGradlePluginIntegrationTest { """.trimMargin(), ) val result = - GradleRunner.create() + GradleRunner + .create() .withProjectDir(testProjectRoot.root) .withPluginClasspath() .withGradleVersion(minSupportGradleVersion) @@ -131,7 +136,8 @@ class FlankGradlePluginIntegrationTest { ) testProjectRoot.newFile("foo").writeText("{}") val result = - GradleRunner.create() + GradleRunner + .create() .withProjectDir(testProjectRoot.root) .withPluginClasspath() .withGradleVersion(minSupportGradleVersion) @@ -155,7 +161,8 @@ class FlankGradlePluginIntegrationTest { ) testProjectRoot.newFile("foo").writeText("{}") val result = - GradleRunner.create() + GradleRunner + .create() .withProjectDir(testProjectRoot.root) .withPluginClasspath() .withGradleVersion(minSupportGradleVersion) @@ -182,7 +189,8 @@ class FlankGradlePluginIntegrationTest { ) testProjectRoot.writeEmptyServiceCredential() val result = - testProjectRoot.gradleRunner() + testProjectRoot + .gradleRunner() .withGradleVersion(minSupportGradleVersion) .withArguments("printYml") .buildAndFail() @@ -209,7 +217,8 @@ class FlankGradlePluginIntegrationTest { ) testProjectRoot.writeEmptyServiceCredential() val result = - testProjectRoot.gradleRunner() + testProjectRoot + .gradleRunner() .withGradleVersion(minSupportGradleVersion) .withArguments("printYml") .buildAndFail() @@ -236,7 +245,8 @@ class FlankGradlePluginIntegrationTest { ) testProjectRoot.writeEmptyServiceCredential() val result = - testProjectRoot.gradleRunner() + testProjectRoot + .gradleRunner() .withGradleVersion(minSupportGradleVersion) .withArguments("printYml") .buildAndFail() @@ -264,7 +274,8 @@ class FlankGradlePluginIntegrationTest { ) testProjectRoot.writeEmptyServiceCredential() val result = - testProjectRoot.gradleRunner() + testProjectRoot + .gradleRunner() .withGradleVersion(minSupportGradleVersion) .withArguments("printYml") .buildAndFail() @@ -291,8 +302,9 @@ class FlankGradlePluginIntegrationTest { ) testProjectRoot.writeEmptyServiceCredential() val result = - testProjectRoot.gradleRunner() - .withGradleVersion("8.0") + testProjectRoot + .gradleRunner() + .withGradleVersion("9.1.0") .withArguments("printYmlFooConfig") .build() assertThat(result.task(":printYmlFooConfig")!!.outcome).isEqualTo(TaskOutcome.SUCCESS) diff --git a/fladle-plugin/src/test/java/com/osacky/flank/gradle/integration/FulladlePluginIntegrationTest.kt b/fladle-plugin/src/test/java/com/osacky/flank/gradle/integration/FulladlePluginIntegrationTest.kt index 6706b2e2..7d2a3ecf 100644 --- a/fladle-plugin/src/test/java/com/osacky/flank/gradle/integration/FulladlePluginIntegrationTest.kt +++ b/fladle-plugin/src/test/java/com/osacky/flank/gradle/integration/FulladlePluginIntegrationTest.kt @@ -10,7 +10,7 @@ class FulladlePluginIntegrationTest { @get:Rule var testProjectRoot = TemporaryFolder() - val agpDependency: String = "com.android.tools.build:gradle:4.2.1" + val agpDependency: String = "com.android.tools.build:gradle:9.0.1" fun writeBuildGradle(build: String) { val file = testProjectRoot.newFile("build.gradle") @@ -26,7 +26,8 @@ class FulladlePluginIntegrationTest { """.trimMargin(), ) val result = - testProjectRoot.gradleRunner() + testProjectRoot + .gradleRunner() .withArguments("help") .build() assertThat(result.output).contains("SUCCESS") @@ -88,7 +89,8 @@ class FulladlePluginIntegrationTest { ) val result = - testProjectRoot.gradleRunner() + testProjectRoot + .gradleRunner() .withArguments(":printYml") .build() @@ -189,7 +191,8 @@ class FulladlePluginIntegrationTest { ) val result = - testProjectRoot.gradleRunner() + testProjectRoot + .gradleRunner() .withArguments(":printYml") .build() @@ -271,7 +274,8 @@ class FulladlePluginIntegrationTest { ) val result = - testProjectRoot.gradleRunner() + testProjectRoot + .gradleRunner() .withArguments(":printYml") .build() @@ -395,7 +399,8 @@ class FulladlePluginIntegrationTest { ) val result = - testProjectRoot.gradleRunner() + testProjectRoot + .gradleRunner() .withArguments(":printYml") .build() @@ -446,10 +451,9 @@ class FulladlePluginIntegrationTest { testProjectRoot.newFile("settings.gradle").writeText( """ include '$appFixture' - include '$libraryFixture' include '$flavourProject' include '$flavourLibrary' - + dependencyResolutionManagement { repositories { mavenCentral() @@ -468,17 +472,17 @@ class FulladlePluginIntegrationTest { repositories { google() } - + dependencies { classpath '$agpDependency' } } - + plugins { id "com.osacky.fulladle" } - - + + fladle { serviceAccountCredentials = project.layout.projectDirectory.file("android-project/flank-gradle-5cf02dc90531.json") } @@ -486,7 +490,8 @@ class FulladlePluginIntegrationTest { ) val result = - testProjectRoot.gradleRunner() + testProjectRoot + .gradleRunner() .withArguments(":printYml") .build() @@ -576,7 +581,8 @@ class FulladlePluginIntegrationTest { ) val result = - testProjectRoot.gradleRunner() + testProjectRoot + .gradleRunner() .withArguments(":printYml") .build() assertThat(result.output).doesNotContain("max-test-shards: 4") @@ -632,7 +638,8 @@ class FulladlePluginIntegrationTest { ) val result = - testProjectRoot.gradleRunner() + testProjectRoot + .gradleRunner() .withArguments(":printYml") .buildAndFail() @@ -708,7 +715,8 @@ class FulladlePluginIntegrationTest { ) val result = - testProjectRoot.gradleRunner() + testProjectRoot + .gradleRunner() .withArguments(":printYml") .buildAndFail() @@ -797,7 +805,8 @@ class FulladlePluginIntegrationTest { ) val result = - testProjectRoot.gradleRunner() + testProjectRoot + .gradleRunner() .withArguments(":printYml") .build() @@ -881,7 +890,8 @@ class FulladlePluginIntegrationTest { ) val result = - testProjectRoot.gradleRunner() + testProjectRoot + .gradleRunner() .withArguments(":printYml") .build() @@ -967,7 +977,8 @@ class FulladlePluginIntegrationTest { ) val result = - testProjectRoot.gradleRunner() + testProjectRoot + .gradleRunner() .withArguments(":printYml") .build() diff --git a/fladle-plugin/src/test/java/com/osacky/flank/gradle/integration/TestFixtures.kt b/fladle-plugin/src/test/java/com/osacky/flank/gradle/integration/TestFixtures.kt index e9f83355..6ad7a89c 100644 --- a/fladle-plugin/src/test/java/com/osacky/flank/gradle/integration/TestFixtures.kt +++ b/fladle-plugin/src/test/java/com/osacky/flank/gradle/integration/TestFixtures.kt @@ -5,7 +5,11 @@ import org.junit.rules.TemporaryFolder import java.io.File fun TemporaryFolder.setupFixture(fixtureName: String) { - File(this::class.java.classLoader.getResource(fixtureName)!!.file).copyRecursively(newFile(fixtureName), true) + File( + this::class.java.classLoader + .getResource(fixtureName)!! + .file, + ).copyRecursively(newFile(fixtureName), true) } internal fun TemporaryFolder.writeBuildDotGradle(buildScript: String) = @@ -13,7 +17,8 @@ internal fun TemporaryFolder.writeBuildDotGradle(buildScript: String) = .writeText(buildScript) fun TemporaryFolder.gradleRunner() = - GradleRunner.create() + GradleRunner + .create() .withPluginClasspath() .forwardOutput() .withProjectDir(root) diff --git a/fladle-plugin/src/test/java/com/osacky/flank/gradle/integration/VariantTests.kt b/fladle-plugin/src/test/java/com/osacky/flank/gradle/integration/VariantTests.kt index c0f9a0c5..29f40468 100644 --- a/fladle-plugin/src/test/java/com/osacky/flank/gradle/integration/VariantTests.kt +++ b/fladle-plugin/src/test/java/com/osacky/flank/gradle/integration/VariantTests.kt @@ -67,15 +67,13 @@ class VariantTests { assertThat(result.output).doesNotContain(":assembleVanillaRelease") assertThat(result.output).doesNotContain(":assembleChocolate") - /** - * See #60 https://github.com/runningcode/fladle/issues/60 - testProjectRoot.writeEmptyServiceCredential() - val resultPrint = testProjectRoot.gradleRunner() - .withArguments("printYmlVanilla") - .build() - assertThat(resultPrint.output).contains("build/outputs/apk/vanilla/debug/chocovanilla-vanilla-debug.apk") - assertThat(resultPrint.output).contains("build/outputs/apk/androidTest/vanilla/debug/chocovanilla-vanilla-debug-androidTest.apk") - **/ + // See #60 https://github.com/runningcode/fladle/issues/60 + // testProjectRoot.writeEmptyServiceCredential() + // val resultPrint = testProjectRoot.gradleRunner() + // .withArguments("printYmlVanilla") + // .build() + // assertThat(resultPrint.output).contains("build/outputs/apk/vanilla/debug/chocovanilla-vanilla-debug.apk") + // assertThat(resultPrint.output).contains("build/outputs/apk/androidTest/vanilla/debug/chocovanilla-vanilla-debug-androidTest.apk") } @Test @@ -106,6 +104,8 @@ class VariantTests { |include ':android-project' """.trimMargin(), ) + testProjectRoot.newFile("local.properties").writeText("sdk.dir=${androidHome()}\n") + testProjectRoot.newFile("gradle.properties").writeText("android.useAndroidX=true") testProjectRoot.setupFixture("android-project") val flavors = if (withFlavors) { @@ -191,7 +191,8 @@ class VariantTests { if (dryRun) { arguments.add("--dry-run") } - return testProjectRoot.gradleRunner() + return testProjectRoot + .gradleRunner() .withArguments(arguments) .build() } diff --git a/fladle-plugin/src/test/java/com/osacky/flank/gradle/validation/ValidateExclusionsTest.kt b/fladle-plugin/src/test/java/com/osacky/flank/gradle/validation/ValidateExclusionsTest.kt index 0b5d05b4..4ffb9517 100644 --- a/fladle-plugin/src/test/java/com/osacky/flank/gradle/validation/ValidateExclusionsTest.kt +++ b/fladle-plugin/src/test/java/com/osacky/flank/gradle/validation/ValidateExclusionsTest.kt @@ -32,7 +32,8 @@ class ValidateExclusionsTest { ) val result = - testProjectRoot.gradleRunner() + testProjectRoot + .gradleRunner() .withArguments("printYml") .buildAndFail() diff --git a/fladle-plugin/src/test/java/com/osacky/flank/gradle/validation/ValidateOptionsTest.kt b/fladle-plugin/src/test/java/com/osacky/flank/gradle/validation/ValidateOptionsTest.kt index 8ef828cd..0800d233 100644 --- a/fladle-plugin/src/test/java/com/osacky/flank/gradle/validation/ValidateOptionsTest.kt +++ b/fladle-plugin/src/test/java/com/osacky/flank/gradle/validation/ValidateOptionsTest.kt @@ -16,7 +16,12 @@ class ValidateOptionsTest { @get:Rule var testProjectRoot = TemporaryFolder() - private val objects = ProjectBuilder.builder().withName("project").build().objects + private val objects = + ProjectBuilder + .builder() + .withName("project") + .build() + .objects private lateinit var config: FladleConfig @Before diff --git a/gradle.properties b/gradle.properties index b2732dd2..b9267d76 100644 --- a/gradle.properties +++ b/gradle.properties @@ -15,8 +15,6 @@ org.gradle.jvmargs=-Xmx1536m # Android operating system, and which are packaged with your app's APK # https://developer.android.com/topic/libraries/support-library/androidx-rn android.useAndroidX=true -# Automatically convert third-party libraries to use AndroidX -android.enableJetifier=false kotlin.code.style=official diff --git a/gradle/gradle-daemon-jvm.properties b/gradle/gradle-daemon-jvm.properties new file mode 100644 index 00000000..5b343e54 --- /dev/null +++ b/gradle/gradle-daemon-jvm.properties @@ -0,0 +1,13 @@ +#This file is generated by updateDaemonJvm +toolchainUrl.FREE_BSD.AARCH64=https\://api.foojay.io/disco/v3.0/ids/536afcd1dff540251f85e5d2c80458cf/redirect +toolchainUrl.FREE_BSD.X86_64=https\://api.foojay.io/disco/v3.0/ids/67a0fee3c4236b6397dcbe8575ca2011/redirect +toolchainUrl.LINUX.AARCH64=https\://api.foojay.io/disco/v3.0/ids/536afcd1dff540251f85e5d2c80458cf/redirect +toolchainUrl.LINUX.X86_64=https\://api.foojay.io/disco/v3.0/ids/ecd23fd7707c683afbcd6052998cb6a9/redirect +toolchainUrl.MAC_OS.AARCH64=https\://api.foojay.io/disco/v3.0/ids/0b98aec810298c2c1d7fdac5dac37910/redirect +toolchainUrl.MAC_OS.X86_64=https\://api.foojay.io/disco/v3.0/ids/658299a896470fbb3103ba3a430ee227/redirect +toolchainUrl.UNIX.AARCH64=https\://api.foojay.io/disco/v3.0/ids/536afcd1dff540251f85e5d2c80458cf/redirect +toolchainUrl.UNIX.X86_64=https\://api.foojay.io/disco/v3.0/ids/67a0fee3c4236b6397dcbe8575ca2011/redirect +toolchainUrl.WINDOWS.AARCH64=https\://api.foojay.io/disco/v3.0/ids/23adb857f3cb3cbe28750bc7faa7abc0/redirect +toolchainUrl.WINDOWS.X86_64=https\://api.foojay.io/disco/v3.0/ids/932015f6361ccaead0c6d9b8717ed96e/redirect +toolchainVendor=JETBRAINS +toolchainVersion=21 diff --git a/gradle/libs.versions.toml b/gradle/libs.versions.toml index cfe2c313..d30bc1c5 100644 --- a/gradle/libs.versions.toml +++ b/gradle/libs.versions.toml @@ -1,16 +1,16 @@ ## Generated by $ ./gradlew refreshVersionsCatalog [plugins] +foojay = { id = "org.gradle.toolchains.foojay-resolver-convention", version = "1.0.0"} ben-manes-versions = { id = "com.github.ben-manes.versions", version = "0.51.0" } -kotlinter = { id = "org.jmailen.kotlinter", version = "4.0.0" } +kotlinter = { id = "org.jmailen.kotlinter", version = "5.4.2" } gradle-plugin-publish = {id = "com.gradle.plugin-publish", version = "2.0.0" } vanniktech-publish = { id = "com.vanniktech.maven.publish", version = "0.35.0" } -kgp = { id = "org.jetbrains.kotlin.android", version.ref = "kotlin"} agp = { id = "com.android.application", version.ref = "agp-version"} [versions] @@ -29,8 +29,8 @@ androidx-test-rules = "1.7.0" junit-version = "4.13.2" -kotlin = "2.3.10" -agp-version = "8.2.2" +agp-version = "9.0.1" + flank-version = "23.10.1" [libraries] @@ -53,8 +53,6 @@ flank = { module = "com.github.flank:flank", version.ref = "flank-version" } junit = { group = "junit", name = "junit", version.ref = "junit-version" } -kotlin-stdlib-jdk7 = { group = "org.jetbrains.kotlin", name = "kotlin-stdlib-jdk7", version.ref = "kotlin" } - gradle-enterprise = { module = "com.gradle:develocity-gradle-plugin", version = "3.19.2" } truth = "com.google.truth:truth:1.4.5" diff --git a/gradle/wrapper/gradle-wrapper.jar b/gradle/wrapper/gradle-wrapper.jar index e6441136..8bdaf60c 100644 Binary files a/gradle/wrapper/gradle-wrapper.jar and b/gradle/wrapper/gradle-wrapper.jar differ diff --git a/gradle/wrapper/gradle-wrapper.properties b/gradle/wrapper/gradle-wrapper.properties index aaaabb3c..2e111328 100644 --- a/gradle/wrapper/gradle-wrapper.properties +++ b/gradle/wrapper/gradle-wrapper.properties @@ -1,6 +1,6 @@ distributionBase=GRADLE_USER_HOME distributionPath=wrapper/dists -distributionUrl=https\://services.gradle.org/distributions/gradle-8.14.4-bin.zip +distributionUrl=https\://services.gradle.org/distributions/gradle-9.1.0-bin.zip networkTimeout=10000 validateDistributionUrl=true zipStoreBase=GRADLE_USER_HOME diff --git a/gradlew b/gradlew index b740cf13..adff685a 100755 --- a/gradlew +++ b/gradlew @@ -1,7 +1,7 @@ #!/bin/sh # -# Copyright © 2015-2021 the original authors. +# Copyright © 2015 the original authors. # # Licensed under the Apache License, Version 2.0 (the "License"); # you may not use this file except in compliance with the License. @@ -15,6 +15,8 @@ # See the License for the specific language governing permissions and # limitations under the License. # +# SPDX-License-Identifier: Apache-2.0 +# ############################################################################## # @@ -84,7 +86,7 @@ done # shellcheck disable=SC2034 APP_BASE_NAME=${0##*/} # Discard cd standard output in case $CDPATH is set (https://github.com/gradle/gradle/issues/25036) -APP_HOME=$( cd "${APP_HOME:-./}" > /dev/null && pwd -P ) || exit +APP_HOME=$( cd -P "${APP_HOME:-./}" > /dev/null && printf '%s\n' "$PWD" ) || exit # Use the maximum available, or set MAX_FD != -1 to use that value. MAX_FD=maximum @@ -112,7 +114,6 @@ case "$( uname )" in #( NONSTOP* ) nonstop=true ;; esac -CLASSPATH=$APP_HOME/gradle/wrapper/gradle-wrapper.jar # Determine the Java command to use to start the JVM. @@ -170,7 +171,6 @@ fi # For Cygwin or MSYS, switch paths to Windows format before running java if "$cygwin" || "$msys" ; then APP_HOME=$( cygpath --path --mixed "$APP_HOME" ) - CLASSPATH=$( cygpath --path --mixed "$CLASSPATH" ) JAVACMD=$( cygpath --unix "$JAVACMD" ) @@ -203,15 +203,14 @@ fi DEFAULT_JVM_OPTS='"-Xmx64m" "-Xms64m"' # Collect all arguments for the java command: -# * DEFAULT_JVM_OPTS, JAVA_OPTS, JAVA_OPTS, and optsEnvironmentVar are not allowed to contain shell fragments, +# * DEFAULT_JVM_OPTS, JAVA_OPTS, and optsEnvironmentVar are not allowed to contain shell fragments, # and any embedded shellness will be escaped. # * For example: A user cannot expect ${Hostname} to be expanded, as it is an environment variable and will be # treated as '${Hostname}' itself on the command line. set -- \ "-Dorg.gradle.appname=$APP_BASE_NAME" \ - -classpath "$CLASSPATH" \ - org.gradle.wrapper.GradleWrapperMain \ + -jar "$APP_HOME/gradle/wrapper/gradle-wrapper.jar" \ "$@" # Stop when "xargs" is not available. diff --git a/gradlew.bat b/gradlew.bat index 7101f8e4..e509b2dd 100644 --- a/gradlew.bat +++ b/gradlew.bat @@ -13,6 +13,8 @@ @rem See the License for the specific language governing permissions and @rem limitations under the License. @rem +@rem SPDX-License-Identifier: Apache-2.0 +@rem @if "%DEBUG%"=="" @echo off @rem ########################################################################## @@ -68,11 +70,10 @@ goto fail :execute @rem Setup the command line -set CLASSPATH=%APP_HOME%\gradle\wrapper\gradle-wrapper.jar @rem Execute Gradle -"%JAVA_EXE%" %DEFAULT_JVM_OPTS% %JAVA_OPTS% %GRADLE_OPTS% "-Dorg.gradle.appname=%APP_BASE_NAME%" -classpath "%CLASSPATH%" org.gradle.wrapper.GradleWrapperMain %* +"%JAVA_EXE%" %DEFAULT_JVM_OPTS% %JAVA_OPTS% %GRADLE_OPTS% "-Dorg.gradle.appname=%APP_BASE_NAME%" -jar "%APP_HOME%\gradle\wrapper\gradle-wrapper.jar" %* :end @rem End local scope for the variables with windows NT shell diff --git a/sample-android-library/build.gradle.kts b/sample-android-library/build.gradle.kts index 8cf64b3f..63a998cb 100644 --- a/sample-android-library/build.gradle.kts +++ b/sample-android-library/build.gradle.kts @@ -1,6 +1,5 @@ plugins { id("com.android.library") - kotlin("android") } fulladleModuleConfig { diff --git a/sample-flavors-kotlin/build.gradle.kts b/sample-flavors-kotlin/build.gradle.kts index ff6a537a..2b131a90 100644 --- a/sample-flavors-kotlin/build.gradle.kts +++ b/sample-flavors-kotlin/build.gradle.kts @@ -1,6 +1,5 @@ plugins { id ("com.android.application") - kotlin("android") id ("com.osacky.fladle") } diff --git a/sample-kotlin/build.gradle.kts b/sample-kotlin/build.gradle.kts index 4c8a977d..5d729cec 100644 --- a/sample-kotlin/build.gradle.kts +++ b/sample-kotlin/build.gradle.kts @@ -1,6 +1,5 @@ plugins { id ("com.android.application") - kotlin("android") id ("com.osacky.fladle") } diff --git a/sample/build.gradle b/sample/build.gradle index f39d1a7c..71b98804 100644 --- a/sample/build.gradle +++ b/sample/build.gradle @@ -1,5 +1,4 @@ apply plugin: 'com.android.application' -apply plugin: 'kotlin-android' apply plugin: 'com.osacky.fladle' android { diff --git a/settings.gradle b/settings.gradle index a5da6364..e6b4450a 100644 --- a/settings.gradle +++ b/settings.gradle @@ -7,6 +7,7 @@ pluginManagement { } plugins { + id "org.gradle.toolchains.foojay-resolver-convention" version "1.0.0" id "com.gradle.develocity" version "4.3.2" }