Skip to content

Changelog

All notable changes to this project will be documented in this document.

The format is based on Keep a Changelog, and this project adheres to Semantic Versioning.

Unreleased

Added

  • Gradle tasks are now cacheable.
  • Support for typesafe project accessors when declaring dependencies.
  • Shorthand for creating binary flags.
    laboratory {
      // Generates 'Feature' with two options - 'Enabled and 'Disabled'. 'Enabled' is the default one.
      enabledFeature("Feature")
      // Generates 'Feature' with two options - 'Enabled and 'Disabled'. 'Disabled' is the default one.
      disabledFeature("Feature")
    }
    
  • Dependencies can now selectively contribute to generation process.
    laboratory {
      featureFactory()
      featureSourceFactory()
      sourcedStorage()
      optionFactory()
    
      dependency(project(":feature"), [
        DependencyContribution.FeatureFactory,
        DependencyContribution.FeatureSourceFactory, 
        DependencyContribution.OptionFactory, 
        DependencyContribution.SourcedStorage,
      ])
    }
    

Changed

  • Gradle tasks are now always registered when plugin is applied in a project. If there is nothing to generate tasks will clear their respective output directories.
  • Upgrade to Kotlin 1.9.24.
  • Upgrade to Coroutines 1.8.1.
  • Upgrade to Gradle 8.7.
  • Upgrade to AGP to 8.4.1.
  • Upgrade to Wire 4.9.9.
  • Upgrade to KotlinPoet 1.16.0.
  • Upgrade to DataStore 1.1.1.
  • Upgrade to ViewPager2 1.3.2.
  • Upgrade to ViewModel-ktx 2.8.0.
  • Upgrade to Fragment-ktx 1.7.1.
  • Upgrade to RecyclerView 1.3.2.
  • Upgrade to Material 1.12.0.
  • Upgrade to Hyperion 0.9.38.
  • Downgrade target and source compatibilities versions to Java 11.
  • Change compile and target SDK to 34.

Fixed

  • Gradle tasks are now correctly marked as internal.

1.1.0 - 2023-06-13

Changed

  • Upgrade to Kotlin 1.8.21.
  • Upgrade to Coroutines 1.6.4.
  • Upgrade to Gradle 8.1.1.
  • Upgrade to Wire 4.7.0.
  • Upgrade to KotlinPoet 1.14.2.
  • Upgrade to Hyperion 0.9.37.
  • Upgrade to AppCompat 1.6.1.
  • Upgrade to ViewModel-ktx 2.6.1.
  • Upgrade to Fragment-ktx 1.5.7.
  • Upgrade to RecyclerView 1.3.0.
  • Upgrade to Material 1.9.0.
  • Upgrade target and source compatibilities versions to Java 17.
  • Change compile and target SDK to 33.

1.0.3 - 2022-10-01

Fixed

  • Generating feature flags and related classes to empty Kotlin source sets in Kotlin 1.7.20.

1.0.2 - 2022-09-29

Fixed

  • Fixed IllegalArgumentException: Did not find Kotlin source set after upgrading to Kotlin 1.7.20.

1.0.1 - 2022-06-21

Added

Removed

  • CoreKtx dependency.

1.0.0 - 2021-02-06

Added

  • setOptions(options) overload which accepts collection instead of varargs.

Removed

  • ConstraintLayout dependency.
  • DynamicAnimation dependency.

1.0.0-rc2 - 2021-12-28

Changed

  • SharedPreferencesFeatureStorage no marked as experimental due to coroutines.
  • Upgrade to Kotlin 1.6.10.
  • Upgrade to Coroutines 1.6.0.
  • Upgrade to Wire 4.0.1.

Fixed

  • Handle usage of deprecated features in a generated OptionFactory.

Removed

  • Builders for generator models. Models are now created via constructors and throw if data is invalid.
  • GenerationFailure interface.
  • Arrow dependency.

1.0.0-rc1 - 2021-12-22

Added

  • Multi-module setup no longer includes other modules implicitly. Instead each module needs to be included via dependency function in Gradle.
    laboratory {
      featureFactory()
    
      // Before, these were included implicitly.
      dependency(project(":module-a"))
      dependency(project(":module-b"))
    }
    

Changed

  • Upgrade Android target and compile SDK to 31.
  • Upgrade to LifecycleViewmodelKtx 2.4.0.
  • Upgrade to KotlinPoet 1.10.2.
  • Upgrade to Wire 4.0.0.
  • Upgrade to Kotlin 1.6.0.
  • Upgrade to ConstraintLayout 2.1.2.
  • Upgrade to FragmentKtx 1.4.0.
  • Upgrade to AppCompat 1.4.0.

Removed

  • Groovy DSL introduced in 0.9.0 for adding feature flags.
  • projectFilter properties from Gradle plugin. Use explicit dependencies instead.
  • Deprecated API.

Fixed

  • Overrides of sources in DefaultOptionFactory are now respected by Laboratory - #220.

0.14.0 - 2021-10-11

Added

  • Better integration with remote sources, like Firebase, via OptionFactory interface. It creates feature options based on a feature key and an option name.
  • Code generation of option factory via Gradle plugin.

Changed

  • Make Feature and other related classes covariant.
  • FeatureStorage functions are no longer parameterized over Feature. They accept raw class type instead.
  • Generator and Gradle plugin no longer validate package names, duplicates and other things that are checked by compiler.
  • Model builders accept now ClassName in constructor.
  • Mark SharedPreferencesFeatureStorage with ExperimentalCoroutinesApi annotation.
  • Upgrade to Kotlin 1.5.31.
  • Upgrade to Material 1.4.0.
  • Upgrade to CoreKtx 1.6.0.
  • Upgrade to DataStore 1.0.0.
  • Upgrade to AGP 4.2.2.
  • Upgrade to Hyperion 0.9.34.
  • Upgrade to FragmentKtx 1.3.6.
  • Upgrade to AppCompat 1.3.1.
  • Upgrade to ConstraintLayout 2.1.1.
  • Upgrade to ArrowKt 1.0.0.
  • Upgrade to Coroutines 1.5.2.
  • Upgrade to KotlinPoet 1.10.1.

Deprecated

  • FeatureStorage.Companion.sharedPreferences(Context) function. Use overload that accepts SharedPreferences instead.
  • FeatureStorage.Companion.dataStore(() -> File) function. Use overload that accepts DataStore instead.
  • FeatureStorage.Companion.dataStore(Context, String) function. Use overload that accepts DataStore instead.
  • generate() methods on generation models. Use prepare() and operate on FileSpec directly instead.

Removed

  • Dependency on Kyrie.
  • Dependency on JCenter.

0.13.1 - 2021-06-27

Changed

  • Upgrade to Kotlin 1.5.20.
  • Upgrade to RecyclerView 1.2.1.
  • Upgrade to FragmentKtx 1.3.5.
  • Upgrade to DataStore 1.0.0-beta02.
  • Upgrade to KotlinPoet 1.9.0.
  • Upgrade to CoreKtx 1.5.0.
  • Upgrade to AppCompat 1.3.0.

0.13.0 - 2021-05-17

Changed

  • Drop deprecated @JvmDefault and switch to JVM default modes.
  • Upgrade to Kotlin 1.5.0.
  • Upgrade to Coroutines 1.5.0.
  • Upgrade to AGP 4.2.1.
  • Upgrade to KotlinPoet 1.8.0.
  • Upgrade to RecyclerView 1.2.0.
  • Upgrade to Hyperion 0.9.32.
  • Upgrade to FragmentKtx 1.3.3.
  • Upgrade to DataStore 1.0.0-beta01.

0.12.1 - 2021-03-28

Added

  • Indication that an option is a supervisor. If an option supervises features it has an eye icon next to it. List of supervised features is available after long pressing a chip.
  • Navigation from supervised feature to supervisor.
  • Navigation from supervisor to supervised feature.
  • Amount of offscreen feature sections in inspector can be controlled with LaboratoryActivity.Configuration.OffscreenSectionsBehavior. Default is unlimited.

Changed

  • Upgrade to Kotlin 1.4.32.
  • Upgrade to LifecycleViewmodelKtx 2.3.1.
  • Upgrade to FragmentKtx 1.3.2.
  • Upgrade to Wire 3.7.0.

0.12.0 - 2021-03-21

Added

  • Gradle plugin generates sourcedBuilder() extension function for SourcedFeatureStorage that returns custom builder with steps for each source. This makes changes to sources compile time safe.
  • Show feature’s supervisor option in inspector – #95.

Changed

  • Upgrade to Coroutines 1.4.3.
  • Upgrade to AGP 4.1.3.

Deprecated

  • sourcedGenerated() extension function generated by Gradle plugin.

0.11.0 - 2021-03-11

Changed

  • Use proto3 for FeatureFlags definition.
  • Upgrade to DataStore 1.0.0-alpha08.
  • Upgrade to Kotlin 1.4.31.
  • Upgrade to Wire 3.6.1.
  • Upgrade to FragmentKtx 1.3.1.

0.10.0 - 2021-02-18

Added

  • Parent–child relationship to Feature. This relationship is controlled with a Feature.supervisorOption property. Whenever supervisor has its option different from this value then the supervised feature flag cannot return any other option than a default one. Option can still be set via Laboratory but it will not be exposed as long as a feature flag is not supervised. This relationship is recursive meaning that grandparents control grandchildren indirectly.
  • Code generation of supervisor options via Gradle plugin.

Changed

  • Gradle plugin no longer changes implicit package name multiple times. Only last value that was set is applied in configuration.
  • Upgrade to DataStore 1.0.0-alpha06.
  • Upgrade to AGP 4.1.2.
  • Upgrade to Kotlin 1.4.30.
  • Upgrade to Wire 3.6.0.
  • Upgrade to Material 1.3.0.
  • Upgrade to FragmentKtx 1.3.0.
  • Upgrade to LifecycleViewmodelKtx 2.3.0.
  • Upgrade to Hyperion 0.9.31.

Fixed

  • Search icon not animating on Android below SDK 24.

Deprecated

  • DataStore custom builder and builder factory methods. Factory method that accepts DataStore directly should be used instead.

0.9.7 - 2020-12-15

Changed

  • DeprecationLevel.Hidden is no longer deprecated. It was a mistake to deprecate it at all since it could work from the start.

0.9.6 - 2020-12-15

Added

  • FeatureFactory can be now appended to another with plus operator.
  • DefaultOptionFactory can be now appended to another with plus operator.

Changed

  • Use description as feature flag’s KDoc content.
  • Upgrade Kotlin to 1.4.21.

Deprecated

  • Using DeprecationLevel.Hidden is temporarily treated as an error until the compiler issue is fixed.

Fixed

  • Make updates to the in-memory Laboratory atomic.

0.9.5 - 2020-12-03

Added

  • Builder pattern for LaboratoryActivity.Configuration construction.
  • Visual representation of deprecated feature flags in the QA module.
  • Visual representation of deprecated feature flags can be configured via LaboratoryActivity.Configuration builder with deprecationPhenotypeSelector() and deprecationAlignmentSelector() functions.
  • Consumer ProGuard rules to laboratory-inspector to keep @Deprecated annotation.
  • QA module displays clickable hyperlinks from a feature flag description if it contains Markdown formatted links.

Changed

  • Upgrade to DataStore 1.0.0-alpha05.

Deprecated

  • LaboratoryActivity.Configuration() constructor. Use LaboratoryActivity.Configuration.create() or LaboratoryActivity.Configuration.builder() instead.

Fixed

  • Warning and error level deprecation on generated feature flags is now correctly suppressed.

0.9.4 - 2020-11-27

Added

  • Kyrie 0.2.1 to laboratory-inspector.
  • DynamicAnimation 1.0.0 to laboratory-inspector.

Changed

  • Animation of search feature in inspector. It no longer makes ugly visibility transitions.
  • Upgrade to Coroutines 1.4.2.

0.9.3 - 2020-11-23

Added

  • Feature flags filtering to the QA module. Features are filtered by their name, options or source options.
  • ConstraintLayout 2.0.4 to laboratory-inspector.

Changed

  • Inspector tabs are now scrollable instead of fixed.
  • Upgrade to Kotlin 1.4.20.

Fixed

  • Shared preferences based FeatureStorage dispatches now changes to feature flag observers when clear() method is used. This fixes an issue with the QA module where it did not update the UI after resetting feature flags if shared preferences where used for feature flags persistence.
  • Preserve feature flags preview adapter scroll position on configuration changes.
  • External feature factories are no longer filtered out when added with the configure() function.

0.9.2 - 2020-11-18

Added

  • BlockingLaboratory class that can read and write feature flags via blocking API.
  • blocking() function to Laboratory class that is an entry point to the blocking API.
  • Deprecation of feature flags from the Gradle plugin with deprecated(message, level) method. level argument is optional and a warning level is used by default.

Changed

  • Upgrade to DataStore 1.0.0-alpha04.

Deprecated

  • All blocking functions on the Laboratory class. BlockingLaboratory available via blocking() function should be used instead.

0.9.1 - 2020-11-12

Added

  • Builder pattern for Laboratory construction.
  • DefaultOptionFactory that can substitute default options for feature flags read by Laboratory.
  • clear() function to FeatureStorage and Laboratory.

Changed

  • Upgrade to DataStore 1.0.0-alpha03.

Deprecated

  • Laboratory(storage) constructor. Use Laboratory.create(storage) or Laboratory.builder() instead.

0.9.0 - 2020-11-11

Added

  • Groovy DSL for adding feature flags via Gradle plugin. This is equivalent to feature("SomeFeatureFlag") function.
    laboratory {
      SomeFeatureFlag {
        withDefaultOption("Enabled")
        withOption("Disabled")
      }
    }
    
  • options extension to Class<Feature<T>> that returns all available feature flag options.
  • defaultOption extension to Class<Feature<T>> that returns a default option of a feature flag.
  • source extension to Class<Feature<*>> that returns a feature flag source if available.
  • description extension to Class<Feature<*>> that returns a feature flag description if available.
  • withOption() and withDefaultOption() to Gradle plugin for adding options to feature flags.
  • defaultOption property to Feature interface.
  • setOption() and setOptions() functions to Laboratory and FeatureStorage.

Changed

  • excludeProjects plugin functions are now called projectFilter and the condition is reversed. Previously they removed projects that matched a condition. Now they allow projects that match it.
  • sourcedWith property on Feature is now named source.
  • Upgrade to Coroutines 1.4.1.

Deprecated

  • withValue() and withDefaultValue() functions in Gradle plugin. withOption() and withDefaultOption() should be used instead.
  • setFeature() and setFeatures() functions. setOption() and setOptions() should be used instead.

Removed

  • ProjectFilter from laboratory-gradle-plugin in favour of java.util.function.Predicate.
  • configure() overload which accepts sources factory as a separate argument.
  • isDefaultValue from Feature interface. defaultOption should be used instead.

Fixed

  • Moved generateSourcedFeatureStorage task to a correct tasks group.

0.8.0 - 2020-10-28

Added

  • KDoc documentation.

Changed

  • Renamed feature/features argument in setFeature() and setFeatures() methods to value/values respectively.
  • Elevation is no longer an attribute in the IoMehowLaboratory.Theme and a regular resource is used instead. This makes sure that when an Activity theme is overridden externally it won’t crash for an unknown attribute.
  • Flatten Hyperion button to visually match other items.
  • Upgrade to Coroutines 1.4.0.
  • Upgrade to Wire 3.5.0.

Removed

  • generateFactory property from sourcedFeatureStorage() method in Gradle plugin. It was added to the public API by a mistake and wasn’t responsible for anything.
  • Wire dependency from the library-shared-preferences artifact. It was added by a mistake.
  • BuildConfig classes from Android library modules.

0.7.0 - 2020-10-22

Changed

  • Changelog format follows now Keep a Changelog format. Format is applied retroactively to this file.
  • R8 rules are now a part of META-INF of the laboratory artifact.
  • SharedPreferencesFeatureStorage is now internal.
  • Gradle plugin no longer has a runtime dependency on Android Gradle Plugin.
  • laboratory-generator generates source code compatible with the explicit API mode.
  • Set compile SDK to 30.
  • Upgrade to KotlinPoet 1.7.2.
  • Upgrade to Hyperion 0.9.30.
  • Upgrade to DataStore 1.0.0-alpha02.

0.6.2 - 2020-10-12

Added

  • FeatureStorage extensions for creation of SharedPreferences based FeatureStorage.
  • FeatureStorage extensions for creation of DataStore based FeatureStorage.
  • Hyperion plugin can be ordered in the debug menu by overriding io_mehow_laboratory_plugin_id resource.

Deprecated

  • SharedPreferenceFeatureStorage soon will become internal.

Changed

  • DataStoreFeatureStorage is now internal. It is not considered a breaking change as DataStore is in the alpha stage.

0.6.1 - 2020-10-12

Fixed

  • Hyperion plugin layout where button was on the wrong side of the debug menu.

0.6.0 - 2020-10-12

Added

  • Feature can have now description. It can be used to add more contextual data to feature flags.
  • LaboratoryActivity observes changes to feature flags instead of loading them every time the screen is opened.
  • LaboratoryActivity displays feature flag sources next to them and allows users to select a source from a drop down menu.
  • Remote feature flag values are displayed in LaboratoryActivity if a source is not local.
  • When a remote source is used for a feature flag a value cannot be changed from LaboratoryActivity.
  • LaboratoryActivity displays feature flag descriptions if they are present.
  • LaboratoryActivity can reset feature flag values to their default state from an item in the action bar.
  • Laboratory.experimentIs() and Laboratory.experimentIsBlocking() functions that allow to check if a feature flag has particular value.
  • ViewPager2 1.0.0 dependency to laboratory-inspector.
  • RecyclerView 1.1.0 dependency to laboratory-inspector.

Changed

  • LaboratoryActivity requires now a Laboratory instance for initialization. This Laboratory should share FeatureStorage with instances of Laboratory used in the application.

0.5.0 - 2020-10-08

Changed

  • fallback nomenclature to default. This affects Gradle plugin withFallbackValue() and withFallbackSources() functions as well as isFallbackValue property on the Feature interface.

0.4.0 - 2020-10-08

Changed

  • Name of the generated sourced FeatureStorage extension function is now sourcedGenerated() in order to align it with the generated feature factory extension function name.

0.3.0 - 2020-10-08

Added

  • Feature flags can have multiple sources. Source is also a feature flag and is optional. If no source is available it is assumed that only a local source is controlled.
  • FeatureStorage that connects feature flags with their sources. It is available via FeatureStorage.sourced() extension function. Feature flag sources are uniquely identified only by their value names.
  • Feature flag sources can be set from the Gradle plugin with withSource("Name") and withFallbackSource("Name") functions in feature() blocks. Any source that has the name “Local” (or a variant of it) is filtered out.
  • Gradle plugin has a new sourcedStorage() function. It is responsible for generating a customized FeatureStorage that is aware of all available feature flag sources.
  • Gradle plugin has a new featureSourceFactory() function. It works similarly to featureFactory() function with a difference that it collects only feature flag sources.
  • LaboratoryActivity is now configurable with the configure() function.
  • LaboratoryActivity can display different sets of feature flags on separate tabs.
  • FragmentKtx 1.2.5 dependency to laboratory-inspector.
  • ViewModelKtx 2.2.0 dependency to laboratory-inspector.

Changed

  • LaboratoryActivity.initialize() function is renamed to configure().
  • Gradle plugin factory() function is renamed to featureFactory().

0.2.1 - 2020-10-02

Added

  • Laboratory exposes a blocking way of reading and writing feature flags. It requires an opt-in BlockingIoCall annotation.

Changed

  • laboratory-android artifact is now laboratory-shared-preferences artifact.
  • laboratory-shared-preferences artifact (old laboratory-android) is no longer automatically applied by Gradle plugin in Android modules.
  • Upgrade to Kotlin 1.4.10.
  • Upgrade to CoreKtx 1.3.2.
  • Upgrade to Wire 3.4.0.
  • Upgrade to KotlinPoet 1.6.0.

0.2.0 - 2020-09-05

Added

  • Laboratory.observe() function to observe feature flag changes via Flow.
  • Support for DataStore with the laboratory-data-store artifact.
  • Laboratory and FeatureStorage return a boolean information whether writes are successful.
  • Feature interface that is used to define feature flags.
  • Wire 3.2.2 dependency to laboratory-data-store.

Changed

  • Kotlin standard library is now part of the public API.
  • Laboratory and FeatureStorage expose their API via suspend functions.
  • Gradle plugin requires exactly one feature flag value to be added with withFallbackValue("Name") function.
  • Upgrade to Kotlin 1.4.0.
  • Upgrade to Material 1.2.1.
  • Upgrade to Hyperion 0.9.29.

Removed

  • @Feature annotation. Feature flags should implement the Feature interface.

0.1.0 - 2020-08-03

  • Initial release.