Add openapiGeneratorIgnoreList option to pre-populate .openapi-generator-ignore (#17164)

* add openapiGeneratorIgnoreList option to pre-populate .openapi-generator-ignore

* minor fix

* better code format

* add tests
This commit is contained in:
William Cheng 2023-11-23 11:10:29 +08:00 committed by GitHub
parent a93bab077f
commit 0dbc108d62
No known key found for this signature in database
GPG Key ID: 4AEE18F83AFDEB23
13 changed files with 270 additions and 25 deletions

View File

@ -266,6 +266,11 @@ Upon first code generation, you may also pass the CLI option `--ignore-file-over
Editor support for `.openapi-generator-ignore` files is available in IntelliJ via the [.ignore plugin](https://plugins.jetbrains.com/plugin/7495--ignore). Editor support for `.openapi-generator-ignore` files is available in IntelliJ via the [.ignore plugin](https://plugins.jetbrains.com/plugin/7495--ignore).
One may want to pre-populate `.openapi-generator-ignore` with a list of entries during the code generation process and the global/general option `openapiGeneatorIgnoreList` (e.g. --openapi-generator-ignore-list in CLI) can do exactly that. For example,
```
java -jar modules/openapi-generator-cli/target/openapi-generator-cli.jar generate -g spring -i modules/openapi-generator/src/test/resources/3_0/petstore.yaml -o /tmp/spring --additional-properties useTags=true --openapi-generator-ignore-list "README.md,pom.xml,docs/*.md,src/main/java/org/openapitools/model/*"
```
## Customizing the generator ## Customizing the generator
There are different aspects of customizing the code generator beyond just creating or modifying templates. Each language has a supporting configuration file to handle different type mappings, etc: There are different aspects of customizing the code generator beyond just creating or modifying templates. Each language has a supporting configuration file to handle different type mappings, etc:

View File

@ -101,6 +101,9 @@ public class ConfigHelp extends OpenApiGeneratorCommand {
@Option(name = {"--language-specific-primitive"}, title = "language specific primitives", description = "displays the language specific primitives (types which require no additional imports, or which may conflict with user defined model names)") @Option(name = {"--language-specific-primitive"}, title = "language specific primitives", description = "displays the language specific primitives (types which require no additional imports, or which may conflict with user defined model names)")
private Boolean languageSpecificPrimitives; private Boolean languageSpecificPrimitives;
@Option(name = {"--openapi-generator-ignore-list"}, title = "openapi generator ignore list", description = "displays the openapi generator ignore list")
private Boolean openapiGeneratorIgnoreList;
@Option(name = {"--reserved-words"}, title = "language specific reserved words", description = "displays the reserved words which may result in renamed model or property names") @Option(name = {"--reserved-words"}, title = "language specific reserved words", description = "displays the reserved words which may result in renamed model or property names")
private Boolean reservedWords; private Boolean reservedWords;
@ -588,6 +591,13 @@ public class ConfigHelp extends OpenApiGeneratorCommand {
sb.append(newline); sb.append(newline);
} }
if (Boolean.TRUE.equals(openapiGeneratorIgnoreList)) {
sb.append(newline).append("OPENAPI GENERATOR IGNORE LIST").append(newline).append(newline);
String[] arr = config.openapiGeneratorIgnoreList().stream().sorted().toArray(String[]::new);
writePlainTextFromArray(sb, arr, optIndent);
sb.append(newline);
}
if (Boolean.TRUE.equals(reservedWords)) { if (Boolean.TRUE.equals(reservedWords)) {
sb.append(newline).append("RESERVED WORDS").append(newline).append(newline); sb.append(newline).append("RESERVED WORDS").append(newline).append(newline);
String[] arr = config.reservedWords().stream().sorted().toArray(String[]::new); String[] arr = config.reservedWords().stream().sorted().toArray(String[]::new);

View File

@ -160,6 +160,13 @@ public class Generate extends OpenApiGeneratorCommand {
+ " You can also have multiple occurrences of this option.") + " You can also have multiple occurrences of this option.")
private List<String> languageSpecificPrimitives = new ArrayList<>(); private List<String> languageSpecificPrimitives = new ArrayList<>();
@Option(
name = {"--openapi-generator-ignore-list"},
title = ".openapi-generaotr-ignore list",
description = "specifies entries in the .openapi-generator-ignore file relative/path/to/file1,relative/path/to/file2. For example: README.md,pom.xml"
+ " You can also have multiple occurrences of this option.")
private List<String> openapiGeneratorIgnoreList = new ArrayList<>();
@Option( @Option(
name = {"--import-mappings"}, name = {"--import-mappings"},
title = "import mappings", title = "import mappings",
@ -504,6 +511,7 @@ public class Generate extends OpenApiGeneratorCommand {
applyTypeMappingsKvpList(typeMappings, configurator); applyTypeMappingsKvpList(typeMappings, configurator);
applyAdditionalPropertiesKvpList(additionalProperties, configurator); applyAdditionalPropertiesKvpList(additionalProperties, configurator);
applyLanguageSpecificPrimitivesCsvList(languageSpecificPrimitives, configurator); applyLanguageSpecificPrimitivesCsvList(languageSpecificPrimitives, configurator);
applyOpenAPIGeneratorIgnoreListCsvList(openapiGeneratorIgnoreList, configurator);
applyReservedWordsMappingsKvpList(reservedWordsMappings, configurator); applyReservedWordsMappingsKvpList(reservedWordsMappings, configurator);
applyServerVariablesKvpList(serverVariableOverrides, configurator); applyServerVariablesKvpList(serverVariableOverrides, configurator);

View File

@ -59,6 +59,7 @@ public final class GeneratorSettings implements Serializable {
private final Map<String, String> enumNameMappings; private final Map<String, String> enumNameMappings;
private final Map<String, String> openapiNormalizer; private final Map<String, String> openapiNormalizer;
private final Set<String> languageSpecificPrimitives; private final Set<String> languageSpecificPrimitives;
private final Set<String> openapiGeneratorIgnoreList;
private final Map<String, String> reservedWordsMappings; private final Map<String, String> reservedWordsMappings;
private final Map<String, String> serverVariables; private final Map<String, String> serverVariables;
@ -330,6 +331,15 @@ public final class GeneratorSettings implements Serializable {
return languageSpecificPrimitives; return languageSpecificPrimitives;
} }
/**
* Gets openapi generator ignore list.
*
* @return the openapi generator ignore list
*/
public Set<String> getOpenAPIGeneratorIgnoreList() {
return openapiGeneratorIgnoreList;
}
/** /**
* Gets reserved word mappings. Values defined here define how a reserved word should be escaped. * Gets reserved word mappings. Values defined here define how a reserved word should be escaped.
* <p> * <p>
@ -438,6 +448,7 @@ public final class GeneratorSettings implements Serializable {
enumNameMappings = Collections.unmodifiableMap(builder.enumNameMappings); enumNameMappings = Collections.unmodifiableMap(builder.enumNameMappings);
openapiNormalizer = Collections.unmodifiableMap(builder.openapiNormalizer); openapiNormalizer = Collections.unmodifiableMap(builder.openapiNormalizer);
languageSpecificPrimitives = Collections.unmodifiableSet(builder.languageSpecificPrimitives); languageSpecificPrimitives = Collections.unmodifiableSet(builder.languageSpecificPrimitives);
openapiGeneratorIgnoreList = Collections.unmodifiableSet(builder.openapiGeneratorIgnoreList);
reservedWordsMappings = Collections.unmodifiableMap(builder.reservedWordsMappings); reservedWordsMappings = Collections.unmodifiableMap(builder.reservedWordsMappings);
serverVariables = Collections.unmodifiableMap(builder.serverVariables); serverVariables = Collections.unmodifiableMap(builder.serverVariables);
gitHost = builder.gitHost; gitHost = builder.gitHost;
@ -516,6 +527,7 @@ public final class GeneratorSettings implements Serializable {
enumNameMappings = Collections.unmodifiableMap(new HashMap<>(0)); enumNameMappings = Collections.unmodifiableMap(new HashMap<>(0));
openapiNormalizer = Collections.unmodifiableMap(new HashMap<>(0)); openapiNormalizer = Collections.unmodifiableMap(new HashMap<>(0));
languageSpecificPrimitives = Collections.unmodifiableSet(new HashSet<>(0)); languageSpecificPrimitives = Collections.unmodifiableSet(new HashSet<>(0));
openapiGeneratorIgnoreList = Collections.unmodifiableSet(new HashSet<>(0));
reservedWordsMappings = Collections.unmodifiableMap(new HashMap<>(0)); reservedWordsMappings = Collections.unmodifiableMap(new HashMap<>(0));
serverVariables = Collections.unmodifiableMap(new HashMap<>(0)); serverVariables = Collections.unmodifiableMap(new HashMap<>(0));
} }
@ -593,6 +605,9 @@ public final class GeneratorSettings implements Serializable {
if (copy.getLanguageSpecificPrimitives() != null) { if (copy.getLanguageSpecificPrimitives() != null) {
builder.languageSpecificPrimitives.addAll(copy.getLanguageSpecificPrimitives()); builder.languageSpecificPrimitives.addAll(copy.getLanguageSpecificPrimitives());
} }
if (copy.getOpenAPIGeneratorIgnoreList() != null) {
builder.openapiGeneratorIgnoreList.addAll(copy.getOpenAPIGeneratorIgnoreList());
}
if (copy.getReservedWordsMappings() != null) { if (copy.getReservedWordsMappings() != null) {
builder.reservedWordsMappings.putAll(copy.getReservedWordsMappings()); builder.reservedWordsMappings.putAll(copy.getReservedWordsMappings());
} }
@ -638,6 +653,7 @@ public final class GeneratorSettings implements Serializable {
private Map<String, String> enumNameMappings; private Map<String, String> enumNameMappings;
private Map<String, String> openapiNormalizer; private Map<String, String> openapiNormalizer;
private Set<String> languageSpecificPrimitives; private Set<String> languageSpecificPrimitives;
private Set<String> openapiGeneratorIgnoreList;
private Map<String, String> reservedWordsMappings; private Map<String, String> reservedWordsMappings;
private Map<String, String> serverVariables; private Map<String, String> serverVariables;
private String gitHost; private String gitHost;
@ -663,6 +679,7 @@ public final class GeneratorSettings implements Serializable {
enumNameMappings = new HashMap<>(); enumNameMappings = new HashMap<>();
openapiNormalizer = new HashMap<>(); openapiNormalizer = new HashMap<>();
languageSpecificPrimitives = new HashSet<>(); languageSpecificPrimitives = new HashSet<>();
openapiGeneratorIgnoreList = new HashSet<>();
reservedWordsMappings = new HashMap<>(); reservedWordsMappings = new HashMap<>();
serverVariables = new HashMap<>(); serverVariables = new HashMap<>();
@ -1137,6 +1154,31 @@ public final class GeneratorSettings implements Serializable {
return this; return this;
} }
/**
* Sets the {@code openapiGeneratorIgnoreList} and returns a reference to this Builder so that the methods can be chained together.
*
* @param openapiGeneratorIgnoreList the {@code openapiGeneratorIgnoreList} to set
* @return a reference to this Builder
*/
public Builder withOpenAPIGeneratorIgnoreList(Set<String> openapiGeneratorIgnoreList) {
this.openapiGeneratorIgnoreList = openapiGeneratorIgnoreList;
return this;
}
/**
* Sets a single {@code openapiGeneratorIgnoreList} and returns a reference to this Builder so that the methods can be chained together.
*
* @param value The value of entry to set
* @return a reference to this Builder
*/
public Builder withOpenAPIGeneratorIgnoreList(String value) {
if (this.openapiGeneratorIgnoreList == null) {
this.openapiGeneratorIgnoreList = new HashSet<>();
}
this.openapiGeneratorIgnoreList.add(value);
return this;
}
/** /**
* Sets the {@code reservedWordsMappings} and returns a reference to this Builder so that the methods can be chained together. * Sets the {@code reservedWordsMappings} and returns a reference to this Builder so that the methods can be chained together.
* *
@ -1266,6 +1308,7 @@ public final class GeneratorSettings implements Serializable {
", additionalProperties=" + additionalProperties + ", additionalProperties=" + additionalProperties +
", importMappings=" + importMappings + ", importMappings=" + importMappings +
", languageSpecificPrimitives=" + languageSpecificPrimitives + ", languageSpecificPrimitives=" + languageSpecificPrimitives +
", openapiGeneratorIgnoreList=" + openapiGeneratorIgnoreList +
", reservedWordsMappings=" + reservedWordsMappings + ", reservedWordsMappings=" + reservedWordsMappings +
", gitHost='" + gitHost + '\'' + ", gitHost='" + gitHost + '\'' +
", gitUserId='" + gitUserId + '\'' + ", gitUserId='" + gitUserId + '\'' +
@ -1305,6 +1348,7 @@ public final class GeneratorSettings implements Serializable {
Objects.equals(getEnumNameMappings(), that.getEnumNameMappings()) && Objects.equals(getEnumNameMappings(), that.getEnumNameMappings()) &&
Objects.equals(getOpenAPINormalizer(), that.getOpenAPINormalizer()) && Objects.equals(getOpenAPINormalizer(), that.getOpenAPINormalizer()) &&
Objects.equals(getLanguageSpecificPrimitives(), that.getLanguageSpecificPrimitives()) && Objects.equals(getLanguageSpecificPrimitives(), that.getLanguageSpecificPrimitives()) &&
Objects.equals(getOpenAPIGeneratorIgnoreList(), that.getOpenAPIGeneratorIgnoreList()) &&
Objects.equals(getReservedWordsMappings(), that.getReservedWordsMappings()) && Objects.equals(getReservedWordsMappings(), that.getReservedWordsMappings()) &&
Objects.equals(getGitHost(), that.getGitHost()) && Objects.equals(getGitHost(), that.getGitHost()) &&
Objects.equals(getGitUserId(), that.getGitUserId()) && Objects.equals(getGitUserId(), that.getGitUserId()) &&
@ -1341,6 +1385,7 @@ public final class GeneratorSettings implements Serializable {
getEnumNameMappings(), getEnumNameMappings(),
getOpenAPINormalizer(), getOpenAPINormalizer(),
getLanguageSpecificPrimitives(), getLanguageSpecificPrimitives(),
getOpenAPIGeneratorIgnoreList(),
getReservedWordsMappings(), getReservedWordsMappings(),
getGitHost(), getGitHost(),
getGitUserId(), getGitUserId(),

View File

@ -147,6 +147,11 @@ open class OpenApiGeneratorGenerateExtension(project: Project) {
*/ */
val languageSpecificPrimitives = project.objects.listProperty<String>() val languageSpecificPrimitives = project.objects.listProperty<String>()
/**
* Specifies .openapi-generator-ignore list in the form of relative/path/to/file1,relative/path/to/file2. For example: README.md,pom.xml.
*/
val openapiGeneratorIgnoreList = project.objects.listProperty<String>()
/** /**
* Specifies mappings between a given class and the import that should be used for that class. * Specifies mappings between a given class and the import that should be used for that class.
*/ */

View File

@ -244,6 +244,13 @@ open class GenerateTask @Inject constructor(private val objectFactory: ObjectFac
@Input @Input
val languageSpecificPrimitives = project.objects.listProperty<String>() val languageSpecificPrimitives = project.objects.listProperty<String>()
/**
* Specifies .openapi-generator-ignore list in the form of relative/path/to/file1,relative/path/to/file2. For example: README.md,pom.xml.
*/
@Optional
@Input
val openapiGeneratorIgnoreList = project.objects.listProperty<String>()
/** /**
* Specifies mappings between a given class and the import that should be used for that class. * Specifies mappings between a given class and the import that should be used for that class.
*/ */
@ -895,6 +902,12 @@ open class GenerateTask @Inject constructor(private val objectFactory: ObjectFac
} }
} }
if (openapiGeneratorIgnoreList.isPresent) {
openapiGeneratorIgnoreList.get().forEach {
configurator.addOpenAPIGeneratorIgnoreList(it)
}
}
if (reservedWordsMappings.isPresent) { if (reservedWordsMappings.isPresent) {
reservedWordsMappings.get().forEach { entry -> reservedWordsMappings.get().forEach { entry ->
configurator.addAdditionalReservedWordMapping(entry.key, entry.value) configurator.addAdditionalReservedWordMapping(entry.key, entry.value)

View File

@ -374,6 +374,12 @@ public class CodeGenMojo extends AbstractMojo {
@Parameter(name = "languageSpecificPrimitives", property = "openapi.generator.maven.plugin.languageSpecificPrimitives") @Parameter(name = "languageSpecificPrimitives", property = "openapi.generator.maven.plugin.languageSpecificPrimitives")
private List<String> languageSpecificPrimitives; private List<String> languageSpecificPrimitives;
/**
* A list of openapi-generator-ignore entries
*/
@Parameter(name = "openapiGeneratorIgnoreList", property = "openapi.generator.maven.plugin.openapiGeneratorIgnoreList")
private List<String> openapiGeneratorIgnoreList;
/** /**
* A map of additional properties that can be referenced by the mustache templates * A map of additional properties that can be referenced by the mustache templates
*/ */
@ -783,6 +789,12 @@ public class CodeGenMojo extends AbstractMojo {
.get("language-specific-primitives").toString(), configurator); .get("language-specific-primitives").toString(), configurator);
} }
// Retained for backwards-compatibility with configOptions -> openapi-generator-ignore-list
if (openapiGeneratorIgnoreList == null && configOptions.containsKey("openapi-generator-ignore-list")) {
applyOpenAPIGeneratorIgnoreListCsv(configOptions
.get("openapi-generator-ignore-list").toString(), configurator);
}
// Retained for backwards-compatibility with configOptions -> additional-properties // Retained for backwards-compatibility with configOptions -> additional-properties
if (additionalProperties == null && configOptions.containsKey("additional-properties")) { if (additionalProperties == null && configOptions.containsKey("additional-properties")) {
applyAdditionalPropertiesKvp(configOptions.get("additional-properties").toString(), applyAdditionalPropertiesKvp(configOptions.get("additional-properties").toString(),
@ -861,6 +873,12 @@ public class CodeGenMojo extends AbstractMojo {
applyLanguageSpecificPrimitivesCsvList(languageSpecificPrimitives, configurator); applyLanguageSpecificPrimitivesCsvList(languageSpecificPrimitives, configurator);
} }
// Apply Language Specific Primitives
if (openapiGeneratorIgnoreList != null
&& (configOptions == null || !configOptions.containsKey("openapi-generator-ignore-list"))) {
applyOpenAPIGeneratorIgnoreListCsvList(openapiGeneratorIgnoreList, configurator);
}
// Apply Additional Properties // Apply Additional Properties
if (additionalProperties != null && (configOptions == null || !configOptions.containsKey("additional-properties"))) { if (additionalProperties != null && (configOptions == null || !configOptions.containsKey("additional-properties"))) {
applyAdditionalPropertiesKvpList(additionalProperties, configurator); applyAdditionalPropertiesKvpList(additionalProperties, configurator);

View File

@ -173,6 +173,8 @@ public interface CodegenConfig {
Set<String> languageSpecificPrimitives(); Set<String> languageSpecificPrimitives();
Set<String> openapiGeneratorIgnoreList();
Map<String, String> reservedWordsMappings(); Map<String, String> reservedWordsMappings();
void preprocessOpenAPI(OpenAPI openAPI); void preprocessOpenAPI(OpenAPI openAPI);
@ -349,4 +351,6 @@ public interface CodegenConfig {
boolean getUseOpenAPINormalizer(); boolean getUseOpenAPINormalizer();
Set<String> getOpenAPIGeneratorIgnoreList();
} }

View File

@ -160,6 +160,7 @@ public class DefaultCodegen implements CodegenConfig {
protected Map<String, String> instantiationTypes; protected Map<String, String> instantiationTypes;
protected Set<String> reservedWords; protected Set<String> reservedWords;
protected Set<String> languageSpecificPrimitives = new HashSet<>(); protected Set<String> languageSpecificPrimitives = new HashSet<>();
protected Set<String> openapiGeneratorIgnoreList = new HashSet<>();
protected Map<String, String> importMapping = new HashMap<>(); protected Map<String, String> importMapping = new HashMap<>();
// a map to store the mapping between a schema and the new one // a map to store the mapping between a schema and the new one
protected Map<String, String> schemaMapping = new HashMap<>(); protected Map<String, String> schemaMapping = new HashMap<>();
@ -1211,6 +1212,11 @@ public class DefaultCodegen implements CodegenConfig {
return languageSpecificPrimitives; return languageSpecificPrimitives;
} }
@Override
public Set<String> openapiGeneratorIgnoreList() {
return openapiGeneratorIgnoreList;
}
@Override @Override
public Map<String, String> importMapping() { public Map<String, String> importMapping() {
return importMapping; return importMapping;
@ -8317,6 +8323,11 @@ public class DefaultCodegen implements CodegenConfig {
@Override @Override
public boolean getUseOpenAPINormalizer() { return true; } public boolean getUseOpenAPINormalizer() { return true; }
@Override
public Set<String> getOpenAPIGeneratorIgnoreList() {
return openapiGeneratorIgnoreList;
}
/* /*
A function to convert yaml or json ingested strings like property names A function to convert yaml or json ingested strings like property names
And convert special characters like newline, tab, carriage return And convert special characters like newline, tab, carriage return

View File

@ -36,12 +36,10 @@ import org.apache.commons.lang3.StringUtils;
import org.openapitools.codegen.api.TemplateDefinition; import org.openapitools.codegen.api.TemplateDefinition;
import org.openapitools.codegen.api.TemplatePathLocator; import org.openapitools.codegen.api.TemplatePathLocator;
import org.openapitools.codegen.api.TemplateProcessor; import org.openapitools.codegen.api.TemplateProcessor;
import org.openapitools.codegen.config.GeneratorSettings;
import org.openapitools.codegen.config.GlobalSettings; import org.openapitools.codegen.config.GlobalSettings;
import org.openapitools.codegen.api.TemplatingEngineAdapter; import org.openapitools.codegen.api.TemplatingEngineAdapter;
import org.openapitools.codegen.api.TemplateFileType; import org.openapitools.codegen.api.TemplateFileType;
import org.openapitools.codegen.ignore.CodegenIgnoreProcessor; import org.openapitools.codegen.ignore.CodegenIgnoreProcessor;
import org.openapitools.codegen.languages.CSharpClientCodegen;
import org.openapitools.codegen.meta.GeneratorMetadata; import org.openapitools.codegen.meta.GeneratorMetadata;
import org.openapitools.codegen.meta.Stability; import org.openapitools.codegen.meta.Stability;
import org.openapitools.codegen.model.ApiInfoMap; import org.openapitools.codegen.model.ApiInfoMap;
@ -65,6 +63,7 @@ import org.slf4j.LoggerFactory;
import java.io.*; import java.io.*;
import java.net.URL; import java.net.URL;
import java.nio.charset.StandardCharsets; import java.nio.charset.StandardCharsets;
import java.nio.file.Files;
import java.nio.file.Path; import java.nio.file.Path;
import java.time.ZonedDateTime; import java.time.ZonedDateTime;
import java.util.*; import java.util.*;
@ -701,17 +700,17 @@ public class DefaultGenerator implements Generator {
String outputDir = config.getOutputDir() + File.separator + config.templateOutputDirs().get(templateName); String outputDir = config.getOutputDir() + File.separator + config.templateOutputDirs().get(templateName);
String filename = config.apiFilename(templateName, tag, outputDir); String filename = config.apiFilename(templateName, tag, outputDir);
// do not overwrite apiController file for spring server // do not overwrite apiController file for spring server
if (apiFilePreCheck(filename, generatorCheck, templateName, templateCheck)){ if (apiFilePreCheck(filename, generatorCheck, templateName, templateCheck)) {
written = processTemplateToFile(operation, templateName, filename, generateApis, CodegenConstants.APIS, outputDir); written = processTemplateToFile(operation, templateName, filename, generateApis, CodegenConstants.APIS, outputDir);
} else { } else {
LOGGER.info("Implementation file {} is not overwritten",filename); LOGGER.info("Implementation file {} is not overwritten", filename);
} }
} else { } else {
String filename = config.apiFilename(templateName, tag); String filename = config.apiFilename(templateName, tag);
if(apiFilePreCheck(filename, generatorCheck, templateName, templateCheck)){ if (apiFilePreCheck(filename, generatorCheck, templateName, templateCheck)) {
written = processTemplateToFile(operation, templateName, filename, generateApis, CodegenConstants.APIS); written = processTemplateToFile(operation, templateName, filename, generateApis, CodegenConstants.APIS);
} else { } else {
LOGGER.info("Implementation file {} is not overwritten",filename); LOGGER.info("Implementation file {} is not overwritten", filename);
} }
} }
if (written != null) { if (written != null) {
@ -764,17 +763,83 @@ public class DefaultGenerator implements Generator {
} }
// checking if apiController file is already existed for spring generator // checking if apiController file is already existed for spring generator
private boolean apiFilePreCheck(String filename, String generator, String templateName, String apiControllerTemplate){ private boolean apiFilePreCheck(String filename, String generator, String templateName, String apiControllerTemplate) {
File apiFile = new File(filename); File apiFile = new File(filename);
return !(apiFile.exists() && config.getName().equals(generator) && templateName.equals(apiControllerTemplate)); return !(apiFile.exists() && config.getName().equals(generator) && templateName.equals(apiControllerTemplate));
} }
/*
* Generate .openapi-generator-ignore if the option openapiGeneratorIgnoreFile is enabled.
*/
private void generateOpenAPIGeneratorIgnoreFile() {
if (config.getOpenAPIGeneratorIgnoreList() == null || config.getOpenAPIGeneratorIgnoreList().isEmpty()) {
return;
}
final String openapiGeneratorIgnore = ".openapi-generator-ignore";
String ignoreFileNameTarget = config.outputFolder() + File.separator + openapiGeneratorIgnore;
File ignoreFile = new File(ignoreFileNameTarget);
// use the entries provided by the users to pre-populate .openapi-generator-ignore
try {
LOGGER.info("Writing file " + ignoreFileNameTarget + " (which is always overwritten when the option `openapiGeneratorIgnoreFile` is enabled.)");
new File(config.outputFolder()).mkdirs();
ignoreFile.createNewFile();
String header = String.join("\n",
"# IMPORTANT: this file is generated with the option `openapiGeneratorIgnoreList` enabled",
"# (--openapi-generator-ignore-list in CLI for example) so the entries below are pre-populated based",
"# on the input provided by the users and this file will be overwritten every time when the option is",
"# enabled (which is the exact opposite of the default behaviour to not overwrite",
"# .openapi-generator-ignore if the file exists).",
"",
"# OpenAPI Generator Ignore",
"# Generated by openapi-generator https://github.com/openapitools/openapi-generator",
"",
"# Use this file to prevent files from being overwritten by the generator.",
"# The patterns follow closely to .gitignore or .dockerignore.",
"",
"# As an example, the C# client generator defines ApiClient.cs.",
"# You can make changes and tell OpenAPI Generator to ignore just this file by uncommenting the following line:",
"#ApiClient.cs",
"",
"# You can match any string of characters against a directory, file or extension with a single asterisk (*):",
"#foo/*/qux",
"# The above matches foo/bar/qux and foo/baz/qux, but not foo/bar/baz/qux",
"",
"# You can recursively match patterns against a directory, file or extension with a double asterisk (**):",
"#foo/**/qux",
"# This matches foo/bar/qux, foo/baz/qux, and foo/bar/baz/qux",
"",
"# You can also negate patterns with an exclamation (!).",
"# For example, you can ignore all files in a docs folder with the file extension .md:",
"#docs/*.md",
"# Then explicitly reverse the ignore rule for a single file:",
"#!docs/README.md",
"",
"# The following entries are pre-populated based on the input obtained via",
"# the option `openapiGeneratorIgnoreList` (--openapi-generator-ignore-list in CLI for example).",
"");
Writer fileWriter = Files.newBufferedWriter(ignoreFile.toPath(), StandardCharsets.UTF_8);
fileWriter.write(header);
// add entries provided by the users
for (String entry : config.getOpenAPIGeneratorIgnoreList()) {
fileWriter.write(entry);
fileWriter.write("\n");
}
fileWriter.close();
// re-create ignore processor based on the newly-created .openapi-generator-ignore
this.ignoreProcessor = new CodegenIgnoreProcessor(ignoreFile);
} catch (IOException e) {
throw new RuntimeException("Failed to generate .openapi-generator-ignore when the option `openapiGeneratorIgnoreList` is enabled: ", e);
}
}
private void generateSupportingFiles(List<File> files, Map<String, Object> bundle) { private void generateSupportingFiles(List<File> files, Map<String, Object> bundle) {
if (!generateSupportingFiles) { if (!generateSupportingFiles) {
// TODO: process these anyway and report via dryRun? // TODO: process these anyway and report via dryRun?
LOGGER.info("Skipping generation of supporting files."); LOGGER.info("Skipping generation of supporting files.");
return; return;
} }
Set<String> supportingFilesToGenerate = null; Set<String> supportingFilesToGenerate = null;
String supportingFiles = GlobalSettings.getProperty(CodegenConstants.SUPPORTING_FILES); String supportingFiles = GlobalSettings.getProperty(CodegenConstants.SUPPORTING_FILES);
if (supportingFiles != null && !supportingFiles.isEmpty()) { if (supportingFiles != null && !supportingFiles.isEmpty()) {
@ -819,27 +884,30 @@ public class DefaultGenerator implements Generator {
// Consider .openapi-generator-ignore a supporting file // Consider .openapi-generator-ignore a supporting file
// Output .openapi-generator-ignore if it doesn't exist and wasn't explicitly created by a generator // Output .openapi-generator-ignore if it doesn't exist and wasn't explicitly created by a generator
final String openapiGeneratorIgnore = ".openapi-generator-ignore"; // and the option openapiGeneratorIgnoreList is not set
String ignoreFileNameTarget = config.outputFolder() + File.separator + openapiGeneratorIgnore; if (config.openapiGeneratorIgnoreList() == null || config.openapiGeneratorIgnoreList().isEmpty()) {
File ignoreFile = new File(ignoreFileNameTarget); final String openapiGeneratorIgnore = ".openapi-generator-ignore";
if (generateMetadata) { String ignoreFileNameTarget = config.outputFolder() + File.separator + openapiGeneratorIgnore;
try { File ignoreFile = new File(ignoreFileNameTarget);
boolean shouldGenerate = !ignoreFile.exists(); if (generateMetadata) {
if (shouldGenerate && supportingFilesToGenerate != null && !supportingFilesToGenerate.isEmpty()) { try {
shouldGenerate = supportingFilesToGenerate.contains(openapiGeneratorIgnore); boolean shouldGenerate = !ignoreFile.exists();
} if (shouldGenerate && supportingFilesToGenerate != null && !supportingFilesToGenerate.isEmpty()) {
File written = processTemplateToFile(bundle, openapiGeneratorIgnore, ignoreFileNameTarget, shouldGenerate, CodegenConstants.SUPPORTING_FILES); shouldGenerate = supportingFilesToGenerate.contains(openapiGeneratorIgnore);
if (written != null) {
files.add(written);
if (config.isEnablePostProcessFile() && !dryRun) {
config.postProcessFile(written, "openapi-generator-ignore");
} }
File written = processTemplateToFile(bundle, openapiGeneratorIgnore, ignoreFileNameTarget, shouldGenerate, CodegenConstants.SUPPORTING_FILES);
if (written != null) {
files.add(written);
if (config.isEnablePostProcessFile() && !dryRun) {
config.postProcessFile(written, "openapi-generator-ignore");
}
}
} catch (Exception e) {
throw new RuntimeException("Could not generate supporting file '" + ignoreFileNameTarget + "'", e);
} }
} catch (Exception e) { } else {
throw new RuntimeException("Could not generate supporting file '" + ignoreFileNameTarget + "'", e); this.templateProcessor.skip(ignoreFile.toPath(), "Skipped by generateMetadata option supplied by user.");
} }
} else {
this.templateProcessor.skip(ignoreFile.toPath(), "Skipped by generateMetadata option supplied by user.");
} }
generateVersionMetadata(files); generateVersionMetadata(files);
@ -984,6 +1052,9 @@ public class DefaultGenerator implements Generator {
processUserDefinedTemplates(); processUserDefinedTemplates();
// generate .openapi-generator-ignore if the option openapiGeneratorIgnoreFile is enabled
generateOpenAPIGeneratorIgnoreFile();
List<File> files = new ArrayList<>(); List<File> files = new ArrayList<>();
// models // models
List<String> filteredSchemas = ModelUtils.getSchemasUsedOnlyInFormParam(openAPI); List<String> filteredSchemas = ModelUtils.getSchemasUsedOnlyInFormParam(openAPI);

View File

@ -77,6 +77,7 @@ public class CodegenConfigurator {
private Map<String, String> enumNameMappings = new HashMap<>(); private Map<String, String> enumNameMappings = new HashMap<>();
private Map<String, String> openapiNormalizer = new HashMap<>(); private Map<String, String> openapiNormalizer = new HashMap<>();
private Set<String> languageSpecificPrimitives = new HashSet<>(); private Set<String> languageSpecificPrimitives = new HashSet<>();
private Set<String> openapiGeneratorIgnoreList = new HashSet<>();
private Map<String, String> reservedWordsMappings = new HashMap<>(); private Map<String, String> reservedWordsMappings = new HashMap<>();
private Map<String, String> serverVariables = new HashMap<>(); private Map<String, String> serverVariables = new HashMap<>();
private String auth; private String auth;
@ -146,6 +147,9 @@ public class CodegenConfigurator {
if(generatorSettings.getLanguageSpecificPrimitives() != null) { if(generatorSettings.getLanguageSpecificPrimitives() != null) {
configurator.languageSpecificPrimitives.addAll(generatorSettings.getLanguageSpecificPrimitives()); configurator.languageSpecificPrimitives.addAll(generatorSettings.getLanguageSpecificPrimitives());
} }
if(generatorSettings.getOpenAPIGeneratorIgnoreList() != null) {
configurator.openapiGeneratorIgnoreList.addAll(generatorSettings.getOpenAPIGeneratorIgnoreList());
}
if(generatorSettings.getReservedWordsMappings() != null) { if(generatorSettings.getReservedWordsMappings() != null) {
configurator.reservedWordsMappings.putAll(generatorSettings.getReservedWordsMappings()); configurator.reservedWordsMappings.putAll(generatorSettings.getReservedWordsMappings());
} }
@ -272,6 +276,12 @@ public class CodegenConfigurator {
return this; return this;
} }
public CodegenConfigurator addOpenAPIGeneratorIgnoreList(String value) {
this.openapiGeneratorIgnoreList.add(value);
generatorSettingsBuilder.withOpenAPIGeneratorIgnoreList(value);
return this;
}
public CodegenConfigurator addGlobalProperty(String key, String value) { public CodegenConfigurator addGlobalProperty(String key, String value) {
this.globalProperties.put(key, value); this.globalProperties.put(key, value);
workflowSettingsBuilder.withGlobalProperty(key, value); workflowSettingsBuilder.withGlobalProperty(key, value);
@ -489,6 +499,13 @@ public class CodegenConfigurator {
return this; return this;
} }
public CodegenConfigurator setOpenAPIGeneratorIgnoreList(
Set<String> openapiGeneratorIgnoreList) {
this.openapiGeneratorIgnoreList = openapiGeneratorIgnoreList;
generatorSettingsBuilder.withOpenAPIGeneratorIgnoreList(openapiGeneratorIgnoreList);
return this;
}
public CodegenConfigurator setLibrary(String library) { public CodegenConfigurator setLibrary(String library) {
generatorSettingsBuilder.withLibrary(library); generatorSettingsBuilder.withLibrary(library);
return this; return this;
@ -747,6 +764,7 @@ public class CodegenConfigurator {
config.enumNameMapping().putAll(generatorSettings.getEnumNameMappings()); config.enumNameMapping().putAll(generatorSettings.getEnumNameMappings());
config.openapiNormalizer().putAll(generatorSettings.getOpenAPINormalizer()); config.openapiNormalizer().putAll(generatorSettings.getOpenAPINormalizer());
config.languageSpecificPrimitives().addAll(generatorSettings.getLanguageSpecificPrimitives()); config.languageSpecificPrimitives().addAll(generatorSettings.getLanguageSpecificPrimitives());
config.openapiGeneratorIgnoreList().addAll(generatorSettings.getOpenAPIGeneratorIgnoreList());
config.reservedWordsMappings().putAll(generatorSettings.getReservedWordsMappings()); config.reservedWordsMappings().putAll(generatorSettings.getReservedWordsMappings());
config.additionalProperties().putAll(generatorSettings.getAdditionalProperties()); config.additionalProperties().putAll(generatorSettings.getAdditionalProperties());

View File

@ -237,6 +237,19 @@ public final class CodegenConfiguratorUtils {
} }
} }
public static void applyOpenAPIGeneratorIgnoreListCsvList(List<String> openapiGeneratorIgnoreList, CodegenConfigurator configurator) {
for (String propString : openapiGeneratorIgnoreList) {
applyOpenAPIGeneratorIgnoreListCsv(propString, configurator);
}
}
public static void applyOpenAPIGeneratorIgnoreListCsv(String openapiGeneratorIgnoreList, CodegenConfigurator configurator) {
final Set<String> set = createSetFromCsvList(openapiGeneratorIgnoreList);
for (String item : set) {
configurator.addOpenAPIGeneratorIgnoreList(item);
}
}
public static void applyReservedWordsMappingsKvpList(List<String> reservedWordsMappings, CodegenConfigurator configurator) { public static void applyReservedWordsMappingsKvpList(List<String> reservedWordsMappings, CodegenConfigurator configurator) {
for (String propString : reservedWordsMappings) { for (String propString : reservedWordsMappings) {
applyReservedWordsMappingsKvp(propString, configurator); applyReservedWordsMappingsKvp(propString, configurator);

View File

@ -2722,4 +2722,28 @@ public class JavaClientCodegenTest {
File apiFile = files.get("AllOfDatetime.java"); File apiFile = files.get("AllOfDatetime.java");
assertEquals(apiFile, null); assertEquals(apiFile, null);
} }
@Test
public void testOpenAPIGeneratorIgnoreListOption() throws IOException {
File output = Files.createTempDirectory("openapi_generator_ignore_list_test_folder").toFile().getCanonicalFile();
output.deleteOnExit();
final OpenAPI openAPI = TestUtils.parseFlattenSpec("src/test/resources/3_0/allof_primitive.yaml");
final DefaultGenerator defaultGenerator = new DefaultGenerator();
final ClientOptInput clientOptInput = new ClientOptInput();
clientOptInput.openAPI(openAPI);
JavaClientCodegen javaClientCodegen = new JavaClientCodegen();
javaClientCodegen.setOutputDir(output.getAbsolutePath());
javaClientCodegen.setAutosetConstants(true);
javaClientCodegen.openapiGeneratorIgnoreList().add("README.md");
javaClientCodegen.openapiGeneratorIgnoreList().add("pom.xml");
clientOptInput.config(javaClientCodegen);
defaultGenerator.opts(clientOptInput);
Map<String, File> files = defaultGenerator.generate().stream()
.collect(Collectors.toMap(File::getName, Function.identity()));
// make sure README.md and pom.xml are not generated
assertEquals(files.get("README.md"), null);
assertEquals(files.get("pom.xml"), null);
}
} }