Refactor set

- Implement inline setters as OpenAPI extensions
- Naming cleanup substitute -> set
- Documentation cleanup
- Simplify implementation
This commit is contained in:
Phillip Wittrock
2020-01-01 22:06:18 -08:00
parent 3bef339186
commit b37abbf057
28 changed files with 934 additions and 1265 deletions

View File

@@ -4,37 +4,35 @@
package fieldmeta
import (
"bytes"
"encoding/json"
"strconv"
"strings"
"github.com/go-openapi/spec"
"sigs.k8s.io/kustomize/kyaml/errors"
"sigs.k8s.io/kustomize/kyaml/yaml"
)
// FieldMeta contains metadata that may be attached to fields as comments
type FieldMeta struct {
// Substitutions are substitutions that may be performed against this field
Substitutions []Substitution `yaml:"substitutions,omitempty" json:"substitutions,omitempty"`
// OwnedBy records the owner of this field
OwnedBy string `yaml:"setBy,omitempty" json:"setBy,omitempty"`
// DefaultedBy records that this field was default, but may be changed by other owners
DefaultedBy string `yaml:"defaultedBy,omitempty" json:"defaultedBy,omitempty"`
// Description is a description of the current field value, e.g. why it was set
Description string `yaml:"description,omitempty" json:"description,omitempty"`
// Type is the type of the field value
Type FieldValueType `yaml:"type,omitempty" json:"type,omitempty"`
Schema spec.Schema
Extensions XKustomize
}
// Substitution defines a substitution that may be performed against the field
type Substitution struct {
// Name is the name of the substitution and read by tools
Name string `yaml:"name,omitempty" json:"name,omitempty"`
// Marker is the marker used for replacement
Marker string `yaml:"marker,omitempty" json:"marker,omitempty"`
// Value is the current value that has been substituted for the Marker
Value string `yaml:"value,omitempty" json:"value,omitempty"`
type XKustomize struct {
SetBy string `yaml:"setBy,omitempty" json:"setBy,omitempty"`
PartialFieldSetters []PartialFieldSetter `yaml:"partialFieldSetters" json:"partialFieldSetters"`
}
// PartialFieldSetter defines how to set part of a field rather than the full field
// value. e.g. the tag part of an image field
type PartialFieldSetter struct {
// Name is the name of this setter.
Name string `yaml:"name" json:"name"`
// Value is the current value that has been set.
Value string `yaml:"value" json:"value"`
}
// Read reads the FieldMeta from a node
@@ -43,16 +41,30 @@ func (fm *FieldMeta) Read(n *yaml.RNode) error {
v := strings.TrimLeft(n.YNode().LineComment, "#")
// if it doesn't Unmarshal that is fine, it means there is no metadata
// other comments are valid, they just don't parse
d := yaml.NewDecoder(bytes.NewBuffer([]byte(v)))
d.KnownFields(false)
_ = d.Decode(fm)
// TODO: consider most sophisticated parsing techniques similar to what is used
// for go struct tags.
if err := fm.Schema.UnmarshalJSON([]byte(v)); err != nil {
// note: don't return an error if the comment isn't a fieldmeta struct
return nil
}
fe := fm.Schema.VendorExtensible.Extensions["x-kustomize"]
if fe == nil {
return nil
}
b, err := json.Marshal(fe)
if err != nil {
return err
}
return json.Unmarshal(b, &fm.Extensions)
}
return nil
}
// Write writes the FieldMeta to a node
func (fm *FieldMeta) Write(n *yaml.RNode) error {
b, err := json.Marshal(fm)
fm.Schema.VendorExtensible.AddExtension("x-kustomize", fm.Extensions)
b, err := json.Marshal(fm.Schema)
if err != nil {
return err
}
@@ -67,11 +79,9 @@ const (
// String defines a string flag
String FieldValueType = "string"
// Bool defines a bool flag
Bool = "bool"
// Float defines a float flag
Float = "float"
Bool = "boolean"
// Int defines an int flag
Int = "int"
Int = "integer"
)
func (it FieldValueType) String() string {
@@ -91,10 +101,6 @@ func (it FieldValueType) Validate(value string) error {
if _, err := strconv.ParseBool(value); err != nil {
return errors.WrapPrefixf(err, "value must be a bool")
}
case Float:
if _, err := strconv.ParseFloat(value, 64); err != nil {
return errors.WrapPrefixf(err, "value must be a float")
}
}
return nil
}
@@ -107,8 +113,6 @@ func (it FieldValueType) Tag() string {
return "!!bool"
case Int:
return "!!int"
case Float:
return "!!float"
}
return ""
}
@@ -127,11 +131,6 @@ func (it FieldValueType) TagForValue(value string) string {
return ""
}
return "!!int"
case Float:
if _, err := strconv.ParseFloat(string(it), 64); err != nil {
return ""
}
return "!!float"
}
return ""
}