Apply explicit CLI configuration overrides
This commit is contained in:
126
load_metadata.go
126
load_metadata.go
@@ -39,40 +39,104 @@ func metadataFromDecoded(decoded decodedConfiguration) Metadata {
|
||||
}
|
||||
|
||||
func applyOverlayMetadata(metadata *Metadata, records []overlayRecord) {
|
||||
for _, record := range records {
|
||||
for _, displaced := range record.displaced {
|
||||
pointer := displaced.path.String()
|
||||
history := metadata.history[pointer]
|
||||
profileIndex := -1
|
||||
for index := len(history) - 1; index >= 0; index-- {
|
||||
if history[index].Origin.Layer == LayerProfile {
|
||||
profileIndex = index
|
||||
break
|
||||
}
|
||||
baseline := make(map[string][]Change, len(metadata.history))
|
||||
for pointer, history := range metadata.history {
|
||||
for _, change := range history {
|
||||
if change.Origin.Layer == LayerDefault {
|
||||
baseline[pointer] = append(baseline[pointer], cloneChange(change))
|
||||
}
|
||||
baseChange := Change{Path: displaced.path.clone(), Origin: cloneOrigin(displaced.origin)}
|
||||
if len(history) != 0 && history[len(history)-1].Origin.Layer == LayerDefault {
|
||||
baseChange.Previous = []Origin{cloneOrigin(history[len(history)-1].Origin)}
|
||||
}
|
||||
if profileIndex >= 0 {
|
||||
history = append(history[:profileIndex], append([]Change{baseChange}, history[profileIndex:]...)...)
|
||||
} else {
|
||||
history = append(history, baseChange)
|
||||
}
|
||||
|
||||
change := cloneChange(record.change)
|
||||
change.Previous = []Origin{cloneOrigin(displaced.origin)}
|
||||
if profileIndex >= 0 {
|
||||
// The effective-input projection created a leaf-shaped profile
|
||||
// record. Replace it with the actual parent operation.
|
||||
profileIndex++
|
||||
history[profileIndex] = change
|
||||
} else {
|
||||
history = append(history, change)
|
||||
}
|
||||
metadata.history[pointer] = history
|
||||
}
|
||||
}
|
||||
events := make(map[string][]Change)
|
||||
for _, record := range records {
|
||||
exact := false
|
||||
for _, displaced := range record.displaced {
|
||||
pointer := displaced.path.String()
|
||||
appendInputOriginEvent(events, baseline, pointer, displaced.path, displaced.origin)
|
||||
appendInputChangeEvent(events, baseline, pointer, record.change)
|
||||
if pointer == record.change.Path.String() {
|
||||
exact = true
|
||||
}
|
||||
}
|
||||
if !exact {
|
||||
pointer := record.change.Path.String()
|
||||
for _, previous := range record.change.Previous {
|
||||
appendInputOriginEvent(events, baseline, pointer, record.change.Path, previous)
|
||||
}
|
||||
appendInputChangeEvent(events, baseline, pointer, record.change)
|
||||
}
|
||||
}
|
||||
for pointer, info := range metadata.fields {
|
||||
if !info.Explicit {
|
||||
continue
|
||||
}
|
||||
path, err := ParsePath(pointer)
|
||||
if err != nil {
|
||||
continue
|
||||
}
|
||||
if history := events[pointer]; len(history) != 0 && history[len(history)-1].Origin.Layer == info.Origin.Layer && history[len(history)-1].Origin.Operation == info.Origin.Operation {
|
||||
continue
|
||||
}
|
||||
appendInputOriginEvent(events, baseline, pointer, path, info.Origin)
|
||||
}
|
||||
metadata.history = make(map[string][]Change, len(baseline)+len(events))
|
||||
for pointer, history := range baseline {
|
||||
metadata.history[pointer] = cloneChanges(history)
|
||||
}
|
||||
for pointer, history := range events {
|
||||
metadata.history[pointer] = append(metadata.history[pointer], cloneChanges(history)...)
|
||||
}
|
||||
}
|
||||
|
||||
func appendInputOriginEvent(events map[string][]Change, baseline map[string][]Change, pointer string, path Path, origin Origin) {
|
||||
if origin.Layer == "" {
|
||||
return
|
||||
}
|
||||
history := events[pointer]
|
||||
if len(history) != 0 && originContainedBy(history[len(history)-1].Origin, origin) {
|
||||
return
|
||||
}
|
||||
appendInputChangeEvent(events, baseline, pointer, Change{Path: path.clone(), Origin: cloneOrigin(origin)})
|
||||
}
|
||||
|
||||
func appendInputChangeEvent(events map[string][]Change, baseline map[string][]Change, pointer string, value Change) {
|
||||
change := cloneChange(value)
|
||||
history := events[pointer]
|
||||
if len(history) != 0 {
|
||||
change.Previous = []Origin{cloneOrigin(history[len(history)-1].Origin)}
|
||||
} else if defaults := baseline[pointer]; len(defaults) != 0 {
|
||||
change.Previous = []Origin{cloneOrigin(defaults[len(defaults)-1].Origin)}
|
||||
} else {
|
||||
change.Previous = nil
|
||||
}
|
||||
events[pointer] = append(history, change)
|
||||
}
|
||||
|
||||
func originContainedBy(candidate, container Origin) bool {
|
||||
if candidate.Layer != container.Layer || candidate.Operation != container.Operation {
|
||||
return false
|
||||
}
|
||||
for _, location := range candidate.Locations {
|
||||
found := false
|
||||
for _, available := range container.Locations {
|
||||
if location == available {
|
||||
found = true
|
||||
break
|
||||
}
|
||||
}
|
||||
if !found {
|
||||
return false
|
||||
}
|
||||
}
|
||||
return true
|
||||
}
|
||||
|
||||
func cloneChanges(changes []Change) []Change {
|
||||
cloned := make([]Change, len(changes))
|
||||
for index, change := range changes {
|
||||
cloned[index] = cloneChange(change)
|
||||
}
|
||||
return cloned
|
||||
}
|
||||
|
||||
func collectFieldInfo(node *document.Node, path Path, decoded decodedConfiguration, fields map[string]FieldInfo) {
|
||||
|
||||
Reference in New Issue
Block a user