Skip to content
Draft
Show file tree
Hide file tree
Changes from 9 commits
Commits
File filter

Filter by extension

Filter by extension

Conversations
Failed to load comments.
Loading
Jump to
Jump to file
Failed to load files.
Loading
Diff view
Diff view
Original file line number Diff line number Diff line change
Expand Up @@ -68,6 +68,14 @@ public class Generate extends OpenApiGeneratorCommand {
@Option(name = "--merged-spec-filename", title = "Name of resulted merged specs file (used along with --input-spec-root-directory option)")
private String mergedFileName;

@Option(name = "--merge-conflict-strategy", title = "Merge conflict strategy",
description = "Strategy when two specs define the same component/path+method with different definitions: WARN (default, keep first) or FAIL (abort). Only applies with --merge-mode DEEP.")
private String mergeConflictStrategy;

@Option(name = "--merge-mode", title = "Merge mode",
description = "How multiple spec files are merged: REF (default, original $ref-based) or DEEP (full inline merge with component deduplication).")
private String mergeMode;

@Option(name = {"-t", "--template-dir"}, title = "template directory",
description = "folder containing the template files")
private String templateDir;
Expand Down Expand Up @@ -346,8 +354,14 @@ public class Generate extends OpenApiGeneratorCommand {
@Override
public void execute() {
if (StringUtils.isNotBlank(inputSpecRootDirectory)) {
spec = new MergedSpecBuilder(inputSpecRootDirectory, StringUtils.isBlank(mergedFileName) ? "_merged_spec" : mergedFileName)
.buildMergedSpec();
MergedSpecBuilder builder = new MergedSpecBuilder(inputSpecRootDirectory, StringUtils.isBlank(mergedFileName) ? "_merged_spec" : mergedFileName);
if (StringUtils.isNotBlank(mergeMode)) {
builder.withMergeMode(MergedSpecBuilder.MergeMode.valueOf(mergeMode.toUpperCase(java.util.Locale.ROOT)));
}
if (StringUtils.isNotBlank(mergeConflictStrategy)) {
builder.withConflictStrategy(MergedSpecBuilder.MergeConflictStrategy.valueOf(mergeConflictStrategy.toUpperCase(java.util.Locale.ROOT)));
}
spec = builder.buildMergedSpec();
System.out.println("Merge input spec would be used - " + spec);
}

Expand Down
Original file line number Diff line number Diff line change
Expand Up @@ -102,6 +102,9 @@ class OpenApiGeneratorPlugin : Plugin<Project> {
inputSpec.set(generate.inputSpec)
inputSpecRootDirectory.set(generate.inputSpecRootDirectory)
inputSpecRootDirectorySkipMerge.set(generate.inputSpecRootDirectorySkipMerge)
mergedFileName.set(generate.mergedFileName)
mergeMode.set(generate.mergeMode)
mergeConflictStrategy.set(generate.mergeConflictStrategy)
remoteInputSpec.set(generate.remoteInputSpec)
templateDir.set(generate.templateDir)
templateResourcePath.set(generate.templateResourcePath)
Expand Down
Original file line number Diff line number Diff line change
Expand Up @@ -80,6 +80,28 @@ open class OpenApiGeneratorGenerateExtension(private val project: Project) {
*/
val inputSpecRootDirectorySkipMerge = project.objects.property<Boolean>()

/**
* Name of the file that will contain all merged specs (used with inputSpecRootDirectory).
*
* Default: "merged"
*/
val mergedFileName = project.objects.property<String>()

/**
* How multiple spec files are merged. Accepted values: "REF" (default, original $ref-based
* shallow merge, backward-compatible) or "DEEP" (full inline merge with component
* deduplication and conflict detection).
*/
val mergeMode = project.objects.property<String>()

/**
* Strategy when two specs define the same component name or path+method with conflicting
* (non-identical) definitions. Accepted values: "WARN" (default, keep first definition and
* log a warning) or "FAIL" (throw an exception and abort the build). Only applies when
* mergeMode is "DEEP".
*/
val mergeConflictStrategy = project.objects.property<String>()

/**
* The remote Open API 2.0/3.x specification URL location.
*/
Expand Down Expand Up @@ -449,6 +471,9 @@ open class OpenApiGeneratorGenerateExtension(private val project: Project) {
fun applyDefaults() {
releaseNote.convention("Minor update")
inputSpecRootDirectorySkipMerge.convention(false)
mergedFileName.convention("merged")
mergeMode.convention("REF")
mergeConflictStrategy.convention("WARN")
modelNamePrefix.convention("")
modelNameSuffix.convention("")
apiNameSuffix.convention("")
Expand Down
Original file line number Diff line number Diff line change
Expand Up @@ -406,6 +406,23 @@ abstract class GenerateTask : DefaultTask() {
@get:Optional
abstract val mergedFileName: Property<String>

/**
* How multiple spec files are merged. Accepted values: "REF" (default, original $ref-based
* shallow merge, backward-compatible) or "DEEP" (full inline merge with component
* deduplication and conflict detection).
*/
@get:Input
@get:Optional
abstract val mergeMode: Property<String>

/**
* Strategy when two specs define the same component name or path+method with conflicting
* definitions. Accepted values: "WARN" (default) or "FAIL". Only applies when mergeMode is "DEEP".
*/
@get:Input
@get:Optional
abstract val mergeConflictStrategy: Property<String>

/**
* The remote Open API 2.0/3.x specification URL location.
*/
Expand Down Expand Up @@ -873,6 +890,8 @@ abstract class GenerateTask : DefaultTask() {
init {
inputSpecRootDirectorySkipMerge.convention(false)
mergedFileName.convention("merged")
mergeMode.convention("REF")
mergeConflictStrategy.convention("WARN")
}

@Suppress("unused")
Expand All @@ -896,6 +915,10 @@ abstract class GenerateTask : DefaultTask() {
finalResolvedInputSpec = MergedSpecBuilder(
inputDir.asFile.absolutePath,
mergedFileName.get()
).withMergeMode(
MergedSpecBuilder.MergeMode.valueOf(mergeMode.get().uppercase())
).withConflictStrategy(
MergedSpecBuilder.MergeConflictStrategy.valueOf(mergeConflictStrategy.get().uppercase())
).buildMergedSpec()
logger.info("Merge input spec used: {}", finalResolvedInputSpec)
}
Expand Down
Original file line number Diff line number Diff line change
Expand Up @@ -10,7 +10,7 @@ paths:
/v3/pets:
get:
summary: List all pets
operationId: listPets
operationId: listPetsV3
tags:
- pets
parameters:
Expand Down Expand Up @@ -41,7 +41,7 @@ paths:
$ref: "#/components/schemas/Error"
post:
summary: Create a pet
operationId: createPets
operationId: createPetsV3
tags:
- pets
responses:
Expand All @@ -56,7 +56,7 @@ paths:
/v3/pets/{petId}:
get:
summary: Info for a specific pet
operationId: showPetById
operationId: showPetByIdV3
tags:
- pets
parameters:
Expand Down
Original file line number Diff line number Diff line change
Expand Up @@ -137,6 +137,22 @@ public class CodeGenMojo extends AbstractMojo {
@Parameter(name = "mergedFileInfoVersion", property = "openapi.generator.maven.plugin.mergedFileInfoVersion", defaultValue = "1.0.0")
private String mergedFileInfoVersion;

/**
* Strategy when two specs define the same component name or path+method with different
* definitions. Accepted values: WARN (default, keep the first definition and log a warning)
* or FAIL (abort the build with an error). Only applies when mergeMode is DEEP.
*/
@Parameter(name = "mergeConflictStrategy", property = "openapi.generator.maven.plugin.mergeConflictStrategy", defaultValue = "WARN")
private String mergeConflictStrategy;

/**
* How multiple spec files are merged. Accepted values: REF (default, original $ref-based
* shallow merge, backward-compatible) or DEEP (full inline merge with component
* deduplication and conflict detection).
*/
@Parameter(name = "mergeMode", property = "openapi.generator.maven.plugin.mergeMode", defaultValue = "REF")
private String mergeMode;

/**
* Git host, e.g. gitlab.com.
*/
Expand Down Expand Up @@ -584,6 +600,8 @@ public void execute() throws MojoExecutionException {

inputSpec = new MergedSpecBuilder(inputSpecRootDirectory, mergedFileName,
mergedFileInfoName, mergedFileInfoDescription, mergedFileInfoVersion, auth)
.withMergeMode(MergedSpecBuilder.MergeMode.valueOf(mergeMode.toUpperCase(java.util.Locale.ROOT)))
.withConflictStrategy(MergedSpecBuilder.MergeConflictStrategy.valueOf(mergeConflictStrategy.toUpperCase(java.util.Locale.ROOT)))
.buildMergedSpec();
LOGGER.info("Merge input spec would be used - {}", inputSpec);
}
Expand Down
Original file line number Diff line number Diff line change
Expand Up @@ -127,6 +127,23 @@ public class ValidateMojo extends AbstractMojo {
*/
@Parameter(name = "mergedFileInfoVersion", property = "openapi.generator.maven.plugin.mergedFileInfoVersion", defaultValue = "1.0.0")
private String mergedFileInfoVersion;

/**
* Strategy when two specs define the same component name or path+method with different
* definitions. Accepted values: WARN (default, keep the first definition and log a warning)
* or FAIL (abort the build with an error). Only applies when mergeMode is DEEP.
*/
@Parameter(name = "mergeConflictStrategy", property = "openapi.generator.maven.plugin.mergeConflictStrategy", defaultValue = "WARN")
private String mergeConflictStrategy;

/**
* How multiple spec files are merged. Accepted values: REF (default, original $ref-based
* shallow merge, backward-compatible) or DEEP (full inline merge with component
* deduplication and conflict detection).
*/
@Parameter(name = "mergeMode", property = "openapi.generator.maven.plugin.mergeMode", defaultValue = "REF")
private String mergeMode;

/**
* The path to the collapsed single-file representation of the OpenAPI spec.
*/
Expand Down Expand Up @@ -251,6 +268,8 @@ private Optional<String> mergeInDirectory() {

mergedSpec = Optional.of(new MergedSpecBuilder(inputSpecRootDirectory, mergedFileName,
mergedFileInfoName, mergedFileInfoDescription, mergedFileInfoVersion, auth)
.withMergeMode(MergedSpecBuilder.MergeMode.valueOf(mergeMode.toUpperCase(java.util.Locale.ROOT)))
.withConflictStrategy(MergedSpecBuilder.MergeConflictStrategy.valueOf(mergeConflictStrategy.toUpperCase(java.util.Locale.ROOT)))
Comment thread
cubic-dev-ai[bot] marked this conversation as resolved.
Outdated
.buildMergedSpec());
LOGGER.info("Merge input spec would be used - {}", mergedSpec.get());
}
Expand Down
Loading
Loading