Skip to content

[BUG] Gradle Plugin - configOptions unclear / inconsistent #7479

New issue

Have a question about this project? Sign up for a free GitHub account to open an issue and contact its maintainers and the community.

By clicking “Sign up for GitHub”, you agree to our terms of service and privacy statement. We’ll occasionally send you account related emails.

Already on GitHub? Sign in to your account

Closed
black-snow opened this issue Sep 22, 2020 · 9 comments
Closed

[BUG] Gradle Plugin - configOptions unclear / inconsistent #7479

black-snow opened this issue Sep 22, 2020 · 9 comments

Comments

@black-snow
Copy link

Bug Report Checklist

x

Couldn't find a repo for the gradle plugin so I'm posting this here.

Description

The gradle plugin offers some configuration option. But it's not clear what has to go where. The docs have an example:

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"
    ]
}

Why is dateLibrary nested inside configOptions or regardingly, why isn't e.g. invokerPackage within configOptions, too? Both are listed in the same table [1] [2] captioned "config options". So I'd expect all those settings to live within configOptions or none.

openapi-generator version

4.x & 5.0.0-beta2

Suggest a fix

I didn't take a look at the other generators. Maybe I'm just blind and it's stated somewhere.

My first shot to fix this would be to unnest configOptions so that above example becomes:

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"
    ]
    dateLibrary = "java8"
}
@black-snow black-snow changed the title [BUG] Gradle Plugin - configOptions unclear [BUG] Gradle Plugin - configOptions unclear / inconsistent Sep 22, 2020
@skyridertk
Copy link

It's broke. Doesn't work

@jimschubert
Copy link
Member

@black-snow the options you're asking about are different from the example. The example from the gradle plugin that you've shared above is for kotlin which does not have an invokerPackage configuration option and you've linked to Java. Every generator has different available options specific to that generator.

For Java, as for the reason why these exist in both locations is a little more of history from swagger-codegen than anything else. That tool was originally a CLI tool only, so all our generators have a CliOptions list. This allows for the generators to define which options they've exposed to users. We have since worked to clarify our user-facing API to call these configOptions. Java was the first supported languages/generators in swagger-codegen, and they included the CliOption for invoker package at the generator level. Then, I guess they realized this didn't present the option to the user as a "cli option" (so users couldn't pass --invoker-package at the CLI). They then added --invoker-package and a handful of other things at the CLI level. We're stuck with that legacy for now.

All of our plugins and the CLI use the same "configurator" object which maps those CLI top-level properties and configOptions properties in the same way. For a generator like Java which duplicates those top-level CLI options as configOptions, you can apply them in either place. It's not clean and that's why I opened #2556. I've been slowly moving away from these, but we're also bound by existing users and our rule to not introduce breaking changes except for major releases (we've had only 1 major release since our fork's initial release).

@black-snow
Copy link
Author

Thanks for your reply!

For a generator like Java which duplicates those top-level CLI options as configOptions, you can apply them in either place.

No, I can't. When I add any of the options to configOptions the build fails.

The example from the gradle plugin that you've shared above is for kotlin which does not have an invokerPackage configuration option ...

I just copy-pasted the example from the linked docs - I didn't come up with this. I (try to) use it for java and of course my config looks a little different.

This issue will probably resolve with #2556.

@jimschubert
Copy link
Member

@black-snow I don't understand this line:

I just copy-pasted the example from the linked docs - I didn't come up with this. I (try to) use it for java and of course my config looks a little different.

Your comments seem to suggest that you're missing a major point. That is - configOptions for one generator (kotlin in the example) can't be applied or transferred to another (java which are the docs you linked to). If you move the option to configOptions as you suggested that you did with kotlin according to your trial at "unnesting", we would expect things to fail because as I mentioned it's not a valid configOption for the kotlin generator.

To make this example concrete, in relation to the java generator you can compare the following configuration options:

These very clearly document "Config Options" for these different generators, and those documented keys are the only values acceptable in configOptions for each respective generator.

You can directly apply the following diff to this repo's master branch. This moves from kotlin configuration (as used in the gradle documentation) to a java generator (which again is the only one of these two the defines a invokerPackage for config options).

diff --git a/modules/openapi-generator-gradle-plugin/samples/local-spec/build.gradle b/modules/openapi-generator-gradle-plugin/samples/local-spec/build.gradle
index cb99b8838f..1be4c2d8e9 100644
--- a/modules/openapi-generator-gradle-plugin/samples/local-spec/build.gradle
+++ b/modules/openapi-generator-gradle-plugin/samples/local-spec/build.gradle
@@ -33,14 +33,14 @@ openApiValidate {
 
 // Builds a Kotlin client by default.
 openApiGenerate {
-    generatorName = "kotlin"
+    generatorName = "java"
     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"
+    outputDir = "$buildDir/java".toString()
     configOptions = [
-            dateLibrary: "java8"
+            dateLibrary: "java8",
+            invokerPackage: "org.openapitools.example.invoker",
+            modelPackage: "org.openapitools.example.model",
+            apiPackage: "org.openapitools.example.api"
     ]
     globalProperties = [
             modelDocs: "false"

Run gradle openApiGenerate and you will see that files are generated:

image

We use Gradle caching so you may not see the message about generation if you've already generated outputs and the generated files have not changed. You can verify the output of generated contents:

tree build/java
build/java
├── README.md
├── api
│   └── openapi.yaml
├── build.gradle
├── build.sbt
├── docs
│   └── PetsApi.md
├── git_push.sh
├── gradle
│   └── wrapper
│       ├── gradle-wrapper.jar
│       └── gradle-wrapper.properties
├── gradle.properties
├── gradlew
├── gradlew.bat
├── pom.xml
├── settings.gradle
└── src
    ├── main
    │   ├── AndroidManifest.xml
    │   └── java
    │       └── org
    │           └── openapitools
    │               └── example
    │                   ├── api
    │                   │   └── PetsApi.java
    │                   ├── invoker
    │                   │   ├── ApiCallback.java
    │                   │   ├── ApiClient.java
    │                   │   ├── ApiException.java
    │                   │   ├── ApiResponse.java
    │                   │   ├── Configuration.java
    │                   │   ├── GzipRequestInterceptor.java
    │                   │   ├── JSON.java
    │                   │   ├── Pair.java
    │                   │   ├── ProgressRequestBody.java
    │                   │   ├── ProgressResponseBody.java
    │                   │   ├── ServerConfiguration.java
    │                   │   ├── ServerVariable.java
    │                   │   ├── StringUtil.java
    │                   │   └── auth
    │                   │       ├── ApiKeyAuth.java
    │                   │       ├── Authentication.java
    │                   │       ├── HttpBasicAuth.java
    │                   │       └── HttpBearerAuth.java
    │                   └── model
    │                       ├── Error.java
    │                       └── Pet.java
    └── test
        └── java
            └── org
                └── openapitools
                    └── example
                        ├── api
                        │   └── PetsApiTest.java
                        └── model
                            ├── ErrorTest.java
                            └── PetTest.java

21 directories, 37 files

To your point about consistency, kotlin and java do have different configOptions. But, they're different generators. When we remove the "top-level" options such as invokerPackage as I have tracked in #2556, those options will become configOptions in generators which support those options. However, if we were to move them now it will cause the same mess of defining them in multiple places as we have in java. This wouldn't just add confusion to Kotlin but to all JVM based generators. I think the only real inconsistency at the moment is that Java includes those top-level options and that we have to maintain them due to the legacy code. We would need to deprecate these through a full minor release if we wanted to change them.

As for the issues you're having with compilation, again I think you're trying to mix config options documented for the Java generator into the kotlin example and that's just not supported. I don't follow what's unclear about this but we're open to improving the docs to make it more clear if you have any recommendation on how to clarify.

@black-snow
Copy link
Author

I'm not doing anything with kotlin, it's 100% java. All I did was picking the example from the docs.

My config looks like

openApiGenerate {
	generatorName = "java"
	library = "webclient"
	verbose = true
	validateSpec = true
	skipValidateSpec = false
	inputSpec = "$rootDir/src/main/resources/schema_oas3.yaml"
	outputDir = "$rootDir/../api"
	configOptions = [
		dateLibrary: "java8",
		openApiNullable: "true"
	]
	apiPackage = 'a.b.xyz.openapi'
	modelPackage = 'a.b.xyz.openapi.model'
	invokerPackage = 'a.b.xyz.openapi.client'
	groupId = 'a.b'
	id = 'xyz'
	version = '0.1'
}

My point was that it's not clear to me what goes inside configOptions and what not, because openApiNullable is listed at the same level as e.g. apiPackage and not nested inside some configOptions.

@jimschubert
Copy link
Member

@black-snow so the confusion is that the table listed as "Config Options" should go inside configOptions, and is specifically caused by those duplicated properties?

I think clarifying this at the top of these pages would be easy enough, if that is indeed where the confusion lies.

@black-snow
Copy link
Author

Yup. It's initially just unclear that there's language specific stuff and general stuff and what goes where. Your issue about this should mostly fix this, I think.

@jimschubert
Copy link
Member

For those top-level tooling options, it looks like I'll need to deprecate with a warning at the very least through 5.1.0, possibly throughout all of 5.x.

In the meantime, I've added a clarification documentation around the different types of properties. See https://openapi-generator.tech/docs/configuration

@black-snow
Copy link
Author

Awesome. Thanks for your efforts. I'll close this specific issue then.

Sign up for free to join this conversation on GitHub. Already have an account? Sign in to comment
Projects
None yet
Development

No branches or pull requests

3 participants