Skip to content

Commit

Permalink
[meta] Support Kotlin meta generator (OpenAPITools#4156)
Browse files Browse the repository at this point in the history
* [meta] Support Kotlin meta generator

* Guard against automatic scripts (assumptions for this script are not fulfilled by some CI which run "run all" type scripts)
  • Loading branch information
jimschubert authored Nov 9, 2019
1 parent db729be commit 357f6ca
Show file tree
Hide file tree
Showing 35 changed files with 1,451 additions and 1 deletion.
52 changes: 52 additions & 0 deletions bin/meta-codegen-kotlin.sh
Original file line number Diff line number Diff line change
@@ -0,0 +1,52 @@
#!/bin/sh

SCRIPT="$0"
echo "# START SCRIPT: $SCRIPT"

if ! command -v gradle > /dev/null; then
echo "[WARN] This script requires a system gradle to be installed. Not treating this as an error."
exit 0
fi

while [ -h "$SCRIPT" ] ; do
ls=`ls -ld "$SCRIPT"`
link=`expr "$ls" : '.*-> \(.*\)$'`
if expr "$link" : '/.*' > /dev/null; then
SCRIPT="$link"
else
SCRIPT=`dirname "$SCRIPT"`/"$link"
fi
done

if [ ! -d "${APP_DIR}" ]; then
APP_DIR=`dirname "$SCRIPT"`/..
APP_DIR=`cd "${APP_DIR}"; pwd`
fi

executable="./modules/openapi-generator-cli/target/openapi-generator-cli.jar"

if [ ! -f "$executable" ]
then
./mvnw -B clean package
fi

\rm -rf "samples/meta-codegen-kotlin/lib"

export JAVA_OPTS="${JAVA_OPTS} -Xmx1024M -DloggerPath=conf/log4j.properties"
ags="meta -n myClientCodegen -t DOCUMENTATION -p com.my.company.codegen -o samples/meta-codegen-kotlin/lib -l kotlin $@"

java $JAVA_OPTS -jar $executable $ags

if [ ! -f samples/meta-codegen-kotlin/gradle/wrapper/gradle-wrapper.jar ]; then
(cd samples/meta-codegen-kotlin/ && gradle wrapper --gradle-version 5.6.2 --distribution-type bin)
fi


(cp samples/meta-codegen-kotlin/gradlew samples/meta-codegen-kotlin/lib/ && \
cp -R samples/meta-codegen-kotlin/gradle samples/meta-codegen-kotlin/lib/ && \
cd samples/meta-codegen-kotlin/lib && \
./gradlew shadowJar)

ags2="generate -g myClientCodegen -i modules/openapi-generator/src/test/resources/2_0/petstore.json -o samples/meta-codegen-kotlin/usage $@"

java $JAVA_OPTS -cp samples/meta-codegen-kotlin/lib/build/libs/my-client-codegen-openapi-generator-1.0-SNAPSHOT-all.jar:$executable org.openapitools.codegen.OpenAPIGenerator $ags2
Original file line number Diff line number Diff line change
Expand Up @@ -72,15 +72,34 @@ public class Meta implements Runnable {
allowedValues = {"CLIENT", "SERVER", "DOCUMENTATION", "CONFIG", "OTHER"})
private String type = "OTHER";

@Option(name = {"-l", "--language"}, title = "language",
description = "the implementation language for the generator class",
allowedValues = {"java", "kotlin"}
)
private String language = "java";

@Override
public void run() {
final File targetDir = new File(outputFolder);
LOGGER.info("writing to folder [{}]", targetDir.getAbsolutePath());

String mainClass = CaseFormat.LOWER_HYPHEN.to(CaseFormat.UPPER_CAMEL, name) + "Generator";
String kebabName = CaseFormat.UPPER_CAMEL.to(CaseFormat.LOWER_HYPHEN, name);

List<SupportingFile> supportingFiles =
List<SupportingFile> supportingFiles = "kotlin".equals(language) ?
ImmutableList.of(
new SupportingFile("kotlin/build_gradle.mustache", "", "build.gradle.kts"),
new SupportingFile("kotlin/gradle.properties", "", "gradle.properties"),
new SupportingFile("kotlin/settings.mustache", "", "settings.gradle"),
new SupportingFile("kotlin/generatorClass.mustache", on(File.separator).join("src/main/kotlin", asPath(targetPackage)), mainClass.concat(".kt")),
new SupportingFile("kotlin/generatorClassTest.mustache", on(File.separator).join("src/test/kotlin", asPath(targetPackage)), mainClass.concat("Test.kt")),
new SupportingFile("kotlin/README.mustache", "", "README.md"),

new SupportingFile("api.template", "src/main/resources" + File.separator + name,"api.mustache"),
new SupportingFile("model.template", "src/main/resources" + File.separator + name,"model.mustache"),
new SupportingFile("myFile.template", String.join(File.separator, "src", "main", "resources", name), "myFile.mustache"),
new SupportingFile("services.mustache", "src/main/resources/META-INF/services", CodegenConfig.class.getCanonicalName()))
: ImmutableList.of(
new SupportingFile("pom.mustache", "", "pom.xml"),
new SupportingFile("generatorClass.mustache", on(File.separator).join("src/main/java", asPath(targetPackage)), mainClass.concat(".java")),
new SupportingFile("generatorClassTest.mustache", on(File.separator).join("src/test/java", asPath(targetPackage)), mainClass.concat("Test.java")),
Expand All @@ -97,6 +116,7 @@ public void run() {
.put("generatorPackage", targetPackage)
.put("generatorClass", mainClass)
.put("name", name)
.put("kebabName", kebabName)
.put("generatorType", type)
.put("fullyQualifiedGeneratorClass", targetPackage + "." + mainClass)
.put("openapiGeneratorVersion", currentVersion).build();
Expand Down
Original file line number Diff line number Diff line change
@@ -0,0 +1,60 @@
# {{kebabName}}-openapi-generator

## Requirements

* Gradle 5.x
* Java 8+

## Getting Started

* Initialize the gradle wrapper:
```bash
gradle wrapper --gradle-version 5.6.2
```
* Modify the codegen class and associated templates
* Compile with `./gradlew standalone`
* Verify:
```bash
java -jar build/libs/{{kebabName}}-openapi-generator-standalone.jar config-help -g {{name}}
```

## Building

### Standalone

As seen in "Getting Started", the generator may be built as a standalone customized version of OpenAPI Generator's CLI. This may be the simplest option for developers who are unfamiliar with working in the JVM. Please be aware of any licensing concerns before distributing this "uber-jar".

To build as a standalone, run:

```bash
./gradlew standalone
```

To list generators via OpenAPI Generator CLI:

```bash
java -jar build/libs/{{kebabName}}-openapi-generator-standalone.jar list --include all
```

### ShadowJar

This generator supports building as a lightweight "fat-jar". This option includes Kotlin or any other `implementation` dependencies you'll add. This will simplify publishing if your generator has many dependencies.

To build as a shadowJar, run:

```bash
./gradlew shadowJar
```

To list generators via OpenAPI Generator CLI, you must refer to the CLI jar explicitly. We add a custom copy task which includes the CLI jar in the build output directory:

```bash
java -cp build/libs/openapi-generator-cli-4.1.3.jar:build/libs/{{kebabName}}-openapi-generator-1.0-SNAPSHOT-all.jar org.openapitools.codegen.OpenAPIGenerator list
```

Notice that this command _must_ pass classpath via `-cp` and include OpenAPI Generator CLI as well as the artifact built from this project. Also notice that the manifest class must be passed explicitly as `org.openapitools.codegen.OpenAPIGenerator`.

## See Also

* [Customization docs](https://openapi-generator.tech/docs/customization)
* [Templating docs](https://openapi-generator.tech/docs/templating)
Original file line number Diff line number Diff line change
@@ -0,0 +1,62 @@
import com.github.jengelman.gradle.plugins.shadow.tasks.ShadowJar
import org.jetbrains.kotlin.gradle.tasks.KotlinCompile

plugins {
kotlin("jvm") version "1.3.41"
id("com.github.johnrengelman.shadow") version("5.0.0")
}

group = "org.openapitools"
version = "1.0-SNAPSHOT"

repositories {
mavenLocal()
mavenCentral()
}

dependencies {
val openapiGeneratorVersion = "4.1.3"
implementation(kotlin("stdlib-jdk8"))
implementation("org.openapitools:openapi-generator:$openapiGeneratorVersion")
runtime("org.openapitools:openapi-generator-cli:$openapiGeneratorVersion")
testImplementation("org.junit.jupiter:junit-jupiter:5.5.2")
}

tasks.test {
useJUnitPlatform()
testLogging {
events("passed", "skipped", "failed")
}
}

tasks.register<Copy>("copyToLib") {
from(project.configurations.runtime)
into(File(buildDir, "libs"))
}

tasks.register<ShadowJar>("standalone") {
archiveFileName.set("{{name}}-openapi-generator-standalone.jar")
archiveClassifier.set("all")
from(sourceSets["main"].output)
configurations.add(project.configurations["runtimeClasspath"])
configurations.add(project.configurations["runtime"])
mergeServiceFiles()
manifest.attributes(mapOf("Main-Class" to "org.openapitools.codegen.OpenAPIGenerator"))
}

tasks.withType<KotlinCompile> {
kotlinOptions.jvmTarget = "1.8"
}

tasks.wrapper {
this.distributionType = Wrapper.DistributionType.BIN
}

tasks.named("shadowJar") { dependsOn("copyToLib") }
Loading

0 comments on commit 357f6ca

Please sign in to comment.