Replay added configuration paths in explanations
This commit is contained in:
47
explain.go
47
explain.go
@@ -134,7 +134,7 @@ func (r *Result[T]) Explain(path Path) (Explanation, bool) {
|
||||
}
|
||||
|
||||
working = document.Clone(r.input)
|
||||
for _, snapshot := range r.resolution {
|
||||
for _, snapshot := range coalescedResolutionSnapshots(r.resolution) {
|
||||
relevant := pathsIntersect(snapshot.change.Path, path)
|
||||
var before ValueSnapshot
|
||||
if relevant {
|
||||
@@ -271,6 +271,37 @@ func mergeHistoryAtPath(root **document.Node, path Path, incoming *document.Node
|
||||
}
|
||||
}
|
||||
|
||||
// Resolution records describe one before/final transformation, not assignment
|
||||
// order. A parent already carries its descendants' final values; merge overlapping
|
||||
// intent into that event rather than replay a child assignment a second time.
|
||||
func coalescedResolutionSnapshots(snapshots []resolutionSnapshot) []resolutionSnapshot {
|
||||
groups := make([]resolutionSnapshot, 0, len(snapshots))
|
||||
for _, snapshot := range snapshots {
|
||||
merged := false
|
||||
for i := range groups {
|
||||
if !pathContains(groups[i].change.Path, snapshot.change.Path) {
|
||||
continue
|
||||
}
|
||||
for _, reason := range snapshot.change.Reasons {
|
||||
groups[i].change.Reasons = appendUniqueString(groups[i].change.Reasons, reason)
|
||||
}
|
||||
for _, dependency := range snapshot.change.Dependencies {
|
||||
groups[i].change.Dependencies = appendUniquePath(groups[i].change.Dependencies, dependency)
|
||||
}
|
||||
if snapshot.change.Origin.Operation == ChangeNormalization {
|
||||
groups[i].change.Origin.Operation = ChangeNormalization
|
||||
}
|
||||
merged = true
|
||||
break
|
||||
}
|
||||
if !merged {
|
||||
snapshot.change = cloneChange(snapshot.change)
|
||||
groups = append(groups, snapshot)
|
||||
}
|
||||
}
|
||||
return groups
|
||||
}
|
||||
|
||||
func replaceHistoryPath(root **document.Node, path Path, replacement *document.Node) {
|
||||
if root == nil || *root == nil {
|
||||
return
|
||||
@@ -289,7 +320,19 @@ func replaceHistoryPath(root **document.Node, path Path, replacement *document.N
|
||||
}
|
||||
position := documentEntryIndex(current.Mapping, segment.key)
|
||||
if position < 0 {
|
||||
return
|
||||
if replacement == nil {
|
||||
return
|
||||
}
|
||||
child := &document.Node{Kind: document.Mapping}
|
||||
if last {
|
||||
child = document.Clone(replacement)
|
||||
}
|
||||
current.Mapping = append(current.Mapping, document.Entry{Key: segment.key, Value: child})
|
||||
if last {
|
||||
return
|
||||
}
|
||||
current = child
|
||||
continue
|
||||
}
|
||||
if last {
|
||||
if replacement == nil {
|
||||
|
||||
Reference in New Issue
Block a user