mirror of
https://github.com/LukeHagar/libopenapi.git
synced 2025-12-08 04:20:17 +00:00
Clearing up some dead code and adding docs to what-changed
Signed-off-by: Dave Shanley <dave@quobix.com>
This commit is contained in:
@@ -8,12 +8,14 @@ import (
|
|||||||
"github.com/pb33f/libopenapi/datamodel/low/v3"
|
"github.com/pb33f/libopenapi/datamodel/low/v3"
|
||||||
)
|
)
|
||||||
|
|
||||||
|
// CallbackChanges represents all changes made between two Callback OpenAPI objects.
|
||||||
type CallbackChanges struct {
|
type CallbackChanges struct {
|
||||||
PropertyChanges
|
PropertyChanges
|
||||||
ExpressionChanges map[string]*PathItemChanges `json:"expressions,omitempty" yaml:"expressions,omitempty"`
|
ExpressionChanges map[string]*PathItemChanges `json:"expressions,omitempty" yaml:"expressions,omitempty"`
|
||||||
ExtensionChanges *ExtensionChanges `json:"extensions,omitempty" yaml:"extensions,omitempty"`
|
ExtensionChanges *ExtensionChanges `json:"extensions,omitempty" yaml:"extensions,omitempty"`
|
||||||
}
|
}
|
||||||
|
|
||||||
|
// TotalChanges returns a total count of all changes made between Callback objects
|
||||||
func (c *CallbackChanges) TotalChanges() int {
|
func (c *CallbackChanges) TotalChanges() int {
|
||||||
d := c.PropertyChanges.TotalChanges()
|
d := c.PropertyChanges.TotalChanges()
|
||||||
for k := range c.ExpressionChanges {
|
for k := range c.ExpressionChanges {
|
||||||
@@ -25,6 +27,7 @@ func (c *CallbackChanges) TotalChanges() int {
|
|||||||
return d
|
return d
|
||||||
}
|
}
|
||||||
|
|
||||||
|
// TotalBreakingChanges returns a total count of all changes made between Callback objects
|
||||||
func (c *CallbackChanges) TotalBreakingChanges() int {
|
func (c *CallbackChanges) TotalBreakingChanges() int {
|
||||||
d := c.PropertyChanges.TotalBreakingChanges()
|
d := c.PropertyChanges.TotalBreakingChanges()
|
||||||
for k := range c.ExpressionChanges {
|
for k := range c.ExpressionChanges {
|
||||||
@@ -36,6 +39,8 @@ func (c *CallbackChanges) TotalBreakingChanges() int {
|
|||||||
return d
|
return d
|
||||||
}
|
}
|
||||||
|
|
||||||
|
// CompareCallback will compare two Callback objects and return a pointer to CallbackChanges with all the things
|
||||||
|
// that have changed between them.
|
||||||
func CompareCallback(l, r *v3.Callback) *CallbackChanges {
|
func CompareCallback(l, r *v3.Callback) *CallbackChanges {
|
||||||
|
|
||||||
cc := new(CallbackChanges)
|
cc := new(CallbackChanges)
|
||||||
|
|||||||
@@ -16,10 +16,10 @@ const (
|
|||||||
// PropertyAdded means that a new property to an object was added
|
// PropertyAdded means that a new property to an object was added
|
||||||
PropertyAdded
|
PropertyAdded
|
||||||
|
|
||||||
// ObjectAdded means that a new object was added
|
// ObjectAdded means that a new object was added to a parent object
|
||||||
ObjectAdded
|
ObjectAdded
|
||||||
|
|
||||||
// ObjectRemoved means that an object was removed
|
// ObjectRemoved means that an object was removed from a parent object
|
||||||
ObjectRemoved
|
ObjectRemoved
|
||||||
|
|
||||||
// PropertyRemoved means that a property of an object was removed
|
// PropertyRemoved means that a property of an object was removed
|
||||||
|
|||||||
@@ -11,18 +11,38 @@ import (
|
|||||||
"reflect"
|
"reflect"
|
||||||
)
|
)
|
||||||
|
|
||||||
|
// ComponentsChanges represents changes made to both OpenAPI and Swagger documents. This model is based on OpenAPI 3
|
||||||
|
// components, however it's also used to contain Swagger definitions changes. Swagger for some reason decided to not
|
||||||
|
// contain definitions inside a single parent like Components, and instead scattered them across the root of the
|
||||||
|
// Swagger document, giving everything a `Definitions` postfix. This design attempts to unify those models into
|
||||||
|
// a single entity that contains all changes.
|
||||||
|
//
|
||||||
|
// Schemas are treated differently from every other component / definition in this library. Schemas can be highly
|
||||||
|
// recursive, and are not resolved by the model, every ref is recorded, but it's not looked at essentially. This means
|
||||||
|
// that when what-changed performs a check, everything that is *not* a schema is checked *inline*, Those references are
|
||||||
|
// resolved in place and a change is recorded in place. Schemas however are *not* resolved. which means no change
|
||||||
|
// will be recorded in place for any object referencing it.
|
||||||
|
//
|
||||||
|
// That is why there is a separate SchemaChanges object in ComponentsChanges. Schemas are checked at the source, and
|
||||||
|
// not inline when referenced. A schema change will only be found once, however a change to ANY other definition or
|
||||||
|
// component, will be found inline (and will duplicate for every use).
|
||||||
|
//
|
||||||
|
// The other oddity here is SecuritySchemes. For some reason OpenAPI does not use a $ref for these entities, it
|
||||||
|
// uses a name lookup, which means there are no direct links between any model and a security scheme reference.
|
||||||
|
// So like Schemas, SecuritySchemes are treated differently and handled individually.
|
||||||
|
//
|
||||||
|
// An important note: Everything EXCEPT Schemas and SecuritySchemes is ONLY checked for additions or removals.
|
||||||
|
// modifications are not checked, these checks occur in-place by implementing objects as they are autp-resolved
|
||||||
|
// when the model is built.
|
||||||
type ComponentsChanges struct {
|
type ComponentsChanges struct {
|
||||||
PropertyChanges
|
PropertyChanges
|
||||||
SchemaChanges map[string]*SchemaChanges `json:"schemas,omitempty" yaml:"schemas,omitempty"`
|
SchemaChanges map[string]*SchemaChanges `json:"schemas,omitempty" yaml:"schemas,omitempty"`
|
||||||
SecuritySchemeChanges map[string]*SecuritySchemeChanges `json:"securitySchemes,omitempty" yaml:"securitySchemes,omitempty"`
|
SecuritySchemeChanges map[string]*SecuritySchemeChanges `json:"securitySchemes,omitempty" yaml:"securitySchemes,omitempty"`
|
||||||
ExtensionChanges *ExtensionChanges `json:"extensions,omitempty" yaml:"extensions,omitempty"`
|
ExtensionChanges *ExtensionChanges `json:"extensions,omitempty" yaml:"extensions,omitempty"`
|
||||||
//ExamplesChanges map[string]*ExampleChanges
|
|
||||||
//RequestBodyChanges map[string]*RequestBodyChanges
|
|
||||||
//HeaderChanges map[string]*HeaderChanges
|
|
||||||
//LinkChanges map[string]*LinkChanges
|
|
||||||
//CallbackChanges map[string]*CallbackChanges
|
|
||||||
}
|
}
|
||||||
|
|
||||||
|
// CompareComponents will compare OpenAPI components for any changes. Accepts Swagger Definition objects
|
||||||
|
// like ParameterDefinitions or Definitions etc.
|
||||||
func CompareComponents(l, r any) *ComponentsChanges {
|
func CompareComponents(l, r any) *ComponentsChanges {
|
||||||
|
|
||||||
var changes []*Change
|
var changes []*Change
|
||||||
@@ -170,37 +190,13 @@ func CompareComponents(l, r any) *ComponentsChanges {
|
|||||||
completedComponents++
|
completedComponents++
|
||||||
cc.SchemaChanges = res.result.(map[string]*SchemaChanges)
|
cc.SchemaChanges = res.result.(map[string]*SchemaChanges)
|
||||||
break
|
break
|
||||||
case v3.ResponsesLabel:
|
|
||||||
completedComponents++
|
|
||||||
//cc.ResponsesChanges = res.result.(map[string]*ResponseChanges)
|
|
||||||
break
|
|
||||||
case v3.ParametersLabel:
|
|
||||||
completedComponents++
|
|
||||||
//cc.ParameterChanges = res.result.(map[string]*ParameterChanges)
|
|
||||||
break
|
|
||||||
case v3.ExamplesLabel:
|
|
||||||
completedComponents++
|
|
||||||
//cc.ExamplesChanges = res.result.(map[string]*ExampleChanges)
|
|
||||||
break
|
|
||||||
case v3.RequestBodiesLabel:
|
|
||||||
completedComponents++
|
|
||||||
//cc.RequestBodyChanges = res.result.(map[string]*RequestBodyChanges)
|
|
||||||
break
|
|
||||||
case v3.HeadersLabel:
|
|
||||||
completedComponents++
|
|
||||||
//cc.HeaderChanges = res.result.(map[string]*HeaderChanges)
|
|
||||||
break
|
|
||||||
case v3.SecuritySchemesLabel:
|
case v3.SecuritySchemesLabel:
|
||||||
completedComponents++
|
completedComponents++
|
||||||
cc.SecuritySchemeChanges = res.result.(map[string]*SecuritySchemeChanges)
|
cc.SecuritySchemeChanges = res.result.(map[string]*SecuritySchemeChanges)
|
||||||
break
|
break
|
||||||
case v3.LinksLabel:
|
case v3.ResponsesLabel, v3.ParametersLabel, v3.ExamplesLabel, v3.RequestBodiesLabel, v3.HeadersLabel,
|
||||||
|
v3.LinksLabel, v3.CallbacksLabel:
|
||||||
completedComponents++
|
completedComponents++
|
||||||
//cc.LinkChanges = res.result.(map[string]*LinkChanges)
|
|
||||||
break
|
|
||||||
case v3.CallbacksLabel:
|
|
||||||
completedComponents++
|
|
||||||
//cc.CallbackChanges = res.result.(map[string]*CallbackChanges)
|
|
||||||
break
|
break
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
@@ -238,66 +234,29 @@ func runComparison[T any, R any](l, r map[low.KeyReference[string]]low.ValueRefe
|
|||||||
}
|
}
|
||||||
}
|
}
|
||||||
|
|
||||||
|
// TotalChanges returns total changes for all Components and Definitions
|
||||||
func (c *ComponentsChanges) TotalChanges() int {
|
func (c *ComponentsChanges) TotalChanges() int {
|
||||||
v := c.PropertyChanges.TotalChanges()
|
v := c.PropertyChanges.TotalChanges()
|
||||||
for k := range c.SchemaChanges {
|
for k := range c.SchemaChanges {
|
||||||
v += c.SchemaChanges[k].TotalChanges()
|
v += c.SchemaChanges[k].TotalChanges()
|
||||||
}
|
}
|
||||||
//for k := range c.ResponsesChanges {
|
|
||||||
// v += c.ResponsesChanges[k].TotalChanges()
|
|
||||||
//}
|
|
||||||
//for k := range c.ParameterChanges {
|
|
||||||
// v += c.ParameterChanges[k].TotalChanges()
|
|
||||||
//}
|
|
||||||
//for k := range c.ExamplesChanges {
|
|
||||||
// v += c.ExamplesChanges[k].TotalChanges()
|
|
||||||
//}
|
|
||||||
//for k := range c.RequestBodyChanges {
|
|
||||||
// v += c.RequestBodyChanges[k].TotalChanges()
|
|
||||||
//}
|
|
||||||
//for k := range c.HeaderChanges {
|
|
||||||
// v += c.HeaderChanges[k].TotalChanges()
|
|
||||||
//}
|
|
||||||
for k := range c.SecuritySchemeChanges {
|
for k := range c.SecuritySchemeChanges {
|
||||||
v += c.SecuritySchemeChanges[k].TotalChanges()
|
v += c.SecuritySchemeChanges[k].TotalChanges()
|
||||||
}
|
}
|
||||||
//for k := range c.LinkChanges {
|
|
||||||
// v += c.LinkChanges[k].TotalChanges()
|
|
||||||
//}
|
|
||||||
//for k := range c.CallbackChanges {
|
|
||||||
// v += c.CallbackChanges[k].TotalChanges()
|
|
||||||
//}
|
|
||||||
if c.ExtensionChanges != nil {
|
if c.ExtensionChanges != nil {
|
||||||
v += c.ExtensionChanges.TotalChanges()
|
v += c.ExtensionChanges.TotalChanges()
|
||||||
}
|
}
|
||||||
return v
|
return v
|
||||||
}
|
}
|
||||||
|
|
||||||
|
// TotalBreakingChanges returns all breaking changes found for all Components and Definitions
|
||||||
func (c *ComponentsChanges) TotalBreakingChanges() int {
|
func (c *ComponentsChanges) TotalBreakingChanges() int {
|
||||||
v := c.PropertyChanges.TotalBreakingChanges()
|
v := c.PropertyChanges.TotalBreakingChanges()
|
||||||
for k := range c.SchemaChanges {
|
for k := range c.SchemaChanges {
|
||||||
v += c.SchemaChanges[k].TotalBreakingChanges()
|
v += c.SchemaChanges[k].TotalBreakingChanges()
|
||||||
}
|
}
|
||||||
//for k := range c.ResponsesChanges {
|
|
||||||
// v += c.ResponsesChanges[k].TotalBreakingChanges()
|
|
||||||
//}
|
|
||||||
//for k := range c.ParameterChanges {
|
|
||||||
// v += c.ParameterChanges[k].TotalBreakingChanges()
|
|
||||||
//}
|
|
||||||
//for k := range c.RequestBodyChanges {
|
|
||||||
// v += c.RequestBodyChanges[k].TotalBreakingChanges()
|
|
||||||
//}
|
|
||||||
//for k := range c.HeaderChanges {
|
|
||||||
// v += c.HeaderChanges[k].TotalBreakingChanges()
|
|
||||||
//}
|
|
||||||
for k := range c.SecuritySchemeChanges {
|
for k := range c.SecuritySchemeChanges {
|
||||||
v += c.SecuritySchemeChanges[k].TotalBreakingChanges()
|
v += c.SecuritySchemeChanges[k].TotalBreakingChanges()
|
||||||
}
|
}
|
||||||
//for k := range c.LinkChanges {
|
|
||||||
// v += c.LinkChanges[k].TotalBreakingChanges()
|
|
||||||
//}
|
|
||||||
//for k := range c.CallbackChanges {
|
|
||||||
// v += c.CallbackChanges[k].TotalBreakingChanges()
|
|
||||||
//}
|
|
||||||
return v
|
return v
|
||||||
}
|
}
|
||||||
|
|||||||
@@ -1,6 +1,13 @@
|
|||||||
// Copyright 2022 Princess B33f Heavy Industries / Dave Shanley
|
// Copyright 2022 Princess B33f Heavy Industries / Dave Shanley
|
||||||
// SPDX-License-Identifier: MIT
|
// SPDX-License-Identifier: MIT
|
||||||
|
|
||||||
|
// Package model
|
||||||
|
//
|
||||||
|
// What-changed models are unified across OpenAPI and Swagger. Everything is kept flat for simplicity, so please
|
||||||
|
// excuse the size of the package. There is a lot of data to crunch!
|
||||||
|
//
|
||||||
|
// Every model in here is either universal (works across both versions of OpenAPI) or is bound to a specific version
|
||||||
|
// of OpenAPI. There is only a single model however - so version specific objects are marked accordingly.
|
||||||
package model
|
package model
|
||||||
|
|
||||||
import (
|
import (
|
||||||
@@ -11,6 +18,7 @@ import (
|
|||||||
"reflect"
|
"reflect"
|
||||||
)
|
)
|
||||||
|
|
||||||
|
// DocumentChanges represents all the changes made to an OpenAPI document.
|
||||||
type DocumentChanges struct {
|
type DocumentChanges struct {
|
||||||
PropertyChanges
|
PropertyChanges
|
||||||
InfoChanges *InfoChanges `json:"info,omitempty" yaml:"info,omitempty"`
|
InfoChanges *InfoChanges `json:"info,omitempty" yaml:"info,omitempty"`
|
||||||
@@ -24,6 +32,7 @@ type DocumentChanges struct {
|
|||||||
ExtensionChanges *ExtensionChanges `json:"extensions,omitempty" yaml:"extensions,omitempty"`
|
ExtensionChanges *ExtensionChanges `json:"extensions,omitempty" yaml:"extensions,omitempty"`
|
||||||
}
|
}
|
||||||
|
|
||||||
|
// TotalChanges returns a total count of all changes made in the Document
|
||||||
func (d *DocumentChanges) TotalChanges() int {
|
func (d *DocumentChanges) TotalChanges() int {
|
||||||
c := d.PropertyChanges.TotalChanges()
|
c := d.PropertyChanges.TotalChanges()
|
||||||
if d.InfoChanges != nil {
|
if d.InfoChanges != nil {
|
||||||
@@ -56,6 +65,7 @@ func (d *DocumentChanges) TotalChanges() int {
|
|||||||
return c
|
return c
|
||||||
}
|
}
|
||||||
|
|
||||||
|
// TotalBreakingChanges returns a total count of all breaking changes made in the Document
|
||||||
func (d *DocumentChanges) TotalBreakingChanges() int {
|
func (d *DocumentChanges) TotalBreakingChanges() int {
|
||||||
c := d.PropertyChanges.TotalBreakingChanges()
|
c := d.PropertyChanges.TotalBreakingChanges()
|
||||||
if d.InfoChanges != nil {
|
if d.InfoChanges != nil {
|
||||||
@@ -85,6 +95,8 @@ func (d *DocumentChanges) TotalBreakingChanges() int {
|
|||||||
return c
|
return c
|
||||||
}
|
}
|
||||||
|
|
||||||
|
// CompareDocuments will compare any two OpenAPI documents (either Swagger or OpenAPI) and return a pointer to
|
||||||
|
// DocumentChanges that outlines everything that was found to have changed.
|
||||||
func CompareDocuments(l, r any) *DocumentChanges {
|
func CompareDocuments(l, r any) *DocumentChanges {
|
||||||
|
|
||||||
var changes []*Change
|
var changes []*Change
|
||||||
|
|||||||
@@ -7,11 +7,13 @@ import (
|
|||||||
v3 "github.com/pb33f/libopenapi/datamodel/low/v3"
|
v3 "github.com/pb33f/libopenapi/datamodel/low/v3"
|
||||||
)
|
)
|
||||||
|
|
||||||
|
// EncodingChanges represent all the changes made to an Encoding object
|
||||||
type EncodingChanges struct {
|
type EncodingChanges struct {
|
||||||
PropertyChanges
|
PropertyChanges
|
||||||
HeaderChanges map[string]*HeaderChanges `json:"headers,omitempty" yaml:"headers,omitempty"`
|
HeaderChanges map[string]*HeaderChanges `json:"headers,omitempty" yaml:"headers,omitempty"`
|
||||||
}
|
}
|
||||||
|
|
||||||
|
// TotalChanges returns the total number of changes made between two Encoding objects
|
||||||
func (e *EncodingChanges) TotalChanges() int {
|
func (e *EncodingChanges) TotalChanges() int {
|
||||||
c := e.PropertyChanges.TotalChanges()
|
c := e.PropertyChanges.TotalChanges()
|
||||||
if e.HeaderChanges != nil {
|
if e.HeaderChanges != nil {
|
||||||
@@ -22,6 +24,7 @@ func (e *EncodingChanges) TotalChanges() int {
|
|||||||
return c
|
return c
|
||||||
}
|
}
|
||||||
|
|
||||||
|
// TotalBreakingChanges returns the number of changes made between two Encoding objects that were breaking.
|
||||||
func (e *EncodingChanges) TotalBreakingChanges() int {
|
func (e *EncodingChanges) TotalBreakingChanges() int {
|
||||||
c := e.PropertyChanges.TotalBreakingChanges()
|
c := e.PropertyChanges.TotalBreakingChanges()
|
||||||
if e.HeaderChanges != nil {
|
if e.HeaderChanges != nil {
|
||||||
@@ -32,6 +35,8 @@ func (e *EncodingChanges) TotalBreakingChanges() int {
|
|||||||
return c
|
return c
|
||||||
}
|
}
|
||||||
|
|
||||||
|
// CompareEncoding returns a pointer to *EncodingChanges that contain all changes made between a left and right
|
||||||
|
// set of Encoding objects.
|
||||||
func CompareEncoding(l, r *v3.Encoding) *EncodingChanges {
|
func CompareEncoding(l, r *v3.Encoding) *EncodingChanges {
|
||||||
|
|
||||||
var changes []*Change
|
var changes []*Change
|
||||||
|
|||||||
@@ -32,8 +32,8 @@ func (e *ExampleChanges) TotalBreakingChanges() int {
|
|||||||
return l
|
return l
|
||||||
}
|
}
|
||||||
|
|
||||||
// TotalChanges
|
// CompareExamples returns a pointer to ExampleChanges that contains all changes made between
|
||||||
|
// left and right Example instances.
|
||||||
func CompareExamples(l, r *base.Example) *ExampleChanges {
|
func CompareExamples(l, r *base.Example) *ExampleChanges {
|
||||||
|
|
||||||
ec := new(ExampleChanges)
|
ec := new(ExampleChanges)
|
||||||
|
|||||||
@@ -8,19 +8,23 @@ import (
|
|||||||
v2 "github.com/pb33f/libopenapi/datamodel/low/v2"
|
v2 "github.com/pb33f/libopenapi/datamodel/low/v2"
|
||||||
)
|
)
|
||||||
|
|
||||||
// v2 Examples object.
|
// ExamplesChanges represents changes made between Swagger Examples objects (Not OpenAPI 3).
|
||||||
type ExamplesChanges struct {
|
type ExamplesChanges struct {
|
||||||
PropertyChanges
|
PropertyChanges
|
||||||
}
|
}
|
||||||
|
|
||||||
|
// TotalChanges represents the total number of changes made between Example instances.
|
||||||
func (a *ExamplesChanges) TotalChanges() int {
|
func (a *ExamplesChanges) TotalChanges() int {
|
||||||
return a.PropertyChanges.TotalChanges()
|
return a.PropertyChanges.TotalChanges()
|
||||||
}
|
}
|
||||||
|
|
||||||
|
// TotalBreakingChanges will always return 0. Examples cannot break a contract.
|
||||||
func (a *ExamplesChanges) TotalBreakingChanges() int {
|
func (a *ExamplesChanges) TotalBreakingChanges() int {
|
||||||
return 0 // not supported.
|
return 0 // not supported.
|
||||||
}
|
}
|
||||||
|
|
||||||
|
// CompareExamplesV2 compares two Swagger Examples objects, returning a pointer to
|
||||||
|
//ExamplesChanges if anything was found.
|
||||||
func CompareExamplesV2(l, r *v2.Examples) *ExamplesChanges {
|
func CompareExamplesV2(l, r *v2.Examples) *ExamplesChanges {
|
||||||
|
|
||||||
lHashes := make(map[string]string)
|
lHashes := make(map[string]string)
|
||||||
|
|||||||
@@ -13,6 +13,7 @@ type ExtensionChanges struct {
|
|||||||
PropertyChanges
|
PropertyChanges
|
||||||
}
|
}
|
||||||
|
|
||||||
|
// TotalChanges returns the total number of object extensions that were made.
|
||||||
func (e *ExtensionChanges) TotalChanges() int {
|
func (e *ExtensionChanges) TotalChanges() int {
|
||||||
return e.PropertyChanges.TotalChanges()
|
return e.PropertyChanges.TotalChanges()
|
||||||
}
|
}
|
||||||
|
|||||||
@@ -10,6 +10,8 @@ import (
|
|||||||
"reflect"
|
"reflect"
|
||||||
)
|
)
|
||||||
|
|
||||||
|
// HeaderChanges represents changes made between two Header objects. Supports both Swagger and OpenAPI header
|
||||||
|
// objects, V2 only property Items is broken out into its own.
|
||||||
type HeaderChanges struct {
|
type HeaderChanges struct {
|
||||||
PropertyChanges
|
PropertyChanges
|
||||||
SchemaChanges *SchemaChanges `json:"schemas,omitempty" yaml:"schemas,omitempty"`
|
SchemaChanges *SchemaChanges `json:"schemas,omitempty" yaml:"schemas,omitempty"`
|
||||||
@@ -17,10 +19,11 @@ type HeaderChanges struct {
|
|||||||
ContentChanges map[string]*MediaTypeChanges `json:"content,omitempty" yaml:"content,omitempty"`
|
ContentChanges map[string]*MediaTypeChanges `json:"content,omitempty" yaml:"content,omitempty"`
|
||||||
ExtensionChanges *ExtensionChanges `json:"extensions,omitempty" yaml:"extensions,omitempty"`
|
ExtensionChanges *ExtensionChanges `json:"extensions,omitempty" yaml:"extensions,omitempty"`
|
||||||
|
|
||||||
// V2 changes
|
// Items only supported by Swagger (V2)
|
||||||
ItemsChanges *ItemsChanges `json:"items,omitempty" yaml:"items,omitempty"`
|
ItemsChanges *ItemsChanges `json:"items,omitempty" yaml:"items,omitempty"`
|
||||||
}
|
}
|
||||||
|
|
||||||
|
// TotalChanges returns the total number of changes made between two Header objects.
|
||||||
func (h *HeaderChanges) TotalChanges() int {
|
func (h *HeaderChanges) TotalChanges() int {
|
||||||
c := h.PropertyChanges.TotalChanges()
|
c := h.PropertyChanges.TotalChanges()
|
||||||
for k := range h.ExamplesChanges {
|
for k := range h.ExamplesChanges {
|
||||||
@@ -41,6 +44,7 @@ func (h *HeaderChanges) TotalChanges() int {
|
|||||||
return c
|
return c
|
||||||
}
|
}
|
||||||
|
|
||||||
|
// TotalBreakingChanges returns the total number of breaking changes made between two Header instances.
|
||||||
func (h *HeaderChanges) TotalBreakingChanges() int {
|
func (h *HeaderChanges) TotalBreakingChanges() int {
|
||||||
c := h.PropertyChanges.TotalBreakingChanges()
|
c := h.PropertyChanges.TotalBreakingChanges()
|
||||||
for k := range h.ContentChanges {
|
for k := range h.ContentChanges {
|
||||||
@@ -55,6 +59,7 @@ func (h *HeaderChanges) TotalBreakingChanges() int {
|
|||||||
return c
|
return c
|
||||||
}
|
}
|
||||||
|
|
||||||
|
// shared header properties
|
||||||
func addOpenAPIHeaderProperties(left, right low.OpenAPIHeader, changes *[]*Change) []*PropertyCheck {
|
func addOpenAPIHeaderProperties(left, right low.OpenAPIHeader, changes *[]*Change) []*PropertyCheck {
|
||||||
var props []*PropertyCheck
|
var props []*PropertyCheck
|
||||||
|
|
||||||
@@ -89,6 +94,7 @@ func addOpenAPIHeaderProperties(left, right low.OpenAPIHeader, changes *[]*Chang
|
|||||||
return props
|
return props
|
||||||
}
|
}
|
||||||
|
|
||||||
|
// swagger only properties
|
||||||
func addSwaggerHeaderProperties(left, right low.SwaggerHeader, changes *[]*Change) []*PropertyCheck {
|
func addSwaggerHeaderProperties(left, right low.SwaggerHeader, changes *[]*Change) []*PropertyCheck {
|
||||||
var props []*PropertyCheck
|
var props []*PropertyCheck
|
||||||
|
|
||||||
@@ -151,6 +157,7 @@ func addSwaggerHeaderProperties(left, right low.SwaggerHeader, changes *[]*Chang
|
|||||||
return props
|
return props
|
||||||
}
|
}
|
||||||
|
|
||||||
|
// common header properties
|
||||||
func addCommonHeaderProperties(left, right low.HasDescription, changes *[]*Change) []*PropertyCheck {
|
func addCommonHeaderProperties(left, right low.HasDescription, changes *[]*Change) []*PropertyCheck {
|
||||||
var props []*PropertyCheck
|
var props []*PropertyCheck
|
||||||
|
|
||||||
@@ -161,14 +168,20 @@ func addCommonHeaderProperties(left, right low.HasDescription, changes *[]*Chang
|
|||||||
return props
|
return props
|
||||||
}
|
}
|
||||||
|
|
||||||
|
// CompareHeadersV2 is a Swagger compatible, typed signature used for other generic functions. It simply
|
||||||
|
// wraps CompareHeaders and provides nothing other that a typed interface.
|
||||||
func CompareHeadersV2(l, r *v2.Header) *HeaderChanges {
|
func CompareHeadersV2(l, r *v2.Header) *HeaderChanges {
|
||||||
return CompareHeaders(l, r)
|
return CompareHeaders(l, r)
|
||||||
}
|
}
|
||||||
|
|
||||||
|
// CompareHeadersV3 is an OpenAPI 3+ compatible, typed signature used for other generic functions. It simply
|
||||||
|
// wraps CompareHeaders and provides nothing other that a typed interface.
|
||||||
func CompareHeadersV3(l, r *v3.Header) *HeaderChanges {
|
func CompareHeadersV3(l, r *v3.Header) *HeaderChanges {
|
||||||
return CompareHeaders(l, r)
|
return CompareHeaders(l, r)
|
||||||
}
|
}
|
||||||
|
|
||||||
|
// CompareHeaders will compare left and right Header objects (any version of Swagger or OpenAPI) and return
|
||||||
|
// a pointer to HeaderChanges with anything that has changed, or nil if nothing changed.
|
||||||
func CompareHeaders(l, r any) *HeaderChanges {
|
func CompareHeaders(l, r any) *HeaderChanges {
|
||||||
|
|
||||||
var changes []*Change
|
var changes []*Change
|
||||||
|
|||||||
@@ -8,11 +8,15 @@ import (
|
|||||||
v3 "github.com/pb33f/libopenapi/datamodel/low/v3"
|
v3 "github.com/pb33f/libopenapi/datamodel/low/v3"
|
||||||
)
|
)
|
||||||
|
|
||||||
|
// ItemsChanges represent changes found between a left (original) and right (modified) object. Items is only
|
||||||
|
// used by Swagger documents.
|
||||||
type ItemsChanges struct {
|
type ItemsChanges struct {
|
||||||
PropertyChanges
|
PropertyChanges
|
||||||
ItemsChanges *ItemsChanges `json:"items,omitempty" yaml:"items,omitempty"`
|
ItemsChanges *ItemsChanges `json:"items,omitempty" yaml:"items,omitempty"`
|
||||||
}
|
}
|
||||||
|
|
||||||
|
// TotalChanges returns the total number of changes found between two Items objects
|
||||||
|
// This is a recursive function because Items can contain Items. Be careful!
|
||||||
func (i *ItemsChanges) TotalChanges() int {
|
func (i *ItemsChanges) TotalChanges() int {
|
||||||
c := i.PropertyChanges.TotalChanges()
|
c := i.PropertyChanges.TotalChanges()
|
||||||
if i.ItemsChanges != nil {
|
if i.ItemsChanges != nil {
|
||||||
@@ -21,6 +25,8 @@ func (i *ItemsChanges) TotalChanges() int {
|
|||||||
return c
|
return c
|
||||||
}
|
}
|
||||||
|
|
||||||
|
// TotalBreakingChanges returns the total number of breaking changes found between two Swagger Items objects
|
||||||
|
// This is a recursive method, Items are recursive, be careful!
|
||||||
func (i *ItemsChanges) TotalBreakingChanges() int {
|
func (i *ItemsChanges) TotalBreakingChanges() int {
|
||||||
c := i.PropertyChanges.TotalBreakingChanges()
|
c := i.PropertyChanges.TotalBreakingChanges()
|
||||||
if i.ItemsChanges != nil {
|
if i.ItemsChanges != nil {
|
||||||
@@ -29,6 +35,11 @@ func (i *ItemsChanges) TotalBreakingChanges() int {
|
|||||||
return c
|
return c
|
||||||
}
|
}
|
||||||
|
|
||||||
|
// CompareItems compares two sets of Swagger Item objects. If there are any changes found then a pointer to
|
||||||
|
// ItemsChanges will be returned, otherwise nil is returned.
|
||||||
|
//
|
||||||
|
// It is worth nothing that Items can contain Items. This means recursion is possible and has the potential for
|
||||||
|
// runaway code if not using the resolver's circular reference checking.
|
||||||
func CompareItems(l, r *v2.Items) *ItemsChanges {
|
func CompareItems(l, r *v2.Items) *ItemsChanges {
|
||||||
|
|
||||||
var changes []*Change
|
var changes []*Change
|
||||||
|
|||||||
@@ -8,12 +8,14 @@ import (
|
|||||||
v3 "github.com/pb33f/libopenapi/datamodel/low/v3"
|
v3 "github.com/pb33f/libopenapi/datamodel/low/v3"
|
||||||
)
|
)
|
||||||
|
|
||||||
|
// LinkChanges represent changes made between two OpenAPI Link Objects.
|
||||||
type LinkChanges struct {
|
type LinkChanges struct {
|
||||||
PropertyChanges
|
PropertyChanges
|
||||||
ExtensionChanges *ExtensionChanges `json:"extensions,omitempty" yaml:"extensions,omitempty"`
|
ExtensionChanges *ExtensionChanges `json:"extensions,omitempty" yaml:"extensions,omitempty"`
|
||||||
ServerChanges *ServerChanges `json:"server,omitempty" yaml:"server,omitempty"`
|
ServerChanges *ServerChanges `json:"server,omitempty" yaml:"server,omitempty"`
|
||||||
}
|
}
|
||||||
|
|
||||||
|
// TotalChanges returns the total changes made between OpenAPI Link objects
|
||||||
func (l *LinkChanges) TotalChanges() int {
|
func (l *LinkChanges) TotalChanges() int {
|
||||||
c := l.PropertyChanges.TotalChanges()
|
c := l.PropertyChanges.TotalChanges()
|
||||||
if l.ExtensionChanges != nil {
|
if l.ExtensionChanges != nil {
|
||||||
@@ -25,6 +27,7 @@ func (l *LinkChanges) TotalChanges() int {
|
|||||||
return c
|
return c
|
||||||
}
|
}
|
||||||
|
|
||||||
|
// TotalBreakingChanges returns the number of breaking changes made between two OpenAPI Link Objects
|
||||||
func (l *LinkChanges) TotalBreakingChanges() int {
|
func (l *LinkChanges) TotalBreakingChanges() int {
|
||||||
c := l.PropertyChanges.TotalBreakingChanges()
|
c := l.PropertyChanges.TotalBreakingChanges()
|
||||||
if l.ServerChanges != nil {
|
if l.ServerChanges != nil {
|
||||||
@@ -33,6 +36,8 @@ func (l *LinkChanges) TotalBreakingChanges() int {
|
|||||||
return c
|
return c
|
||||||
}
|
}
|
||||||
|
|
||||||
|
// CompareLinks checks a left and right OpenAPI Link for any changes. If they are found, returns a pointer to
|
||||||
|
// LinkChanges, and returns nil if nothing is found.
|
||||||
func CompareLinks(l, r *v3.Link) *LinkChanges {
|
func CompareLinks(l, r *v3.Link) *LinkChanges {
|
||||||
if low.AreEqual(l, r) {
|
if low.AreEqual(l, r) {
|
||||||
return nil
|
return nil
|
||||||
|
|||||||
@@ -7,6 +7,7 @@ import (
|
|||||||
"github.com/pb33f/libopenapi/datamodel/low/v3"
|
"github.com/pb33f/libopenapi/datamodel/low/v3"
|
||||||
)
|
)
|
||||||
|
|
||||||
|
// MediaTypeChanges represent changes made between two OpenAPI MediaType instances.
|
||||||
type MediaTypeChanges struct {
|
type MediaTypeChanges struct {
|
||||||
PropertyChanges
|
PropertyChanges
|
||||||
SchemaChanges *SchemaChanges `json:"schemas,omitempty" yaml:"schemas,omitempty"`
|
SchemaChanges *SchemaChanges `json:"schemas,omitempty" yaml:"schemas,omitempty"`
|
||||||
@@ -15,6 +16,7 @@ type MediaTypeChanges struct {
|
|||||||
EncodingChanges map[string]*EncodingChanges `json:"encoding,omitempty" yaml:"encoding,omitempty"`
|
EncodingChanges map[string]*EncodingChanges `json:"encoding,omitempty" yaml:"encoding,omitempty"`
|
||||||
}
|
}
|
||||||
|
|
||||||
|
// TotalChanges returns the total number of changes between two MediaType instances.
|
||||||
func (m *MediaTypeChanges) TotalChanges() int {
|
func (m *MediaTypeChanges) TotalChanges() int {
|
||||||
c := m.PropertyChanges.TotalChanges()
|
c := m.PropertyChanges.TotalChanges()
|
||||||
for k := range m.ExampleChanges {
|
for k := range m.ExampleChanges {
|
||||||
@@ -34,6 +36,7 @@ func (m *MediaTypeChanges) TotalChanges() int {
|
|||||||
return c
|
return c
|
||||||
}
|
}
|
||||||
|
|
||||||
|
// TotalBreakingChanges returns the total number of breaking changes made between two MediaType instances.
|
||||||
func (m *MediaTypeChanges) TotalBreakingChanges() int {
|
func (m *MediaTypeChanges) TotalBreakingChanges() int {
|
||||||
c := m.PropertyChanges.TotalBreakingChanges()
|
c := m.PropertyChanges.TotalBreakingChanges()
|
||||||
for k := range m.ExampleChanges {
|
for k := range m.ExampleChanges {
|
||||||
@@ -50,6 +53,8 @@ func (m *MediaTypeChanges) TotalBreakingChanges() int {
|
|||||||
return c
|
return c
|
||||||
}
|
}
|
||||||
|
|
||||||
|
// CompareMediaTypes compares a left and a right MediaType object for any changes. If found, a pointer to a
|
||||||
|
// MediaTypeChanges instance is returned, otherwise nothing is returned.
|
||||||
func CompareMediaTypes(l, r *v3.MediaType) *MediaTypeChanges {
|
func CompareMediaTypes(l, r *v3.MediaType) *MediaTypeChanges {
|
||||||
|
|
||||||
var props []*PropertyCheck
|
var props []*PropertyCheck
|
||||||
|
|||||||
@@ -8,6 +8,7 @@ import (
|
|||||||
"github.com/pb33f/libopenapi/datamodel/low/v3"
|
"github.com/pb33f/libopenapi/datamodel/low/v3"
|
||||||
)
|
)
|
||||||
|
|
||||||
|
// OAuthFlowsChanges represents changes found between two OpenAPI OAuthFlows objects.
|
||||||
type OAuthFlowsChanges struct {
|
type OAuthFlowsChanges struct {
|
||||||
PropertyChanges
|
PropertyChanges
|
||||||
ImplicitChanges *OAuthFlowChanges `json:"implicit,omitempty" yaml:"implicit,omitempty"`
|
ImplicitChanges *OAuthFlowChanges `json:"implicit,omitempty" yaml:"implicit,omitempty"`
|
||||||
@@ -17,6 +18,7 @@ type OAuthFlowsChanges struct {
|
|||||||
ExtensionChanges *ExtensionChanges `json:"extensions,omitempty" yaml:"extensions,omitempty"`
|
ExtensionChanges *ExtensionChanges `json:"extensions,omitempty" yaml:"extensions,omitempty"`
|
||||||
}
|
}
|
||||||
|
|
||||||
|
// TotalChanges returns the number of changes made between two OAuthFlows instances.
|
||||||
func (o *OAuthFlowsChanges) TotalChanges() int {
|
func (o *OAuthFlowsChanges) TotalChanges() int {
|
||||||
c := o.PropertyChanges.TotalChanges()
|
c := o.PropertyChanges.TotalChanges()
|
||||||
if o.ImplicitChanges != nil {
|
if o.ImplicitChanges != nil {
|
||||||
@@ -37,6 +39,7 @@ func (o *OAuthFlowsChanges) TotalChanges() int {
|
|||||||
return c
|
return c
|
||||||
}
|
}
|
||||||
|
|
||||||
|
// TotalBreakingChanges returns the number of breaking changes made between two OAuthFlows objects.
|
||||||
func (o *OAuthFlowsChanges) TotalBreakingChanges() int {
|
func (o *OAuthFlowsChanges) TotalBreakingChanges() int {
|
||||||
c := o.PropertyChanges.TotalBreakingChanges()
|
c := o.PropertyChanges.TotalBreakingChanges()
|
||||||
if o.ImplicitChanges != nil {
|
if o.ImplicitChanges != nil {
|
||||||
@@ -54,6 +57,8 @@ func (o *OAuthFlowsChanges) TotalBreakingChanges() int {
|
|||||||
return c
|
return c
|
||||||
}
|
}
|
||||||
|
|
||||||
|
// CompareOAuthFlows compares a left and right OAuthFlows object. If changes are found a pointer to *OAuthFlowsChanges
|
||||||
|
// is returned, otherwise nil is returned.
|
||||||
func CompareOAuthFlows(l, r *v3.OAuthFlows) *OAuthFlowsChanges {
|
func CompareOAuthFlows(l, r *v3.OAuthFlows) *OAuthFlowsChanges {
|
||||||
if low.AreEqual(l, r) {
|
if low.AreEqual(l, r) {
|
||||||
return nil
|
return nil
|
||||||
@@ -126,11 +131,13 @@ func CompareOAuthFlows(l, r *v3.OAuthFlows) *OAuthFlowsChanges {
|
|||||||
return oa
|
return oa
|
||||||
}
|
}
|
||||||
|
|
||||||
|
// OAuthFlowChanges represents an OpenAPI OAuthFlow object.
|
||||||
type OAuthFlowChanges struct {
|
type OAuthFlowChanges struct {
|
||||||
PropertyChanges
|
PropertyChanges
|
||||||
ExtensionChanges *ExtensionChanges `json:"extensions,omitempty" yaml:"extensions,omitempty"`
|
ExtensionChanges *ExtensionChanges `json:"extensions,omitempty" yaml:"extensions,omitempty"`
|
||||||
}
|
}
|
||||||
|
|
||||||
|
// TotalChanges returns the total number of changes made between two OAuthFlow objects
|
||||||
func (o *OAuthFlowChanges) TotalChanges() int {
|
func (o *OAuthFlowChanges) TotalChanges() int {
|
||||||
c := o.PropertyChanges.TotalChanges()
|
c := o.PropertyChanges.TotalChanges()
|
||||||
if o.ExtensionChanges != nil {
|
if o.ExtensionChanges != nil {
|
||||||
@@ -139,10 +146,12 @@ func (o *OAuthFlowChanges) TotalChanges() int {
|
|||||||
return c
|
return c
|
||||||
}
|
}
|
||||||
|
|
||||||
|
// TotalBreakingChanges returns the total number of breaking changes made between two OAuthFlow objects
|
||||||
func (o *OAuthFlowChanges) TotalBreakingChanges() int {
|
func (o *OAuthFlowChanges) TotalBreakingChanges() int {
|
||||||
return o.PropertyChanges.TotalBreakingChanges()
|
return o.PropertyChanges.TotalBreakingChanges()
|
||||||
}
|
}
|
||||||
|
|
||||||
|
// CompareOAuthFlow checks a left and a right OAuthFlow object
|
||||||
func CompareOAuthFlow(l, r *v3.OAuthFlow) *OAuthFlowChanges {
|
func CompareOAuthFlow(l, r *v3.OAuthFlow) *OAuthFlowChanges {
|
||||||
if low.AreEqual(l, r) {
|
if low.AreEqual(l, r) {
|
||||||
return nil
|
return nil
|
||||||
|
|||||||
@@ -3,28 +3,34 @@
|
|||||||
|
|
||||||
// Package what_changed
|
// Package what_changed
|
||||||
//
|
//
|
||||||
// The low level (or plumbing) models are designed to capture every single detail about specification, including
|
// what changed is a feature that performs an accurate and deep analysis of what has changed between two OpenAPI
|
||||||
// all lines, columns, positions, tags, comments and essentially everything you would ever want to know.
|
// documents. The report generated outlines every single change made between two specifications (left and right)
|
||||||
// Positions of every key, value and meta-data that is lost when blindly un-marshaling JSON/YAML into a struct.
|
// rendered in the document hierarchy, so exploring it is the same as exploring the document model.
|
||||||
//
|
//
|
||||||
// The high model (porcelain) is a much simpler representation of the low model, keys are simple strings and indices
|
// There are two main functions, one of generating a report for Swagger documents (OpenAPI 2)
|
||||||
// are numbers. When developing consumers of the model, the high model is really what you want to use instead of the
|
// And OpenAPI 3+ documents.
|
||||||
// low model, it's much easier to navigate and is designed for easy consumption.
|
|
||||||
//
|
//
|
||||||
// The high model requires the low model to be built. Every high model has a 'GoLow' method that allows the consumer
|
// This package uses a combined model for OpenAPI and Swagger changes, it does not break them out into separate
|
||||||
// to 'drop down' from the porcelain API to the plumbing API, which gives instant access to everything low.
|
// versions like the datamodel package. The reason for this is to prevent sprawl across versions and to provide
|
||||||
|
// a single API and model for any application that wants to use this feature.
|
||||||
package what_changed
|
package what_changed
|
||||||
|
|
||||||
import (
|
import (
|
||||||
"github.com/pb33f/libopenapi/datamodel/low/v2"
|
"github.com/pb33f/libopenapi/datamodel/low/v2"
|
||||||
"github.com/pb33f/libopenapi/datamodel/low/v3"
|
"github.com/pb33f/libopenapi/datamodel/low/v3"
|
||||||
"github.com/pb33f/libopenapi/what_changed/model"
|
"github.com/pb33f/libopenapi/what-changed/model"
|
||||||
)
|
)
|
||||||
|
|
||||||
|
// CompareOpenAPIDocuments will compare left (original) and right (updated) OpenAPI 3+ documents and extract every change
|
||||||
|
// made across the entire specification. The report outlines every property changed, everything that was added,
|
||||||
|
// or removed and which of those changes were breaking.
|
||||||
func CompareOpenAPIDocuments(original, updated *v3.Document) *model.DocumentChanges {
|
func CompareOpenAPIDocuments(original, updated *v3.Document) *model.DocumentChanges {
|
||||||
return model.CompareDocuments(original, updated)
|
return model.CompareDocuments(original, updated)
|
||||||
}
|
}
|
||||||
|
|
||||||
|
// CompareSwaggerDocuments will compare left (original) and a right (updated) Swagger documents and extract every change
|
||||||
|
// made across the entire specification. The report outlines every property changes, everything that was added,
|
||||||
|
// or removed and which of those changes were breaking.
|
||||||
func CompareSwaggerDocuments(original, updated *v2.Swagger) *model.DocumentChanges {
|
func CompareSwaggerDocuments(original, updated *v2.Swagger) *model.DocumentChanges {
|
||||||
return model.CompareDocuments(original, updated)
|
return model.CompareDocuments(original, updated)
|
||||||
}
|
}
|
||||||
|
|||||||
Reference in New Issue
Block a user