mirror of
https://github.com/OpenAPITools/openapi-generator.git
synced 2025-12-09 11:56:10 +00:00
[all] Adds strict spec option (#2783)
* [all] Adds strict spec option Introduces an option to allow user customization of strict specification behaviors. For instance, OpenAPI 3.x requires a path object name to be prefixed with '/' so we append any missing '/', but this may not be desirable to some users or generators. In this commit, this fix specifically is the only modification affected. * Clarify strict-spec docs, add option to README.md * Update CLI options in docs/usage.md
This commit is contained in:
@@ -447,6 +447,7 @@ SYNOPSIS
|
||||
[--remove-operation-id-prefix]
|
||||
[--reserved-words-mappings <reserved word mappings>...]
|
||||
[(-s | --skip-overwrite)] [--skip-validate-spec]
|
||||
[--strict-spec <true/false strict behavior>]
|
||||
[(-t <template directory> | --template-dir <template directory>)]
|
||||
[--type-mappings <type mappings>...] [(-v | --verbose)]
|
||||
|
||||
|
||||
@@ -239,7 +239,9 @@ SYNOPSIS
|
||||
[--api-package <api package>] [--artifact-id <artifact id>]
|
||||
[--artifact-version <artifact version>]
|
||||
[(-c <configuration file> | --config <configuration file>)]
|
||||
[-D <system properties>...] [--enable-post-process-file]
|
||||
[-D <system properties>...]
|
||||
[(-e <templating engine> | --engine <templating engine>)]
|
||||
[--enable-post-process-file]
|
||||
[(-g <generator name> | --generator-name <generator name>)]
|
||||
[--generate-alias-as-model] [--git-repo-id <git repo id>]
|
||||
[--git-user-id <git user id>] [--group-id <group id>]
|
||||
@@ -259,6 +261,7 @@ SYNOPSIS
|
||||
[--remove-operation-id-prefix]
|
||||
[--reserved-words-mappings <reserved word mappings>...]
|
||||
[(-s | --skip-overwrite)] [--skip-validate-spec]
|
||||
[--strict-spec <true/false strict behavior>]
|
||||
[(-t <template directory> | --template-dir <template directory>)]
|
||||
[--type-mappings <type mappings>...] [(-v | --verbose)]
|
||||
|
||||
@@ -289,9 +292,11 @@ OPTIONS
|
||||
artifact version in generated pom.xml
|
||||
|
||||
-c <configuration file>, --config <configuration file>
|
||||
Path to json configuration file. File content should be in a json
|
||||
format {"optionKey":"optionValue", "optionKey1":"optionValue1"...}
|
||||
Supported options can be different for each language. Run
|
||||
Path to configuration file configuration file. It can be json or
|
||||
yaml.If file is json, the content should have the format
|
||||
{"optionKey":"optionValue", "optionKey1":"optionValue1"...}.If file
|
||||
is yaml, the content should have the format optionKey:
|
||||
optionValueSupported options can be different for each language. Run
|
||||
config-help -g {generator name} command for language specific config
|
||||
options.
|
||||
|
||||
@@ -299,11 +304,17 @@ OPTIONS
|
||||
sets specified system properties in the format of
|
||||
name=value,name=value (or multiple options, each with name=value)
|
||||
|
||||
-e <templating engine>, --engine <templating engine>
|
||||
templating engine: "mustache" (default) or "handlebars" (beta)
|
||||
|
||||
--enable-post-process-file
|
||||
enablePostProcessFile
|
||||
|
||||
-g <generator name>, --generator-name <generator name>
|
||||
generator to use (see langs command for list)
|
||||
generator to use (see list command for list)
|
||||
|
||||
--generate-alias-as-model
|
||||
Generate alias to map, array as models
|
||||
|
||||
--git-repo-id <git repo id>
|
||||
Git repo ID, e.g. openapi-generator.
|
||||
@@ -354,6 +365,9 @@ OPTIONS
|
||||
piping the JSON output of debug options (e.g. `-DdebugOperations`)
|
||||
to an external parser directly while testing a generator.
|
||||
|
||||
--minimal-update
|
||||
Only write output files that have changed.
|
||||
|
||||
--model-name-prefix <model name prefix>
|
||||
Prefix that will be prepended to all model names. Default is the
|
||||
empty string.
|
||||
@@ -368,6 +382,9 @@ OPTIONS
|
||||
-o <output directory>, --output <output directory>
|
||||
where to write the generated files (current dir by default)
|
||||
|
||||
--package-name <package name>
|
||||
package for generated classes (where supported)
|
||||
|
||||
--release-note <release note>
|
||||
Release note, default to 'Minor update'.
|
||||
|
||||
@@ -386,12 +403,17 @@ OPTIONS
|
||||
--skip-validate-spec
|
||||
Skips the default behavior of validating an input specification.
|
||||
|
||||
--strict-spec <true/false strict behavior>
|
||||
'MUST' and 'SHALL' wording in OpenAPI spec is strictly adhered to.
|
||||
e.g. when false, no fixes will be applied to documents which pass
|
||||
validation but don't follow the spec.
|
||||
|
||||
-t <template directory>, --template-dir <template directory>
|
||||
folder containing the template files
|
||||
|
||||
--type-mappings <type mappings>
|
||||
sets mappings between OpenAPI spec types and generated code types in
|
||||
the format of OpenaAPIType=generatedType,OpenAPIType=generatedType.
|
||||
the format of OpenAPIType=generatedType,OpenAPIType=generatedType.
|
||||
For example: array=List,map=Map,string=String. You can also have
|
||||
multiple occurrences of this option.
|
||||
|
||||
|
||||
@@ -214,6 +214,12 @@ public class Generate implements Runnable {
|
||||
description = "Skips the default behavior of validating an input specification.")
|
||||
private Boolean skipValidateSpec;
|
||||
|
||||
@Option(name = {"--strict-spec"},
|
||||
title = "true/false strict behavior",
|
||||
description = "'MUST' and 'SHALL' wording in OpenAPI spec is strictly adhered to. e.g. when false, no fixes will be applied to documents which pass validation but don't follow the spec.",
|
||||
arity = 1)
|
||||
private Boolean strictSpecBehavior;
|
||||
|
||||
@Option(name = {"--log-to-stderr"},
|
||||
title = "Log to STDERR",
|
||||
description = "write all log messages (not just errors) to STDOUT."
|
||||
@@ -368,10 +374,15 @@ public class Generate implements Runnable {
|
||||
if (generateAliasAsModel != null) {
|
||||
configurator.setGenerateAliasAsModel(generateAliasAsModel);
|
||||
}
|
||||
|
||||
if (minimalUpdate != null) {
|
||||
configurator.setEnableMinimalUpdate(minimalUpdate);
|
||||
}
|
||||
|
||||
if (strictSpecBehavior != null) {
|
||||
configurator.setStrictSpecBehavior(strictSpecBehavior);
|
||||
}
|
||||
|
||||
applySystemPropertiesKvpList(systemProperties, configurator);
|
||||
applyInstantiationTypesKvpList(instantiationTypes, configurator);
|
||||
applyImportMappingsKvpList(importMappings, configurator);
|
||||
|
||||
@@ -277,6 +277,26 @@ public class GenerateTest {
|
||||
};
|
||||
}
|
||||
|
||||
@Test
|
||||
public void testStrictSpec() throws Exception {
|
||||
|
||||
setupAndRunGenericTest("--strict-spec", "true");
|
||||
new FullVerifications() {
|
||||
{
|
||||
configurator.setStrictSpecBehavior(true);
|
||||
times = 1;
|
||||
}
|
||||
};
|
||||
|
||||
setupAndRunGenericTest("--strict-spec", "false");
|
||||
new FullVerifications() {
|
||||
{
|
||||
configurator.setStrictSpecBehavior(false);
|
||||
times = 1;
|
||||
}
|
||||
};
|
||||
}
|
||||
|
||||
@Test
|
||||
public void testPackageName() throws Exception {
|
||||
final String value = "io.foo.bar.baz";
|
||||
|
||||
@@ -57,6 +57,7 @@ mvn clean compile
|
||||
- `logToStderr` - write all log messages (not just errors) to STDOUT
|
||||
- `enablePostProcessFile` - enable file post-processing hook
|
||||
- `skipValidateSpec` - Whether or not to skip validating the input spec prior to generation. By default, invalid specifications will result in an error.
|
||||
- `strictSpec` - Whether or not to treat an input document strictly against the spec. 'MUST' and 'SHALL' wording in OpenAPI spec is strictly adhered to. e.g. when false, no fixes will be applied to documents which pass validation but don't follow the spec.
|
||||
- `generateAliasAsModel` - generate alias (array, map) as model
|
||||
- `generateApis` - generate the apis (`true` by default)
|
||||
- `generateApiTests` - generate the api tests (`true` by default. Only available if `generateApis` is `true`)
|
||||
|
||||
@@ -235,6 +235,12 @@ public class CodeGenMojo extends AbstractMojo {
|
||||
@Parameter(name = "skipValidateSpec", required = false)
|
||||
private Boolean skipValidateSpec;
|
||||
|
||||
/**
|
||||
* To treat a document strictly against the spec.
|
||||
*/
|
||||
@Parameter(name = "strictSpec", required = false)
|
||||
private Boolean strictSpecBehavior;
|
||||
|
||||
/**
|
||||
* To generate alias (array, map) as model
|
||||
*/
|
||||
@@ -459,6 +465,10 @@ public class CodeGenMojo extends AbstractMojo {
|
||||
configurator.setValidateSpec(!skipValidateSpec);
|
||||
}
|
||||
|
||||
if (strictSpecBehavior != null) {
|
||||
configurator.setStrictSpecBehavior(strictSpecBehavior);
|
||||
}
|
||||
|
||||
if (logToStderr != null) {
|
||||
configurator.setLogToStderr(logToStderr);
|
||||
}
|
||||
|
||||
@@ -270,4 +270,8 @@ public interface CodegenConfig {
|
||||
public boolean isEnableMinimalUpdate();
|
||||
|
||||
public void setEnableMinimalUpdate(boolean isEnableMinimalUpdate);
|
||||
|
||||
boolean isStrictSpecBehavior();
|
||||
|
||||
void setStrictSpecBehavior(boolean strictSpecBehavior);
|
||||
}
|
||||
|
||||
@@ -118,6 +118,9 @@ public class DefaultCodegen implements CodegenConfig {
|
||||
// flag to indicate whether to only update files whose contents have changed
|
||||
protected boolean enableMinimalUpdate = false;
|
||||
|
||||
// acts strictly upon a spec, potentially modifying it to have consistent behavior across generators.
|
||||
protected boolean strictSpecBehavior = true;
|
||||
|
||||
// make openapi available to all methods
|
||||
protected OpenAPI openAPI;
|
||||
|
||||
@@ -2387,11 +2390,13 @@ public class DefaultCodegen implements CodegenConfig {
|
||||
}
|
||||
operationId = removeNonNameElementToCamelCase(operationId);
|
||||
|
||||
if (path.startsWith("/")) {
|
||||
op.path = path;
|
||||
} else {
|
||||
if (isStrictSpecBehavior() && !path.startsWith("/")) {
|
||||
// modifies an operation.path to strictly conform to OpenAPI Spec
|
||||
op.path = "/" + path;
|
||||
} else {
|
||||
op.path = path;
|
||||
}
|
||||
|
||||
op.operationId = toOperationId(operationId);
|
||||
op.summary = escapeText(operation.getSummary());
|
||||
op.unescapedNotes = operation.getDescription();
|
||||
@@ -4900,4 +4905,24 @@ public class DefaultCodegen implements CodegenConfig {
|
||||
this.enableMinimalUpdate = enableMinimalUpdate;
|
||||
}
|
||||
|
||||
/**
|
||||
* Indicates whether the codegen configuration should treat documents as strictly defined by the OpenAPI specification.
|
||||
*
|
||||
* @return true to act strictly upon spec documents, potentially modifying the spec to strictly fit the spec.
|
||||
*/
|
||||
@Override
|
||||
public boolean isStrictSpecBehavior() {
|
||||
return this.strictSpecBehavior;
|
||||
}
|
||||
|
||||
/**
|
||||
* Sets the boolean valid indicating whether generation will work strictly against the specification, potentially making
|
||||
* minor changes to the input document.
|
||||
*
|
||||
* @param strictSpecBehavior true if we will behave strictly, false to allow specification documents which pass validation to be loosely interpreted against the spec.
|
||||
*/
|
||||
@Override
|
||||
public void setStrictSpecBehavior(final boolean strictSpecBehavior) {
|
||||
this.strictSpecBehavior = strictSpecBehavior;
|
||||
}
|
||||
}
|
||||
|
||||
@@ -68,6 +68,7 @@ public class CodegenConfigurator implements Serializable {
|
||||
private boolean validateSpec;
|
||||
private boolean enablePostProcessFile;
|
||||
private boolean enableMinimalUpdate;
|
||||
private boolean strictSpecBehavior;
|
||||
private String templateDir;
|
||||
private String templatingEngineName;
|
||||
private String auth;
|
||||
@@ -100,6 +101,7 @@ public class CodegenConfigurator implements Serializable {
|
||||
|
||||
public CodegenConfigurator() {
|
||||
this.validateSpec = true;
|
||||
this.strictSpecBehavior = true;
|
||||
this.setOutputDir(".");
|
||||
}
|
||||
|
||||
@@ -225,6 +227,15 @@ public class CodegenConfigurator implements Serializable {
|
||||
return this;
|
||||
}
|
||||
|
||||
public boolean isStrictSpecBehavior() {
|
||||
return strictSpecBehavior;
|
||||
}
|
||||
|
||||
public CodegenConfigurator setStrictSpecBehavior(boolean strictSpecBehavior) {
|
||||
this.strictSpecBehavior = strictSpecBehavior;
|
||||
return this;
|
||||
}
|
||||
|
||||
public boolean isVerbose() {
|
||||
return verbose;
|
||||
}
|
||||
|
||||
@@ -48,7 +48,35 @@ public class DefaultGeneratorTest {
|
||||
Assert.assertEquals(defaultList.get(3).path, "/path4");
|
||||
Assert.assertEquals(defaultList.get(3).allParams.size(), 1);
|
||||
}
|
||||
|
||||
|
||||
|
||||
@Test
|
||||
public void testNonStrictProcessPaths() throws Exception {
|
||||
OpenAPI openAPI = TestUtils.createOpenAPI();
|
||||
openAPI.setPaths(new Paths());
|
||||
openAPI.getPaths().addPathItem("path1/", new PathItem().get(new Operation().operationId("op1").responses(new ApiResponses().addApiResponse("201", new ApiResponse().description("OK")))));
|
||||
openAPI.getPaths().addPathItem("path2/", new PathItem().get(new Operation().operationId("op2").addParametersItem(new QueryParameter().name("p1").schema(new StringSchema())).responses(new ApiResponses().addApiResponse("201", new ApiResponse().description("OK")))));
|
||||
|
||||
ClientOptInput opts = new ClientOptInput();
|
||||
opts.setOpenAPI(openAPI);
|
||||
CodegenConfig config = new DefaultCodegen();
|
||||
config.setStrictSpecBehavior(false);
|
||||
opts.setConfig(config);
|
||||
opts.setOpts(new ClientOpts());
|
||||
|
||||
DefaultGenerator generator = new DefaultGenerator();
|
||||
generator.opts(opts);
|
||||
Map<String, List<CodegenOperation>> result = generator.processPaths(openAPI.getPaths());
|
||||
Assert.assertEquals(result.size(), 1);
|
||||
List<CodegenOperation> defaultList = result.get("Default");
|
||||
Assert.assertEquals(defaultList.size(), 2);
|
||||
Assert.assertEquals(defaultList.get(0).path, "path1/");
|
||||
Assert.assertEquals(defaultList.get(0).allParams.size(), 0);
|
||||
Assert.assertEquals(defaultList.get(1).path, "path2/");
|
||||
Assert.assertEquals(defaultList.get(1).allParams.size(), 1);
|
||||
}
|
||||
|
||||
|
||||
@Test
|
||||
public void minimalUpdateTest() throws IOException {
|
||||
OpenAPI openAPI = TestUtils.createOpenAPI();
|
||||
|
||||
Reference in New Issue
Block a user