Skip to content

Commit

Permalink
Merge pull request #2 from trafi/business-names
Browse files Browse the repository at this point in the history
Generate both business and publish names
  • Loading branch information
justasm authored Jun 30, 2020
2 parents 34ee6e5 + e9c3167 commit 699e557
Show file tree
Hide file tree
Showing 7 changed files with 167 additions and 84 deletions.
14 changes: 7 additions & 7 deletions build.gradle.kts
Original file line number Diff line number Diff line change
@@ -1,12 +1,12 @@
plugins {
val kotlinVersion = "1.3.61"
val kotlinVersion = "1.3.72"
kotlin("jvm") version kotlinVersion
id("org.jetbrains.kotlin.plugin.serialization") version kotlinVersion
id("com.github.johnrengelman.shadow") version "5.2.0"
id("com.github.johnrengelman.shadow") version "6.0.0"
}

group = "com.trafi"
version = "1.1"
version = "2.0"

repositories {
mavenCentral()
Expand All @@ -15,10 +15,10 @@ repositories {

dependencies {
implementation(kotlin("stdlib-jdk8"))
implementation("org.jetbrains.kotlinx:kotlinx-serialization-runtime:0.14.0")
implementation("com.squareup:kotlinpoet:1.5.0")
implementation("com.github.ajalt:clikt:2.4.0")
implementation("com.squareup.okhttp3:okhttp:4.3.1")
implementation("org.jetbrains.kotlinx:kotlinx-serialization-runtime:0.20.0")
implementation("com.squareup:kotlinpoet:1.6.0")
implementation("com.github.ajalt:clikt:2.8.0")
implementation("com.squareup.okhttp3:okhttp:4.7.2")

testImplementation("org.junit.jupiter:junit-jupiter-api:5.6.0")
testRuntimeOnly("org.junit.jupiter:junit-jupiter-engine:5.6.0")
Expand Down
Binary file modified gradle/wrapper/gradle-wrapper.jar
Binary file not shown.
2 changes: 1 addition & 1 deletion gradle/wrapper/gradle-wrapper.properties
Original file line number Diff line number Diff line change
@@ -1,5 +1,5 @@
distributionBase=GRADLE_USER_HOME
distributionPath=wrapper/dists
distributionUrl=https\://services.gradle.org/distributions/gradle-6.1-bin.zip
distributionUrl=https\://services.gradle.org/distributions/gradle-6.5-bin.zip
zipStoreBase=GRADLE_USER_HOME
zipStorePath=wrapper/dists
51 changes: 31 additions & 20 deletions gradlew
Original file line number Diff line number Diff line change
@@ -1,5 +1,21 @@
#!/usr/bin/env sh

#
# Copyright 2015 the original author or authors.
#
# Licensed under the Apache License, Version 2.0 (the "License");
# you may not use this file except in compliance with the License.
# You may obtain a copy of the License at
#
# https://www.apache.org/licenses/LICENSE-2.0
#
# Unless required by applicable law or agreed to in writing, software
# distributed under the License is distributed on an "AS IS" BASIS,
# WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied.
# See the License for the specific language governing permissions and
# limitations under the License.
#

##############################################################################
##
## Gradle start up script for UN*X
Expand Down Expand Up @@ -28,7 +44,7 @@ APP_NAME="Gradle"
APP_BASE_NAME=`basename "$0"`

# Add default JVM options here. You can also use JAVA_OPTS and GRADLE_OPTS to pass JVM options to this script.
DEFAULT_JVM_OPTS='"-Xmx64m"'
DEFAULT_JVM_OPTS='"-Xmx64m" "-Xms64m"'

# Use the maximum available, or set MAX_FD != -1 to use that value.
MAX_FD="maximum"
Expand Down Expand Up @@ -109,8 +125,8 @@ if $darwin; then
GRADLE_OPTS="$GRADLE_OPTS \"-Xdock:name=$APP_NAME\" \"-Xdock:icon=$APP_HOME/media/gradle.icns\""
fi

# For Cygwin, switch paths to Windows format before running java
if $cygwin ; then
# For Cygwin or MSYS, switch paths to Windows format before running java
if [ "$cygwin" = "true" -o "$msys" = "true" ] ; then
APP_HOME=`cygpath --path --mixed "$APP_HOME"`
CLASSPATH=`cygpath --path --mixed "$CLASSPATH"`
JAVACMD=`cygpath --unix "$JAVACMD"`
Expand Down Expand Up @@ -138,19 +154,19 @@ if $cygwin ; then
else
eval `echo args$i`="\"$arg\""
fi
i=$((i+1))
i=`expr $i + 1`
done
case $i in
(0) set -- ;;
(1) set -- "$args0" ;;
(2) set -- "$args0" "$args1" ;;
(3) set -- "$args0" "$args1" "$args2" ;;
(4) set -- "$args0" "$args1" "$args2" "$args3" ;;
(5) set -- "$args0" "$args1" "$args2" "$args3" "$args4" ;;
(6) set -- "$args0" "$args1" "$args2" "$args3" "$args4" "$args5" ;;
(7) set -- "$args0" "$args1" "$args2" "$args3" "$args4" "$args5" "$args6" ;;
(8) set -- "$args0" "$args1" "$args2" "$args3" "$args4" "$args5" "$args6" "$args7" ;;
(9) set -- "$args0" "$args1" "$args2" "$args3" "$args4" "$args5" "$args6" "$args7" "$args8" ;;
0) set -- ;;
1) set -- "$args0" ;;
2) set -- "$args0" "$args1" ;;
3) set -- "$args0" "$args1" "$args2" ;;
4) set -- "$args0" "$args1" "$args2" "$args3" ;;
5) set -- "$args0" "$args1" "$args2" "$args3" "$args4" ;;
6) set -- "$args0" "$args1" "$args2" "$args3" "$args4" "$args5" ;;
7) set -- "$args0" "$args1" "$args2" "$args3" "$args4" "$args5" "$args6" ;;
8) set -- "$args0" "$args1" "$args2" "$args3" "$args4" "$args5" "$args6" "$args7" ;;
9) set -- "$args0" "$args1" "$args2" "$args3" "$args4" "$args5" "$args6" "$args7" "$args8" ;;
esac
fi

Expand All @@ -159,14 +175,9 @@ save () {
for i do printf %s\\n "$i" | sed "s/'/'\\\\''/g;1s/^/'/;\$s/\$/' \\\\/" ; done
echo " "
}
APP_ARGS=$(save "$@")
APP_ARGS=`save "$@"`

# Collect all arguments for the java command, following the shell quoting and substitution rules
eval set -- $DEFAULT_JVM_OPTS $JAVA_OPTS $GRADLE_OPTS "\"-Dorg.gradle.appname=$APP_BASE_NAME\"" -classpath "\"$CLASSPATH\"" org.gradle.wrapper.GradleWrapperMain "$APP_ARGS"

# by default we should be in the correct project dir, but when run from Finder on Mac, the cwd is wrong
if [ "$(uname)" = "Darwin" ] && [ "$HOME" = "$PWD" ]; then
cd "$(dirname "$0")"
fi

exec "$JAVACMD" "$@"
18 changes: 17 additions & 1 deletion gradlew.bat
Original file line number Diff line number Diff line change
@@ -1,3 +1,19 @@
@rem
@rem Copyright 2015 the original author or authors.
@rem
@rem Licensed under the Apache License, Version 2.0 (the "License");
@rem you may not use this file except in compliance with the License.
@rem You may obtain a copy of the License at
@rem
@rem https://www.apache.org/licenses/LICENSE-2.0
@rem
@rem Unless required by applicable law or agreed to in writing, software
@rem distributed under the License is distributed on an "AS IS" BASIS,
@rem WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied.
@rem See the License for the specific language governing permissions and
@rem limitations under the License.
@rem

@if "%DEBUG%" == "" @echo off
@rem ##########################################################################
@rem
Expand All @@ -14,7 +30,7 @@ set APP_BASE_NAME=%~n0
set APP_HOME=%DIRNAME%

@rem Add default JVM options here. You can also use JAVA_OPTS and GRADLE_OPTS to pass JVM options to this script.
set DEFAULT_JVM_OPTS="-Xmx64m"
set DEFAULT_JVM_OPTS="-Xmx64m" "-Xms64m"

@rem Find java.exe
if defined JAVA_HOME goto findJavaFromJavaHome
Expand Down
39 changes: 19 additions & 20 deletions src/main/kotlin/Mammoth.kt
Original file line number Diff line number Diff line change
Expand Up @@ -10,6 +10,7 @@ import okhttp3.Request
import java.io.File
import java.io.FileWriter
import java.io.IOException
import java.net.SocketTimeoutException

class Mammoth : CliktCommand() {

Expand All @@ -22,33 +23,31 @@ class Mammoth : CliktCommand() {
try {
val url = "https://mammoth.trafi.com/$project/schema/$version"
echo(if (business) "Downloading schema from $url" else "Hunting for mammoths at $url")
OkHttpClient().newCall(
Request.Builder()
.url(url)
.build()
).execute().use { response ->
if (response.code != 200) {
throw IOException("${response.code} ${response.message}\n${response.body?.string().orEmpty()}")
}

val schemaJsonString =
val schemaJsonString =
OkHttpClient().newCall(Request.Builder().url(url).build()).execute().use { response ->
if (response.code != 200) {
throw IOException("${response.code} ${response.message}\n${response.body?.string().orEmpty()}")
}
response.body?.string() ?: throw IOException("${response.code} ${response.message} with empty body")
}

echo(if (business) "Parsing schema" else "Grooming mammoth")
val json = Json(JsonConfiguration.Stable.copy(strictMode = false))
val schema = json.parse(Schema.serializer(), schemaJsonString)
echo(if (business) "Parsing schema" else "Grooming mammoth")
val json = Json(JsonConfiguration.Stable.copy(ignoreUnknownKeys = true))
val schema = json.parse(Schema.serializer(), schemaJsonString)

echo(if (business) "Generating code" else "Cooking kotlet")
val code = CodeGenerator.generateCode(schema)
echo(if (business) "Generating code" else "Cooking kotlet")
val code = CodeGenerator.generateCode(schema)

val file = File(outputPath).resolve(outputFilename)
echo(if (business) "Writing generated code to $file" else "Serving hot kotlet at $file")
FileWriter(file).use { it.write(code) }
val file = File(outputPath).resolve(outputFilename)
echo(if (business) "Writing generated code to $file" else "Serving hot kotlet at $file")
FileWriter(file).use { it.write(code) }

echo(if (business) "Success" else "Victory")
}
echo(if (business) "Success" else "Victory")
} catch (e: Exception) {
echo(if (business) "Error: $e" else "Oops, something went wrong: $e")
if (e is SocketTimeoutException) {
echo("Please make sure you are connected to the Trafi VPN")
}
}
}
}
Expand Down
127 changes: 92 additions & 35 deletions src/main/kotlin/com/trafi/mammoth/CodeGenerator.kt
Original file line number Diff line number Diff line change
Expand Up @@ -6,11 +6,14 @@ private const val packageName = "com.trafi.analytics"
private const val enumValuePropertyName = "value"
private const val schemaVersionPropertyName = "mammothSchemaVersion"
private const val schemaVersionPublishName = "score"
private const val schemaVersionBusinessName = "schema_version"
private const val eventIdPublishName = "achievement_id"
private const val eventIdBusinessName = "schema_event_id"

object CodeGenerator {
private val analytics = ClassName(packageName, "Analytics")
private val rawEvent = ClassName(packageName, "RawEvent")
private val analyticsObject = ClassName(packageName, "Analytics")
private val eventClass = ClassName(packageName, "Analytics", "Event")
private val rawEventClass = ClassName(packageName, "RawEvent")
private val schemaVersion = MemberName(packageName, schemaVersionPropertyName)

fun generateCode(schema: Schema): String {
Expand Down Expand Up @@ -61,7 +64,7 @@ object CodeGenerator {
private fun generateEventFunction(event: Schema.Event): FunSpec {
return FunSpec.builder(event.nativeFunctionName)
.addKdoc(event.description)
.returns(rawEvent)
.returns(eventClass)
.addParameters(event.parameters.map { parameter ->
ParameterSpec
.builder(parameter.nativeParameterName, parameter.nativeTypeName)
Expand All @@ -70,50 +73,98 @@ object CodeGenerator {
when (parameter.name) {
Schema.Event.Parameter.screenNameParameterName,
Schema.Event.Parameter.previousScreenNameParameterName -> {
defaultValue("%T.screenName", analytics)
defaultValue("%T.screenName", analyticsObject)
}
Schema.Event.Parameter.modalNameParameterName -> {
defaultValue("%T.modalName", analytics)
defaultValue("%T.modalName", analyticsObject)
}
}
}
.build()
}.sortedBy { it.defaultValue != null })
.addStatement(
"return %T(\n⇥name = %S,\nparameters = %L⇤\n)",
rawEvent,
event.publishName,
"return %T(\n⇥business = %L,\npublish = %L⇤\n)",
eventClass,
generateBusinessEvent(event),
generatePublishEvent(event)
)
.build()
}

private fun generatePublishEvent(event: Schema.Event): CodeBlock {
return generateRawEvent(
name = event.publishName,
parameterCodeBlocks = event.publishValues.map {
CodeBlock.of(
"mapOf(\n⇥%L⇤\n)",
event.publishValues.map {
CodeBlock.of(
"%S to %S",
it.first,
it.second
)
}.plus(event.publishParameterExpressions.map {
CodeBlock.of(
"%S to %L",
it.first,
it.second
)
}).plus(
CodeBlock.of(
"%S to %S",
eventIdPublishName,
event.id
)
).plus(
CodeBlock.of(
"%S to %M",
schemaVersionPublishName,
schemaVersion
)
).joinToCode(separator = ",\n")
"%S to %S",
it.first,
it.second
)
}.plus(event.publishParameterExpressions.map {
CodeBlock.of(
"%S to %L",
it.first,
it.second
)
}).plus(event.publishMetadataParameters)
)
}

private fun generateBusinessEvent(event: Schema.Event): CodeBlock {
return generateRawEvent(
name = event.name,
parameterCodeBlocks = event.businessValues.map {
CodeBlock.of(
"%S to %S",
it.first,
it.second
)
}.plus(event.businessParameterExpressions.map {
CodeBlock.of(
"%S to %L",
it.first,
it.second
)
}).plus(event.businessMetadataParameters)
)
}

private fun generateRawEvent(name: String, parameterCodeBlocks: List<CodeBlock>): CodeBlock {
return CodeBlock.of("%T(\n⇥name = %S,\nparameters = %L⇤\n)",
rawEventClass,
name,
CodeBlock.of(
"mapOf(\n⇥%L⇤\n)",
parameterCodeBlocks.joinToCode(separator = ",\n")
)
.build()
)
}

private val Schema.Event.publishMetadataParameters: List<CodeBlock> get() = listOf(
CodeBlock.of(
"%S to %S",
eventIdPublishName,
id
),
CodeBlock.of(
"%S to %M",
schemaVersionPublishName,
schemaVersion
)
)

private val Schema.Event.businessMetadataParameters: List<CodeBlock> get() = listOf(
CodeBlock.of(
"%S to %S",
eventIdBusinessName,
id
),
CodeBlock.of(
"%S to %M",
schemaVersionBusinessName,
schemaVersion
)
)
}

private val Schema.Event.nativeFunctionName: String get() = name.normalized.decapitalize()
Expand Down Expand Up @@ -141,13 +192,19 @@ private val Schema.Event.publishValues: List<Pair<String, String>>
.filterNot { it.parameter.name == Schema.Event.Parameter.eventTypeParameterName }
.map { it.parameter.publishName to it.publishValue }

private val Schema.Event.businessValues: List<Pair<String, String>>
get() = values.map { it.parameter.name to it.publishValue }

private val Schema.Event.Value.publishValue: String
get() = stringValue ?: integerValue?.toString() ?: stringEnumValue ?: booleanValue?.toString()
?: throw IllegalArgumentException("Invalid publish parameter value. Parameter: ${parameter.name}")

private val Schema.Event.publishParameterExpressions: List<Pair<String, String>>
get() = parameters.map { it.publishName to it.nativeParameterExpression }

private val Schema.Event.businessParameterExpressions: List<Pair<String, String>>
get() = parameters.map { it.name to it.nativeParameterExpression }

private val Schema.Event.Parameter.nativeParameterExpression: String
get() = when (typeName) {
"String" -> nativeParameterName
Expand Down

0 comments on commit 699e557

Please sign in to comment.