diff --git a/docs/generators.md b/docs/generators.md index 7d7746b508c..87bae1186e5 100644 --- a/docs/generators.md +++ b/docs/generators.md @@ -16,7 +16,7 @@ The following generators are available: - [cpp-restsdk](generators/cpp-restsdk.md) - [cpp-tizen](generators/cpp-tizen.md) - [csharp](generators/csharp.md) - - [csharp-dotnet2](generators/csharp-dotnet2.md) + - [csharp-dotnet2](generators/csharp-dotnet2.md) (deprecated) - [csharp-netcore](generators/csharp-netcore.md) - [dart](generators/dart.md) - [dart-jaguar](generators/dart-jaguar.md) @@ -47,10 +47,10 @@ The following generators are available: - [rust](generators/rust.md) - [scala-akka](generators/scala-akka.md) - [scala-gatling](generators/scala-gatling.md) - - [scala-httpclient-deprecated](generators/scala-httpclient-deprecated.md) + - [scala-httpclient-deprecated](generators/scala-httpclient-deprecated.md) (deprecated) - [scalaz](generators/scalaz.md) - - [swift2-deprecated](generators/swift2-deprecated.md) - - [swift3-deprecated](generators/swift3-deprecated.md) + - [swift2-deprecated](generators/swift2-deprecated.md) (deprecated) + - [swift3-deprecated](generators/swift3-deprecated.md) (deprecated) - [swift4](generators/swift4.md) - [typescript-angular](generators/typescript-angular.md) - [typescript-angularjs](generators/typescript-angularjs.md) diff --git a/modules/openapi-generator-cli/src/main/java/org/openapitools/codegen/cmd/ListGenerators.java b/modules/openapi-generator-cli/src/main/java/org/openapitools/codegen/cmd/ListGenerators.java index 18fb5839161..afffaae90f5 100644 --- a/modules/openapi-generator-cli/src/main/java/org/openapitools/codegen/cmd/ListGenerators.java +++ b/modules/openapi-generator-cli/src/main/java/org/openapitools/codegen/cmd/ListGenerators.java @@ -8,6 +8,8 @@ import io.airlift.airline.Option; import org.openapitools.codegen.CodegenConfig; import org.openapitools.codegen.CodegenConfigLoader; import org.openapitools.codegen.CodegenType; +import org.openapitools.codegen.meta.GeneratorMetadata; +import org.openapitools.codegen.meta.Stability; import java.util.Comparator; import java.util.List; @@ -70,16 +72,27 @@ public class ListGenerators implements Runnable { sb.append(System.lineSeparator()); list.forEach(generator -> { + GeneratorMetadata meta = generator.getGeneratorMetadata(); if (docusaurus) { sb.append("* "); String id = "generators/" + generator.getName(); - sb.append("[").append(generator.getName()).append("](").append(id).append(")"); + sb.append("[").append(generator.getName()); + + if (meta != null && meta.getStability() != null && meta.getStability() != Stability.STABLE) { + sb.append(" (").append(meta.getStability().value()).append(")"); + } + + sb.append("](").append(id).append(")"); // trailing space is important for markdown list formatting sb.append(" "); } else { sb.append(" - "); sb.append(generator.getName()); + + if (meta != null && meta.getStability() != null && meta.getStability() != Stability.STABLE) { + sb.append(" (").append(meta.getStability().value()).append(")"); + } } sb.append(System.lineSeparator()); }); diff --git a/modules/openapi-generator-core/src/main/java/org/openapitools/codegen/meta/GeneratorMetadata.java b/modules/openapi-generator-core/src/main/java/org/openapitools/codegen/meta/GeneratorMetadata.java new file mode 100644 index 00000000000..0c87104c7b5 --- /dev/null +++ b/modules/openapi-generator-core/src/main/java/org/openapitools/codegen/meta/GeneratorMetadata.java @@ -0,0 +1,99 @@ +package org.openapitools.codegen.meta; + +/** + * Represents metadata about a generator. + */ +public class GeneratorMetadata { + private Stability stability; + private String generationMessage; + + private GeneratorMetadata(Builder builder) { + stability = builder.stability; + generationMessage = builder.generationMessage; + } + + /** + * Creates a new builder object for {@link GeneratorMetadata}. + * + * @return A new builder instance. + */ + public static Builder newBuilder() { + return new Builder(); + } + + /** + * Creates a new builder object for {@link GeneratorMetadata}, accepting another instance from which to copy properties. + * + * @param copy An existing instance to copy defaults from + * + * @return A new builder instance, with values preset to those of 'copy'. + */ + public static Builder newBuilder(GeneratorMetadata copy) { + Builder builder = new Builder(); + if (copy != null) { + builder.stability = copy.getStability(); + builder.generationMessage = copy.getGenerationMessage(); + } + return builder; + } + + /** + * Returns a message which can be displayed during generation. + * + * @return A message, if defined. + */ + public String getGenerationMessage() { + return generationMessage; + } + + /** + * Returns an enum describing the stability index of the generator. + * + * @return The defined stability index. + */ + public Stability getStability() { + return stability; + } + + /** + * {@code GeneratorMetadata} builder static inner class. + */ + public static final class Builder { + private Stability stability; + private String generationMessage; + + private Builder() { + } + + /** + * Sets the {@code stability} and returns a reference to this Builder so that the methods can be chained together. + * + * @param stability the {@code stability} to set + * @return a reference to this Builder + */ + public Builder stability(Stability stability) { + this.stability = stability; + return this; + } + + /** + * Sets the {@code generationMessage} and returns a reference to this Builder so that the methods can be chained together. + * + * @param generationMessage the {@code generationMessage} to set + * @return a reference to this Builder + */ + public Builder generationMessage(String generationMessage) { + this.generationMessage = generationMessage; + return this; + } + + /** + * Returns a {@code GeneratorMetadata} built from the parameters previously set. + * + * @return a {@code GeneratorMetadata} built with parameters of this {@code GeneratorMetadata.Builder} + */ + public GeneratorMetadata build() { + return new GeneratorMetadata(this); + } + } +} diff --git a/modules/openapi-generator-core/src/main/java/org/openapitools/codegen/meta/Stability.java b/modules/openapi-generator-core/src/main/java/org/openapitools/codegen/meta/Stability.java new file mode 100644 index 00000000000..6e12c64f7d1 --- /dev/null +++ b/modules/openapi-generator-core/src/main/java/org/openapitools/codegen/meta/Stability.java @@ -0,0 +1,37 @@ +package org.openapitools.codegen.meta; + +/** + * Represents the "stability index" of a generator or feature, based on the stability indexes defined in the node.js ecosystem. + */ +public enum Stability { + /** + * The feature or features are considered complete and "production-ready". + */ + STABLE("stable"), + /** + * The feature may be partially incomplete, but breaking changes will be avoided between major releases. + */ + BETA("beta"), + /** + * The feature is still under active development and subject to non-backward compatible changes or removal in any + * future version. Use of the feature is not recommended in production environments. + */ + EXPERIMENTAL("experimental"), + /** + * The feature may emit warnings. Backward compatibility is not guaranteed. Removal is likely to occur in a subsequent major release. + */ + DEPRECATED("deprecated"); + + private String description; + + Stability(String description) { + this.description = description; + } + + /** + * Returns a value for this stability index. + * + * @return The descriptive value of this enum. + */ + public String value() { return description; } +} 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 137676771eb..dec7bc751b4 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 @@ -25,6 +25,7 @@ import io.swagger.v3.oas.models.security.SecurityScheme; import io.swagger.v3.oas.models.servers.Server; import io.swagger.v3.oas.models.servers.ServerVariable; import org.openapitools.codegen.api.TemplatingEngineAdapter; +import org.openapitools.codegen.meta.GeneratorMetadata; import java.io.File; import java.util.List; @@ -32,6 +33,8 @@ import java.util.Map; import java.util.Set; public interface CodegenConfig { + GeneratorMetadata getGeneratorMetadata(); + CodegenType getTag(); String getName(); 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 0d608768561..5550a099734 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 @@ -44,6 +44,8 @@ import org.openapitools.codegen.CodegenDiscriminator.MappedModel; import org.openapitools.codegen.api.TemplatingEngineAdapter; import org.openapitools.codegen.config.GeneratorProperties; import org.openapitools.codegen.examples.ExampleGenerator; +import org.openapitools.codegen.meta.GeneratorMetadata; +import org.openapitools.codegen.meta.Stability; import org.openapitools.codegen.serializer.SerializerUtils; import org.openapitools.codegen.templating.MustacheEngineAdapter; import org.openapitools.codegen.utils.ModelUtils; @@ -63,6 +65,7 @@ import static org.openapitools.codegen.utils.StringUtils.*; public class DefaultCodegen implements CodegenConfig { private static final Logger LOGGER = LoggerFactory.getLogger(DefaultCodegen.class); + protected GeneratorMetadata generatorMetadata; protected String inputSpec; protected String outputFolder = ""; protected Set defaultIncludes = new HashSet(); @@ -816,6 +819,16 @@ public class DefaultCodegen implements CodegenConfig { return camelize(name); } + /** + * Returns metadata about the generator. + * + * @return A provided {@link GeneratorMetadata} instance + */ + @Override + public GeneratorMetadata getGeneratorMetadata() { + return generatorMetadata; + } + /** * Return the operation ID (method name) * @@ -932,6 +945,15 @@ public class DefaultCodegen implements CodegenConfig { * returns string presentation of the example path (it's a constructor) */ public DefaultCodegen() { + CodegenType codegenType = getTag(); + if (codegenType == null) { + codegenType = CodegenType.OTHER; + } + generatorMetadata = GeneratorMetadata.newBuilder() + .stability(Stability.STABLE) + .generationMessage(String.format(Locale.ROOT, "OpenAPI Generator: %s (%s)", getName(), codegenType.toValue())) + .build(); + defaultIncludes = new HashSet( Arrays.asList("double", "int", 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 fed1fe0ad65..69931a20104 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 @@ -35,6 +35,8 @@ import org.apache.commons.lang3.StringUtils; import org.openapitools.codegen.config.GeneratorProperties; import org.openapitools.codegen.api.TemplatingEngineAdapter; import org.openapitools.codegen.ignore.CodegenIgnoreProcessor; +import org.openapitools.codegen.meta.GeneratorMetadata; +import org.openapitools.codegen.meta.Stability; import org.openapitools.codegen.templating.MustacheEngineAdapter; import org.openapitools.codegen.config.GeneratorProperties; import org.openapitools.codegen.utils.ImplementationVersion; @@ -883,6 +885,23 @@ public class DefaultGenerator extends AbstractGenerator implements Generator { throw new RuntimeException("missing config!"); } + if (config.getGeneratorMetadata() == null) { + LOGGER.warn(String.format(Locale.ROOT, "Generator '%s' is missing generator metadata!", config.getName())); + } else { + GeneratorMetadata generatorMetadata = config.getGeneratorMetadata(); + if (StringUtils.isNotEmpty(generatorMetadata.getGenerationMessage())) { + LOGGER.info(generatorMetadata.getGenerationMessage()); + } + + Stability stability = generatorMetadata.getStability(); + String stabilityMessage = String.format(Locale.ROOT, "Generator '%s' is considered %s.", config.getName(), stability.value()); + if (stability == Stability.DEPRECATED) { + LOGGER.warn(stabilityMessage); + } else { + LOGGER.info(stabilityMessage); + } + } + // resolve inline models InlineModelResolver inlineModelResolver = new InlineModelResolver(); inlineModelResolver.flatten(openAPI); diff --git a/modules/openapi-generator/src/main/java/org/openapitools/codegen/languages/CSharpDotNet2ClientCodegen.java b/modules/openapi-generator/src/main/java/org/openapitools/codegen/languages/CSharpDotNet2ClientCodegen.java index f836901cf4f..d3cd3a73063 100644 --- a/modules/openapi-generator/src/main/java/org/openapitools/codegen/languages/CSharpDotNet2ClientCodegen.java +++ b/modules/openapi-generator/src/main/java/org/openapitools/codegen/languages/CSharpDotNet2ClientCodegen.java @@ -22,6 +22,8 @@ import org.openapitools.codegen.CodegenConstants; import org.openapitools.codegen.CodegenType; import org.openapitools.codegen.SupportingFile; +import org.openapitools.codegen.meta.GeneratorMetadata; +import org.openapitools.codegen.meta.Stability; import org.slf4j.Logger; import org.slf4j.LoggerFactory; @@ -38,6 +40,10 @@ public class CSharpDotNet2ClientCodegen extends AbstractCSharpCodegen { public CSharpDotNet2ClientCodegen() { super(); + generatorMetadata = GeneratorMetadata.newBuilder(generatorMetadata) + .stability(Stability.DEPRECATED) + .build(); + // clear import mapping (from default generator) as C# (2.0) does not use it // at the moment importMapping.clear(); diff --git a/modules/openapi-generator/src/main/java/org/openapitools/codegen/languages/ScalaHttpClientCodegen.java b/modules/openapi-generator/src/main/java/org/openapitools/codegen/languages/ScalaHttpClientCodegen.java index 33ce6ce3dcf..637a5c819cc 100644 --- a/modules/openapi-generator/src/main/java/org/openapitools/codegen/languages/ScalaHttpClientCodegen.java +++ b/modules/openapi-generator/src/main/java/org/openapitools/codegen/languages/ScalaHttpClientCodegen.java @@ -19,6 +19,8 @@ package org.openapitools.codegen.languages; import org.apache.commons.lang3.StringUtils; import org.openapitools.codegen.*; +import org.openapitools.codegen.meta.GeneratorMetadata; +import org.openapitools.codegen.meta.Stability; import org.slf4j.Logger; import org.slf4j.LoggerFactory; @@ -46,6 +48,11 @@ public class ScalaHttpClientCodegen extends AbstractScalaCodegen implements Code public ScalaHttpClientCodegen() { super(); + + generatorMetadata = GeneratorMetadata.newBuilder(generatorMetadata) + .stability(Stability.DEPRECATED) + .build(); + outputFolder = "generated-code/scala-http-client"; modelTemplateFiles.put("model.mustache", ".scala"); apiTemplateFiles.put("api.mustache", ".scala"); diff --git a/modules/openapi-generator/src/main/java/org/openapitools/codegen/languages/Swift3Codegen.java b/modules/openapi-generator/src/main/java/org/openapitools/codegen/languages/Swift3Codegen.java index e68b6df2496..2c5e001d794 100644 --- a/modules/openapi-generator/src/main/java/org/openapitools/codegen/languages/Swift3Codegen.java +++ b/modules/openapi-generator/src/main/java/org/openapitools/codegen/languages/Swift3Codegen.java @@ -24,6 +24,8 @@ import org.apache.commons.lang3.ArrayUtils; import org.apache.commons.lang3.StringUtils; import org.apache.commons.lang3.text.WordUtils; import org.openapitools.codegen.*; +import org.openapitools.codegen.meta.GeneratorMetadata; +import org.openapitools.codegen.meta.Stability; import org.openapitools.codegen.utils.ModelUtils; import org.slf4j.Logger; import org.slf4j.LoggerFactory; @@ -68,6 +70,11 @@ public class Swift3Codegen extends DefaultCodegen implements CodegenConfig { public Swift3Codegen() { super(); + + generatorMetadata = GeneratorMetadata.newBuilder(generatorMetadata) + .stability(Stability.DEPRECATED) + .build(); + outputFolder = "generated-code" + File.separator + "swift"; modelTemplateFiles.put("model.mustache", ".swift"); apiTemplateFiles.put("api.mustache", ".swift"); diff --git a/modules/openapi-generator/src/main/java/org/openapitools/codegen/languages/SwiftClientCodegen.java b/modules/openapi-generator/src/main/java/org/openapitools/codegen/languages/SwiftClientCodegen.java index 077a1ec8767..1f6fc32b3f2 100644 --- a/modules/openapi-generator/src/main/java/org/openapitools/codegen/languages/SwiftClientCodegen.java +++ b/modules/openapi-generator/src/main/java/org/openapitools/codegen/languages/SwiftClientCodegen.java @@ -25,6 +25,8 @@ import org.apache.commons.lang3.ArrayUtils; import org.apache.commons.lang3.StringUtils; import org.apache.commons.lang3.text.WordUtils; import org.openapitools.codegen.*; +import org.openapitools.codegen.meta.GeneratorMetadata; +import org.openapitools.codegen.meta.Stability; import org.openapitools.codegen.utils.ModelUtils; import org.slf4j.Logger; import org.slf4j.LoggerFactory; @@ -87,6 +89,11 @@ public class SwiftClientCodegen extends DefaultCodegen implements CodegenConfig public SwiftClientCodegen() { super(); + + generatorMetadata = GeneratorMetadata.newBuilder(generatorMetadata) + .stability(Stability.DEPRECATED) + .build(); + outputFolder = "generated-code" + File.separator + "swift"; modelTemplateFiles.put("model.mustache", ".swift"); apiTemplateFiles.put("api.mustache", ".swift");