Skip to content

Commit 77df3d6

Browse files
jimschubertwing328
authored andcommitted
Validate spec on generation by default (#251)
* Validate spec on generation by default Adds a validation parameter to CodegenConfigurator, and passes through options from CLI, Maven Plugin and Gradle Plugin to that property. Default is to validate the spec during generation. If spec has errors, we will output errors as well as warnings to the user. Option can be disabled by passing false to validateSpec (Maven/Gradle) or --validate-spec (CLI). * Prepare version 3.1.1-SNAPSHOT * fix version * Use last prod version for the sample * Update README.md Fix * [cli] Option parser does not support true/false for boolean options
1 parent a8e8ace commit 77df3d6

File tree

17 files changed

+391
-15
lines changed

17 files changed

+391
-15
lines changed

modules/openapi-generator-cli/src/main/java/org/openapitools/codegen/cmd/ConfigHelp.java

Lines changed: 1 addition & 1 deletion
Original file line numberDiff line numberDiff line change
@@ -72,4 +72,4 @@ public void run() {
7272
System.exit(1);
7373
}
7474
}
75-
}
75+
}

modules/openapi-generator-cli/src/main/java/org/openapitools/codegen/cmd/Generate.java

Lines changed: 9 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -194,6 +194,11 @@ public class Generate implements Runnable {
194194
description = CodegenConstants.REMOVE_OPERATION_ID_PREFIX_DESC)
195195
private Boolean removeOperationIdPrefix;
196196

197+
@Option(name = {"--skip-validate-spec"},
198+
title = "skip spec validation",
199+
description = "Skips the default behavior of validating an input specification.")
200+
private Boolean skipValidateSpec;
201+
197202
@Override
198203
public void run() {
199204

@@ -207,6 +212,10 @@ public void run() {
207212
}
208213

209214
// now override with any specified parameters
215+
if (skipValidateSpec != null) {
216+
configurator.setValidateSpec(false);
217+
}
218+
210219
if (verbose != null) {
211220
configurator.setVerbose(verbose);
212221
}

modules/openapi-generator-gradle-plugin/README.adoc

Lines changed: 5 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -59,6 +59,11 @@ The gradle plugin is not currently published to https://plugins.gradle.org/m2/.
5959
|false
6060
|The verbosity of generation
6161

62+
|validateSpec
63+
|Boolean
64+
|true
65+
|Whether or not we should validate the input spec before generation. Invalid specs result in an error.
66+
6267
|generatorName
6368
|String
6469
|None

modules/openapi-generator-gradle-plugin/samples/local-spec/README.md

Lines changed: 1 addition & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -11,6 +11,7 @@ gradle openApiGenerate
1111
gradle openApiMeta
1212
gradle openApiValidate
1313
gradle buildGoSdk
14+
gradle generateGoWithInvalidSpec
1415
```
1516

1617
The samples can be tested against other versions of the plugin using the `openApiGeneratorVersion` property. For example:

modules/openapi-generator-gradle-plugin/samples/local-spec/build.gradle

Lines changed: 13 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -54,3 +54,16 @@ task buildGoSdk(type: org.openapitools.generator.gradle.plugin.tasks.GenerateTas
5454
dateLibrary: "threetenp"
5555
]
5656
}
57+
58+
task generateGoWithInvalidSpec(type: org.openapitools.generator.gradle.plugin.tasks.GenerateTask){
59+
validateSpec = true
60+
generatorName = "go"
61+
inputSpec = "$rootDir/petstore-v3.0-invalid.yaml".toString()
62+
additionalProperties = [
63+
packageName: "petstore"
64+
]
65+
outputDir = "$buildDir/go".toString()
66+
configOptions = [
67+
dateLibrary: "threetenp"
68+
]
69+
}

modules/openapi-generator-gradle-plugin/src/main/kotlin/org/openapitools/generator/gradle/plugin/OpenApiGeneratorPlugin.kt

Lines changed: 1 addition & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -80,6 +80,7 @@ class OpenApiGeneratorPlugin : Plugin<Project> {
8080
description = "Generate code via Open API Tools Generator for Open API 2.0 or 3.x specification documents."
8181

8282
verbose.set(generate.verbose)
83+
validateSpec.set(generate.validateSpec)
8384
generatorName.set(generate.generatorName)
8485
outputDir.set(generate.outputDir)
8586
inputSpec.set(generate.inputSpec)

modules/openapi-generator-gradle-plugin/src/main/kotlin/org/openapitools/generator/gradle/plugin/extensions/OpenApiGeneratorGenerateExtension.kt

Lines changed: 11 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -32,6 +32,11 @@ open class OpenApiGeneratorGenerateExtension(project: Project) {
3232
*/
3333
val verbose = project.objects.property<Boolean>()
3434

35+
/**
36+
* Whether or not an input specification should be validated upon generation.
37+
*/
38+
val validateSpec = project.objects.property<Boolean>()
39+
3540
/**
3641
* The name of the generator which will handle codegen. (see "openApiGenerators" task)
3742
*/
@@ -262,6 +267,11 @@ open class OpenApiGeneratorGenerateExtension(project: Project) {
262267
val configOptions = project.objects.property<Map<String, String>>()
263268

264269
init {
270+
applyDefaults()
271+
}
272+
273+
@Suppress("MemberVisibilityCanBePrivate")
274+
fun applyDefaults(){
265275
releaseNote.set("Minor update")
266276
modelNamePrefix.set("")
267277
modelNameSuffix.set("")
@@ -271,5 +281,6 @@ open class OpenApiGeneratorGenerateExtension(project: Project) {
271281
generateApiDocumentation.set(true)
272282
withXml.set(false)
273283
configOptions.set(mapOf())
284+
validateSpec.set(true)
274285
}
275286
}

modules/openapi-generator-gradle-plugin/src/main/kotlin/org/openapitools/generator/gradle/plugin/tasks/GenerateTask.kt

Lines changed: 11 additions & 3 deletions
Original file line numberDiff line numberDiff line change
@@ -28,7 +28,6 @@ import org.gradle.kotlin.dsl.property
2828
import org.openapitools.codegen.CodegenConstants
2929
import org.openapitools.codegen.DefaultGenerator
3030
import org.openapitools.codegen.config.CodegenConfigurator
31-
import org.openapitools.codegen.config.CodegenConfiguratorUtils.*
3231

3332

3433
/**
@@ -48,6 +47,12 @@ open class GenerateTask : DefaultTask() {
4847
@get:Internal
4948
val verbose = project.objects.property<Boolean>()
5049

50+
/**
51+
* Whether or not an input specification should be validated upon generation.
52+
*/
53+
@get:Internal
54+
val validateSpec = project.objects.property<Boolean>()
55+
5156
/**
5257
* The name of the generator which will handle codegen. (see "openApiGenerators" task)
5358
*/
@@ -382,6 +387,10 @@ open class GenerateTask : DefaultTask() {
382387
configurator.isVerbose = value
383388
}
384389

390+
validateSpec.ifNotEmpty { value ->
391+
configurator.isValidateSpec = value
392+
}
393+
385394
skipOverwrite.ifNotEmpty { value ->
386395
configurator.isSkipOverwrite = value ?: false
387396
}
@@ -528,8 +537,7 @@ open class GenerateTask : DefaultTask() {
528537

529538
out.println("Successfully generated code to ${configurator.outputDir}")
530539
} catch (e: RuntimeException) {
531-
logger.error(e.message)
532-
throw GradleException("Code generation failed.")
540+
throw GradleException("Code generation failed.", e)
533541
}
534542
} finally {
535543
originalEnvironmentVariables.forEach { entry ->

modules/openapi-generator-gradle-plugin/src/test/kotlin/GenerateTaskDslTest.kt

Lines changed: 1 addition & 1 deletion
Original file line numberDiff line numberDiff line change
@@ -31,7 +31,7 @@ class GenerateTaskDslTest : TestBase() {
3131
fun `openApiGenerate should create an expected file structure from DSL config`() {
3232
// Arrange
3333
val projectFiles = mapOf(
34-
"spec.yaml" to javaClass.classLoader.getResourceAsStream("specs/petstore-v3.0-invalid.yaml")
34+
"spec.yaml" to javaClass.classLoader.getResourceAsStream("specs/petstore-v3.0.yaml")
3535
)
3636
withProject(defaultBuildGradle, projectFiles)
3737

modules/openapi-generator-maven-plugin/README.md

Lines changed: 6 additions & 1 deletion
Original file line numberDiff line numberDiff line change
@@ -38,6 +38,7 @@ mvn clean compile
3838
### General Configuration parameters
3939

4040
- `inputSpec` - OpenAPI Spec file path
41+
- `validateSpec` - Whether or not to validate the input spec prior to generation. Invalid specifications will result in an error.
4142
- `language` - target generation language (deprecated, replaced by `generatorName` as values here don't represent only 'language' any longer)
4243
- `generatorName` - target generator name
4344
- `output` - target output path (default is `${project.build.directory}/generated-sources/swagger`)
@@ -102,4 +103,8 @@ Specifying a custom generator is a bit different. It doesn't support the classpa
102103

103104
### Sample configuration
104105

105-
- Please see [an example configuration](examples) for using the plugin
106+
Please see [an example configuration](examples) for using the plugin. To run these examples, explicitly pass the file to maven. Example:
107+
108+
```bash
109+
mvn -f non-java.xml compile
110+
```

modules/openapi-generator-maven-plugin/examples/java-client.xml

Lines changed: 1 addition & 1 deletion
Original file line numberDiff line numberDiff line change
@@ -12,7 +12,7 @@
1212
<plugin>
1313
<groupId>org.openapitools</groupId>
1414
<artifactId>openapi-generator-maven-plugin</artifactId>
15-
<version>3.0.1-SNAPSHOT</version>
15+
<version>3.1.1-SNAPSHOT</version>
1616
<executions>
1717
<execution>
1818
<goals>
Lines changed: 34 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -0,0 +1,34 @@
1+
<project xmlns="http://maven.apache.org/POM/4.0.0" xmlns:xsi="http://www.w3.org/2001/XMLSchema-instance" xsi:schemaLocation="http://maven.apache.org/POM/4.0.0 http://maven.apache.org/maven-v4_0_0.xsd">
2+
<modelVersion>4.0.0</modelVersion>
3+
<groupId>org.openapitools</groupId>
4+
<artifactId>sample-project</artifactId>
5+
<packaging>jar</packaging>
6+
<version>1.0-SNAPSHOT</version>
7+
<name>sample-project</name>
8+
<url>http://maven.apache.org</url>
9+
<build>
10+
<plugins>
11+
<!-- activate the plugin -->
12+
<plugin>
13+
<groupId>org.openapitools</groupId>
14+
<artifactId>openapi-generator-maven-plugin</artifactId>
15+
<version>3.1.1-SNAPSHOT</version>
16+
<executions>
17+
<execution>
18+
<goals>
19+
<goal>generate</goal>
20+
</goals>
21+
<configuration>
22+
<validateSpec>false</validateSpec>
23+
<inputSpec>petstore-v3.0-invalid.yaml</inputSpec>
24+
<generatorName>aspnetcore</generatorName>
25+
<configOptions>
26+
<additional-properties>optionalProjectFile=true</additional-properties>
27+
</configOptions>
28+
</configuration>
29+
</execution>
30+
</executions>
31+
</plugin>
32+
</plugins>
33+
</build>
34+
</project>

modules/openapi-generator-maven-plugin/examples/non-java.xml

Lines changed: 1 addition & 1 deletion
Original file line numberDiff line numberDiff line change
@@ -12,7 +12,7 @@
1212
<plugin>
1313
<groupId>org.openapitools</groupId>
1414
<artifactId>openapi-generator-maven-plugin</artifactId>
15-
<version>3.0.1-SNAPSHOT</version>
15+
<version>3.1.1-SNAPSHOT</version>
1616
<executions>
1717
<execution>
1818
<goals>
Lines changed: 103 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -0,0 +1,103 @@
1+
openapi: "3.0.0"
2+
servers:
3+
- url: http://petstore.swagger.io/v1
4+
paths:
5+
/pets:
6+
get:
7+
summary: List all pets
8+
operationId: listPets
9+
tags:
10+
- pets
11+
parameters:
12+
- name: limit
13+
in: query
14+
description: How many items to return at one time (max 100)
15+
required: false
16+
schema:
17+
type: integer
18+
format: int32
19+
responses:
20+
'200':
21+
description: A paged array of pets
22+
headers:
23+
x-next:
24+
description: A link to the next page of responses
25+
schema:
26+
type: string
27+
content:
28+
application/json:
29+
schema:
30+
$ref: "#/components/schemas/Pets"
31+
default:
32+
description: unexpected error
33+
content:
34+
application/json:
35+
schema:
36+
$ref: "#/components/schemas/Error"
37+
post:
38+
summary: Create a pet
39+
tags:
40+
- pets
41+
responses:
42+
'201':
43+
description: Null response
44+
default:
45+
description: unexpected error
46+
content:
47+
application/json:
48+
schema:
49+
$ref: "#/components/schemas/Error"
50+
/pets/{petId}:
51+
get:
52+
summary: Info for a specific pet
53+
operationId: showPetById
54+
tags:
55+
- pets
56+
parameters:
57+
- name: petId
58+
in: path
59+
required: true
60+
description: The id of the pet to retrieve
61+
schema:
62+
type: string
63+
responses:
64+
'200':
65+
description: Expected response to a valid request
66+
content:
67+
application/json:
68+
schema:
69+
$ref: "#/components/schemas/Pets"
70+
default:
71+
description: unexpected error
72+
content:
73+
application/json:
74+
schema:
75+
$ref: "#/components/schemas/Error"
76+
components:
77+
schemas:
78+
Pet:
79+
required:
80+
- id
81+
- name
82+
properties:
83+
id:
84+
type: integer
85+
format: int64
86+
name:
87+
type: string
88+
tag:
89+
type: string
90+
Pets:
91+
type: array
92+
items:
93+
$ref: "#/components/schemas/Pet"
94+
Error:
95+
required:
96+
- code
97+
- message
98+
properties:
99+
code:
100+
type: integer
101+
format: int32
102+
message:
103+
type: string

modules/openapi-generator-maven-plugin/src/main/java/org/openapitools/codegen/plugin/CodeGenMojo.java

Lines changed: 8 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -60,6 +60,9 @@ public class CodeGenMojo extends AbstractMojo {
6060

6161
private static final Logger LOGGER = LoggerFactory.getLogger(CodeGenMojo.class);
6262

63+
@Parameter(name="validateSpec", required = false, defaultValue = "true")
64+
private Boolean validateSpec;
65+
6366
@Parameter(name = "verbose", required = false, defaultValue = "false")
6467
private boolean verbose;
6568

@@ -348,6 +351,11 @@ public void execute() throws MojoExecutionException {
348351

349352
configurator.setVerbose(verbose);
350353

354+
// now override with any specified parameters
355+
if (validateSpec != null) {
356+
configurator.setValidateSpec(validateSpec);
357+
}
358+
351359
if (skipOverwrite != null) {
352360
configurator.setSkipOverwrite(skipOverwrite);
353361
}

0 commit comments

Comments
 (0)