-
Notifications
You must be signed in to change notification settings - Fork 14
CLOUDP-271223: Skip conflict when x-xgen-soa-migration is set #243
New issue
Have a question about this project? Sign up for a free GitHub account to open an issue and contact its maintainers and the community.
By clicking “Sign up for GitHub”, you agree to our terms of service and privacy statement. We’ll occasionally send you account related emails.
Already on GitHub? Sign in to your account
Changes from 12 commits
2f091dd
04c2eb8
5c1b255
b69e8a1
9df5a39
ef3b6e6
dd500c8
fa10ddf
d35e601
5ded458
0a5d7df
8eb3c9e
e45a90b
bf5ed4b
580dcd5
61613ab
03e789d
413a716
eaed0f0
73e8aae
354f4d9
d78e2c2
a97ba4e
File filter
Filter by extension
Conversations
Jump to
Diff view
Diff view
There are no files selected for viewing
Some generated files are not rendered by default. Learn more about how customized files appear on GitHub.
Some generated files are not rendered by default. Learn more about how customized files appear on GitHub.
Original file line number | Diff line number | Diff line change |
---|---|---|
|
@@ -22,16 +22,18 @@ import ( | |
"github.com/getkin/kin-openapi/openapi3" | ||
"github.com/mongodb/openapi/tools/cli/internal/openapi/errors" | ||
"github.com/tufin/oasdiff/diff" | ||
|
||
"github.com/tufin/oasdiff/flatten/allof" | ||
"github.com/tufin/oasdiff/load" | ||
) | ||
|
||
type OasDiff struct { | ||
base *load.SpecInfo | ||
external *load.SpecInfo | ||
config *diff.Config | ||
specDiff *diff.Diff | ||
parser Parser | ||
base *load.SpecInfo | ||
external *load.SpecInfo | ||
config *diff.Config | ||
specDiff *diff.Diff | ||
noExtDiff NoExtensionDiff | ||
|
||
parser Parser | ||
} | ||
|
||
type OasDiffResult struct { | ||
|
@@ -111,16 +113,18 @@ func (o OasDiff) mergePaths() error { | |
return nil | ||
} | ||
|
||
for k, v := range pathsToMerge.Map() { | ||
if ok := basePaths.Value(k); ok == nil { | ||
basePaths.Set(k, removeExternalRefs(v)) | ||
for path, externalPathData := range pathsToMerge.Map() { | ||
// Tries to find if the path already exists or not | ||
if originalPathData := basePaths.Value(path); originalPathData == nil { | ||
basePaths.Set(path, removeExternalRefs(externalPathData)) | ||
} else { | ||
return errors.PathConflictError{ | ||
Entry: k, | ||
err := o.handlePathConflict(originalPathData, path) | ||
if err != nil { | ||
return err | ||
blva marked this conversation as resolved.
Outdated
Show resolved
Hide resolved
|
||
} | ||
basePaths.Set(path, removeExternalRefs(externalPathData)) | ||
} | ||
} | ||
|
||
o.base.Spec.Paths = basePaths | ||
return nil | ||
} | ||
|
@@ -160,6 +164,69 @@ func removeExternalRefs(path *openapi3.PathItem) *openapi3.PathItem { | |
return path | ||
} | ||
|
||
// handlePathConflict handles the path conflict by checking if the conflict should be skipped or not. | ||
func (o OasDiff) handlePathConflict(basePath *openapi3.PathItem, basePathName string) error { | ||
if !o.shouldSkipPathConflict(basePath, basePathName) { | ||
return errors.PathConflictError{ | ||
Entry: basePathName, | ||
} | ||
} | ||
|
||
var pathsAreIdentical bool | ||
var err error | ||
if pathsAreIdentical, err = o.arePathsIdenticalWithExcludeExtensions(basePathName); err != nil { | ||
return err | ||
} | ||
|
||
log.Printf("Skipping conflict for path: %s, pathsAreIdentical: %v", basePathName, pathsAreIdentical) | ||
if pathsAreIdentical { | ||
return nil | ||
} | ||
|
||
// allowDocsDiff = true not supported | ||
There was a problem hiding this comment. Choose a reason for hiding this commentThe reason will be displayed to describe this comment to others. Learn more. Could you update this comment to add more context: what is |
||
if allOperationsAllowDocsDiff(basePath) { | ||
return errors.AllowDocsDiffNotSupportedError{ | ||
Entry: basePathName, | ||
} | ||
} | ||
|
||
d, err := o.noExtDiff.GetPathDiffWithoutExtensions(o.base.Spec, o.external.Spec) | ||
if err != nil { | ||
return err | ||
} | ||
|
||
return errors.PathDocsDiffConflictError{ | ||
Entry: basePathName, | ||
Diff: d, | ||
} | ||
} | ||
|
||
// shouldSkipConflict checks if the conflict should be skipped. | ||
// The method goes through each path operation and performs the following checks: | ||
// 1. Validates if both paths have same operations, if not, then it returns false. | ||
// 2. If both paths have the same operations, then it checks if there is an x-xgen-soa-migration annotation. | ||
andreaangiolillo marked this conversation as resolved.
Show resolved
Hide resolved
|
||
// If there is no annotation, then it returns false. | ||
func (o OasDiff) shouldSkipPathConflict(basePath *openapi3.PathItem, basePathName string) bool { | ||
var pathsDiff *diff.PathsDiff | ||
if o.specDiff != nil { | ||
pathsDiff = o.specDiff.PathsDiff | ||
} | ||
|
||
if pathsDiff != nil && pathsDiff.Modified != nil && pathsDiff.Modified[basePathName] != nil { | ||
if ok := o.specDiff.PathsDiff.Modified[basePathName].OperationsDiff.Added; !ok.Empty() { | ||
return false | ||
} | ||
|
||
if ok := o.specDiff.PathsDiff.Modified[basePathName].OperationsDiff.Deleted; !ok.Empty() { | ||
return false | ||
} | ||
} | ||
|
||
// now check if there is an x-xgen-soa-migration annotation in any of the operations, but if any of the operations | ||
// doesn't have, then we should not skip the conflict | ||
return allOperationsHaveExtension(basePath, basePathName, xgenSoaMigration) | ||
} | ||
|
||
// updateExternalRefResponses updates the external references of OASes to remove the reference to openapi-mms.json | ||
// in the Responses. | ||
// A Response can have an external ref in Response.Ref or in its content (Response.Content.Schema.Ref) | ||
|
@@ -417,6 +484,27 @@ func (o OasDiff) areSchemaIdentical(name string) bool { | |
return !ok | ||
} | ||
|
||
// arePathsIdenticalWithExcludeExtensions checks if the paths are identical with the extensions excluded | ||
|
||
func (o OasDiff) arePathsIdenticalWithExcludeExtensions(name string) (bool, error) { | ||
There was a problem hiding this comment. Choose a reason for hiding this commentThe reason will be displayed to describe this comment to others. Learn more. the code seems to be checking if the path are identical with and without extensions 🤔 is this correct? if yes , we should rename the function to reflect this logic There was a problem hiding this comment. Choose a reason for hiding this commentThe reason will be displayed to describe this comment to others. Learn more. no, it's excluding extensions from the diff since there will always be Extensions, will update! |
||
// If the diff only has extensions diff, then we consider the paths to be identical | ||
d, err := o.noExtDiff.GetPathDiffWithoutExtensions(o.base.Spec, o.external.Spec) | ||
if err != nil { | ||
return false, err | ||
} | ||
|
||
if d.Empty() || d.PathsDiff.Empty() { | ||
return true, nil | ||
} | ||
v, ok := d.PathsDiff.Modified[name] | ||
if ok { | ||
if v.Empty() { | ||
return true, nil | ||
} | ||
} | ||
|
||
return !ok, nil | ||
} | ||
|
||
type ByName []*openapi3.Tag | ||
|
||
func (a ByName) Len() int { return len(a) } | ||
|
There was a problem hiding this comment.
Choose a reason for hiding this comment
The reason will be displayed to describe this comment to others. Learn more.
could you also provide the two files involved in this mismatch? We have a ticket to improve the error message of a conflict to list also the files that are involved to help investigate the issue.
There was a problem hiding this comment.
Choose a reason for hiding this comment
The reason will be displayed to describe this comment to others. Learn more.
let me do this in another task, so that we can update all the error outputs or else this will grow. maybe we can defer to the ticket you mentioned