diff --git a/README.md b/README.md index 257b77264..e6090e030 100644 --- a/README.md +++ b/README.md @@ -237,6 +237,17 @@ sources either. When you enable this feature, don't forget to remove the Dagger annotation processor. You should keep all other dependencies. +If you want to only enable Dagger factory generation on some source sets +(such as only in main source set or only in tests), you can add those source sets +to the allowlist: + +```groovy +anvil { + generateDaggerFactoriesSourceSetAllowlist.add("main") +} +``` + + ## Extending Anvil Every codebase has its own dependency injection patterns where certain code structures need to be diff --git a/gradle-plugin/src/main/java/com/squareup/anvil/plugin/AnvilExtension.kt b/gradle-plugin/src/main/java/com/squareup/anvil/plugin/AnvilExtension.kt index 2f12d0325..465a53084 100644 --- a/gradle-plugin/src/main/java/com/squareup/anvil/plugin/AnvilExtension.kt +++ b/gradle-plugin/src/main/java/com/squareup/anvil/plugin/AnvilExtension.kt @@ -2,6 +2,7 @@ package com.squareup.anvil.plugin import org.gradle.api.Action import org.gradle.api.model.ObjectFactory +import org.gradle.api.provider.ListProperty import org.gradle.api.provider.Property import javax.inject.Inject @@ -33,6 +34,15 @@ public abstract class AnvilExtension @Inject constructor(objects: ObjectFactory) public val generateDaggerFactoriesOnly: Property = objects.property(Boolean::class.java) .convention(false) + /** + * Allowlist of all source sets (such as main, test etc.) that Anvil should generate dagger + * factories in, if factory generation is enabled. + * + * When empty, Anvil will generate factories in all source sets. + */ + public var generateDaggerFactoriesSourceSetAllowlist: ListProperty = + objects.listProperty(String::class.java) + /** * Enabling this indicates that only code generation should run and no component merging should * run. This is useful for cases where you want to use `@ContributesTo`, `@ContributesBinding`, 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..6f22fcdf4 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 @@ -20,6 +20,7 @@ import org.gradle.api.artifacts.Configuration import org.gradle.api.provider.Provider import org.gradle.api.tasks.TaskContainer import org.gradle.api.tasks.TaskProvider +import org.jetbrains.kotlin.gradle.dsl.kotlinExtension import org.jetbrains.kotlin.gradle.dsl.KotlinVersion.KOTLIN_1_9 import org.jetbrains.kotlin.gradle.dsl.KotlinVersion.KOTLIN_2_0 import org.jetbrains.kotlin.gradle.internal.KaptGenerateStubsTask @@ -29,6 +30,7 @@ import org.jetbrains.kotlin.gradle.plugin.KotlinCompilation import org.jetbrains.kotlin.gradle.plugin.KotlinCompilerPluginSupportPlugin import org.jetbrains.kotlin.gradle.plugin.KotlinPlatformType.androidJvm import org.jetbrains.kotlin.gradle.plugin.KotlinPlatformType.jvm +import org.jetbrains.kotlin.gradle.plugin.KotlinSourceSet import org.jetbrains.kotlin.gradle.plugin.PLUGIN_CLASSPATH_CONFIGURATION_NAME import org.jetbrains.kotlin.gradle.plugin.SubpluginArtifact import org.jetbrains.kotlin.gradle.plugin.SubpluginOption @@ -170,6 +172,23 @@ internal open class AnvilPlugin : KotlinCompilerPluginSupportPlugin { } } + val allowlistedVariants = variant.variantFilter + .generateDaggerFactoriesSourceSetAllowlist.map { sourceSetName -> + val sourceSet = variant.kotlinSourceSets.singleOrNull { it.name == sourceSetName } + ?: throw GradleException("Unknown variant $sourceSetName. Available variants: " + + "${variant.kotlinSourceSets.joinToString { it.name }}" + ) + + sourceSet + } + + val enableDaggerFactoriesInThisVariant = allowlistedVariants.isEmpty() || + variant.androidSourceSets?.any { androidSourceSet -> + allowlistedVariants.any { allowlistedSourceSet -> + allowlistedSourceSet.name == androidSourceSet.name + } + } == true + return project.provider { listOf( FilesSubpluginOption( @@ -178,11 +197,13 @@ internal open class AnvilPlugin : KotlinCompilerPluginSupportPlugin { ), SubpluginOption( key = "generate-dagger-factories", - lazy { variant.variantFilter.generateDaggerFactories.toString() } + lazy { (variant.variantFilter.generateDaggerFactories && + enableDaggerFactoriesInThisVariant).toString() } ), SubpluginOption( key = "generate-dagger-factories-only", - lazy { variant.variantFilter.generateDaggerFactoriesOnly.toString() } + lazy { (variant.variantFilter.generateDaggerFactoriesOnly && + enableDaggerFactoriesInThisVariant).toString() } ), SubpluginOption( key = "disable-component-merging", @@ -359,6 +380,7 @@ internal class Variant private constructor( val compileTaskProvider: TaskProvider, val androidVariant: BaseVariant?, val androidSourceSets: List?, + val kotlinSourceSets: List, val compilerPluginClasspathName: String, val variantFilter: VariantFilter, ) { @@ -391,6 +413,8 @@ internal class Variant private constructor( null } + val kotlinSourceSets = project.kotlinExtension.sourceSets.toList() + val commonFilter = CommonFilter(kotlinCompilation.name, extension) val variantFilter = if (androidVariant != null) { AndroidVariantFilter(commonFilter, androidVariant) @@ -406,6 +430,7 @@ internal class Variant private constructor( TaskProvider, androidVariant = androidVariant, androidSourceSets = androidSourceSets, + kotlinSourceSets = kotlinSourceSets, compilerPluginClasspathName = PLUGIN_CLASSPATH_CONFIGURATION_NAME + kotlinCompilation.target.targetName.replaceFirstChar(Char::uppercase) + kotlinCompilation.name.replaceFirstChar(Char::uppercase), 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..f3ac4c880 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 @@ -24,6 +24,14 @@ public interface VariantFilter : Named { */ public var generateDaggerFactoriesOnly: Boolean + /** + * Allowlist of all source sets (such as main, test etc.) that Anvil should generate dagger + * factories in, if factory generation is enabled. + * + * When empty, Anvil will generate factories in all source sets. + */ + public var generateDaggerFactoriesSourceSetAllowlist: List + /** * Indicate whether component merging for this variant should be disabled. The default * value comes from the [AnvilExtension]. See [AnvilExtension.disableComponentMerging] for more @@ -66,6 +74,14 @@ internal class CommonFilter( generateDaggerFactoriesOnlyOverride = value } + private var generateDaggerFactoriesSourceSetAllowOverride: List? = null + override var generateDaggerFactoriesSourceSetAllowlist: List + get() = generateDaggerFactoriesSourceSetAllowOverride + ?: extension.generateDaggerFactoriesSourceSetAllowlist.get() + set(value) { + generateDaggerFactoriesSourceSetAllowOverride = value + } + private var disableComponentMergingOverride: Boolean? = null override var disableComponentMerging: Boolean get() = disableComponentMergingOverride ?: extension.disableComponentMerging.get()