diff --git a/datamodel/low/base/external_doc.go b/datamodel/low/base/external_doc.go index cb1c678..828fe92 100644 --- a/datamodel/low/base/external_doc.go +++ b/datamodel/low/base/external_doc.go @@ -31,6 +31,7 @@ func (ex *ExternalDoc) Build(root *yaml.Node, idx *index.SpecIndex) error { return nil } +// GetExtensions returns all ExternalDoc extensions and satisfies the low.HasExtensions interface. func (ex *ExternalDoc) GetExtensions() map[low.KeyReference[string]]low.ValueReference[any] { if ex == nil { return nil diff --git a/datamodel/low/base/tag.go b/datamodel/low/base/tag.go index 0057243..9fef01f 100644 --- a/datamodel/low/base/tag.go +++ b/datamodel/low/base/tag.go @@ -37,6 +37,14 @@ func (t *Tag) Build(root *yaml.Node, idx *index.SpecIndex) error { return err } +// GetExtensions returns all Tag extensions and satisfies the low.HasExtensions interface. +func (t *Tag) GetExtensions() map[low.KeyReference[string]]low.ValueReference[any] { + if t == nil { + return nil + } + return t.Extensions +} + // TODO: future mutation API experiment code is here. this snippet is to re-marshal the object. //func (t *Tag) MarshalYAML() (interface{}, error) { // m := make(map[string]interface{}) diff --git a/what-changed/external_docs.go b/what-changed/external_docs.go index 51015a9..41184c4 100644 --- a/what-changed/external_docs.go +++ b/what-changed/external_docs.go @@ -25,7 +25,7 @@ func CompareExternalDocs(l, r *lowbase.ExternalDoc) *ExternalDocChanges { var changes []*Change[*lowbase.ExternalDoc] var props []*PropertyCheck[*lowbase.ExternalDoc] - // check URL + // URL props = append(props, &PropertyCheck[*lowbase.ExternalDoc]{ LeftNode: l.URL.ValueNode, RightNode: r.URL.ValueNode, @@ -36,6 +36,7 @@ func CompareExternalDocs(l, r *lowbase.ExternalDoc) *ExternalDocChanges { New: r, }) + // description. props = append(props, &PropertyCheck[*lowbase.ExternalDoc]{ LeftNode: l.Description.ValueNode, RightNode: r.Description.ValueNode, diff --git a/what-changed/tags.go b/what-changed/tags.go index 8e89ca5..1cdab12 100644 --- a/what-changed/tags.go +++ b/what-changed/tags.go @@ -46,57 +46,41 @@ func CompareTags(l, r []low.ValueReference[*lowbase.Tag]) *TagChanges { // check for removals, modifications and moves for i := range seenLeft { - if seenRight[i] == nil { - // deleted - CreateChange[*lowbase.Tag](&changes, ObjectRemoved, i, seenLeft[i].ValueNode, nil, - false, seenLeft[i].Value, nil) - continue - } + + CheckForAdditionOrRemoval[*lowbase.Tag](seenLeft, seenRight, i, &changes, false, true) // if the existing tag exists, let's check it. if seenRight[i] != nil { - // check if name has moved - ctx := CreateContext(seenLeft[i].Value.Name.ValueNode, seenRight[i].Value.Name.ValueNode) - if ctx.HasChanged() { - CreateChange[*lowbase.Tag](&changes, Moved, lowv3.NameLabel, - seenLeft[i].Value.Name.ValueNode, seenRight[i].Value.Name.ValueNode, - false, seenLeft[i].Value, seenRight[i].Value) + var props []*PropertyCheck[*lowbase.Tag] - } + // Name + props = append(props, &PropertyCheck[*lowbase.Tag]{ + LeftNode: seenLeft[i].Value.Name.ValueNode, + RightNode: seenRight[i].Value.Name.ValueNode, + Label: lowv3.NameLabel, + Changes: &changes, + Breaking: true, + Original: seenLeft[i].Value, + New: seenRight[i].Value, + }) - // check if description has been modified - if seenLeft[i].Value.Description.Value != seenRight[i].Value.Description.Value { - var changeType int - changeType = Modified - ctx = CreateContext(seenLeft[i].Value.Description.ValueNode, seenRight[i].Value.Description.ValueNode) - if ctx.HasChanged() { - changeType = ModifiedAndMoved - } - CreateChange[*lowbase.Tag](&changes, changeType, lowv3.DescriptionLabel, - seenLeft[i].Value.Description.ValueNode, seenRight[i].Value.Description.ValueNode, - false, seenLeft[i].Value, seenRight[i].Value) - } + // Description + props = append(props, &PropertyCheck[*lowbase.Tag]{ + LeftNode: seenLeft[i].Value.Description.ValueNode, + RightNode: seenRight[i].Value.Description.ValueNode, + Label: lowv3.DescriptionLabel, + Changes: &changes, + Breaking: true, + Original: seenLeft[i].Value, + New: seenRight[i].Value, + }) - // check if description has moved - if seenLeft[i].Value.Description.Value == seenRight[i].Value.Description.Value { - ctx = CreateContext(seenLeft[i].Value.Description.ValueNode, seenRight[i].Value.Description.ValueNode) - if ctx.HasChanged() { - CreateChange[*lowbase.Tag](&changes, Moved, lowv3.DescriptionLabel, - seenLeft[i].Value.Description.ValueNode, seenRight[i].Value.Description.ValueNode, - false, seenLeft[i].Value, seenRight[i].Value) - } - } + // check properties + CheckProperties(props) - // compare extensions - var lExt, rExt map[low.KeyReference[string]]low.ValueReference[any] - if l != nil && len(seenLeft[i].Value.Extensions) > 0 { - lExt = seenLeft[i].Value.Extensions - } - if r != nil && len(seenRight[i].Value.Extensions) > 0 { - rExt = seenRight[i].Value.Extensions - } - tc.ExtensionChanges = CompareExtensions(lExt, rExt) + // check extensions + tc.ExtensionChanges = CheckExtensions(seenLeft[i].GetValue(), seenRight[i].GetValue()) // compare external docs tc.ExternalDocs = CompareExternalDocs(seenLeft[i].Value.ExternalDocs.Value, @@ -104,15 +88,6 @@ func CompareTags(l, r []low.ValueReference[*lowbase.Tag]) *TagChanges { } } - // check for additions - for i := range seenRight { - if seenLeft[i] == nil { - // added - CreateChange[*lowbase.Tag](&changes, ObjectAdded, i, - nil, seenRight[i].ValueNode, - false, nil, seenRight[i].Value) - } - } if len(changes) <= 0 { return nil } diff --git a/what-changed/what_changed.go b/what-changed/what_changed.go index dfab5e0..fc55dc8 100644 --- a/what-changed/what_changed.go +++ b/what-changed/what_changed.go @@ -108,6 +108,39 @@ type PropertyCheck[T any] struct { Changes *[]*Change[T] } +func CheckForAdditionOrRemoval[T any](l, r map[string]*low.ValueReference[T], label string, changes *[]*Change[T], + breakingAdd, breakingRemove bool) { + var left, right T + if CheckObjectRemoved(l, r) { + left = l[label].GetValue() + CreateChange[T](changes, ObjectRemoved, label, l[label].GetValueNode(), nil, + breakingRemove, left, right) + } + if added, key := CheckObjectAdded(l, r); added { + right = r[key].GetValue() + CreateChange[T](changes, ObjectAdded, label, nil, r[key].GetValueNode(), + breakingAdd, left, right) + } +} + +func CheckObjectRemoved[T any](l, r map[string]*T) bool { + for i := range l { + if r[i] == nil { + return true + } + } + return false +} + +func CheckObjectAdded[T any](l, r map[string]*T) (bool, string) { + for i := range r { + if l[i] == nil { + return true, i + } + } + return false, "" +} + func CheckProperties[T any](properties []*PropertyCheck[T]) { for _, n := range properties { CheckPropertyAdditionOrRemoval(n.LeftNode, n.RightNode, n.Label, n.Changes, n.Breaking, n.Original, n.New)