Apply CLI overrides after typed decoding

This commit is contained in:
2026-10-23 21:37:13 +00:00
parent ecfb78d84d
commit 41b5dff69b
20 changed files with 516 additions and 299 deletions

View File

@@ -32,25 +32,13 @@ type overridePreparationInput struct {
inputNodes int
}
func overridePreparationInputFor(base *composedDocument) overridePreparationInput {
if base == nil {
return overridePreparationInput{}
}
return overridePreparationInput{root: base.root, inputBytes: base.inputBytes, inputNodes: base.inputNodes}
}
func prepareOverrides(base *composedDocument, sources []SourceInfo, overrides []Override, rule *VersionRule, limits importLimits) (preparedOverrideBatch, []Diagnostic) {
return prepareOverrideBatch(overridePreparationInputFor(base), sources, overrides, rule, limits, false)
}
// preparePostStructuralOverrides prepares the same detached batch for the
// lifecycle after structural expansion, where record inheritance directives
// are no longer valid CLI input.
// preparePostStructuralOverrides snapshots CLI input for typed assignment after
// structural expansion, when inheritance directives can no longer be supplied.
func preparePostStructuralOverrides(base overridePreparationInput, sources []SourceInfo, overrides []Override, rule *VersionRule, limits importLimits) (preparedOverrideBatch, []Diagnostic) {
return prepareOverrideBatch(base, sources, overrides, rule, limits, true)
return prepareOverrideBatch(base, sources, overrides, rule, limits)
}
func prepareOverrideBatch(base overridePreparationInput, sources []SourceInfo, overrides []Override, rule *VersionRule, limits importLimits, rejectInheritanceDirectives bool) (preparedOverrideBatch, []Diagnostic) {
func prepareOverrideBatch(base overridePreparationInput, sources []SourceInfo, overrides []Override, rule *VersionRule, limits importLimits) (preparedOverrideBatch, []Diagnostic) {
if len(overrides) > maxOverrides || len(sources)+len(overrides) > limits.sources {
return preparedOverrideBatch{sources: cloneSourceInfos(sources)}, []Diagnostic{{
Code: CodeOverrideLimitExceeded, Severity: SeverityError,
@@ -120,7 +108,7 @@ func prepareOverrideBatch(base overridePreparationInput, sources []SourceInfo, o
})
continue
}
if pathContainsDirective(override.Path) || (rejectInheritanceDirectives && pathContainsInheritanceDirective(override.Path)) {
if pathContainsDirective(override.Path) || pathContainsInheritanceDirective(override.Path) {
diagnostics = append(diagnostics, Diagnostic{
Code: CodeOverrideDirective, Severity: SeverityError, Path: override.Path.clone(),
Message: "configuration overrides cannot create configuration directives", Primary: location,
@@ -137,11 +125,7 @@ func prepareOverrideBatch(base overridePreparationInput, sources []SourceInfo, o
diagnostics = append(diagnostics, diagnostic)
continue
}
findDirective := overrideDirectivePath
if rejectInheritanceDirectives {
findDirective = overrideStructuralDirectivePath
}
if relative, ok := findDirective(value, Path{}); ok {
if relative, ok := overrideStructuralDirectivePath(value, Path{}); ok {
diagnostics = append(diagnostics, Diagnostic{
Code: CodeOverrideDirective, Severity: SeverityError, Path: appendOverridePath(override.Path, relative),
Message: "configuration overrides cannot create configuration directives", Primary: location,
@@ -241,28 +225,27 @@ func appendOverridePath(base, relative Path) Path {
return result
}
func overrideDirectivePath(node *document.Node, path Path) (Path, bool) {
return overrideDirectivePathWithInheritance(node, path, false)
}
func overrideStructuralDirectivePath(node *document.Node, path Path) (Path, bool) {
return overrideDirectivePathWithInheritance(node, path, true)
return overrideStructuralDirectivePathAt(node, path)
}
func overrideDirectivePathWithInheritance(node *document.Node, path Path, rejectInheritanceDirectives bool) (Path, bool) {
func overrideStructuralDirectivePathAt(node *document.Node, path Path) (Path, bool) {
if node == nil {
return Path{}, false
}
if node.Kind == document.Mapping {
for _, entry := range node.Mapping {
child := path.Key(entry.Key)
if entry.Key == directiveKey || (rejectInheritanceDirectives && entry.Key == inheritanceKey) {
if entry.Key == directiveKey || entry.Key == inheritanceKey {
return child, true
}
if found, ok := overrideDirectivePathWithInheritance(entry.Value, child, rejectInheritanceDirectives); ok {
if found, ok := overrideStructuralDirectivePathAt(entry.Value, child); ok {
return found, true
}
}
} else if node.Kind == document.Sequence {
for index, child := range node.Sequence {
if found, ok := overrideDirectivePathWithInheritance(child, path.Index(index), rejectInheritanceDirectives); ok {
if found, ok := overrideStructuralDirectivePathAt(child, path.Index(index)); ok {
return found, true
}
}