diff --git a/.github/workflows/ci.yml b/.github/workflows/ci.yml index 6106bc203..ba4fd9b2b 100644 --- a/.github/workflows/ci.yml +++ b/.github/workflows/ci.yml @@ -115,7 +115,7 @@ jobs : check-latest : true - name : Publish to Maven Local - run : ./gradlew clean publishToMavenLocal --no-build-cache --no-daemon --stacktrace --no-parallel && cd gradle-plugin && ./gradlew clean publishToMavenLocal --no-build-cache --no-daemon --stacktrace && cd .. + run : ./gradlew clean publishToMavenLocal --no-build-cache --no-daemon --stacktrace --no-parallel publish-snapshot : runs-on : ubuntu-latest @@ -123,7 +123,7 @@ jobs : timeout-minutes : 25 needs : - test-ubuntu - - build-gradle-plugin + - test-gradle-plugin - gradle-wrapper-validation - publish-maven-local @@ -136,23 +136,20 @@ jobs : check-latest : true - name : Publish Snapshots 1.9 - run : ./gradlew clean publish --no-build-cache --no-daemon --stacktrace --no-parallel && cd gradle-plugin && ./gradlew clean publish --no-build-cache --no-daemon --stacktrace && cd .. + run : ./gradlew clean publish --no-build-cache --no-daemon --stacktrace --no-parallel env : ORG_GRADLE_PROJECT_mavenCentralUsername : ${{ secrets.SONATYPE_NEXUS_USERNAME }} ORG_GRADLE_PROJECT_mavenCentralPassword : ${{ secrets.SONATYPE_NEXUS_PASSWORD }} # TODO: Remove when we drop Kotlin 1.8 support - name : Publish Snapshots 1.8 - run : ./gradlew clean publish --no-build-cache --no-daemon --stacktrace --no-parallel -Doverride_kotlin=1.8.22 -PVERSION_NAME=2.4.9-1-8-SNAPSHOT && cd gradle-plugin && ./gradlew clean publish --no-build-cache --no-daemon --stacktrace -Doverride_kotlin=1.8.22 -PVERSION_NAME=2.4.9-1-8-SNAPSHOT && cd .. + run : ./gradlew clean publish --no-build-cache --no-daemon --stacktrace --no-parallel -Doverride_kotlin=1.8.22 -PVERSION_NAME=2.4.9-1-8-SNAPSHOT env : ORG_GRADLE_PROJECT_mavenCentralUsername : ${{ secrets.SONATYPE_NEXUS_USERNAME }} ORG_GRADLE_PROJECT_mavenCentralPassword : ${{ secrets.SONATYPE_NEXUS_PASSWORD }} - build-gradle-plugin : + test-gradle-plugin : runs-on : ubuntu-latest - defaults : - run : - working-directory : gradle-plugin timeout-minutes : 15 @@ -174,7 +171,7 @@ jobs : check-latest : true - name : Test Gradle Plugin - run : ./gradlew assemble test --no-build-cache --no-daemon --stacktrace -Doverride_kotlin=${{ matrix.kotlin-version }} -Doverride_agp=${{ matrix.agp-version }} + run : ./gradlew :gradle-plugin:assemble :gradle-plugin:test --no-build-cache --no-daemon --stacktrace -Doverride_kotlin=${{ matrix.kotlin-version }} -Doverride_agp=${{ matrix.agp-version }} - name : Upload Test Results uses : actions/upload-artifact@v3 @@ -184,25 +181,6 @@ jobs : name : test-results-gradle-plugin-${{ matrix.kotlin-version }}-${{ matrix.agp-version }} path : ./**/build/reports/tests/ - ktlint-gradle-plugin : - runs-on : ubuntu-latest - defaults : - run : - working-directory : gradle-plugin - - timeout-minutes : 15 - - steps : - - uses : actions/checkout@v3 - - uses : actions/setup-java@v3 - with : - distribution : 'temurin' - java-version : '11' - check-latest : true - - - name : KtLint Gradle Plugin - run : ./gradlew ktlintCheck --no-build-cache --no-daemon --stacktrace - kapt-for-dagger-factories : runs-on : ubuntu-latest timeout-minutes : 25 diff --git a/.gitignore b/.gitignore index cd396173a..2f0746984 100644 --- a/.gitignore +++ b/.gitignore @@ -42,3 +42,7 @@ out # Ignore the generated project. /benchmark/ + +# Since :gradle-plugin is in two builds, it has two build directories +/gradle-plugin/build-anvil/ +/gradle-plugin/build-composite-wrapper/ diff --git a/build-logic/settings.gradle b/build-logic/settings.gradle index 752d661c8..3c717b494 100644 --- a/build-logic/settings.gradle +++ b/build-logic/settings.gradle @@ -10,21 +10,14 @@ rootProject.name = "build-logic" dependencyResolutionManagement { versionCatalogs { - Map overrides = new LinkedHashMap() - System.getProperties().forEach { key, value -> - String keyString = key.toString() - if (keyString.startsWith("override_")) { - overrides.put(keyString, value.toString()) - } - } libs { from(files("../gradle/libs.versions.toml")) - for (Map.Entry entry : overrides.entrySet()) { - String key = entry.getKey() - String value = entry.getValue() - String catalogKey = key.substring("override_".length()) - println("Overriding $catalogKey with $value") - version(catalogKey, value) + System.properties.each { key, value -> + if (key.toString().startsWith("override_")) { + String catalogKey = key.substring("override_".length()) + println "Overriding $catalogKey with $value" + version(catalogKey, value.toString()) + } } } } diff --git a/build-logic/src/main/kotlin/com/squareup/anvil/RootPlugin.kt b/build-logic/src/main/kotlin/com/squareup/anvil/RootPlugin.kt index 1c5c72b93..675eadbac 100644 --- a/build-logic/src/main/kotlin/com/squareup/anvil/RootPlugin.kt +++ b/build-logic/src/main/kotlin/com/squareup/anvil/RootPlugin.kt @@ -1,9 +1,10 @@ package com.squareup.anvil +import com.rickbusarow.kgx.libsCatalog +import com.rickbusarow.kgx.pluginId import com.squareup.anvil.benchmark.BenchmarkPlugin import org.gradle.api.Plugin import org.gradle.api.Project -import org.jetbrains.kotlin.gradle.plugin.KotlinPlatformJvmPlugin open class RootPlugin : Plugin { override fun apply(target: Project) { @@ -14,7 +15,7 @@ open class RootPlugin : Plugin { open class LibraryPlugin : Plugin { override fun apply(target: Project) { - target.plugins.apply(KotlinPlatformJvmPlugin::class.java) + target.plugins.apply(target.libsCatalog.pluginId("kotlin-jvm")) target.plugins.apply(KtlintConventionPlugin::class.java) } } diff --git a/build.gradle b/build.gradle index a2ab6aa4d..bb323f6fb 100644 --- a/build.gradle +++ b/build.gradle @@ -2,12 +2,6 @@ import org.gradle.api.internal.project.DefaultProject import org.jetbrains.kotlin.gradle.dsl.JvmTarget import org.jetbrains.kotlin.gradle.tasks.KotlinCompile -buildscript { - dependencies { - classpath("com.squareup.anvil:gradle-plugin:${findProperty("VERSION_NAME")}",) - } -} - plugins { alias(libs.plugins.agp.application) apply false alias(libs.plugins.agp.library) apply false @@ -20,6 +14,11 @@ plugins { alias(libs.plugins.ktlint) apply false alias(libs.plugins.mavenPublishBase) apply false id 'com.squareup.anvil.root' + id 'com.squareup.anvil' apply false +} + +allprojects { + version = property("VERSION_NAME") } boolean isCi = (System.getenv('CI') ?: 'false').toBoolean() @@ -54,7 +53,8 @@ subprojects { // Dynamically configure JVM targets because Dagger compiler always uses the java 11 @Generated // annotation regardless of release target - boolean isIntegrationTestOrSample = project.path.startsWith(":integration-test") || project.path.startsWith(":sample") + boolean isIntegrationTestOrSample = project.path.startsWith(":integration-test") || + project.path.startsWith(":sample") pluginManager.withPlugin("java") { // Use JDK 11 but target Java 8 for maximum compatibility. @@ -88,7 +88,7 @@ subprojects { && project.name != "annotations-optional" && project.name != "scopes" && project.name != "dagger-factories-only" - if (optInExperimental) { + if (project.path != ':gradle-plugin' && optInExperimental) { freeCompilerArgs.add("-opt-in=com.squareup.anvil.annotations.ExperimentalAnvilApi") } } @@ -121,13 +121,6 @@ subprojects { } } -// For any publish task invoked in the main build, there's a corresponding task in the gradle-plugin -// included build. Gradle doesn't invoke those included build tasks when the main build's tasks are -// run, and that's annoying. This fixes that behavior. -tasks.withType(PublishToMavenRepository).configureEach { mainTask -> - mainTask.dependsOn(gradle.includedBuild("gradle-plugin").task(":${mainTask.name}")) -} - def getProperty(String name, String defaultValue) { return project.hasProperty(name) ? project.getProperty(name) : defaultValue } diff --git a/gradle-plugin-build-logic/build.gradle b/gradle-plugin-build-logic/build.gradle new file mode 100644 index 000000000..55c1f3816 --- /dev/null +++ b/gradle-plugin-build-logic/build.gradle @@ -0,0 +1,9 @@ +plugins { + id 'java-base' +} + +java { + toolchain { + languageVersion.set(JavaLanguageVersion.of(11)) + } +} diff --git a/gradle-plugin/gradle.properties b/gradle-plugin-build-logic/gradle.properties similarity index 100% rename from gradle-plugin/gradle.properties rename to gradle-plugin-build-logic/gradle.properties diff --git a/gradle-plugin/settings.gradle b/gradle-plugin-build-logic/settings.gradle similarity index 52% rename from gradle-plugin/settings.gradle rename to gradle-plugin-build-logic/settings.gradle index 207c21fc0..3cfa4b502 100644 --- a/gradle-plugin/settings.gradle +++ b/gradle-plugin-build-logic/settings.gradle @@ -8,27 +8,24 @@ pluginManagement { includeBuild('../build-logic') } +rootProject.name = "gradle-plugin-build-logic" + dependencyResolutionManagement { versionCatalogs { - Map overrides = new LinkedHashMap() - System.getProperties().forEach { key, value -> - String keyString = key.toString() - if (keyString.startsWith("override_")) { - overrides.put(keyString, value.toString()) - } - } libs { - for (Map.Entry entry : overrides.entrySet()) { - String key = entry.getKey() - String value = entry.getValue() - String catalogKey = key.substring("override_".length()) - println("Overriding $catalogKey with $value") - version(catalogKey, value) + from(files("../gradle/libs.versions.toml")) + System.properties.each { key, value -> + if (key.toString().startsWith("override_")) { + String catalogKey = key.substring("override_".length()) + println "Overriding $catalogKey with $value" + version(catalogKey, value.toString()) + } } } } repositories { + gradlePluginPortal() google() mavenCentral() if (hasProperty("anvil.allowSnapshots")) { @@ -40,4 +37,5 @@ dependencyResolutionManagement { } } -rootProject.name = "gradle-plugin" +include ':gradle-plugin' +project(':gradle-plugin').projectDir = new File('../gradle-plugin') diff --git a/gradle-plugin/build.gradle b/gradle-plugin/build.gradle index 8a6821875..d37fc08c6 100644 --- a/gradle-plugin/build.gradle +++ b/gradle-plugin/build.gradle @@ -3,30 +3,43 @@ plugins { alias libs.plugins.gradlePublish alias libs.plugins.buildconfig id 'java-gradle-plugin' - id 'com.squareup.anvil.publish' +} + +def pomName = 'Anvil Gradle Plugin' +def pomDescription = 'A Kotlin compiler plugin to make dependency injection with Dagger 2 ' + + 'easier by automatically merging Dagger modules and component interfaces.' + +// This module is part of two builds: +// 1. The main build, which publishes the plugin to the Gradle plugin portal. +// 2. The included build, which is used by the main build to test the plugin. +// Only the main build should publish the plugin. +if (rootProject.name == 'anvil') { + apply plugin: 'com.squareup.anvil.publish' + + publish { + configurePom( + artifactId: 'gradle-plugin', + pomName: pomName, + pomDescription: pomDescription + ) + } + layout.buildDirectory.set(file('build-anvil')) +} else { + layout.buildDirectory.set(file('build-composite-wrapper')) } buildConfig { className('BuildProperties') packageName('com.squareup.anvil.plugin') - useKotlinOutput { topLevelConstants = true } + useKotlinOutput { + internalVisibility = true + topLevelConstants = true + } buildConfigField('String', 'GROUP', "\"$GROUP\"") buildConfigField('String', 'VERSION', "\"$VERSION_NAME\"") } -def pomName = 'Anvil Gradle Plugin' -def pomDescription = 'A Kotlin compiler plugin to make dependency injection with Dagger 2 ' + - 'easier by automatically merging Dagger modules and component interfaces.' - -publish { - configurePom( - artifactId: 'gradle-plugin', - pomName: pomName, - pomDescription: pomDescription - ) -} - gradlePlugin { website = project.findProperty('POM_URL') as String vcsUrl = project.findProperty('POM_SCM_URL') as String diff --git a/gradle-plugin/copy_properties.gradle b/gradle-plugin/copy_properties.gradle deleted file mode 100644 index 04963bd9b..000000000 --- a/gradle-plugin/copy_properties.gradle +++ /dev/null @@ -1,15 +0,0 @@ -Properties properties = new Properties() -file("../gradle.properties").withInputStream { properties.load(it) } - -properties.each { key, value -> - ext.set(key, getGradleProperty(key, value)) -} - -def getGradleProperty(String name, String defaultValue = null) { - def provider = providers.gradleProperty(name) - if (defaultValue) { - return provider.getOrElse(defaultValue) - } else { - return provider.getOrNull() - } -} diff --git a/gradle-plugin/gradle b/gradle-plugin/gradle deleted file mode 120000 index 3337596a2..000000000 --- a/gradle-plugin/gradle +++ /dev/null @@ -1 +0,0 @@ -../gradle \ No newline at end of file diff --git a/gradle-plugin/gradlew b/gradle-plugin/gradlew deleted file mode 120000 index 502f5a2d3..000000000 --- a/gradle-plugin/gradlew +++ /dev/null @@ -1 +0,0 @@ -../gradlew \ No newline at end of file diff --git a/gradle-plugin/gradlew.bat b/gradle-plugin/gradlew.bat deleted file mode 120000 index 284013288..000000000 --- a/gradle-plugin/gradlew.bat +++ /dev/null @@ -1 +0,0 @@ -../gradlew.bat \ No newline at end of file diff --git a/gradle-plugin/src/main/java/com/squareup/anvil/plugin/AnvilPlugin.kt b/gradle-plugin/src/main/java/com/squareup/anvil/plugin/AnvilPlugin.kt index 9257f3417..3804603c4 100644 --- a/gradle-plugin/src/main/java/com/squareup/anvil/plugin/AnvilPlugin.kt +++ b/gradle-plugin/src/main/java/com/squareup/anvil/plugin/AnvilPlugin.kt @@ -8,9 +8,6 @@ import com.android.build.gradle.BaseExtension import com.android.build.gradle.LibraryExtension import com.android.build.gradle.TestExtension import com.android.build.gradle.TestedExtension -import com.android.build.gradle.api.BaseVariant -import com.android.build.gradle.api.TestVariant -import com.android.build.gradle.api.UnitTestVariant import org.gradle.api.Action import org.gradle.api.GradleException import org.gradle.api.Project @@ -37,6 +34,15 @@ import org.jetbrains.kotlin.gradle.tasks.KotlinCompile import java.io.File import java.util.concurrent.ConcurrentHashMap +@Suppress("DEPRECATION") +internal typealias BaseVariantDeprecated = com.android.build.gradle.api.BaseVariant + +@Suppress("DEPRECATION") +private typealias TestVariantDeprecated = com.android.build.gradle.api.TestVariant + +@Suppress("DEPRECATION") +private typealias UnitTestVariantDeprecated = com.android.build.gradle.api.UnitTestVariant + @Suppress("unused") internal open class AnvilPlugin : KotlinCompilerPluginSupportPlugin { @@ -69,9 +75,10 @@ internal open class AnvilPlugin : KotlinCompilerPluginSupportPlugin { // E.g. "anvilDebug", "anvilTestRelease", ... val configuration = getConfiguration(target, buildType = variant.name) + @Suppress("TYPEALIAS_EXPANSION_DEPRECATION") when (variant) { - is UnitTestVariant -> configuration.extendsFrom(testConfiguration) - is TestVariant -> configuration.extendsFrom(androidTestVariant) + is UnitTestVariantDeprecated -> configuration.extendsFrom(testConfiguration) + is TestVariantDeprecated -> configuration.extendsFrom(androidTestVariant) // non-test variants like "debug" extend the main config else -> configuration.extendsFrom(commonConfiguration) } @@ -101,7 +108,9 @@ internal open class AnvilPlugin : KotlinCompilerPluginSupportPlugin { kotlinCompilation: KotlinCompilation<*> ): Provider> { kotlinCompilation.compilerOptions.options.let { - if (it.useK2.get() || it.languageVersion.getOrElse(KOTLIN_1_9) >= KOTLIN_2_0) { + @Suppress("DEPRECATION") + val useK2 = it.useK2.get() + if (useK2 || it.languageVersion.getOrElse(KOTLIN_1_9) >= KOTLIN_2_0) { kotlinCompilation.project.logger .error( "NOTE: Anvil is currently incompatible with the K2 compiler. Related GH issue:" + @@ -145,10 +154,8 @@ internal open class AnvilPlugin : KotlinCompilerPluginSupportPlugin { // Notice that we use the name of the variant as a directory name. Generated code // for this specific compile task will be included in the task output. The output of different // compile tasks shouldn't be mixed. - val srcGenDir = File( - project.buildDir, - "anvil${File.separator}src-gen-${variant.name}" - ) + val srcGenDir = project.layout.buildDirectory.get().asFile + .resolve("anvil${File.separator}src-gen-${variant.name}") if (variant.variantFilter.syncGeneratedSources) { val isIdeSyncProvider = project.providers @@ -322,7 +329,11 @@ private inline fun Project.namedLazy( /** * Runs the given [action] for each Android variant including androidTest and unit test variants. */ -private fun Project.androidVariantsConfigure(action: (BaseVariant) -> Unit) { + +private fun Project.androidVariantsConfigure( + @Suppress("TYPEALIAS_EXPANSION_DEPRECATION") + action: (BaseVariantDeprecated) -> Unit +) { val androidExtension = extensions.findByName("android") when (androidExtension) { @@ -348,7 +359,7 @@ private val agpPlugins = listOf( "com.android.library", "com.android.application", "com.android.test", - "com.android.dynamic-feature", + "com.android.dynamic-feature" ) private const val KAPT_PLUGIN_ID = "org.jetbrains.kotlin.kapt" @@ -357,10 +368,11 @@ internal class Variant private constructor( val name: String, val project: Project, val compileTaskProvider: TaskProvider, - val androidVariant: BaseVariant?, + @Suppress("TYPEALIAS_EXPANSION_DEPRECATION") + val androidVariant: BaseVariantDeprecated?, val androidSourceSets: List?, val compilerPluginClasspathName: String, - val variantFilter: VariantFilter, + val variantFilter: VariantFilter ) { // E.g. compileKotlin, compileKotlinJvm, compileDebugKotlin. private val taskSuffix = compileTaskProvider.name.substringAfter("compile") diff --git a/gradle-plugin/src/main/java/com/squareup/anvil/plugin/VariantFilter.kt b/gradle-plugin/src/main/java/com/squareup/anvil/plugin/VariantFilter.kt index f35a60ca7..547b32233 100644 --- a/gradle-plugin/src/main/java/com/squareup/anvil/plugin/VariantFilter.kt +++ b/gradle-plugin/src/main/java/com/squareup/anvil/plugin/VariantFilter.kt @@ -1,6 +1,5 @@ package com.squareup.anvil.plugin -import com.android.build.gradle.api.BaseVariant import org.gradle.api.Named public interface VariantFilter : Named { @@ -94,5 +93,6 @@ public class JvmVariantFilter internal constructor( public class AndroidVariantFilter internal constructor( commonFilter: CommonFilter, - public val androidVariant: BaseVariant + @Suppress("TYPEALIAS_EXPANSION_DEPRECATION") + public val androidVariant: BaseVariantDeprecated ) : VariantFilter by commonFilter diff --git a/settings.gradle b/settings.gradle index e8aca3edb..c53962717 100644 --- a/settings.gradle +++ b/settings.gradle @@ -6,35 +6,33 @@ pluginManagement { } includeBuild('build-logic') + includeBuild('gradle-plugin-build-logic') } +rootProject.name = 'anvil' + dependencyResolutionManagement { versionCatalogs { - Map overrides = new LinkedHashMap() - System.getProperties().forEach { key, value -> - String keyString = key.toString() - if (keyString.startsWith("override_")) { - overrides.put(keyString, value.toString()) - if (keyString.endsWith("_kotlin")) { - // TODO hardcoded to match what's in libs.versions.toml, but kinda ugly - String kspPartialVersion = "1.0.13" - if (value.toString().startsWith("1.8")) { - // Latest KSP releases currently don't support Kotlin 1.8.x - kspPartialVersion = "1.0.11" + libs { + System.properties.each { key, value -> + if (key.toString().startsWith("override_")) { + String catalogKey = key.substring("override_".length()) + println "Overriding $catalogKey with $value" + version(catalogKey, value.toString()) + + if (catalogKey == "kotlin") { + // TODO hardcoded to match what's in libs.versions.toml, but kinda ugly + String kspPartialVersion = "1.0.13" + if (value.toString().startsWith("1.8")) { + // Latest KSP releases currently don't support Kotlin 1.8.x + kspPartialVersion = "1.0.11" + } + println "Overriding ksp with $value-$kspPartialVersion" + version("ksp", "$value-$kspPartialVersion") } - overrides.put("override_ksp", "$value-$kspPartialVersion") } } } - libs { - for (Map.Entry entry : overrides.entrySet()) { - String key = entry.getKey() - String value = entry.getValue() - String catalogKey = key.substring("override_".length()) - println("Overriding $catalogKey with $value") - version(catalogKey, value) - } - } } repositories { @@ -65,12 +63,9 @@ include ':sample:app' include ':sample:library' include ':sample:scopes' -// Use the local version instead of a remote artifact. -includeBuild('gradle-plugin') { - dependencySubstitution { - substitute module('com.squareup.anvil:gradle-plugin') using project(':') - } -} +include ':gradle-plugin' + +includeBuild('gradle-plugin-build-logic') // Include the benchmark modules if they exist. def benchmarkSettingsFile = file('benchmark/settings.gradle')