update the dependency sigs.k8s.io/structured-merge-diff/v4 to latest tag

This commit is contained in:
Keerthan Reddy Mala
2023-07-14 09:47:59 -07:00
parent f3f5dd99ac
commit d2df65ba6c
70 changed files with 163 additions and 115 deletions

2
vendor/modules.txt vendored
View File

@@ -2511,7 +2511,7 @@ sigs.k8s.io/kustomize/kyaml/yaml/merge2
sigs.k8s.io/kustomize/kyaml/yaml/merge3
sigs.k8s.io/kustomize/kyaml/yaml/schema
sigs.k8s.io/kustomize/kyaml/yaml/walk
# sigs.k8s.io/structured-merge-diff/v4 v4.2.3
# sigs.k8s.io/structured-merge-diff/v4 v4.3.0
## explicit; go 1.13
sigs.k8s.io/structured-merge-diff/v4/fieldpath
sigs.k8s.io/structured-merge-diff/v4/merge

View File

@@ -112,7 +112,7 @@ func ConflictsFromManagers(sets fieldpath.ManagedFields) Conflicts {
set.Set().Iterate(func(p fieldpath.Path) {
conflicts = append(conflicts, Conflict{
Manager: manager,
Path: p,
Path: p.Copy(),
})
})
}

View File

@@ -18,6 +18,7 @@ import (
"sigs.k8s.io/structured-merge-diff/v4/fieldpath"
"sigs.k8s.io/structured-merge-diff/v4/typed"
"sigs.k8s.io/structured-merge-diff/v4/value"
)
// Converter is an interface to the conversion logic. The converter
@@ -27,17 +28,50 @@ type Converter interface {
IsMissingVersionError(error) bool
}
// Updater is the object used to compute updated FieldSets and also
// merge the object on Apply.
type Updater struct {
// UpdateBuilder allows you to create a new Updater by exposing all of
// the options and setting them once.
type UpdaterBuilder struct {
Converter Converter
IgnoredFields map[fieldpath.APIVersion]*fieldpath.Set
EnableUnions bool
// Stop comparing the new object with old object after applying.
// This was initially used to avoid spurious etcd update, but
// since that's vastly inefficient, we've come-up with a better
// way of doing that. Create this flag to stop it.
// Comparing has become more expensive too now that we're not using
// `Compare` but `value.Equals` so this gives an option to avoid it.
ReturnInputOnNoop bool
}
func (u *UpdaterBuilder) BuildUpdater() *Updater {
return &Updater{
Converter: u.Converter,
IgnoredFields: u.IgnoredFields,
enableUnions: u.EnableUnions,
returnInputOnNoop: u.ReturnInputOnNoop,
}
}
// Updater is the object used to compute updated FieldSets and also
// merge the object on Apply.
type Updater struct {
// Deprecated: This will eventually become private.
Converter Converter
// Deprecated: This will eventually become private.
IgnoredFields map[fieldpath.APIVersion]*fieldpath.Set
enableUnions bool
returnInputOnNoop bool
}
// EnableUnionFeature turns on union handling. It is disabled by default until the
// feature is complete.
//
// Deprecated: Use the builder instead.
func (s *Updater) EnableUnionFeature() {
s.enableUnions = true
}
@@ -157,8 +191,7 @@ func (s *Updater) Update(liveObject, newObject *typed.TypedValue, version fieldp
// Apply should be called when Apply is run, given the current object as
// well as the configuration that is applied. This will merge the object
// and return it. If the object hasn't changed, nil is returned (the
// managers can still have changed though).
// and return it.
func (s *Updater) Apply(liveObject, configObject *typed.TypedValue, version fieldpath.APIVersion, managers fieldpath.ManagedFields, manager string, force bool) (*typed.TypedValue, fieldpath.ManagedFields, error) {
var err error
managers, err = s.reconcileManagedFieldsWithSchemaChanges(liveObject, managers)
@@ -200,11 +233,11 @@ func (s *Updater) Apply(liveObject, configObject *typed.TypedValue, version fiel
if err != nil {
return nil, fieldpath.ManagedFields{}, fmt.Errorf("failed to prune fields: %v", err)
}
managers, compare, err := s.update(liveObject, newObject, version, managers, manager, force)
managers, _, err = s.update(liveObject, newObject, version, managers, manager, force)
if err != nil {
return nil, fieldpath.ManagedFields{}, err
}
if compare.IsSame() {
if !s.returnInputOnNoop && value.EqualsUsing(value.NewFreelistAllocator(), liveObject.AsValue(), newObject.AsValue()) {
newObject = nil
}
return newObject, managers, nil
@@ -218,7 +251,8 @@ func (s *Updater) prune(merged *typed.TypedValue, managers fieldpath.ManagedFiel
if lastSet == nil || lastSet.Set().Empty() {
return merged, nil
}
convertedMerged, err := s.Converter.Convert(merged, lastSet.APIVersion())
version := lastSet.APIVersion()
convertedMerged, err := s.Converter.Convert(merged, version)
if err != nil {
if s.Converter.IsMissingVersionError(err) {
return merged, nil
@@ -228,7 +262,7 @@ func (s *Updater) prune(merged *typed.TypedValue, managers fieldpath.ManagedFiel
sc, tr := convertedMerged.Schema(), convertedMerged.TypeRef()
pruned := convertedMerged.RemoveItems(lastSet.Set().EnsureNamedFieldsAreMembers(sc, tr))
pruned, err = s.addBackOwnedItems(convertedMerged, pruned, managers, applyingManager)
pruned, err = s.addBackOwnedItems(convertedMerged, pruned, version, managers, applyingManager)
if err != nil {
return nil, fmt.Errorf("failed add back owned items: %v", err)
}
@@ -241,7 +275,7 @@ func (s *Updater) prune(merged *typed.TypedValue, managers fieldpath.ManagedFiel
// addBackOwnedItems adds back any fields, list and map items that were removed by prune,
// but other appliers or updaters (or the current applier's new config) claim to own.
func (s *Updater) addBackOwnedItems(merged, pruned *typed.TypedValue, managedFields fieldpath.ManagedFields, applyingManager string) (*typed.TypedValue, error) {
func (s *Updater) addBackOwnedItems(merged, pruned *typed.TypedValue, prunedVersion fieldpath.APIVersion, managedFields fieldpath.ManagedFields, applyingManager string) (*typed.TypedValue, error) {
var err error
managedAtVersion := map[fieldpath.APIVersion]*fieldpath.Set{}
for _, managerSet := range managedFields {
@@ -252,7 +286,6 @@ func (s *Updater) addBackOwnedItems(merged, pruned *typed.TypedValue, managedFie
}
// Add back owned items at pruned version first to avoid conversion failure
// caused by pruned fields which are required for conversion.
prunedVersion := fieldpath.APIVersion(*pruned.TypeRef().NamedType)
if managed, ok := managedAtVersion[prunedVersion]; ok {
merged, pruned, err = s.addBackOwnedItemsForVersion(merged, pruned, prunedVersion, managed)
if err != nil {

View File

@@ -73,7 +73,7 @@ type Atom struct {
}
// Scalar (AKA "primitive") represents a type which has a single value which is
// either numeric, string, or boolean.
// either numeric, string, or boolean, or untyped for any of them.
//
// TODO: split numeric into float/int? Something even more fine-grained?
type Scalar string
@@ -82,6 +82,7 @@ const (
Numeric = Scalar("numeric")
String = Scalar("string")
Boolean = Scalar("boolean")
Untyped = Scalar("untyped")
)
// ElementRelationship is an enum of the different possible relationships

View File

@@ -110,7 +110,7 @@ var SchemaSchemaYAML = `types:
scalar: string
- name: deduceInvalidDiscriminator
type:
scalar: bool
scalar: boolean
- name: fields
type:
list:

View File

@@ -113,11 +113,12 @@ func (w *mergingWalker) doLeaf() {
w.rule(w)
}
func (w *mergingWalker) doScalar(t *schema.Scalar) (errs ValidationErrors) {
errs = append(errs, validateScalar(t, w.lhs, "lhs: ")...)
errs = append(errs, validateScalar(t, w.rhs, "rhs: ")...)
if len(errs) > 0 {
return errs
func (w *mergingWalker) doScalar(t *schema.Scalar) ValidationErrors {
// Make sure at least one side is a valid scalar.
lerrs := validateScalar(t, w.lhs, "lhs: ")
rerrs := validateScalar(t, w.rhs, "rhs: ")
if len(lerrs) > 0 && len(rerrs) > 0 {
return append(lerrs, rerrs...)
}
// All scalars are leaf fields.

View File

@@ -45,6 +45,10 @@ func AsTyped(v value.Value, s *schema.Schema, typeRef schema.TypeRef) (*TypedVal
// conforms to the schema, for cases where that has already been checked or
// where you're going to call a method that validates as a side-effect (like
// ToFieldSet).
//
// Deprecated: This function was initially created because validation
// was expensive. Now that this has been solved, objects should always
// be created as validated, using `AsTyped`.
func AsTypedUnvalidated(v value.Value, s *schema.Schema, typeRef schema.TypeRef) *TypedValue {
tv := &TypedValue{
value: v,
@@ -125,12 +129,13 @@ func (tv TypedValue) Compare(rhs *TypedValue) (c *Comparison, err error) {
Modified: fieldpath.NewSet(),
Added: fieldpath.NewSet(),
}
a := value.NewFreelistAllocator()
_, err = merge(&tv, rhs, func(w *mergingWalker) {
if w.lhs == nil {
c.Added.Insert(w.path)
} else if w.rhs == nil {
c.Removed.Insert(w.path)
} else if !value.Equals(w.rhs, w.lhs) {
} else if !value.EqualsUsing(a, w.rhs, w.lhs) {
// TODO: Equality is not sufficient for this.
// Need to implement equality check on the value type.
c.Modified.Insert(w.path)

View File

@@ -102,6 +102,12 @@ func validateScalar(t *schema.Scalar, v value.Value, prefix string) (errs Valida
if !v.IsBool() {
return errorf("%vexpected boolean, got %v", prefix, v)
}
case schema.Untyped:
if !v.IsFloat() && !v.IsInt() && !v.IsString() && !v.IsBool() {
return errorf("%vexpected any scalar, got %v", prefix, v)
}
default:
return errorf("%vunexpected scalar type in schema: %v", prefix, *t)
}
return nil
}

View File

@@ -136,7 +136,7 @@ func (r mapReflect) EqualsUsing(a Allocator, m Map) bool {
if !ok {
return false
}
return Equals(vr.mustReuse(lhsVal, entry, nil, nil), value)
return EqualsUsing(a, vr.mustReuse(lhsVal, entry, nil, nil), value)
})
}

View File

@@ -88,12 +88,12 @@ func (m mapUnstructuredInterface) EqualsUsing(a Allocator, other Map) bool {
}
vv := a.allocValueUnstructured()
defer a.Free(vv)
return other.Iterate(func(key string, value Value) bool {
return other.IterateUsing(a, func(key string, value Value) bool {
lhsVal, ok := m[key]
if !ok {
return false
}
return Equals(vv.reuse(lhsVal), value)
return EqualsUsing(a, vv.reuse(lhsVal), value)
})
}
@@ -168,12 +168,12 @@ func (m mapUnstructuredString) EqualsUsing(a Allocator, other Map) bool {
}
vv := a.allocValueUnstructured()
defer a.Free(vv)
return other.Iterate(func(key string, value Value) bool {
return other.IterateUsing(a, func(key string, value Value) bool {
lhsVal, ok := m[key]
if !ok {
return false
}
return Equals(vv.reuse(lhsVal), value)
return EqualsUsing(a, vv.reuse(lhsVal), value)
})
}

View File

@@ -154,7 +154,9 @@ func buildStructCacheEntry(t reflect.Type, infos map[string]*FieldCacheEntry, fi
if field.Type.Kind() == reflect.Ptr {
e = field.Type.Elem()
}
buildStructCacheEntry(e, infos, append(fieldPath, field.Index))
if e.Kind() == reflect.Struct {
buildStructCacheEntry(e, infos, append(fieldPath, field.Index))
}
continue
}
info := &FieldCacheEntry{JsonName: jsonName, isOmitEmpty: isOmitempty, fieldPath: append(fieldPath, field.Index), fieldType: field.Type}