diff --git a/library/docs/changelog.md b/library/docs/changelog.md index 9c715cf3..b4060c8b 100644 --- a/library/docs/changelog.md +++ b/library/docs/changelog.md @@ -9,26 +9,6 @@ and this project adheres to [Semantic Versioning](https://semver.org/spec/v2.0.0 ### Added - Gradle [configuration cache](https://docs.gradle.org/current/userguide/configuration_cache.html) support. -### Changed -- Package name in the `laboratory` block no longer applies to all features retroactively. Before, the following configuration would generate `second.FeatureA` and `second.FeatureB`. Now, it will generate `first.FeatureA` and `second.FeatureB`. - ```groovy - laboratory { - packageName = "first" - - feature("FeatureA") { - withDefaultOption("A") - withOption("B") - } - - packageName = "second" - - feature("FeatureB") { - withDefaultOption("A") - withOption("B") - } - } - ``` - ### Removed - CoreKtx dependency. diff --git a/library/gradle-plugin/src/main/java/io/mehow/laboratory/gradle/ChildFeatureFlagsInput.kt b/library/gradle-plugin/src/main/java/io/mehow/laboratory/gradle/ChildFeatureFlagsInput.kt index 75d90d2f..1c06635a 100644 --- a/library/gradle-plugin/src/main/java/io/mehow/laboratory/gradle/ChildFeatureFlagsInput.kt +++ b/library/gradle-plugin/src/main/java/io/mehow/laboratory/gradle/ChildFeatureFlagsInput.kt @@ -7,7 +7,7 @@ import org.gradle.api.Action * An entry point for configuration of supervised feature flags code generation. */ public class ChildFeatureFlagsInput internal constructor( - private val parentPackageName: String, + private val packageNameProvider: () -> String, private val supervisor: () -> Supervisor, ) { private val mutableFeatureInputs = mutableListOf() @@ -18,7 +18,7 @@ public class ChildFeatureFlagsInput internal constructor( * Generates a new supervised feature flag. */ public fun feature(name: String, action: Action) { - mutableFeatureInputs += FeatureFlagInput(name, parentPackageName, supervisor).let { input -> + mutableFeatureInputs += FeatureFlagInput(name, packageNameProvider, supervisor).let { input -> action.execute(input) return@let input } diff --git a/library/gradle-plugin/src/main/java/io/mehow/laboratory/gradle/FeatureFactoryInput.kt b/library/gradle-plugin/src/main/java/io/mehow/laboratory/gradle/FeatureFactoryInput.kt index 9d836faf..d5b737b0 100644 --- a/library/gradle-plugin/src/main/java/io/mehow/laboratory/gradle/FeatureFactoryInput.kt +++ b/library/gradle-plugin/src/main/java/io/mehow/laboratory/gradle/FeatureFactoryInput.kt @@ -10,7 +10,7 @@ import io.mehow.laboratory.generator.Visibility.Public * Representation of a generated feature factory class. */ public class FeatureFactoryInput internal constructor( - private val parentPackageName: String, + private val packageNameProvider: () -> String, ) { /** * Sets whether the generated feature factory should be public or internal. @@ -24,7 +24,7 @@ public class FeatureFactoryInput internal constructor( internal fun toModel(features: List, simpleName: String) = FeatureFactoryModel( visibility = if (isPublic) Public else Internal, - className = ClassName(packageName ?: parentPackageName, simpleName), + className = ClassName(packageName ?: packageNameProvider(), simpleName), features = features, ) } diff --git a/library/gradle-plugin/src/main/java/io/mehow/laboratory/gradle/FeatureFlagInput.kt b/library/gradle-plugin/src/main/java/io/mehow/laboratory/gradle/FeatureFlagInput.kt index cf9cd347..74a56124 100644 --- a/library/gradle-plugin/src/main/java/io/mehow/laboratory/gradle/FeatureFlagInput.kt +++ b/library/gradle-plugin/src/main/java/io/mehow/laboratory/gradle/FeatureFlagInput.kt @@ -15,7 +15,7 @@ import org.gradle.api.Action */ public class FeatureFlagInput internal constructor( private val name: String, - private val parentPackageName: String, + private val packageNameProvider: () -> String, private val supervisor: (() -> Supervisor)? = null, ) { /** @@ -69,8 +69,9 @@ public class FeatureFlagInput internal constructor( private fun withOption(name: String, isDefault: Boolean, action: Action) { val option = FeatureFlagOption(name, isDefault) options += option + val packageNameProvider = { packageName ?: packageNameProvider() } val supervisorBuilder = { Supervisor(toModel(), option) } - childFeatureInputs += ChildFeatureFlagsInput(packageName ?: parentPackageName, supervisorBuilder).let { input -> + childFeatureInputs += ChildFeatureFlagsInput(packageNameProvider, supervisorBuilder).let { input -> action.execute(input) return@let input } @@ -106,7 +107,7 @@ public class FeatureFlagInput internal constructor( private fun toModel() = FeatureFlagModel( visibility = if (isPublic) Public else Internal, - className = ClassName(packageName ?: parentPackageName, name), + className = ClassName(packageName ?: packageNameProvider(), name), options = options, sourceOptions = sources, key = key, diff --git a/library/gradle-plugin/src/main/java/io/mehow/laboratory/gradle/LaboratoryExtension.kt b/library/gradle-plugin/src/main/java/io/mehow/laboratory/gradle/LaboratoryExtension.kt index 2ea434d0..a1951d3d 100644 --- a/library/gradle-plugin/src/main/java/io/mehow/laboratory/gradle/LaboratoryExtension.kt +++ b/library/gradle-plugin/src/main/java/io/mehow/laboratory/gradle/LaboratoryExtension.kt @@ -12,7 +12,13 @@ public abstract class LaboratoryExtension { * Sets package name for any factories or feature flags defined in this extension. * Package names can be individually overwritten in each generating block */ - public var packageName: String = "" + public var packageName: String + get() = packageNameProvider() + set(value) { + packageNameProvider.value = value + } + + private val packageNameProvider = PackageNameProvider() private val mutableFeatureInputs = mutableListOf() @@ -28,7 +34,7 @@ public abstract class LaboratoryExtension { * Generates a new feature in this module. */ public fun feature(name: String, action: Action) { - mutableFeatureInputs += FeatureFlagInput(name, packageName).let { input -> + mutableFeatureInputs += FeatureFlagInput(name, packageNameProvider).let { input -> action.execute(input) return@let input } @@ -49,7 +55,7 @@ public abstract class LaboratoryExtension { * that needs to have information about all feature flags for QA purposes. */ public fun featureFactory(action: Action) { - factoryInput = FeatureFactoryInput(packageName).let { input -> + factoryInput = FeatureFactoryInput(packageNameProvider).let { input -> action.execute(input) return@let input } @@ -72,7 +78,7 @@ public abstract class LaboratoryExtension { * Feature storage generated by this method should be then used in the application. */ public fun sourcedStorage(action: Action) { - storageInput = SourcedFeatureStorageInput(packageName).let { input -> + storageInput = SourcedFeatureStorageInput(packageNameProvider).let { input -> action.execute(input) return@let input } @@ -93,7 +99,7 @@ public abstract class LaboratoryExtension { * that needs to have information about all feature flags for QA purposes. */ public fun featureSourceFactory(action: Action) { - featureSourcesFactory = FeatureFactoryInput(packageName).let { input -> + featureSourcesFactory = FeatureFactoryInput(packageNameProvider).let { input -> action.execute(input) return@let input } @@ -113,7 +119,7 @@ public abstract class LaboratoryExtension { * be visible to it during compilation. */ public fun optionFactory(action: Action) { - optionFactoryInput = OptionFactoryInput(packageName).let { input -> + optionFactoryInput = OptionFactoryInput(packageNameProvider).let { input -> action.execute(input) return@let input } @@ -125,9 +131,10 @@ public abstract class LaboratoryExtension { */ public fun dependency(project: Project) { this.project.evaluationDependsOn(project.path) - val laboratoryExtension = requireNotNull(project.extensions.findByType(LaboratoryExtension::class.java)) { - "Cannot depend on a project without laboratory plugin" - } + val laboratoryExtension = + requireNotNull(project.extensions.findByType(LaboratoryExtension::class.java)) { + "Cannot depend on a project without laboratory plugin" + } mutableDependencies += laboratoryExtension.featureInputs } } diff --git a/library/gradle-plugin/src/main/java/io/mehow/laboratory/gradle/OptionFactoryInput.kt b/library/gradle-plugin/src/main/java/io/mehow/laboratory/gradle/OptionFactoryInput.kt index 8fab7648..3366aedb 100644 --- a/library/gradle-plugin/src/main/java/io/mehow/laboratory/gradle/OptionFactoryInput.kt +++ b/library/gradle-plugin/src/main/java/io/mehow/laboratory/gradle/OptionFactoryInput.kt @@ -10,7 +10,7 @@ import io.mehow.laboratory.generator.Visibility.Public * Representation of a generated option factory that is aware of feature flags. */ public class OptionFactoryInput internal constructor( - private val parentPackageName: String, + private val packageNameProvider: () -> String, ) { /** * Sets whether the generated option factory should be public or internal. @@ -24,7 +24,7 @@ public class OptionFactoryInput internal constructor( internal fun toModel(features: List) = OptionFactoryModel( visibility = if (isPublic) Public else Internal, - className = ClassName(packageName ?: parentPackageName, "GeneratedOptionFactory"), + className = ClassName(packageName ?: packageNameProvider(), "GeneratedOptionFactory"), features = features, ) } diff --git a/library/gradle-plugin/src/main/java/io/mehow/laboratory/gradle/PackageNameProvider.kt b/library/gradle-plugin/src/main/java/io/mehow/laboratory/gradle/PackageNameProvider.kt new file mode 100644 index 00000000..b124e272 --- /dev/null +++ b/library/gradle-plugin/src/main/java/io/mehow/laboratory/gradle/PackageNameProvider.kt @@ -0,0 +1,7 @@ +package io.mehow.laboratory.gradle + +internal class PackageNameProvider : () -> String { + var value = "" + + override fun invoke() = value +} diff --git a/library/gradle-plugin/src/main/java/io/mehow/laboratory/gradle/SourcedFeatureStorageInput.kt b/library/gradle-plugin/src/main/java/io/mehow/laboratory/gradle/SourcedFeatureStorageInput.kt index e5b12b93..54937529 100644 --- a/library/gradle-plugin/src/main/java/io/mehow/laboratory/gradle/SourcedFeatureStorageInput.kt +++ b/library/gradle-plugin/src/main/java/io/mehow/laboratory/gradle/SourcedFeatureStorageInput.kt @@ -9,7 +9,7 @@ import io.mehow.laboratory.generator.Visibility.Public * Representation of a generated feature storage that is aware of feature flags sources. */ public class SourcedFeatureStorageInput internal constructor( - private val parentPackageName: String, + private val packageNameProvider: () -> String, ) { /** * Sets whether the generated feature storage should be public or internal. @@ -23,7 +23,7 @@ public class SourcedFeatureStorageInput internal constructor( internal fun toModel(sourceNames: List) = SourcedFeatureStorageModel( visibility = if (isPublic) Public else Internal, - className = ClassName(packageName ?: parentPackageName, "SourcedGeneratedFeatureStorage"), + className = ClassName(packageName ?: packageNameProvider(), "SourcedGeneratedFeatureStorage"), sourceNames = sourceNames, ) } diff --git a/library/gradle-plugin/src/test/java/io/mehow/laboratory/gradle/GenerateFeatureFlagsTaskSpec.kt b/library/gradle-plugin/src/test/java/io/mehow/laboratory/gradle/GenerateFeatureFlagsTaskSpec.kt index 1377dd7e..ae43967b 100644 --- a/library/gradle-plugin/src/test/java/io/mehow/laboratory/gradle/GenerateFeatureFlagsTaskSpec.kt +++ b/library/gradle-plugin/src/test/java/io/mehow/laboratory/gradle/GenerateFeatureFlagsTaskSpec.kt @@ -277,15 +277,15 @@ internal class GenerateFeatureFlagsTaskSpec : StringSpec({ featureB.shouldExist() } - "switches implicit package name to a new one" { + "uses last implicit package name for all features" { val fixture = "feature-flag-package-name-implicit-switching".toFixture() gradleRunner.withProjectDir(fixture).build() - val featureA = fixture.featureFile("io.mehow.implicit.FeatureA") + val featureA = fixture.featureFile("io.mehow.implicit.switch.FeatureA") featureA.shouldExist() - featureA.readText() shouldContain "package io.mehow.implicit" + featureA.readText() shouldContain "package io.mehow.implicit.switch" val featureB = fixture.featureFile("io.mehow.implicit.switch.FeatureB") featureB.shouldExist()