Git Product home page Git Product logo

poetimizely's Introduction

codecov CI generator gradle-plugin maven-plugin

What is poetimizely

poetimizely is a library to generate type safe accessors for Optimizely 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.
  • packageName (String): package where the code will be placed. The expected format is your.destination.package.

Gradle 🐘

Kotlin DSL (build.gradle.kts)

plugins {
  id("com.patxi.poetimizely") version "1.0.0-beta02"
}

poetimizely {
    optimizelyProjectId = $OPTIMIZELY_PROJECT_ID
    optimizelyToken = $PERSONAL_ACCESS_TOKEN
    packageName = $PACKAGE_NAME
}

Groovy (build.gradle)

plugins {
  id "com.patxi.poetimizely" version "1.0.0-beta02"
}

poetimizely {
    optimizelyProjectId = $OPTIMIZELY_PROJECT_ID
    optimizelyToken = $PERSONAL_ACCESS_TOKEN
    packageName = $PACKAGE_NAME
}

Maven 🕊️

pom.xml

<build>
    <plugins>
        <plugin>
            <groupId>com.patxi</groupId>
            <artifactId>poetimizely-maven-plugin</artifactId>
            <version>1.0.0-beta02</version>
            <configuration>
                <optimizelyProjectId>$OPTIMIZELY_PROJECT_ID</optimizelyProjectId>
                <optimizelyToken>$PERSONAL_ACCESS_TOKEN</optimizelyToken>
                <packageName>$PACKAGE_NAME</packageName>
            </configuration>
        </plugin>
    </plugins>
</build>

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:

./gradlew poetimize

or with Maven:

./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 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:

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:

if (optimizely.isFeatureEnabled(Features.ExampleFeature, userId)) {
    TODO()
}

and also for getting feature variables values:

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

interface BaseVariation {
    val key: String
}

fun Optimizely.getAllExperiments(): List<Experiments<out BaseVariation>> =
    listOf(Experiments.ExampleExperiment)

fun <V : BaseVariation> Optimizely.getVariationForExperiment(
    experiment: Experiments<out V>,
    userId: String,
    attributes: Map<String, Any> = 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<V : BaseVariation>(
    val key: String,
    val variations: Array<V>
) {
    object ExampleExperiment : Experiments<ExampleExperimentVariations> (
        "example-experiment",
        ExampleExperimentVariations.values()
    )
}

Features.kt

class FeatureVariable<T>(
    val featureKey: String,
    val variableKey: String
)

sealed class Features(
    val key: String
) {
    object ExampleFeature("example-feature") {
        val exampleVariable: FeatureVariable<Boolean> = FeatureVariable("example-feature", "example-variable")
    } 
}

fun Optimizely.isFeatureEnabled(
    feature: Features,
    userId: String,
    attributes: Map<String, Any> = emptyMap()
): Boolean = this.isFeatureEnabled(feature.key, userId, attributes)

fun Optimizely.getFeatureVariable(
    variable: FeatureVariable<Boolean>,
    userId: String,
    attributes: Map<String, Any> = emptyMap()
): Boolean? =
    this.getFeatureVariableBoolean(variable.featureKey, variable.variableKey, userId, attributes)

fun Optimizely.getFeatureVariable(
    variable: FeatureVariable<String>,
    userId: String,
    attributes: Map<String, Any> = emptyMap()
): String? =
    this.getFeatureVariableString(variable.featureKey, variable.variableKey, userId, attributes)

fun Optimizely.getFeatureVariable(
    variable: FeatureVariable<Double>,
    userId: String,
    attributes: Map<String, Any> = emptyMap()
): Double? =
    this.getFeatureVariableDouble(variable.featureKey, variable.variableKey, userId, attributes)

fun Optimizely.getFeatureVariable(
    variable: FeatureVariable<Int>,
    userId: String,
    attributes: Map<String, Any> = emptyMap()
): Int? =
    this.getFeatureVariableInteger(variable.featureKey, variable.variableKey, userId, attributes)

poetimizely's People

Contributors

patxibocos avatar ralphpina avatar

Watchers

 avatar

Recommend Projects

  • React photo React

    A declarative, efficient, and flexible JavaScript library for building user interfaces.

  • Vue.js photo Vue.js

    🖖 Vue.js is a progressive, incrementally-adoptable JavaScript framework for building UI on the web.

  • Typescript photo Typescript

    TypeScript is a superset of JavaScript that compiles to clean JavaScript output.

  • TensorFlow photo TensorFlow

    An Open Source Machine Learning Framework for Everyone

  • Django photo Django

    The Web framework for perfectionists with deadlines.

  • D3 photo D3

    Bring data to life with SVG, Canvas and HTML. 📊📈🎉

Recommend Topics

  • javascript

    JavaScript (JS) is a lightweight interpreted programming language with first-class functions.

  • web

    Some thing interesting about web. New door for the world.

  • server

    A server is a program made to process requests and deliver data to clients.

  • Machine learning

    Machine learning is a way of modeling and interpreting data that allows a piece of software to respond intelligently.

  • Game

    Some thing interesting about game, make everyone happy.

Recommend Org

  • Facebook photo Facebook

    We are working to build community through open source technology. NB: members must have two-factor auth.

  • Microsoft photo Microsoft

    Open source projects and samples from Microsoft.

  • Google photo Google

    Google ❤️ Open Source for everyone.

  • D3 photo D3

    Data-Driven Documents codes.