Skip to content

Commit 45d6975

Browse files
authored
Merge pull request #3983 from jooby-project/complement-3977
complement: persist openapi specification
2 parents adcc4e5 + b1859ed commit 45d6975

6 files changed

Lines changed: 203 additions & 185 deletions

File tree

docs/asciidoc/modules/openapi.adoc

Lines changed: 19 additions & 15 deletions
Original file line numberDiff line numberDiff line change
@@ -108,6 +108,25 @@ To avoid this behaviour you can specify maven build phase which suits your needs
108108
| `${project.dir}`
109109
|Set base directory used it for loading openAPI template file name.
110110

111+
|`copyOpenApiSpecTo`
112+
|
113+
|Copy the generated OpenAPI spec to the given file in the project repository. It must be one or
114+
more directories or file names. In case of directory both the `.json` and `.yaml` file are copy.
115+
Example:
116+
117+
.Maven:
118+
119+
<copyOpenApiSpecTo>
120+
<file>${project.basedir}/spec<file>
121+
<file>${project.basedir}/docs/openapi.yaml<file>
122+
</copyOpenApiSpecTo>
123+
124+
.Gradle:
125+
126+
{
127+
copyOpenApiSpecTo = ["${project.basedir}/spec", "$projectDir/docs/openapi.yaml"]
128+
}
129+
111130
|`excludes`
112131
|
113132
|Regular expression used to excludes route. Example: `/web`.
@@ -128,21 +147,6 @@ To avoid this behaviour you can specify maven build phase which suits your needs
128147
|`openapi.yaml`
129148
|Set openAPI template file path.
130149

131-
|`copyOpenApiSpecTo`
132-
|
133-
|Copy the generated OpenAPI spec to the given file in the project repository. The format is
134-
determined by the file extension: `.yaml`, `.yml` or `.json`. Example:
135-
136-
.Maven:
137-
138-
<copyOpenApiSpecTo>${project.basedir}/docs/openapi.yaml</copyOpenApiSpecTo>
139-
140-
.Gradle:
141-
142-
{
143-
copyOpenApiSpecTo = file("$projectDir/docs/openapi.yaml")
144-
}
145-
146150
|===
147151

148152
=== Usage

modules/jooby-gradle-plugin/src/main/java/io/jooby/gradle/OpenAPITask.java

Lines changed: 10 additions & 57 deletions
Original file line numberDiff line numberDiff line change
@@ -49,7 +49,7 @@ public class OpenAPITask extends BaseTask {
4949

5050
private String javadoc;
5151

52-
private File copyOpenApiSpecTo;
52+
private List<File> copyOpenApiSpecTo;
5353

5454
/**
5555
* Creates an OpenAPI task.
@@ -89,6 +89,7 @@ public void generate() throws Throwable {
8989
tool.setClassLoader(classLoader);
9090
tool.setOutputDir(outputDir);
9191
tool.setSources(sources);
92+
tool.setCopyOpenApiSpecTo(copyOpenApiSpecTo == null ? null : copyOpenApiSpecTo.stream().map(File::toPath).toList());
9293
if (specVersion != null) {
9394
tool.setSpecVersion(specVersion);
9495
}
@@ -101,48 +102,10 @@ public void generate() throws Throwable {
101102
OpenAPI result = tool.generate(mainClass);
102103

103104
var adocPath = ofNullable(adoc).orElse(List.of()).stream().map(File::toPath).toList();
104-
var written = new ArrayList<Path>();
105105
for (var format : OpenAPIGenerator.Format.values()) {
106-
written.addAll(tool.export(result, format, Map.of("adoc", adocPath)));
106+
tool.export(result, format, Map.of("adoc", adocPath))
107+
.forEach(output -> getLogger().info(" writing: " + output));
107108
}
108-
written.forEach(output -> getLogger().info(" writing: " + output));
109-
110-
if (copyOpenApiSpecTo != null) {
111-
var destination = copyOpenApiSpecTo.toPath();
112-
copySpec(written, destination);
113-
getLogger().info(" copying: " + destination);
114-
}
115-
}
116-
117-
static void copySpec(List<Path> written, Path destination) throws IOException {
118-
var format = specFormat(destination);
119-
var source =
120-
written.stream()
121-
.filter(path -> path.getFileName().toString().endsWith("." + format.extension()))
122-
.findFirst()
123-
.orElseThrow(
124-
() ->
125-
new IOException(
126-
String.format(
127-
"OpenAPI %s output not found for copyOpenApiSpecTo: %s",
128-
format.name(), destination)));
129-
var parent = destination.getParent();
130-
if (parent != null) {
131-
Files.createDirectories(parent);
132-
}
133-
Files.copy(source, destination, StandardCopyOption.REPLACE_EXISTING);
134-
}
135-
136-
static OpenAPIGenerator.Format specFormat(Path destination) {
137-
var name = destination.getFileName().toString().toLowerCase(Locale.ROOT);
138-
if (name.endsWith(".json")) {
139-
return OpenAPIGenerator.Format.JSON;
140-
}
141-
if (name.endsWith(".yaml") || name.endsWith(".yml")) {
142-
return OpenAPIGenerator.Format.YAML;
143-
}
144-
throw new IllegalArgumentException(
145-
"copyOpenApiSpecTo must end with .yaml, .yml or .json: " + destination);
146109
}
147110

148111
/**
@@ -289,32 +252,22 @@ public void setAdoc(List<File> adoc) {
289252
}
290253

291254
/**
292-
* Copy the generated OpenAPI spec to the given file. The format is determined by the file
293-
* extension: <code>.yaml</code>, <code>.yml</code> or <code>.json</code>.
255+
* List directories or files where the openAPI spec must be copied.
294256
*
295-
* @return Destination file.
257+
* @return List directories or files where the openAPI spec must be copied.
296258
*/
297259
@Input
298260
@org.gradle.api.tasks.Optional
299-
public @Nullable File getCopyOpenApiSpecTo() {
261+
public @Nullable List<File> getCopyOpenApiSpecTo() {
300262
return copyOpenApiSpecTo;
301263
}
302264

303265
/**
304-
* Copy the generated OpenAPI spec to the given file. The format is determined by the file
305-
* extension: <code>.yaml</code>, <code>.yml</code> or <code>.json</code>.
306-
*
307-
* <p>Example:
308-
*
309-
* <pre>{@code
310-
* openAPI {
311-
* copyOpenApiSpecTo = file("$projectDir/docs/openapi.yaml")
312-
* }
313-
* }</pre>
266+
* Copy open API files to either an output location or specific file.
314267
*
315-
* @param copyOpenApiSpecTo Destination file.
268+
* @param copyOpenApiSpecTo Output directory or file.
316269
*/
317-
public void setCopyOpenApiSpecTo(@Nullable File copyOpenApiSpecTo) {
270+
public void setCopyOpenApiSpecTo(@Nullable List<File> copyOpenApiSpecTo) {
318271
this.copyOpenApiSpecTo = copyOpenApiSpecTo;
319272
}
320273

modules/jooby-maven-plugin/src/main/java/io/jooby/maven/OpenAPIMojo.java

Lines changed: 7 additions & 49 deletions
Original file line numberDiff line numberDiff line change
@@ -10,14 +10,9 @@
1010
import static org.apache.maven.plugins.annotations.ResolutionScope.COMPILE_PLUS_RUNTIME;
1111

1212
import java.io.File;
13-
import java.io.IOException;
14-
import java.nio.file.Files;
1513
import java.nio.file.Path;
1614
import java.nio.file.Paths;
17-
import java.nio.file.StandardCopyOption;
18-
import java.util.ArrayList;
1915
import java.util.List;
20-
import java.util.Locale;
2116
import java.util.Map;
2217
import java.util.Optional;
2318

@@ -58,8 +53,7 @@ public class OpenAPIMojo extends BaseMojo {
5853

5954
@Parameter private List<File> adoc;
6055

61-
@Parameter(property = "openAPI.copyOpenApiSpecTo")
62-
private File copyOpenApiSpecTo;
56+
@Parameter private List<File> copyOpenApiSpecTo;
6357

6458
@Override
6559
protected void doExecute(List<MavenProject> projects, String mainClass) throws Exception {
@@ -83,6 +77,8 @@ protected void doExecute(List<MavenProject> projects, String mainClass) throws E
8377
tool.setClassLoader(classLoader);
8478
tool.setOutputDir(outputDir);
8579
tool.setSources(sources);
80+
tool.setCopyOpenApiSpecTo(
81+
copyOpenApiSpecTo == null ? null : copyOpenApiSpecTo.stream().map(File::toPath).toList());
8682
trim(includes).ifPresent(tool::setIncludes);
8783
trim(excludes).ifPresent(tool::setExcludes);
8884
if (javadoc != null && !javadoc.trim().isEmpty()) {
@@ -92,48 +88,10 @@ protected void doExecute(List<MavenProject> projects, String mainClass) throws E
9288
var result = tool.generate(mainClass);
9389

9490
var adocPath = ofNullable(adoc).orElse(List.of()).stream().map(File::toPath).toList();
95-
var written = new ArrayList<Path>();
9691
for (var format : OpenAPIGenerator.Format.values()) {
97-
written.addAll(tool.export(result, format, Map.of("adoc", adocPath)));
92+
tool.export(result, format, Map.of("adoc", adocPath))
93+
.forEach(output -> getLog().info(" writing: " + output));
9894
}
99-
written.forEach(output -> getLog().info(" writing: " + output));
100-
101-
if (copyOpenApiSpecTo != null) {
102-
var destination = copyOpenApiSpecTo.toPath();
103-
copySpec(written, destination);
104-
getLog().info(" copying: " + destination);
105-
}
106-
}
107-
108-
public static void copySpec(List<Path> written, Path destination) throws IOException {
109-
var format = specFormat(destination);
110-
var source =
111-
written.stream()
112-
.filter(path -> path.getFileName().toString().endsWith("." + format.extension()))
113-
.findFirst()
114-
.orElseThrow(
115-
() ->
116-
new IOException(
117-
String.format(
118-
"OpenAPI %s output not found for copyOpenApiSpecTo: %s",
119-
format.name(), destination)));
120-
var parent = destination.getParent();
121-
if (parent != null) {
122-
Files.createDirectories(parent);
123-
}
124-
Files.copy(source, destination, StandardCopyOption.REPLACE_EXISTING);
125-
}
126-
127-
public static OpenAPIGenerator.Format specFormat(Path destination) {
128-
var name = destination.getFileName().toString().toLowerCase(Locale.ROOT);
129-
if (name.endsWith(".json")) {
130-
return OpenAPIGenerator.Format.JSON;
131-
}
132-
if (name.endsWith(".yaml") || name.endsWith(".yml")) {
133-
return OpenAPIGenerator.Format.YAML;
134-
}
135-
throw new IllegalArgumentException(
136-
"copyOpenApiSpecTo must end with .yaml, .yml or .json: " + destination);
13795
}
13896

13997
private Optional<String> trim(String value) {
@@ -239,7 +197,7 @@ public String getJavadoc() {
239197
*
240198
* @return Destination file.
241199
*/
242-
public @Nullable File getCopyOpenApiSpecTo() {
200+
public @Nullable List<File> getCopyOpenApiSpecTo() {
243201
return copyOpenApiSpecTo;
244202
}
245203

@@ -255,7 +213,7 @@ public String getJavadoc() {
255213
*
256214
* @param copyOpenApiSpecTo Destination file.
257215
*/
258-
public void setCopyOpenApiSpecTo(@Nullable File copyOpenApiSpecTo) {
216+
public void setCopyOpenApiSpecTo(@Nullable List<File> copyOpenApiSpecTo) {
259217
this.copyOpenApiSpecTo = copyOpenApiSpecTo;
260218
}
261219
}

modules/jooby-maven-plugin/src/test/java/io/jooby/maven/OpenAPIMojoTest.java

Lines changed: 0 additions & 57 deletions
This file was deleted.

0 commit comments

Comments
 (0)