openapi-generator/modules/openapi-generator-gradle-plugin
Jim Schubert c8cd255ad3
[gradle] Add recommendations to validate task (#5183)
* [gradle] Add recommendations to validate task

* Use current version of Gradle Plugin in build checks.

* Fix gradle project build version confusion in CI

* [gradle] Bump samples to 5.2.1 wrapper

Previously, the Gradle plugin was building in CI against
openapi-generator 4.2.0 and Gradle version 4.10.2. At some point, a
contribution was made with an API which is incomatible at 4.10.2 and due
to a release script error which pinned the local-spec version to release
4.2.0, we didn't notice this inconsistency.

This bumps the project to build against Gradle 5.2.1.
2020-02-01 04:03:34 -05:00
..
gradle/wrapper [gradle] Add recommendations to validate task (#5183) 2020-02-01 04:03:34 -05:00
samples [gradle] Add recommendations to validate task (#5183) 2020-02-01 04:03:34 -05:00
src [gradle] Add recommendations to validate task (#5183) 2020-02-01 04:03:34 -05:00
.gitignore [gradle-plugin] Initial implementation (#162) 2018-05-31 19:23:05 +08:00
build.gradle [gradle] Reorganize build repositories (#5168) 2020-01-30 20:18:39 -05:00
gradle.properties Prepare 4.2.3 release (#5172) 2020-01-31 16:24:06 +08:00
gradlew [gradle-plugin] Initial implementation (#162) 2018-05-31 19:23:05 +08:00
gradlew.bat [gradle-plugin] Initial implementation (#162) 2018-05-31 19:23:05 +08:00
pom.xml [gradle] Add recommendations to validate task (#5183) 2020-02-01 04:03:34 -05:00
README.adoc [gradle] Add recommendations to validate task (#5183) 2020-02-01 04:03:34 -05:00
settings.gradle [gradle] Reworking publishing pipeline (#2886) 2019-05-31 20:43:21 +08:00

= OpenAPI Generator Gradle Plugin

This document describes the gradle plugin for OpenAPI Generator.

This gradle plugin offers a declarative DSL via _extensions_ (these are Gradle project extensions).
These map almost fully 1:1 with the options you'd pass to the CLI or Maven plugin. The plugin maps the extensions to a task of the same name to provide a clean API. If you're interested in the extension/task mapping concept from a high-level, you can https://docs.gradle.org/current/userguide/custom_plugins.html#sec:mapping_extension_properties_to_task_properties[check out Gradle's docs].

== Tasks

Tasks are listed under the "OpenAPI Tools" tasks heading.

.OpenAPI Tools Tasks
|===
|task name |description

|*openApiGenerate*
|Generate code via Open API Tools Generator for Open API 2.0 or 3.x specification documents.

|*openApiGenerators*
|Lists generators available via Open API Generators.

|*openApiMeta*
|Generates a new generator to be consumed via Open API Generator.

|*openApiValidate*
|Validates an Open API 2.0 or 3.x specification document.
|===


[NOTE]
====
The plugin implements the above tasks as project extensions of the same name. If you'd like to declare
these tasks as dependencies to other tasks (using `dependsOn`), you'll need  a task reference. e.g.:

```
compileJava.dependsOn tasks.openApiGenerate
```
====

All extensions can be rewritten as tasks. Where you can have only a single extension defined in your gradle file, you may have multiple tasks.

.One Extension, multiple tasks
[source,groovy]
----
// Validating a single specification
openApiValidate {
    inputSpec = "$rootDir/petstore-v3.0-invalid.yaml".toString()
}

// Define a task for validating one specification
task validateGoodSpec(type: org.openapitools.generator.gradle.plugin.tasks.ValidateTask){
    inputSpec = "$rootDir/petstore-v3.0.yaml".toString()
}

// Define a task for validating another specification
task validateBadSpec(type: org.openapitools.generator.gradle.plugin.tasks.ValidateTask){
    inputSpec = "$rootDir/petstore-v3.0-invalid.yaml".toString()
}

// Define a task for batch validations
task validateSpecs(dependsOn: ['validateGoodSpec', 'validateBadSpec'])
----

== Plugin Setup

//# RELEASE_VERSION

[source,group]
----
plugins {
  id "org.openapi.generator" version "4.2.3"
}
----

Using https://docs.gradle.org/current/userguide/plugins.html#sec:old_plugin_application[legacy plugin application]:

[source,groovy]
----
buildscript {
  repositories {
    mavenLocal()
    maven { url "https://repo1.maven.org/maven2" }
    // or, via Gradle Plugin Portal:
    // url "https://plugins.gradle.org/m2/"
  }
  dependencies {
    classpath "org.openapitools:openapi-generator-gradle-plugin:4.2.3"
  }
}

apply plugin: 'org.openapi.generator'
----
//# /RELEASE_VERSION

== Configuration

=== openApiGenerate

.Options
|===
|Key |Data Type |Default |Description

|verbose
|Boolean
|false
|The verbosity of generation

|validateSpec
|Boolean
|true
|Whether or not we should validate the input spec before generation. Invalid specs result in an error.

|generatorName
|String
|None
|The name of the generator which will handle codegen.

|outputDir
|String
|None
|The output target directory into which code will be generated.

|inputSpec
|String
|None
|The Open API 2.0/3.x specification location.

|templateDir
|String
|None
|The template directory holding a custom template.

|auth
|String
|None
|Adds authorization headers when fetching the OpenAPI definitions remotely. Pass in a URL-encoded string of name:header with a comma separating multiple values.

|systemProperties
|Map(String,String)
|None
|Sets specified system properties.

|configFile
|String
|None
|Path to json configuration file. See OpenAPI Generator readme for structure details.

|skipOverwrite
|Boolean
|false
|Specifies if the existing files should be overwritten during the generation.

|packageName
|String
|(generator specific)
|Package for generated classes (where supported).

|apiPackage
|String
|(generator specific)
|Package for generated api classes.

|modelPackage
|String
|(generator specific)
|Package for generated model classes.

|modelNamePrefix
|String
|None
|Prefix that will be prepended to all model names.

|modelNameSuffix
|String
|None
|Suffix that will be appended to all model names.

|instantiationTypes
|Map(String,String)
|None
|Sets instantiation type mappings.

|typeMappings
|Map(String,String)
|None
|Sets mappings between OpenAPI spec types and generated code types.

|additionalProperties
|Map(String,String)
|None
|Sets additional properties that can be referenced by the mustache templates.

|languageSpecificPrimitives
|List(String)
|None
|Specifies additional language specific primitive types in the format of type1,type2,type3,type3. For example: String,boolean,Boolean,Double.

|importMappings
|Map(String,String)
|None
|Specifies mappings between a given class and the import that should be used for that class.

|invokerPackage
|String
|None
|Root package for generated code.

|groupId
|String
|None
|GroupId in generated pom.xml/build.gradle or other build script. Language-specific conversions occur in non-jvm generators.

|id
|String
|None
|ArtifactId in generated pom.xml/build.gradle or other build script. Language-specific conversions occur in non-jvm generators.

|version
|String
|None
|Artifact version in generated pom.xml/build.gradle or other build script. Language-specific conversions occur in non-jvm generators.

|library
|String
|None
|Reference the library template (sub-template) of a generator.

|gitHost
|String
|github.com
|Git user ID, e.g. gitlab.com.

|gitUserId
|String
|None
|Git user ID, e.g. openapitools.

|gitRepoId
|String
|None
|Git repo ID, e.g. openapi-generator.

|releaseNote
|String
|'Minor update'
|Release note.

|httpUserAgent
|String
|None
|HTTP user agent, e.g. codegen_csharp_api_client. Generator default is 'OpenAPI-Generator/{packageVersion}}/{language}', but may be generator-specific.

|reservedWordsMappings
|Map(String,String)
|None
|Specifies how a reserved name should be escaped to. Otherwise, the default _<name> is used.

|ignoreFileOverride
|String
|None
|Specifies an override location for the .openapi-generator-ignore file. Most useful on initial generation.

|removeOperationIdPrefix
|Boolean
|false
|Remove prefix of operationId, e.g. config_getId => getId.

|apiFilesConstrainedTo
|List(String)
|None
|Defines which API-related files should be generated. This allows you to create a subset of generated files (or none at all). See Note Below.

|modelFilesConstrainedTo
|List(String)
|None
|Defines which model-related files should be generated. This allows you to create a subset of generated files (or none at all). See Note Below.

|supportingFilesConstrainedTo
|List(String)
|None
|Defines which supporting files should be generated. This allows you to create a subset of generated files (or none at all). See Note Below.

|generateModelTests
|Boolean
|true
|Defines whether or not model-related _test_ files should be generated.

|generateModelDocumentation
|Boolean
|true
|Defines whether or not model-related _documentation_ files should be generated.

|generateApiTests
|Boolean
|true
|Defines whether or not api-related _test_ files should be generated.

|generateApiDocumentation
|Boolean
|true
|Defines whether or not api-related _documentation_ files should be generated.

|withXml
|Boolean
|false
|A special-case setting which configures some generators with XML support. In some cases, this forces json OR xml, so the default here is false.

|configOptions
|Map(String,String)
|None
|A map of options specific to a generator. To see the full list of generator-specified parameters, please refer to [generators docs](https://github.com/OpenAPITools/openapi-generator/blob/master/docs/generators.md)

|logToStderr
|Boolean
|false
|To write all log messages (not just errors) to STDOUT

|enablePostProcessFile
|Boolean
|false
|To enable the file post-processing hook. This enables executing an external post-processor (usually a linter program). This only enables the post-processor. To define the post-processing command, define an environment variable such as LANG_POST_PROCESS_FILE (e.g. GO_POST_PROCESS_FILE, SCALA_POST_PROCESS_FILE). Please open an issue if your target generator does not support this functionality.

|skipValidateSpec
|Boolean
|false
|To skip spec validation. When true, we will skip the default behavior of validating a spec before generation.

|generateAliasAsModel
|Boolean
|false
|To generate alias (array, list, map) as model. When false, top-level objects defined as array, list, or map will result in those definitions generated as top-level Array-of-items, List-of-items, Map-of-items definitions. When true, A model representation either containing or extending the array,list,map (depending on specific generator implementation) will be generated.

|===

[NOTE]
====
Configuring any one of `apiFilesConstrainedTo`, `modelFilesConstrainedTo`, or `supportingFilesConstrainedTo` results
in others being disabled. That is, OpenAPI Generator considers any one of these to define a subset of generation.

For more control over generation of individual files, configure an ignore file and refer to it via `ignoreFileOverride`.
====

[NOTE]
====
When configuring `systemProperties` in order to perform selective generation you can disable generation of some parts by providing `"false"` value:
[source,groovy]
----
openApiGenerate {
    // other settings omitted
    systemProperties = [
        modelDocs: "false",
        apis: "false"
    ]
}
----
When enabling generation of only specific parts you either have to provide CSV list of what you particularly are generating or provide an empty string `""` to generate everything. If you provide `"true"` it will be treated as a specific name of model or api you want to generate.
[source,groovy]
----
openApiGenerate {
    // other settings omitted
    systemProperties = [
        apis: "",
        models: "User,Pet"
    ]
}
----
====

=== openApiValidate

.Options
|===
|Key |Data Type |Default |Description

|inputSpec
|String
|None
|The input specification to validate. Supports all formats supported by the Parser.

|recommend
|Boolean
|true
|Whether or not to offer recommendations related to the validated specification document.

|===

=== openApiMeta

.Options
|===
|Key |Data Type |Default |Description

|generatorName
|String
|None
|The human-readable generator name of the newly created template generator.

|packageName
|String
|org.openapitools.codegen
|The packageName generatorName to put the main class into.

|outputFolder
|String
|Current Directory
|Where to write the generated files

|===

=== openApiGenerators

.Options
|===
|Key |Data Type |Default |Description

|include
|String[]
|None
|A list of stability indexes to include (values: all,beta,stable,experimental,deprecated). Excludes deprecated by default.

|===

== Examples

=== openApiGenerate

This task exposes all options available via OpenAPI Generator CLI and the OpenAPI Generator Maven Plugin.

.in build.gradle
[source,groovy]
----
openApiGenerate {
    generatorName = "kotlin"
    inputSpec = "$rootDir/specs/petstore-v3.0.yaml".toString()
    outputDir = "$buildDir/generated".toString()
    apiPackage = "org.openapi.example.api"
    invokerPackage = "org.openapi.example.invoker"
    modelPackage = "org.openapi.example.model"
    modelFilesConstrainedTo = [
            "Error"
    ]
    configOptions = [
        dateLibrary: "java8"
    ]
}
----

The above code demonstrates configuration of global options as well as generator-specific config options.

=== openApiGenerators

This is an output-only listing task. There's no need to add configuration to build.gradle.

.Example output of openApiGenerators task
[source,terminal]
----
$ ./gradlew openApiGenerators

> Task :openApiGenerators
The following generators are available:

CLIENT generators:
    - ada
…

SERVER generators:
    - ada-server
…

DOCUMENTATION generators:
    - cwiki
…

CONFIG generators:
    - apache2

OTHER generators:
…

BUILD SUCCESSFUL in 0s
1 actionable task: 1 executed
----

[NOTE]
====
Generator type listings in the above example have been truncated to avoid potential confusion with changing generator support.

Please run the above task to list all available generators.
====

=== openApiMeta

.in build.gradle
[source,groovy]
----
openApiMeta {
   generatorName = "Jim"
   packageName = "us.jimschubert.example"
}
----

.Example output of openApiMeta task
[source,terminal]
----
$ ./gradlew openApiMeta

> Task :openApiMeta
Wrote file to /Users/jim/my_project/pom.xml
Wrote file to /Users/jim/my_project/src/main/java/us/jimschubert/example/JimGenerator.java
Wrote file to /Users/jim/my_project/README.md
Wrote file to /Users/jim/my_project/src/main/resources/jim/api.mustache
Wrote file to /Users/jim/my_project/src/main/resources/jim/model.mustache
Wrote file to /Users/jim/my_project/src/main/resources/jim/myFile.mustache
Wrote file to /Users/jim/my_project/src/main/resources/META-INF/services/org.openapitools.codegen.CodegenConfig
Created generator JimGenerator

BUILD SUCCESSFUL in 0s
1 actionable task: 1 executed
----


=== openApiValidate

.in buid.gradle
[source,groovy]
----
openApiValidate {
   inputSpec = "/src/openapi-generator/modules/openapi-generator/src/test/resources/3_0/petstore.yaml"
   recommend = true
}
----

.Example output of openApiValidate task (success)
[source,terminal]
----
$ ./gradlew openApiValidate --input=/Users/jim/projects/openapi-generator/modules/openapi-generator/src/test/resources/3_0/ping.yaml

> Task :openApiValidate
Validating spec /Users/jim/projects/openapi-generator/modules/openapi-generator/src/test/resources/3_0/ping.yaml
Spec is valid.

BUILD SUCCESSFUL in 0s
1 actionable task: 1 executed
----

.Example output of openApiValidate task (failure)
[source,terminal]
----
$ ./gradlew openApiValidate

> Task :openApiValidate FAILED
Validating spec /Users/jim/projects/openapi-generator/modules/openapi-generator/src/test/resources/3_0/petstore.yaml

Spec is invalid.
Issues:

        attribute info is missing


FAILURE: Build failed with an exception.

* What went wrong:
Execution failed for task ':openApiValidate'.
> Validation failed.

* Try:
Run with --stacktrace option to get the stack trace. Run with --info or --debug option to get more log output. Run with --scan to get full insights.

* Get more help at https://help.gradle.org

----

.in terminal (alternate)
[source,terminal]
----
$ ./gradlew openApiValidate --input=/Users/jim/projects/openapi-generator/modules/openapi-generator/src/test/resources/3_0/petstore.yaml
----

=== Generate multiple sources

If you want to perform multiple generation tasks, you'd want to create a task that inherits from the `GenerateTask`.
Examples can be found in https://github.com/OpenAPITools/openapi-generator/blob/master/modules/openapi-generator-gradle-plugin/samples/local-spec/build.gradle[samples/local-spec/build.gradle].

You can define any number of generator tasks; the generated code does _not_ need to be a JVM language.

```gradle
task buildGoClient(type: org.openapitools.generator.gradle.plugin.tasks.GenerateTask){
    generatorName = "go"
    inputSpec = "$rootDir/petstore-v3.0.yaml".toString()
    additionalProperties = [
            packageName: "petstore"
    ]
    outputDir = "$buildDir/go".toString()
    configOptions = [
            dateLibrary: "threetenp"
    ]
}
task buildKotlinClient(type: org.openapitools.generator.gradle.plugin.tasks.GenerateTask){
    generatorName = "kotlin"
    inputSpec = "$rootDir/petstore-v3.0.yaml".toString()
    outputDir = "$buildDir/kotlin".toString()
    apiPackage = "org.openapitools.example.api"
    invokerPackage = "org.openapitools.example.invoker"
    modelPackage = "org.openapitools.example.model"
    configOptions = [
            dateLibrary: "java8"
    ]
    systemProperties = [
            modelDocs: "false"
    ]
}
```

To execute your specs, you'd then do:

```
./gradlew buildGoClient buildKotlinClient
```

If you want to simplify the execution, you could create a new task with `dependsOn`.

```gradle
task codegen(dependsOn: ['buildGoClient', 'buildKotlinClient'])
```

Or, if you're generating the code on compile, you can add these as a dependency to `compileJava` or any other existing task.
You can also mix the default task `openApiGenerate` with custom tasks:

```gradle
compileJava.dependsOn buildKotlinClient, tasks.openApiGenerate
```

[NOTE]
====
`openApiGenerate` is a project extension _and_ a task. If you want to use this in `dependsOn`,
you need a task reference or instance. One way to do this is to access it as `tasks.openApiGenerate`.

You can run `gradle tasks --debug` to see this registration.
====

== Troubleshooting

=== Android Studio

Android Studio may experience a Windows-specific Guava dependency conflict with openapig-enerator-gradle-plugin versions greater than 3.0.0.

As a workaround, you may force exclude conflicting Guava dependencies.

//# RELEASE_VERSION
```gradle
buildscript {
    repositories {
        google()
        jcenter()
    }
    dependencies {
        classpath 'com.android.tools.build:gradle:3.2.1'
        classpath('org.openapitools:openapi-generator-gradle-plugin:4.2.3') {
            exclude group: 'com.google.guava'
        }
    }
}
// …

configurations {
    compile.exclude module: 'guava-jdk5'
}
// …
apply plugin: 'org.openapi.generator'
```
//# /RELEASE_VERSION

See https://github.com/OpenAPITools/openapi-generator/issues/1818[OpenAPITools/openapi-generator#1818] for more details.