-
Notifications
You must be signed in to change notification settings - Fork 6k
How to add an option to a specific language or framework
With Swagger Codegen V3 development a new feature has been added for CLI tool. It's the capability to add an option for a specific language on code generation. This feature is related to #6041 issue.
swagger-codegen-cli contains a list of options for generate command. You can see this list using this command:
java -jar modules/swagger-codegen-cli/target/swagger-codegen-cli.jar generate -h
You should see a list like this:
-h, --help show this help message and exit
-v [], --verbose [] verbose mode
-l, --lang client language to generate (maybe class name in classpath, required)
-o, --output where to write the generated files (current dir by default)
-i, --input-spec location of the swagger spec, as URL or file (required)
-t, --template-dir folder containing the template files
--template-version version of the template used on generation.
. . .
--http-user-agent HTTP user agent, e.g. codegen_csharp_api_client, default to 'Swagger-Codegen/{packageVersion}}/{language}'
--reserved-words-mappings [ [ ...]]
pecifies how a reserved name should be escaped to. Otherwise, the default _<name> is used. For example id=identifier. You can also have multiple occurrences of this option.
--ignore-file-override
Specifies an override location for the .swagger-codegen-ignore file. Most useful on initial generation.
--remove-operation-id-prefix
Remove prefix of operationId, e.g. config_getId => getId
-u, --url load arguments from a local file or remote URL. Arguments found will replace any one placed on command.
In order to add a new option and let somebody else use it, we need to follow these steps:
Each language class is related to an argument file, right now only java and inflector languages have one. Files should be placed on resources main folder for swagger-codegen-generators project, preferably inside resources/arguments folder.
If the file arguments for exists, for example, resources/arguments/inflector, we must edit the file. The file itself is an array on yaml format. This is the current content for inflector
arguments:
- option: "--model-docs"
description: "generate models documentation."
type: "boolean"
- option: "--api-docs"
description: "generate apis documentation."
type: "boolean"
- option: "--model-tests"
description: "generate model tests."
type: "boolean"
- option: "--api-tests"
description: "generate apis tests."
type: "boolean"So, we can note in example above that an option is a object inside a list, where:
option field is the element used in CLI and it will be listed on command list, for example if we use this command to show options for inflector language:
java -jar modules/swagger-codegen-cli/target/swagger-codegen-cli.jar generate -l inflector -h
We should get an output like this:
-h, --help show this help message and exit
-v [], --verbose [] verbose mode
-l, --lang client language to generate (maybe class name in classpath, required)
-o, --output where to write the generated files (current dir by default)
-i, --input-spec location of the swagger spec, as URL or file (required)
-t, --template-dir folder containing the template files
--template-version version of the template used on generation.
. . .
--http-user-agent HTTP user agent, e.g. codegen_csharp_api_client, default to 'Swagger-Codegen/{packageVersion}}/{language}'
--reserved-words-mappings [ [ ...]]
pecifies how a reserved name should be escaped to. Otherwise, the default _<name> is used. For example id=identifier. You can also have multiple occurrences of this option.
--ignore-file-override
Specifies an override location for the .swagger-codegen-ignore file. Most useful on initial generation.
--remove-operation-id-prefix
Remove prefix of operationId, e.g. config_getId => getId
-u, --url load arguments from a local file or remote URL. Arguments found will replace any one placed on command.
--model-docs generate models documentation.
--api-docs generate apis documentation.
--model-tests generate model tests.
--api-tests generate apis tests.
This way we can see the options for inflector language at bottom of the list.
Now, because currently there are only additional options for two languages (java and inflector) It will be required to create the arguments file if you want to add a new option for a different file.
On this case, the file just need to follow the format shown in previous sample. But there are a couple of things to keep in mind, that will be described in next steps.
This is a very simple step, from this method we just need to return the arguments file location, like this example with JavaClientCodegen class.
@Override
public String getArgumentsLocation() {
return "/arguments/java.yaml";
}In order to know if the options were used on CLI tool we need to override the setLanguageArguments method. Let's check this example from JavaInflectorServerCodegen class.
@Override
public void setLanguageArguments(List<CodegenArgument> languageArguments) {
if (languageArguments == null) {
languageArguments = new ArrayList<>();
}
if (!languageArguments.stream()
.anyMatch(codegenArgument -> CodegenConstants.MODEL_DOCS_OPTION.equalsIgnoreCase(codegenArgument.getOption()) && StringUtils.isNotBlank(codegenArgument.getValue()))) {
languageArguments.add(new CodegenArgument()
.option(CodegenConstants.MODEL_DOCS_OPTION)
.type("boolean")
.value(Boolean.FALSE.toString()));
}
if (!languageArguments.stream()
.anyMatch(codegenArgument -> CodegenConstants.API_DOCS_OPTION.equalsIgnoreCase(codegenArgument.getOption()) && StringUtils.isNotBlank(codegenArgument.getValue()))) {
languageArguments.add(new CodegenArgument()
.option(CodegenConstants.API_DOCS_OPTION)
.type("boolean")
.value(Boolean.FALSE.toString()));
}
if (!languageArguments.stream()
.anyMatch(codegenArgument -> CodegenConstants.MODEL_TESTS_OPTION.equalsIgnoreCase(codegenArgument.getOption()) && StringUtils.isNotBlank(codegenArgument.getValue()))) {
languageArguments.add(new CodegenArgument()
.option(CodegenConstants.MODEL_TESTS_OPTION)
.type("boolean")
.value(Boolean.FALSE.toString()));
}
if (!languageArguments.stream()
.anyMatch(codegenArgument -> CodegenConstants.API_TESTS_OPTION.equalsIgnoreCase(codegenArgument.getOption()) && StringUtils.isNotBlank(codegenArgument.getValue()))) {
languageArguments.add(new CodegenArgument()
.option(CodegenConstants.API_TESTS_OPTION)
.type("boolean")
.value(Boolean.FALSE.toString()));
}
super.setLanguageArguments(languageArguments);
}On this example we can note that these options are matched to a list of CodegenArgument objects. We must keep in mind that these CodegenArgument objects are set from CLI options before generation and they are still available on the whole generation process. So we are free to decide when they must be used.
would suggest when compiling to use flag to ignore tests. The tests requires extra dependencies and the compilation might fail due to that.