fix(MergedSpecBuilder): merge path items by HTTP method instead of overwriting on path collision#24100
fix(MergedSpecBuilder): merge path items by HTTP method instead of overwriting on path collision#24100Picazsoo wants to merge 20 commits into
Conversation
…erwriting on path collision
…or reactive generators
… types for reactive generators" This reverts commit 8972528.
…lisions in open api merging test
…omponent and path+method conflicts
There was a problem hiding this comment.
1 issue found and verified against the latest diff
Reply with feedback, questions, or to request a fix.
Re-trigger cubic
There was a problem hiding this comment.
5 issues found across 17 files
Prompt for AI agents (unresolved issues)
Check if these issues are valid — if so, understand the root cause of each and fix them. If appropriate, use sub-agents to investigate and fix each issue separately.
<file name="modules/openapi-generator/src/main/java/org/openapitools/codegen/config/MergedSpecBuilder.java">
<violation number="1" location="modules/openapi-generator/src/main/java/org/openapitools/codegen/config/MergedSpecBuilder.java:356">
P1: Deep merge path+method conflict detection is unconditional: it treats any duplicate method as a conflict without comparing whether the incoming operation is identical to the existing one. In FAIL mode this throws RuntimeException even for identical operations, which is inconsistent with component merging (where identical duplicates are silently deduplicated via Objects.equals) and contradicts documented intent of only warning on "different definitions".</violation>
</file>
Reply with feedback, questions, or to request a fix.
Re-trigger cubic
| return; | ||
| } | ||
| incoming.readOperationsMap().forEach((method, operation) -> { | ||
| if (existing.readOperationsMap() != null && existing.readOperationsMap().containsKey(method)) { |
There was a problem hiding this comment.
P1: Deep merge path+method conflict detection is unconditional: it treats any duplicate method as a conflict without comparing whether the incoming operation is identical to the existing one. In FAIL mode this throws RuntimeException even for identical operations, which is inconsistent with component merging (where identical duplicates are silently deduplicated via Objects.equals) and contradicts documented intent of only warning on "different definitions".
Prompt for AI agents
Check if this issue is valid — if so, understand the root cause and fix it. At modules/openapi-generator/src/main/java/org/openapitools/codegen/config/MergedSpecBuilder.java, line 356:
<comment>Deep merge path+method conflict detection is unconditional: it treats any duplicate method as a conflict without comparing whether the incoming operation is identical to the existing one. In FAIL mode this throws RuntimeException even for identical operations, which is inconsistent with component merging (where identical duplicates are silently deduplicated via Objects.equals) and contradicts documented intent of only warning on "different definitions".</comment>
<file context>
@@ -99,51 +186,238 @@ public String buildMergedSpec() {
+ return;
+ }
+ incoming.readOperationsMap().forEach((method, operation) -> {
+ if (existing.readOperationsMap() != null && existing.readOperationsMap().containsKey(method)) {
+ String message = String.format(Locale.ROOT,
+ "Path+method collision during spec merge: %s %s is defined in multiple specs with different definitions. Keeping the first definition.",
</file context>
There was a problem hiding this comment.
This is on purpose - schema reuse across multiple specs (e.g. sharing from some common-schemas.yaml file is expected and the merging should be able to handle that. Having POST operation defined for the same path in multiple specs is unexpected. But having POST operation for a path and PUT operation for the same path in different specs is expected and handled correctly. The documentation now tries to explain it clearly
…rameter loss caused by resolve:true in parseSpecFiles
… with full parity for mergedFileInfoName/Description/Version across all three plugins
PR checklist
Commit all changed files.
This is important, as CI jobs will verify all generator outputs of your HEAD commit as it would merge with master.
These must match the expectations made by your contribution.
You may regenerate an individual generator by passing the relevant config(s) as an argument to the script, for example
./bin/generate-samples.sh bin/configs/java*.IMPORTANT: Do NOT purge/delete any folders/files (e.g. tests) when regenerating the samples as manually written tests may be removed.
Summary by cubic
Improves multi-spec merging with a new DEEP mode that merges path items by HTTP method and detects conflicts. Keeps REF mode as the original $ref index merge, and adds explicit ordered file merging across CLI, Gradle, and Maven.
Bug Fixes
mergeConflictStrategy(WARN keeps first, FAIL aborts); REF keeps the last definition.x-vendor extensions; merge top-levelx-extensions (first wins).http://localhost:8080if none..yaml,.yml,.jsonin deterministic order; ignore other files; choose JSON if the first valid spec is JSON.New Features
mergeMode(REF,DEEP) andmergeConflictStrategy(WARN,FAIL) in CLI (--merge-mode,--merge-conflict-strategy), Gradle (mergeMode,mergeConflictStrategy), and Maven (mergeMode,mergeConflictStrategy); invalid values fail fast.--input-spec-fileswith--merged-file-output-dir), Gradle (inputSpecFiles,mergedFileOutputDir), and Maven (inputSpecFiles,mergedFileOutputDir); order is respected and overrides directory scanning.mergedFileInfoName,mergedFileInfoDescription,mergedFileInfoVersion); Gradle also addsmergedFileName(defaults tomerged).Written for commit 13baea2. Summary will update on new commits.