@@ -22,6 +22,7 @@ import (
2222 "github.com/getkin/kin-openapi/openapi3"
2323 "github.com/mongodb/openapi/tools/cli/internal/openapi/errors"
2424 "github.com/tufin/oasdiff/diff"
25+
2526 "github.com/tufin/oasdiff/flatten/allof"
2627 "github.com/tufin/oasdiff/load"
2728)
@@ -111,20 +112,91 @@ func (o OasDiff) mergePaths() error {
111112 return nil
112113 }
113114
114- for k , v := range pathsToMerge .Map () {
115- if ok := basePaths .Value (k ); ok == nil {
116- basePaths .Set (k , removeExternalRefs (v ))
115+ for externalPath , externalPathData := range pathsToMerge .Map () {
116+ // Tries to find if the path already exists or not
117+ if originalPath := basePaths .Value (externalPath ); originalPath == nil {
118+ basePaths .Set (externalPath , removeExternalRefs (externalPathData ))
117119 } else {
120+ if shouldSkipConflict (originalPath , externalPathData , externalPath ) {
121+ log .Println ("Skipping conflict for path: " , externalPath )
122+ continue
123+ }
118124 return errors.PathConflictError {
119- Entry : k ,
125+ Entry : externalPath ,
120126 }
121127 }
122128 }
123-
124129 o .base .Spec .Paths = basePaths
125130 return nil
126131}
127132
133+ // shouldSkipConflict checks if the conflict should be skipped.
134+ // The method goes through each path operation, and validates if it exists for
135+ // both paths, if it does not, the path conflict should not be ignored.
136+ // If it does, then we check if there is an x-xgen-soa-migration annotation
137+ // If it does, then we allow the conflict to be skipped.
138+ func shouldSkipConflict (basePath , externalPath * openapi3.PathItem , basePathName string ) bool {
139+ if basePath .Get != nil && externalPath .Get == nil {
140+ return false
141+ }
142+
143+ if basePath .Put != nil && externalPath .Put == nil {
144+ return false
145+ }
146+
147+ if basePath .Post != nil && externalPath .Post == nil {
148+ return false
149+ }
150+
151+ if basePath .Patch != nil && externalPath .Patch == nil {
152+ return false
153+ }
154+
155+ if basePath .Delete != nil && externalPath .Delete == nil {
156+ return false
157+ }
158+
159+ // now check if there is an x-xgen-soa-migration annotation in any of the operations, but if any of the operations
160+ // doesn't have, then we should not skip the conflict
161+ return allMethodsHaveExtension (basePath , basePathName )
162+ }
163+
164+ // allMethodsHaveExtension checks if all the methods in a path have the x-xgen-soa-migration extension.
165+ func allMethodsHaveExtension (basePath * openapi3.PathItem , basePathName string ) bool {
166+ if basePath .Get != nil {
167+ if basePath .Get .Extensions == nil || basePath .Get .Extensions ["x-xgen-soa-migration" ] == nil {
168+ return false
169+ }
170+ }
171+
172+ if basePath .Put != nil {
173+ if basePath .Put .Extensions == nil || basePath .Put .Extensions ["x-xgen-soa-migration" ] == nil {
174+ return false
175+ }
176+ }
177+
178+ if basePath .Post != nil {
179+ if basePath .Post .Extensions == nil || basePath .Post .Extensions ["x-xgen-soa-migration" ] == nil {
180+ return false
181+ }
182+ }
183+
184+ if basePath .Patch != nil {
185+ if basePath .Patch .Extensions == nil || basePath .Patch .Extensions ["x-xgen-soa-migration" ] == nil {
186+ return false
187+ }
188+ }
189+
190+ if basePath .Delete != nil {
191+ if basePath .Delete .Extensions == nil || basePath .Delete .Extensions ["x-xgen-soa-migration" ] == nil {
192+ return false
193+ }
194+ }
195+
196+ log .Println ("Detected x-xgen-soa-migration annotation in all operations for path: " , basePathName )
197+ return true
198+ }
199+
128200// removeExternalRefs updates the external references of OASes to remove the reference to openapi-mms.json.
129201// Example of an external ref is "$ref": "openapi-mms.json#/components/responses/internalServerError"
130202// Example of an external ref after removeExternalRefs: "$ref": "#/components/responses/internalServerError"
0 commit comments