https://github.com/patxibocos/poetimizely
Generate Kotlin type safe accessors for Optimizely experiments and features
https://github.com/patxibocos/poetimizely
gradle-plugin kotlin kotlinpoet maven-plugin optimizely typesafe
Last synced: about 1 month ago
JSON representation
Generate Kotlin type safe accessors for Optimizely experiments and features
- Host: GitHub
- URL: https://github.com/patxibocos/poetimizely
- Owner: patxibocos
- License: mit
- Created: 2020-03-07T04:08:46.000Z (about 5 years ago)
- Default Branch: main
- Last Pushed: 2025-04-09T21:40:17.000Z (about 1 month ago)
- Last Synced: 2025-04-09T22:30:02.257Z (about 1 month ago)
- Topics: gradle-plugin, kotlin, kotlinpoet, maven-plugin, optimizely, typesafe
- Language: Kotlin
- Homepage:
- Size: 1020 KB
- Stars: 19
- Watchers: 3
- Forks: 1
- Open Issues: 4
-
Metadata Files:
- Readme: README.md
- License: LICENSE
Awesome Lists containing this project
README
[](https://codecov.io/gh/patxibocos/poetimizely)
[](https://github.com/patxibocos/poetimizely/actions?query=workflow%3ACI)
[](https://search.maven.org/artifact/io.github.patxibocos/poetimizely-core)
[](https://plugins.gradle.org/plugin/io.github.patxibocos.poetimizely)
[](https://search.maven.org/artifact/io.github.patxibocos/poetimizely-maven-plugin)## What is poetimizely โ
**poetimizely** is a library to generate type safe accessors for [Optimizely](https://www.optimizely.com/) experiments and features.
Given a Project ID and a token it will generate classes for every experiment + variations and features + variables.## Setup โ
โน๏ธ Before editing the build file, there are three properties required to configure explained below:
- **optimizelyProjectId** (Long): id of the Optimizely project to grab experiments and features from.
- **optimizelyToken** (String): Optimizely personal access token. See [Personal token authentication](https://docs.developers.optimizely.com/web/docs/personal-token).
- **packageName** (String): package where the code will be placed. The expected format is `your.destination.package`.### Gradle ๐
#### Kotlin DSL (build.gradle.kts)
```kotlin
plugins {
id("io.github.patxibocos.poetimizely") version "1.0.5"
}poetimizely {
optimizelyProjectId = $OPTIMIZELY_PROJECT_ID
optimizelyToken = $PERSONAL_ACCESS_TOKEN
packageName = $PACKAGE_NAME
}
```#### Groovy (build.gradle)
```groovy
plugins {
id "io.github.patxibocos.poetimizely" version "1.0.5"
}poetimizely {
optimizelyProjectId = $OPTIMIZELY_PROJECT_ID
optimizelyToken = $PERSONAL_ACCESS_TOKEN
packageName = $PACKAGE_NAME
}```
### Maven ๐๏ธ
#### pom.xml
```xml
io.github.patxibocos
poetimizely-maven-plugin
1.0.5
$OPTIMIZELY_PROJECT_ID
$PERSONAL_ACCESS_TOKEN
$PACKAGE_NAME
```
## Usage ๐
After the plugin has been setup, a new Gradle task / Maven goal named **poetimize** will be available. In order to run it successfully, both Optimizely project id and token must be valid.
For Gradle projects run:
```shell
./gradlew poetimize
```or with Maven:
```shell
./mvnw poetimizely:poetimize
```This will generate all the code based on the experiments (and its variants) and features defined for the given Optimizely project.
### Experiments ๐งช
For each of the experiments, a new [object](https://kotlinlang.org/docs/reference/object-declarations.html#object-declarations) will be generated. And for the set of variations for each of the experiments an enum class will be also created.
An extension function for the Optimizely class is also available that brings the **type safety**:
```kotlin
when (optimizely.getVariationForExperiment(Experiments.ExampleExperiment, userId)) {
EXAMPLE_VARIATION -> TODO()
null -> TODO()
}
```### Features ๐ก
Kotlin objects will also be generated for features. For the set of variables that each of the features may have, a property is added to the object.
To check whether a feature is enabled an extension function is provided:
```kotlin
if (optimizely.isFeatureEnabled(Features.ExampleFeature, userId)) {
TODO()
}
```and also for getting feature variables values:
```kotlin
val booleanVariable: Boolean? = optimizely.getFeatureVariable(Features.ExampleFeature.exampleBooleanVariable)
val stringVariable: String? = optimizely.getFeatureVariable(Features.ExampleFeature.exampleStringVariable)
val doubleVariable: Double? = optimizely.getFeatureVariable(Features.ExampleFeature.exampleDoubleVariable)
val intVariable: Int? = optimizely.getFeatureVariable(Features.ExampleFeature.exampleIntVariable)
```## A look at the generated code ๐
After running the task there will be two new classes generated in the given **packageName**:
#### `Experiments.kt`
```kotlin
interface BaseVariation {
val key: String
}fun getAllExperiments(): List> =
listOf(Experiments.ExampleExperiment)fun Optimizely.getVariationForExperiment(
experiment: Experiments,
userId: String,
attributes: Map = emptyMap()
): V? {
val variation = this.activate(experiment.key, userId, attributes)
return experiment.variations.find { it.key == variation?.key }
}enum class ExampleExperimentVariations : BaseVariation {
EXAMPLE_VARIATION {
override val key: String = "example-variation"
}
}sealed class Experiments(
val key: String,
val variations: Array
) {
object ExampleExperiment : Experiments (
"example-experiment",
ExampleExperimentVariations.values()
)
}
```#### `Features.kt`
```kotlin
class FeatureVariable(
val featureKey: String,
val variableKey: String
)sealed class Features(
val key: String
) {
object ExampleFeature("example-feature") {
val exampleVariable: FeatureVariable = FeatureVariable("example-feature", "example-variable")
}
}public fun getAllFeatures(): List = listOf(Features.ExampleFeature)
fun Optimizely.isFeatureEnabled(
feature: Features,
userId: String,
attributes: Map = emptyMap()
): Boolean = this.isFeatureEnabled(feature.key, userId, attributes)fun Optimizely.getFeatureVariable(
variable: FeatureVariable,
userId: String,
attributes: Map = emptyMap()
): Boolean? =
this.getFeatureVariableBoolean(variable.featureKey, variable.variableKey, userId, attributes)fun Optimizely.getFeatureVariable(
variable: FeatureVariable,
userId: String,
attributes: Map = emptyMap()
): String? =
this.getFeatureVariableString(variable.featureKey, variable.variableKey, userId, attributes)fun Optimizely.getFeatureVariable(
variable: FeatureVariable,
userId: String,
attributes: Map = emptyMap()
): Double? =
this.getFeatureVariableDouble(variable.featureKey, variable.variableKey, userId, attributes)fun Optimizely.getFeatureVariable(
variable: FeatureVariable,
userId: String,
attributes: Map = emptyMap()
): Int? =
this.getFeatureVariableInteger(variable.featureKey, variable.variableKey, userId, attributes)
```