diff --git a/docs/customization.md b/docs/customization.md index 5833650b98f..ade155b1ba1 100644 --- a/docs/customization.md +++ b/docs/customization.md @@ -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). +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 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: diff --git a/modules/openapi-generator-cli/src/main/java/org/openapitools/codegen/cmd/ConfigHelp.java b/modules/openapi-generator-cli/src/main/java/org/openapitools/codegen/cmd/ConfigHelp.java index 15ae470ea30..070ae689611 100644 --- a/modules/openapi-generator-cli/src/main/java/org/openapitools/codegen/cmd/ConfigHelp.java +++ b/modules/openapi-generator-cli/src/main/java/org/openapitools/codegen/cmd/ConfigHelp.java @@ -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)") 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") private Boolean reservedWords; @@ -588,6 +591,13 @@ public class ConfigHelp extends OpenApiGeneratorCommand { 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)) { sb.append(newline).append("RESERVED WORDS").append(newline).append(newline); String[] arr = config.reservedWords().stream().sorted().toArray(String[]::new); diff --git a/modules/openapi-generator-cli/src/main/java/org/openapitools/codegen/cmd/Generate.java b/modules/openapi-generator-cli/src/main/java/org/openapitools/codegen/cmd/Generate.java index 14c251133fe..963b626269c 100644 --- a/modules/openapi-generator-cli/src/main/java/org/openapitools/codegen/cmd/Generate.java +++ b/modules/openapi-generator-cli/src/main/java/org/openapitools/codegen/cmd/Generate.java @@ -160,6 +160,13 @@ public class Generate extends OpenApiGeneratorCommand { + " You can also have multiple occurrences of this option.") private List 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 openapiGeneratorIgnoreList = new ArrayList<>(); + @Option( name = {"--import-mappings"}, title = "import mappings", @@ -504,6 +511,7 @@ public class Generate extends OpenApiGeneratorCommand { applyTypeMappingsKvpList(typeMappings, configurator); applyAdditionalPropertiesKvpList(additionalProperties, configurator); applyLanguageSpecificPrimitivesCsvList(languageSpecificPrimitives, configurator); + applyOpenAPIGeneratorIgnoreListCsvList(openapiGeneratorIgnoreList, configurator); applyReservedWordsMappingsKvpList(reservedWordsMappings, configurator); applyServerVariablesKvpList(serverVariableOverrides, configurator); diff --git a/modules/openapi-generator-core/src/main/java/org/openapitools/codegen/config/GeneratorSettings.java b/modules/openapi-generator-core/src/main/java/org/openapitools/codegen/config/GeneratorSettings.java index 8be7441ff03..5ba28f278c8 100644 --- a/modules/openapi-generator-core/src/main/java/org/openapitools/codegen/config/GeneratorSettings.java +++ b/modules/openapi-generator-core/src/main/java/org/openapitools/codegen/config/GeneratorSettings.java @@ -59,6 +59,7 @@ public final class GeneratorSettings implements Serializable { private final Map enumNameMappings; private final Map openapiNormalizer; private final Set languageSpecificPrimitives; + private final Set openapiGeneratorIgnoreList; private final Map reservedWordsMappings; private final Map serverVariables; @@ -330,6 +331,15 @@ public final class GeneratorSettings implements Serializable { return languageSpecificPrimitives; } + /** + * Gets openapi generator ignore list. + * + * @return the openapi generator ignore list + */ + public Set getOpenAPIGeneratorIgnoreList() { + return openapiGeneratorIgnoreList; + } + /** * Gets reserved word mappings. Values defined here define how a reserved word should be escaped. *

@@ -438,6 +448,7 @@ public final class GeneratorSettings implements Serializable { enumNameMappings = Collections.unmodifiableMap(builder.enumNameMappings); openapiNormalizer = Collections.unmodifiableMap(builder.openapiNormalizer); languageSpecificPrimitives = Collections.unmodifiableSet(builder.languageSpecificPrimitives); + openapiGeneratorIgnoreList = Collections.unmodifiableSet(builder.openapiGeneratorIgnoreList); reservedWordsMappings = Collections.unmodifiableMap(builder.reservedWordsMappings); serverVariables = Collections.unmodifiableMap(builder.serverVariables); gitHost = builder.gitHost; @@ -516,6 +527,7 @@ public final class GeneratorSettings implements Serializable { enumNameMappings = Collections.unmodifiableMap(new HashMap<>(0)); openapiNormalizer = Collections.unmodifiableMap(new HashMap<>(0)); languageSpecificPrimitives = Collections.unmodifiableSet(new HashSet<>(0)); + openapiGeneratorIgnoreList = Collections.unmodifiableSet(new HashSet<>(0)); reservedWordsMappings = 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) { builder.languageSpecificPrimitives.addAll(copy.getLanguageSpecificPrimitives()); } + if (copy.getOpenAPIGeneratorIgnoreList() != null) { + builder.openapiGeneratorIgnoreList.addAll(copy.getOpenAPIGeneratorIgnoreList()); + } if (copy.getReservedWordsMappings() != null) { builder.reservedWordsMappings.putAll(copy.getReservedWordsMappings()); } @@ -638,6 +653,7 @@ public final class GeneratorSettings implements Serializable { private Map enumNameMappings; private Map openapiNormalizer; private Set languageSpecificPrimitives; + private Set openapiGeneratorIgnoreList; private Map reservedWordsMappings; private Map serverVariables; private String gitHost; @@ -663,6 +679,7 @@ public final class GeneratorSettings implements Serializable { enumNameMappings = new HashMap<>(); openapiNormalizer = new HashMap<>(); languageSpecificPrimitives = new HashSet<>(); + openapiGeneratorIgnoreList = new HashSet<>(); reservedWordsMappings = new HashMap<>(); serverVariables = new HashMap<>(); @@ -1137,6 +1154,31 @@ public final class GeneratorSettings implements Serializable { 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 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. * @@ -1266,6 +1308,7 @@ public final class GeneratorSettings implements Serializable { ", additionalProperties=" + additionalProperties + ", importMappings=" + importMappings + ", languageSpecificPrimitives=" + languageSpecificPrimitives + + ", openapiGeneratorIgnoreList=" + openapiGeneratorIgnoreList + ", reservedWordsMappings=" + reservedWordsMappings + ", gitHost='" + gitHost + '\'' + ", gitUserId='" + gitUserId + '\'' + @@ -1305,6 +1348,7 @@ public final class GeneratorSettings implements Serializable { Objects.equals(getEnumNameMappings(), that.getEnumNameMappings()) && Objects.equals(getOpenAPINormalizer(), that.getOpenAPINormalizer()) && Objects.equals(getLanguageSpecificPrimitives(), that.getLanguageSpecificPrimitives()) && + Objects.equals(getOpenAPIGeneratorIgnoreList(), that.getOpenAPIGeneratorIgnoreList()) && Objects.equals(getReservedWordsMappings(), that.getReservedWordsMappings()) && Objects.equals(getGitHost(), that.getGitHost()) && Objects.equals(getGitUserId(), that.getGitUserId()) && @@ -1341,6 +1385,7 @@ public final class GeneratorSettings implements Serializable { getEnumNameMappings(), getOpenAPINormalizer(), getLanguageSpecificPrimitives(), + getOpenAPIGeneratorIgnoreList(), getReservedWordsMappings(), getGitHost(), getGitUserId(), diff --git a/modules/openapi-generator-gradle-plugin/src/main/kotlin/org/openapitools/generator/gradle/plugin/extensions/OpenApiGeneratorGenerateExtension.kt b/modules/openapi-generator-gradle-plugin/src/main/kotlin/org/openapitools/generator/gradle/plugin/extensions/OpenApiGeneratorGenerateExtension.kt index 50d78ac6ee1..6270c8df6a3 100644 --- a/modules/openapi-generator-gradle-plugin/src/main/kotlin/org/openapitools/generator/gradle/plugin/extensions/OpenApiGeneratorGenerateExtension.kt +++ b/modules/openapi-generator-gradle-plugin/src/main/kotlin/org/openapitools/generator/gradle/plugin/extensions/OpenApiGeneratorGenerateExtension.kt @@ -147,6 +147,11 @@ open class OpenApiGeneratorGenerateExtension(project: Project) { */ val languageSpecificPrimitives = project.objects.listProperty() + /** + * 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() + /** * Specifies mappings between a given class and the import that should be used for that class. */ diff --git a/modules/openapi-generator-gradle-plugin/src/main/kotlin/org/openapitools/generator/gradle/plugin/tasks/GenerateTask.kt b/modules/openapi-generator-gradle-plugin/src/main/kotlin/org/openapitools/generator/gradle/plugin/tasks/GenerateTask.kt index b6f90a9aa05..1d4cefb7ca1 100644 --- a/modules/openapi-generator-gradle-plugin/src/main/kotlin/org/openapitools/generator/gradle/plugin/tasks/GenerateTask.kt +++ b/modules/openapi-generator-gradle-plugin/src/main/kotlin/org/openapitools/generator/gradle/plugin/tasks/GenerateTask.kt @@ -244,6 +244,13 @@ open class GenerateTask @Inject constructor(private val objectFactory: ObjectFac @Input val languageSpecificPrimitives = project.objects.listProperty() + /** + * 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() + /** * 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) { reservedWordsMappings.get().forEach { entry -> configurator.addAdditionalReservedWordMapping(entry.key, entry.value) diff --git a/modules/openapi-generator-maven-plugin/src/main/java/org/openapitools/codegen/plugin/CodeGenMojo.java b/modules/openapi-generator-maven-plugin/src/main/java/org/openapitools/codegen/plugin/CodeGenMojo.java index 8a2d021d250..b06aface93e 100644 --- a/modules/openapi-generator-maven-plugin/src/main/java/org/openapitools/codegen/plugin/CodeGenMojo.java +++ b/modules/openapi-generator-maven-plugin/src/main/java/org/openapitools/codegen/plugin/CodeGenMojo.java @@ -374,6 +374,12 @@ public class CodeGenMojo extends AbstractMojo { @Parameter(name = "languageSpecificPrimitives", property = "openapi.generator.maven.plugin.languageSpecificPrimitives") private List languageSpecificPrimitives; + /** + * A list of openapi-generator-ignore entries + */ + @Parameter(name = "openapiGeneratorIgnoreList", property = "openapi.generator.maven.plugin.openapiGeneratorIgnoreList") + private List openapiGeneratorIgnoreList; + /** * 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); } + // 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 if (additionalProperties == null && configOptions.containsKey("additional-properties")) { applyAdditionalPropertiesKvp(configOptions.get("additional-properties").toString(), @@ -861,6 +873,12 @@ public class CodeGenMojo extends AbstractMojo { applyLanguageSpecificPrimitivesCsvList(languageSpecificPrimitives, configurator); } + // Apply Language Specific Primitives + if (openapiGeneratorIgnoreList != null + && (configOptions == null || !configOptions.containsKey("openapi-generator-ignore-list"))) { + applyOpenAPIGeneratorIgnoreListCsvList(openapiGeneratorIgnoreList, configurator); + } + // Apply Additional Properties if (additionalProperties != null && (configOptions == null || !configOptions.containsKey("additional-properties"))) { applyAdditionalPropertiesKvpList(additionalProperties, configurator); diff --git a/modules/openapi-generator/src/main/java/org/openapitools/codegen/CodegenConfig.java b/modules/openapi-generator/src/main/java/org/openapitools/codegen/CodegenConfig.java index 1fedb4eeead..acb4e9afa99 100644 --- a/modules/openapi-generator/src/main/java/org/openapitools/codegen/CodegenConfig.java +++ b/modules/openapi-generator/src/main/java/org/openapitools/codegen/CodegenConfig.java @@ -173,6 +173,8 @@ public interface CodegenConfig { Set languageSpecificPrimitives(); + Set openapiGeneratorIgnoreList(); + Map reservedWordsMappings(); void preprocessOpenAPI(OpenAPI openAPI); @@ -349,4 +351,6 @@ public interface CodegenConfig { boolean getUseOpenAPINormalizer(); + Set getOpenAPIGeneratorIgnoreList(); + } diff --git a/modules/openapi-generator/src/main/java/org/openapitools/codegen/DefaultCodegen.java b/modules/openapi-generator/src/main/java/org/openapitools/codegen/DefaultCodegen.java index 406344aa082..50a9d551cc2 100644 --- a/modules/openapi-generator/src/main/java/org/openapitools/codegen/DefaultCodegen.java +++ b/modules/openapi-generator/src/main/java/org/openapitools/codegen/DefaultCodegen.java @@ -160,6 +160,7 @@ public class DefaultCodegen implements CodegenConfig { protected Map instantiationTypes; protected Set reservedWords; protected Set languageSpecificPrimitives = new HashSet<>(); + protected Set openapiGeneratorIgnoreList = new HashSet<>(); protected Map importMapping = new HashMap<>(); // a map to store the mapping between a schema and the new one protected Map schemaMapping = new HashMap<>(); @@ -1211,6 +1212,11 @@ public class DefaultCodegen implements CodegenConfig { return languageSpecificPrimitives; } + @Override + public Set openapiGeneratorIgnoreList() { + return openapiGeneratorIgnoreList; + } + @Override public Map importMapping() { return importMapping; @@ -8317,6 +8323,11 @@ public class DefaultCodegen implements CodegenConfig { @Override public boolean getUseOpenAPINormalizer() { return true; } + @Override + public Set getOpenAPIGeneratorIgnoreList() { + return openapiGeneratorIgnoreList; + } + /* A function to convert yaml or json ingested strings like property names And convert special characters like newline, tab, carriage return diff --git a/modules/openapi-generator/src/main/java/org/openapitools/codegen/DefaultGenerator.java b/modules/openapi-generator/src/main/java/org/openapitools/codegen/DefaultGenerator.java index a1383cac91d..dce032a025e 100644 --- a/modules/openapi-generator/src/main/java/org/openapitools/codegen/DefaultGenerator.java +++ b/modules/openapi-generator/src/main/java/org/openapitools/codegen/DefaultGenerator.java @@ -36,12 +36,10 @@ import org.apache.commons.lang3.StringUtils; import org.openapitools.codegen.api.TemplateDefinition; import org.openapitools.codegen.api.TemplatePathLocator; import org.openapitools.codegen.api.TemplateProcessor; -import org.openapitools.codegen.config.GeneratorSettings; import org.openapitools.codegen.config.GlobalSettings; import org.openapitools.codegen.api.TemplatingEngineAdapter; import org.openapitools.codegen.api.TemplateFileType; import org.openapitools.codegen.ignore.CodegenIgnoreProcessor; -import org.openapitools.codegen.languages.CSharpClientCodegen; import org.openapitools.codegen.meta.GeneratorMetadata; import org.openapitools.codegen.meta.Stability; import org.openapitools.codegen.model.ApiInfoMap; @@ -65,6 +63,7 @@ import org.slf4j.LoggerFactory; import java.io.*; import java.net.URL; import java.nio.charset.StandardCharsets; +import java.nio.file.Files; import java.nio.file.Path; import java.time.ZonedDateTime; import java.util.*; @@ -701,17 +700,17 @@ public class DefaultGenerator implements Generator { String outputDir = config.getOutputDir() + File.separator + config.templateOutputDirs().get(templateName); String filename = config.apiFilename(templateName, tag, outputDir); // 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); } else { - LOGGER.info("Implementation file {} is not overwritten",filename); + LOGGER.info("Implementation file {} is not overwritten", filename); } } else { 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); } else { - LOGGER.info("Implementation file {} is not overwritten",filename); + LOGGER.info("Implementation file {} is not overwritten", filename); } } if (written != null) { @@ -764,17 +763,83 @@ public class DefaultGenerator implements 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); 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 files, Map bundle) { if (!generateSupportingFiles) { // TODO: process these anyway and report via dryRun? LOGGER.info("Skipping generation of supporting files."); return; } + Set supportingFilesToGenerate = null; String supportingFiles = GlobalSettings.getProperty(CodegenConstants.SUPPORTING_FILES); if (supportingFiles != null && !supportingFiles.isEmpty()) { @@ -819,27 +884,30 @@ public class DefaultGenerator implements Generator { // Consider .openapi-generator-ignore a supporting file // Output .openapi-generator-ignore if it doesn't exist and wasn't explicitly created by a generator - final String openapiGeneratorIgnore = ".openapi-generator-ignore"; - String ignoreFileNameTarget = config.outputFolder() + File.separator + openapiGeneratorIgnore; - File ignoreFile = new File(ignoreFileNameTarget); - if (generateMetadata) { - try { - boolean shouldGenerate = !ignoreFile.exists(); - if (shouldGenerate && supportingFilesToGenerate != null && !supportingFilesToGenerate.isEmpty()) { - shouldGenerate = supportingFilesToGenerate.contains(openapiGeneratorIgnore); - } - 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"); + // and the option openapiGeneratorIgnoreList is not set + if (config.openapiGeneratorIgnoreList() == null || config.openapiGeneratorIgnoreList().isEmpty()) { + final String openapiGeneratorIgnore = ".openapi-generator-ignore"; + String ignoreFileNameTarget = config.outputFolder() + File.separator + openapiGeneratorIgnore; + File ignoreFile = new File(ignoreFileNameTarget); + if (generateMetadata) { + try { + boolean shouldGenerate = !ignoreFile.exists(); + if (shouldGenerate && supportingFilesToGenerate != null && !supportingFilesToGenerate.isEmpty()) { + shouldGenerate = supportingFilesToGenerate.contains(openapiGeneratorIgnore); } + 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) { - throw new RuntimeException("Could not generate supporting file '" + ignoreFileNameTarget + "'", e); + } else { + 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); @@ -984,6 +1052,9 @@ public class DefaultGenerator implements Generator { processUserDefinedTemplates(); + // generate .openapi-generator-ignore if the option openapiGeneratorIgnoreFile is enabled + generateOpenAPIGeneratorIgnoreFile(); + List files = new ArrayList<>(); // models List filteredSchemas = ModelUtils.getSchemasUsedOnlyInFormParam(openAPI); diff --git a/modules/openapi-generator/src/main/java/org/openapitools/codegen/config/CodegenConfigurator.java b/modules/openapi-generator/src/main/java/org/openapitools/codegen/config/CodegenConfigurator.java index 234efba154f..dd9bdc16122 100644 --- a/modules/openapi-generator/src/main/java/org/openapitools/codegen/config/CodegenConfigurator.java +++ b/modules/openapi-generator/src/main/java/org/openapitools/codegen/config/CodegenConfigurator.java @@ -77,6 +77,7 @@ public class CodegenConfigurator { private Map enumNameMappings = new HashMap<>(); private Map openapiNormalizer = new HashMap<>(); private Set languageSpecificPrimitives = new HashSet<>(); + private Set openapiGeneratorIgnoreList = new HashSet<>(); private Map reservedWordsMappings = new HashMap<>(); private Map serverVariables = new HashMap<>(); private String auth; @@ -146,6 +147,9 @@ public class CodegenConfigurator { if(generatorSettings.getLanguageSpecificPrimitives() != null) { configurator.languageSpecificPrimitives.addAll(generatorSettings.getLanguageSpecificPrimitives()); } + if(generatorSettings.getOpenAPIGeneratorIgnoreList() != null) { + configurator.openapiGeneratorIgnoreList.addAll(generatorSettings.getOpenAPIGeneratorIgnoreList()); + } if(generatorSettings.getReservedWordsMappings() != null) { configurator.reservedWordsMappings.putAll(generatorSettings.getReservedWordsMappings()); } @@ -272,6 +276,12 @@ public class CodegenConfigurator { return this; } + public CodegenConfigurator addOpenAPIGeneratorIgnoreList(String value) { + this.openapiGeneratorIgnoreList.add(value); + generatorSettingsBuilder.withOpenAPIGeneratorIgnoreList(value); + return this; + } + public CodegenConfigurator addGlobalProperty(String key, String value) { this.globalProperties.put(key, value); workflowSettingsBuilder.withGlobalProperty(key, value); @@ -489,6 +499,13 @@ public class CodegenConfigurator { return this; } + public CodegenConfigurator setOpenAPIGeneratorIgnoreList( + Set openapiGeneratorIgnoreList) { + this.openapiGeneratorIgnoreList = openapiGeneratorIgnoreList; + generatorSettingsBuilder.withOpenAPIGeneratorIgnoreList(openapiGeneratorIgnoreList); + return this; + } + public CodegenConfigurator setLibrary(String library) { generatorSettingsBuilder.withLibrary(library); return this; @@ -747,6 +764,7 @@ public class CodegenConfigurator { config.enumNameMapping().putAll(generatorSettings.getEnumNameMappings()); config.openapiNormalizer().putAll(generatorSettings.getOpenAPINormalizer()); config.languageSpecificPrimitives().addAll(generatorSettings.getLanguageSpecificPrimitives()); + config.openapiGeneratorIgnoreList().addAll(generatorSettings.getOpenAPIGeneratorIgnoreList()); config.reservedWordsMappings().putAll(generatorSettings.getReservedWordsMappings()); config.additionalProperties().putAll(generatorSettings.getAdditionalProperties()); diff --git a/modules/openapi-generator/src/main/java/org/openapitools/codegen/config/CodegenConfiguratorUtils.java b/modules/openapi-generator/src/main/java/org/openapitools/codegen/config/CodegenConfiguratorUtils.java index 5b57bde6abf..21cbde34c9a 100644 --- a/modules/openapi-generator/src/main/java/org/openapitools/codegen/config/CodegenConfiguratorUtils.java +++ b/modules/openapi-generator/src/main/java/org/openapitools/codegen/config/CodegenConfiguratorUtils.java @@ -237,6 +237,19 @@ public final class CodegenConfiguratorUtils { } } + public static void applyOpenAPIGeneratorIgnoreListCsvList(List openapiGeneratorIgnoreList, CodegenConfigurator configurator) { + for (String propString : openapiGeneratorIgnoreList) { + applyOpenAPIGeneratorIgnoreListCsv(propString, configurator); + } + } + + public static void applyOpenAPIGeneratorIgnoreListCsv(String openapiGeneratorIgnoreList, CodegenConfigurator configurator) { + final Set set = createSetFromCsvList(openapiGeneratorIgnoreList); + for (String item : set) { + configurator.addOpenAPIGeneratorIgnoreList(item); + } + } + public static void applyReservedWordsMappingsKvpList(List reservedWordsMappings, CodegenConfigurator configurator) { for (String propString : reservedWordsMappings) { applyReservedWordsMappingsKvp(propString, configurator); diff --git a/modules/openapi-generator/src/test/java/org/openapitools/codegen/java/JavaClientCodegenTest.java b/modules/openapi-generator/src/test/java/org/openapitools/codegen/java/JavaClientCodegenTest.java index 14db5e929f6..921ba069b09 100644 --- a/modules/openapi-generator/src/test/java/org/openapitools/codegen/java/JavaClientCodegenTest.java +++ b/modules/openapi-generator/src/test/java/org/openapitools/codegen/java/JavaClientCodegenTest.java @@ -2722,4 +2722,28 @@ public class JavaClientCodegenTest { File apiFile = files.get("AllOfDatetime.java"); 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 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); + } }