Skip to content

Commit e05f303

Browse files
authored
Merge branch 'main' into mock-module
2 parents 78b73fe + 029828b commit e05f303

File tree

50 files changed

+2512
-117
lines changed

Some content is hidden

Large Commits have some content hidden by default. Use the searchbox below for content that may be hidden.

50 files changed

+2512
-117
lines changed

.all-contributorsrc

Lines changed: 19 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -350,6 +350,25 @@
350350
"contributions": [
351351
"doc"
352352
]
353+
},
354+
{
355+
"login": "kfebert",
356+
"name": "Karl Ferdinand Ebert",
357+
"avatar_url": "https://avatars.githubusercontent.com/u/848796?v=4",
358+
"profile": "https://github.com/kfebert",
359+
"contributions": [
360+
"code",
361+
"doc"
362+
]
363+
},
364+
{
365+
"login": "michalkolenda",
366+
"name": "Michał Kolenda",
367+
"avatar_url": "https://avatars.githubusercontent.com/u/29705783?v=4",
368+
"profile": "https://github.com/michalkolenda",
369+
"contributions": [
370+
"code"
371+
]
353372
}
354373
],
355374
"contributorsPerLine": 7,

.github/CODEOWNERS

Lines changed: 14 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -0,0 +1,14 @@
1+
# Lines starting with '#' are comments.
2+
# Each line is a file pattern followed by one or more owners.
3+
4+
# More details are here: https://docs.github.com/en/repositories/managing-your-repositorys-settings-and-features/customizing-your-repository/about-code-owners
5+
6+
# The '*' pattern is global owners.
7+
8+
# Order is important. The last matching pattern has the most precedence.
9+
# The folders are ordered as follows:
10+
11+
# In each subsection folders are ordered first by depth, then alphabetically.
12+
# This should make it easy to add new rules without breaking existing ones.
13+
14+
* @quarkiverse/quarkiverse-openapi-generator

README.md

Lines changed: 3 additions & 1 deletion
Original file line numberDiff line numberDiff line change
@@ -1,7 +1,7 @@
11
# Quarkus - OpenAPI Generator
22

33
<!-- ALL-CONTRIBUTORS-BADGE:START - Do not remove or modify this section -->
4-
[![All Contributors](https://img.shields.io/badge/all_contributors-37-orange.svg?style=flat-square)](#contributors-)
4+
[![All Contributors](https://img.shields.io/badge/all_contributors-39-orange.svg?style=flat-square)](#contributors-)
55
<!-- ALL-CONTRIBUTORS-BADGE:END -->
66
[![Build](<https://img.shields.io/github/actions/workflow/status/quarkiverse/quarkus-openapi-generator/build.yml?branch=main&logo=GitHub&style=flat-square>)](https://github.com/quarkiverse/quarkus-openapi-generator/actions?query=workflow%3ABuild)
77
[![Maven Central](https://img.shields.io/maven-central/v/io.quarkiverse.openapi.generator/quarkus-openapi-generator.svg?label=Maven%20Central&style=flat-square)](https://search.maven.org/artifact/io.quarkiverse.openapi.generator/quarkus-openapi-generator)
@@ -87,6 +87,8 @@ Thanks goes to these wonderful people ([emoji key](https://allcontributors.org/d
8787
<tr>
8888
<td align="center" valign="top" width="14.28%"><a href="https://github.com/brice-laurencin"><img src="https://avatars.githubusercontent.com/u/135709187?v=4?s=100" width="100px;" alt="Brice Laurencin"/><br /><sub><b>Brice Laurencin</b></sub></a><br /><a href="https://github.com/quarkiverse/quarkus-openapi-generator/commits?author=brice-laurencin" title="Code">💻</a></td>
8989
<td align="center" valign="top" width="14.28%"><a href="https://github.com/gmalheiro"><img src="https://avatars.githubusercontent.com/u/92603922?v=4?s=100" width="100px;" alt="Gabriel Malheiro"/><br /><sub><b>Gabriel Malheiro</b></sub></a><br /><a href="https://github.com/quarkiverse/quarkus-openapi-generator/commits?author=gmalheiro" title="Documentation">📖</a></td>
90+
<td align="center" valign="top" width="14.28%"><a href="https://github.com/kfebert"><img src="https://avatars.githubusercontent.com/u/848796?v=4?s=100" width="100px;" alt="Karl Ferdinand Ebert"/><br /><sub><b>Karl Ferdinand Ebert</b></sub></a><br /><a href="https://github.com/quarkiverse/quarkus-openapi-generator/commits?author=kfebert" title="Code">💻</a> <a href="https://github.com/quarkiverse/quarkus-openapi-generator/commits?author=kfebert" title="Documentation">📖</a></td>
91+
<td align="center" valign="top" width="14.28%"><a href="https://github.com/michalkolenda"><img src="https://avatars.githubusercontent.com/u/29705783?v=4?s=100" width="100px;" alt="Michał Kolenda"/><br /><sub><b>Michał Kolenda</b></sub></a><br /><a href="https://github.com/quarkiverse/quarkus-openapi-generator/commits?author=michalkolenda" title="Code">💻</a></td>
9092
</tr>
9193
</tbody>
9294
</table>

client/deployment/pom.xml

Lines changed: 18 additions & 10 deletions
Original file line numberDiff line numberDiff line change
@@ -11,7 +11,7 @@
1111
<name>Quarkus - Openapi Generator - Client - Deployment</name>
1212

1313
<properties>
14-
<version.org.openapitools>7.6.0</version.org.openapitools>
14+
<version.org.openapitools>7.8.0</version.org.openapitools>
1515
<version.org.slf4j>2.0.16</version.org.slf4j>
1616
<version.com.github.jknack>4.3.1</version.com.github.jknack>
1717
</properties>
@@ -138,15 +138,23 @@
138138
<plugins>
139139
<plugin>
140140
<artifactId>maven-compiler-plugin</artifactId>
141-
<configuration>
142-
<annotationProcessorPaths>
143-
<path>
144-
<groupId>io.quarkus</groupId>
145-
<artifactId>quarkus-extension-processor</artifactId>
146-
<version>${quarkus.version}</version>
147-
</path>
148-
</annotationProcessorPaths>
149-
</configuration>
141+
<executions>
142+
<execution>
143+
<id>default-compile</id>
144+
<configuration>
145+
<annotationProcessorPaths>
146+
<path>
147+
<groupId>io.quarkus</groupId>
148+
<artifactId>quarkus-extension-processor</artifactId>
149+
<version>${quarkus.version}</version>
150+
</path>
151+
</annotationProcessorPaths>
152+
<compilerArgs>
153+
<arg>-AlegacyConfigRoot=true</arg>
154+
</compilerArgs>
155+
</configuration>
156+
</execution>
157+
</executions>
150158
</plugin>
151159
</plugins>
152160
</build>

client/deployment/src/main/java/io/quarkiverse/openapi/generator/deployment/CodegenConfig.java

Lines changed: 3 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -34,6 +34,7 @@ public enum ConfigName {
3434
//global configs
3535
VERBOSE("verbose"),
3636
INPUT_BASE_DIR("input-base-dir"),
37+
TEMPLATE_BASE_DIR("template-base-dir"),
3738
INCLUDE("include"),
3839
EXCLUDE("exclude"),
3940
VALIDATE_SPEC("validateSpec"),
@@ -48,6 +49,8 @@ public enum ConfigName {
4849
//global & spec configs
4950
SKIP_FORM_MODEL("skip-form-model"),
5051
MUTINY("mutiny"),
52+
MUTINY_RETURN_RESPONSE("mutiny.return-response"),
53+
MUTINY_OPERATION_IDS("mutiny.operation-ids"),
5154
ADDITIONAL_MODEL_TYPE_ANNOTATIONS("additional-model-type-annotations"),
5255
ADDITIONAL_ENUM_TYPE_UNEXPECTED_MEMBER("additional-enum-type-unexpected-member"),
5356
ADDITIONAL_ENUM_TYPE_UNEXPECTED_MEMBER_NAME("additional-enum-type-unexpected-member-name"),

client/deployment/src/main/java/io/quarkiverse/openapi/generator/deployment/CommonItemConfig.java

Lines changed: 36 additions & 1 deletion
Original file line numberDiff line numberDiff line change
@@ -86,6 +86,41 @@ public class CommonItemConfig {
8686
@ConfigItem(name = "mutiny")
8787
public Optional<Boolean> supportMutiny;
8888

89+
/**
90+
* Defines with SmallRye Mutiny enabled if methods should return {@link jakarta.ws.rs.core.Response} or a model. Default is
91+
* {@code false}.
92+
*/
93+
@ConfigItem(name = "mutiny.return-response")
94+
public Optional<Boolean> mutinyReturnResponse;
95+
96+
/**
97+
* Handles the return type for each operation, depending on the configuration.
98+
* The following cases are supported:
99+
* <p>
100+
* 1. If {@code mutiny} is enabled and the operation ID is specified to return {@code Multi}:
101+
* - The return type will be wrapped in {@link io.smallrye.mutiny.Multi}.
102+
* - If {@code mutiny.return-response} is enabled, the return type will be
103+
* {@link io.smallrye.mutiny.Multi<jakarta.ws.rs.core.Response>}.
104+
* - If the operation has a void return type, it will return {@link io.smallrye.mutiny.Multi<jakarta.ws.rs.core.Response>}.
105+
* - Otherwise, it will return {@link io.smallrye.mutiny.Multi<returnType>}.
106+
* <p>
107+
* 2. If {@code mutiny} is enabled and the operation ID is specified to return {@code Uni}:
108+
* - The return type will be wrapped in {@link io.smallrye.mutiny.Uni}.
109+
* - If {@code mutiny.return-response} is enabled, the return type will be
110+
* {@link io.smallrye.mutiny.Uni<jakarta.ws.rs.core.Response>}.
111+
* - If the operation has a void return type, it will return {@link io.smallrye.mutiny.Uni<jakarta.ws.rs.core.Response>}.
112+
* - Otherwise, it will return {@link io.smallrye.mutiny.Uni<returnType>}.
113+
* <p>
114+
* 3. If {@code mutiny} is enabled but no specific operation ID is configured for {@code Multi} or {@code Uni}:
115+
* - The return type defaults to {@code Uni}.
116+
* - If {@code mutiny.return-response} is enabled, the return type will be
117+
* {@link io.smallrye.mutiny.Uni<jakarta.ws.rs.core.Response>}.
118+
* - If the operation has a void return type, it will return {@link io.smallrye.mutiny.Uni<jakarta.ws.rs.core.Response>}.
119+
* - Otherwise, it will return {@link io.smallrye.mutiny.Uni<returnType>}`.
120+
*/
121+
@ConfigItem(name = "mutiny.operation-ids")
122+
public Optional<Map<String, String>> mutinyMultiOperationIds;
123+
89124
/**
90125
* Defines, whether the `PartFilename` ({@link org.jboss.resteasy.reactive.PartFilename} or
91126
* {@link org.jboss.resteasy.annotations.providers.multipart.PartFilename}) annotation should be generated for
@@ -118,4 +153,4 @@ public class CommonItemConfig {
118153
*/
119154
@ConfigItem(name = "use-bean-validation")
120155
public Optional<Boolean> useBeanValidation;
121-
}
156+
}

client/deployment/src/main/java/io/quarkiverse/openapi/generator/deployment/GlobalCodegenConfig.java

Lines changed: 6 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -27,6 +27,12 @@ public class GlobalCodegenConfig extends CommonItemConfig {
2727
@ConfigItem(name = "input-base-dir")
2828
public Optional<String> inputBaseDir;
2929

30+
/**
31+
* Option to change the directory where template files must be found.
32+
*/
33+
@ConfigItem(name = "template-base-dir")
34+
public Optional<String> templateBaseDir;
35+
3036
/**
3137
* Whether or not to skip validating the input spec prior to generation. By default, invalid specifications will result in
3238
* an error.

client/deployment/src/main/java/io/quarkiverse/openapi/generator/deployment/codegen/OpenApiGeneratorCodeGenBase.java

Lines changed: 21 additions & 5 deletions
Original file line numberDiff line numberDiff line change
@@ -13,6 +13,7 @@
1313
import static io.quarkiverse.openapi.generator.deployment.CodegenConfig.ConfigName.INPUT_BASE_DIR;
1414
import static io.quarkiverse.openapi.generator.deployment.CodegenConfig.ConfigName.MODEL_NAME_PREFIX;
1515
import static io.quarkiverse.openapi.generator.deployment.CodegenConfig.ConfigName.MODEL_NAME_SUFFIX;
16+
import static io.quarkiverse.openapi.generator.deployment.CodegenConfig.ConfigName.TEMPLATE_BASE_DIR;
1617
import static io.quarkiverse.openapi.generator.deployment.CodegenConfig.ConfigName.VALIDATE_SPEC;
1718

1819
import java.io.IOException;
@@ -119,7 +120,9 @@ public boolean trigger(CodeGenContext context) throws CodeGenException {
119120
}
120121

121122
try (Stream<Path> openApiFilesPaths = Files.walk(openApiDir)) {
122-
Path templateDir = context.workDir().resolve("classes").resolve("templates");
123+
Optional<String> templateBaseDir = getTemplateBaseDirRelativeToSourceRoot(context.inputDir(), context.config());
124+
Path templateDir = templateBaseDir.map(Path::of)
125+
.orElseGet(() -> context.workDir().resolve("classes").resolve("templates"));
123126
openApiFilesPaths
124127
.filter(Files::isRegularFile)
125128
.filter(path -> {
@@ -232,6 +235,10 @@ protected void generate(final Config config, final Path openApiFilePath, final P
232235
generator.withReturnResponse(
233236
getValues(config, openApiFilePath, CodegenConfig.ConfigName.RETURN_RESPONSE, Boolean.class).orElse(false));
234237

238+
generator.withMutinyReturnResponse(
239+
getValues(config, openApiFilePath, CodegenConfig.ConfigName.MUTINY_RETURN_RESPONSE, Boolean.class)
240+
.orElse(false));
241+
235242
generator.withEnabledSecurityGeneration(
236243
getValues(config, openApiFilePath, CodegenConfig.ConfigName.ENABLE_SECURITY_GENERATION, Boolean.class)
237244
.orElse(true));
@@ -266,6 +273,9 @@ protected void generate(final Config config, final Path openApiFilePath, final P
266273
CodegenConfig.ConfigName.ADDITIONAL_PROPERTIES_AS_ATTRIBUTE, Boolean.class)
267274
.orElse(Boolean.FALSE);
268275

276+
getValues(smallRyeConfig, openApiFilePath, CodegenConfig.ConfigName.MUTINY_OPERATION_IDS, String.class, String.class)
277+
.ifPresent(generator::withMutinyReturnTypes);
278+
269279
generator.withAdditionalPropertiesAsAttribute(additionalPropertiesAsAttribute);
270280
GlobalSettings.setProperty(
271281
OpenApiClientGeneratorWrapper.SUPPORTS_ADDITIONAL_PROPERTIES_AS_ATTRIBUTE,
@@ -292,8 +302,7 @@ private static OpenApiClientGeneratorWrapper createGeneratorWrapper(Path openApi
292302
}
293303

294304
private String getBasePackage(final Config config, final Path openApiFilePath) {
295-
return config
296-
.getOptionalValue(getSpecConfigName(BASE_PACKAGE, openApiFilePath), String.class)
305+
return getValues(config, openApiFilePath, BASE_PACKAGE, String.class)
297306
.orElse(String.format("%s.%s", DEFAULT_PACKAGE, getSanitizedFileName(openApiFilePath)));
298307
}
299308

@@ -312,9 +321,16 @@ private Optional<String> getModelNamePrefix(final Config config, final Path open
312321
}
313322

314323
private Optional<String> getInputBaseDirRelativeToModule(final Path sourceDir, final Config config) {
315-
return config.getOptionalValue(getGlobalConfigName(INPUT_BASE_DIR), String.class).map(inputBaseDir -> {
324+
return config.getOptionalValue(getGlobalConfigName(INPUT_BASE_DIR), String.class).map(baseDir -> {
316325
int srcIndex = sourceDir.toString().lastIndexOf("src");
317-
return srcIndex < 0 ? null : sourceDir.toString().substring(0, srcIndex) + inputBaseDir;
326+
return srcIndex < 0 ? null : sourceDir.toString().substring(0, srcIndex) + baseDir;
327+
});
328+
}
329+
330+
private Optional<String> getTemplateBaseDirRelativeToSourceRoot(final Path sourceDir, final Config config) {
331+
return config.getOptionalValue(getGlobalConfigName(TEMPLATE_BASE_DIR), String.class).map(baseDir -> {
332+
int srcIndex = sourceDir.toString().lastIndexOf(inputDirectory());
333+
return srcIndex < 0 ? null : sourceDir.toString().substring(0, srcIndex) + baseDir;
318334
});
319335
}
320336

client/deployment/src/main/java/io/quarkiverse/openapi/generator/deployment/wrapper/OpenApiClientGeneratorWrapper.java

Lines changed: 16 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -12,6 +12,7 @@
1212
import java.io.File;
1313
import java.nio.file.Path;
1414
import java.util.Collections;
15+
import java.util.HashMap;
1516
import java.util.List;
1617
import java.util.Map;
1718
import java.util.Optional;
@@ -117,6 +118,21 @@ public OpenApiClientGeneratorWrapper withMutiny(final Boolean config) {
117118
return this;
118119
}
119120

121+
public OpenApiClientGeneratorWrapper withMutinyReturnResponse(final Boolean config) {
122+
if (config != null) {
123+
configurator.addAdditionalProperty("mutiny-return-response", config);
124+
}
125+
return this;
126+
}
127+
128+
public OpenApiClientGeneratorWrapper withMutinyReturnTypes(final Map<String, String> returnTypeMappings) {
129+
if (returnTypeMappings != null && !returnTypeMappings.isEmpty()) {
130+
Map<String, Object> mutinyOperationIdsMap = new HashMap<>(returnTypeMappings);
131+
configurator.addAdditionalProperty("mutiny-operation-ids", mutinyOperationIdsMap);
132+
}
133+
return this;
134+
}
135+
120136
/**
121137
* Sets the global 'skipFormModel' setting. If not set this setting will default to true.
122138
*

client/deployment/src/main/java/io/quarkiverse/openapi/generator/deployment/wrapper/QuarkusJavaClientCodegen.java

Lines changed: 2 additions & 2 deletions
Original file line numberDiff line numberDiff line change
@@ -140,7 +140,7 @@ public String toEnumVarName(String value, String datatype) {
140140
return this.getSymbolName(value).toUpperCase(Locale.ROOT);
141141
}
142142

143-
String enumVarName = super.toEnumVarName(value, datatype);
143+
String enumVarName = super.toEnumVarName(value.toLowerCase(Locale.ROOT), datatype);
144144

145145
if (enumVarName.startsWith("NUMBER_")) {
146146
return enumVarName;
@@ -189,4 +189,4 @@ private void configureAdditionalPropertiesAsAttribute() {
189189
this.supportsAdditionalPropertiesWithComposedSchema = true;
190190
}
191191
}
192-
}
192+
}

0 commit comments

Comments
 (0)