patxibocos / poetimizely Goto Github PK
View Code? Open in Web Editor NEWGenerate Kotlin type safe accessors for Optimizely experiments and features
License: MIT License
Generate Kotlin type safe accessors for Optimizely experiments and features
License: MIT License
We should write a post to share in social media and get feedback.
This task depends on #26
Running the Gradle task should generate the code and write the files to the package.
In addition to the current support for features that we already have, variables for features should also be included.
Some Optimizely docs regarding Feature variables:
A feature variable is a property tied to a specific feature. They can be of 4 different types: boolean, string, double and integer.
The proposal is to have an API that would allow the following:
val variable1String: String? = optimizely.getFeatureVariable(Features.Feature1, Feature1.Variables.Variable1, userId)
or:
val variable1Boolean: Boolean? = optimizely.getFeatureVariable(Features.Feature1, Feature1.Variables.Variable2, userId)
For this we need to represent a feature with an interface as now we need to make it generic:
interface BaseFeature<V : BaseVariable<*, *>> {
val key: String
}
and then a variable:
interface BaseVariable<F, T> {
val key: String
}
A variable is doubled parameterized, first with the type of the feature that belongs to, and secondly with the type of the variable (String, Int, Boolean or Double).
A feature is now also parameterized with the variable type that will hold.
This would allow defining features as objects:
object Feature1 : BaseFeature<Feature1Variables<*>> {
override val key: String = "Feature1"
}
and variables too:
sealed class Feature1Variables<T> : BaseVariable<Features.Feature1, T> {
object Variable1 : Feature1Variables<String>() {
override val key: String = "feature1"
}
object Variable2 : Feature1Variables<Boolean>() {
override val key: String = "feature2"
}
}
With all of the above, 4 new extension functions could be defined:
fun <V : BaseVariable<F, *>, F : BaseFeature<V>> Optimizely.getFeatureVariable(
feature: BaseFeature<V>,
variable: BaseVariable<F, Boolean>,
userId: String,
attributes: Map<String, Any> = emptyMap()
): Boolean? {
return this.getFeatureVariableBoolean(feature.key, variable.key, userId, attributes)
}
fun <V : BaseVariable<F, *>, F : BaseFeature<V>> Optimizely.getFeatureVariable(
feature: BaseFeature<V>,
variable: BaseVariable<F, String>,
userId: String,
attributes: Map<String, Any> = emptyMap()
): String? {
return this.getFeatureVariableString(feature.key, variable.key, userId, attributes)
}
fun <V : BaseVariable<F, *>, F : BaseFeature<V>> Optimizely.getFeatureVariable(
feature: BaseFeature<V>,
variable: BaseVariable<F, Double>,
userId: String,
attributes: Map<String, Any> = emptyMap()
): Double? {
return this.getFeatureVariableDouble(feature.key, variable.key, userId, attributes)
}
fun <V : BaseVariable<F, *>, F : BaseFeature<V>> Optimizely.getFeatureVariable(
feature: BaseFeature<V>,
variable: BaseVariable<F, Int>,
userId: String,
attributes: Map<String, Any> = emptyMap()
): Int? {
return this.getFeatureVariableInteger(feature.key, variable.key, userId, attributes)
}
The great benefits of this approach:
optimizely.getFeatureVariable(Features.Feature1, Feature2Variables.Variable2, userId)
π It will not compile because the type of the first argument is BaseFeature<Feature1Variables>
and the second is Feature2Variables<Feature1Variables, Boolean>
How do we get access to test Optimizely? It seems we can create an account for free, see screenshot below.
This issue lists Renovate updates and detected dependencies. Read the Dependency Dashboard docs to learn more.
These updates have all been created already. Click a checkbox below to force a retry/rebase of any.
.github/workflows/build_test.yml
actions/checkout v4
actions/setup-java v4
codecov/codecov-action v4
.github/workflows/release.yml
actions/checkout v4
actions/setup-java v4
poetimizely-core/gradle.properties
poetimizely-core/settings.gradle.kts
poetimizely-core/build.gradle.kts
poetimizely-core/gradle/libs.versions.toml
com.optimizely.ab:core-api 4.1.1
io.kotest:kotest-runner-junit5-jvm 5.9.1
io.kotest:kotest-assertions-core-jvm 5.9.1
dev.zacsweers.kctfork:core 0.5.1
org.jetbrains.kotlinx:kotlinx-coroutines-core 1.8.1
org.jetbrains.kotlinx:kotlinx-serialization-json 1.7.1
com.squareup:kotlinpoet 1.18.1
com.pinterest.ktlint:ktlint-core 0.49.1
com.pinterest.ktlint:ktlint-ruleset-standard 1.3.1
com.pinterest.ktlint:ktlint-rule-engine 1.3.1
com.pinterest.ktlint:ktlint-rule-engine-core 1.3.1
io.ktor:ktor-client-content-negotiation 2.3.12
io.ktor:ktor-client-core 2.3.12
io.ktor:ktor-client-cio 2.3.12
io.ktor:ktor-serialization-kotlinx-json 2.3.12
io.mockk:mockk 1.13.12
net.lingala.zip4j:zip4j 2.11.5
org.jetbrains.kotlin.jvm 2.0.10
org.jetbrains.kotlin.plugin.serialization 2.0.10
io.github.gradle-nexus.publish-plugin 2.0.0
com.diffplug.spotless 6.25.0
poetimizely-gradle-plugin/settings.gradle.kts
poetimizely-gradle-plugin/build.gradle.kts
poetimizely-gradle-plugin/gradle/libs.versions.toml
io.kotest:kotest-runner-junit5-jvm 5.9.1
io.kotest:kotest-assertions-core-jvm 5.9.1
io.github.patxibocos:poetimizely-core 1.0.8
org.jetbrains.kotlin.jvm 2.0.10
org.jetbrains.kotlin.plugin.serialization 2.0.10
io.github.gradle-nexus.publish-plugin 2.0.0
com.diffplug.spotless 6.25.0
com.gradle.plugin-publish 1.2.1
samples/gradle-plugin/gradle.properties
samples/gradle-plugin/settings.gradle.kts
samples/gradle-plugin/build.gradle.kts
org.jetbrains.kotlin.jvm 2.0.10
io.github.patxibocos.poetimizely 1.0.8
com.optimizely.ab:core-api 4.1.1
com.optimizely.ab:core-httpclient-impl 4.1.1
poetimizely-core/gradle/wrapper/gradle-wrapper.properties
gradle 8.10
poetimizely-gradle-plugin/gradle/wrapper/gradle-wrapper.properties
gradle 8.10
samples/gradle-plugin/gradle/wrapper/gradle-wrapper.properties
gradle 8.10
poetimizely-maven-plugin/pom.xml
org.jetbrains.kotlin:kotlin-maven-plugin 2.0.10
org.apache.maven.plugins:maven-plugin-plugin 3.13.1
com.diffplug.spotless:spotless-maven-plugin 2.43.0
org.apache.maven.plugins:maven-source-plugin 3.3.1
org.apache.maven.plugins:maven-surefire-plugin 3.3.1
org.sonatype.plugins:nexus-staging-maven-plugin 1.7.0
org.simplify4u.plugins:sign-maven-plugin 1.1.0
org.jacoco:jacoco-maven-plugin 0.8.12
org.apache.maven:maven-compat 3.9.8
org.apache.maven.plugin-testing:maven-plugin-testing-harness 4.0.0-alpha-2
org.apache.maven:maven-plugin-api 3.9.8
org.apache.maven.plugin-tools:maven-plugin-annotations 3.13.1
org.apache.maven:maven-project 2.2.1
org.junit.jupiter:junit-jupiter-api 5.11.0
org.junit.jupiter:junit-jupiter-engine 5.11.0
io.mockk:mockk-jvm 1.13.12
samples/maven-plugin/pom.xml
com.optimizely.ab:core-api 4.1.1
com.optimizely.ab:core-httpclient-impl 4.1.1
org.jetbrains.kotlin:kotlin-stdlib 2.0.10
io.github.patxibocos:poetimizely-maven-plugin 1.0.8
org.jetbrains.kotlin:kotlin-maven-plugin 2.0.10
poetimizely-maven-plugin/.mvn/wrapper/maven-wrapper.properties
maven 3.9.8
samples/maven-plugin/.mvn/wrapper/maven-wrapper.properties
maven 3.9.8
Things to change:
Support Optimizely Features in a similar way it is done for experiments.
I think it would be better to have this extension functions instead of wrapper clients:
fun <V : BaseVariation> Optimizely.getVariationForExperiment(
experiment: BaseExperiment<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 }
}
fun Optimizely.isFeatureEnabled(feature: Features, userId: String): Boolean =
this.isFeatureEnabled(feature.key, userId)
As a POC this library is a regular Java application, but for convenience it should be a Gradle plugin
Developers will apply the plugin which will create a new Gradle task to generate the code + allow some configuration such as destination package, experiments to exclude, etc...
Consumers should know how to:
We have already started documenting this in various Google Docs.
The docs should probably be in the README. Should we also setup GitHub pages for a fancy website?
Version: 1.0.0-beta02
The ./gradlew poetimize
task fails with the error message:
Execution failed for task ':app:poetimize'.
> SourceSet with name 'main' not found.
The ./gradlew sourceSets
task indicates a main exists:
main
----
Compile configuration: compile
build.gradle name: android.sourceSets.main
Java sources: [app/src/main/java, app/src/main/kotlin]
Manifest file: app/src/main/AndroidManifest.xml
Android resources: [app/src/main/res]
Assets: [app/src/main/assets]
AIDL sources: [app/src/main/aidl]
RenderScript sources: [app/src/main/rs]
JNI sources: [app/src/main/jni]
JNI libraries: [app/src/main/jniLibs]
Java-style resources: [app/src/main/resources]
Let me know if there's other info I may provide to help.
Share project with Optimizely once we have some adoption (maybe just us?). Maybe they can give feedback, help improve it, share their roadmap, etc. Maybe they can help promote it to their user base?
GitHub actions' workflows can be triggered when a new release is done
https://help.github.com/en/actions/reference/events-that-trigger-workflows#release-event-release
So we should:
publishPlugins
task./gradlew publishPlugins -Pgradle.publish.key=<GRADLE_PUBLISH_KEY> -Pgradle.publish.secret=<GRADLE_PUBLISH_SECRET>
A declarative, efficient, and flexible JavaScript library for building user interfaces.
π Vue.js is a progressive, incrementally-adoptable JavaScript framework for building UI on the web.
TypeScript is a superset of JavaScript that compiles to clean JavaScript output.
An Open Source Machine Learning Framework for Everyone
The Web framework for perfectionists with deadlines.
A PHP framework for web artisans
Bring data to life with SVG, Canvas and HTML. πππ
JavaScript (JS) is a lightweight interpreted programming language with first-class functions.
Some thing interesting about web. New door for the world.
A server is a program made to process requests and deliver data to clients.
Machine learning is a way of modeling and interpreting data that allows a piece of software to respond intelligently.
Some thing interesting about visualization, use data art
Some thing interesting about game, make everyone happy.
We are working to build community through open source technology. NB: members must have two-factor auth.
Open source projects and samples from Microsoft.
Google β€οΈ Open Source for everyone.
Alibaba Open Source for everyone
Data-Driven Documents codes.
China tencent open source team.