Prepare reusable CLI override batches
This commit is contained in:
@@ -19,9 +19,40 @@ type preparedOverride struct {
|
||||
nodes int
|
||||
}
|
||||
|
||||
func prepareOverrides(base *composedDocument, sources []SourceInfo, overrides []Override, rule *VersionRule, limits importLimits) ([]preparedOverride, []SourceInfo, []Diagnostic) {
|
||||
// preparedOverrideBatch owns all override values and synthetic source records
|
||||
// needed to apply one CLI batch after its preparation checks succeed.
|
||||
type preparedOverrideBatch struct {
|
||||
overrides []preparedOverride
|
||||
sources []SourceInfo
|
||||
}
|
||||
|
||||
type overridePreparationInput struct {
|
||||
root *document.Node
|
||||
inputBytes int64
|
||||
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.
|
||||
func preparePostStructuralOverrides(base overridePreparationInput, sources []SourceInfo, overrides []Override, rule *VersionRule, limits importLimits) (preparedOverrideBatch, []Diagnostic) {
|
||||
return prepareOverrideBatch(base, sources, overrides, rule, limits, true)
|
||||
}
|
||||
|
||||
func prepareOverrideBatch(base overridePreparationInput, sources []SourceInfo, overrides []Override, rule *VersionRule, limits importLimits, rejectInheritanceDirectives bool) (preparedOverrideBatch, []Diagnostic) {
|
||||
if len(overrides) > maxOverrides || len(sources)+len(overrides) > limits.sources {
|
||||
return nil, cloneSourceInfos(sources), []Diagnostic{{
|
||||
return preparedOverrideBatch{sources: cloneSourceInfos(sources)}, []Diagnostic{{
|
||||
Code: CodeOverrideLimitExceeded, Severity: SeverityError,
|
||||
Message: "configuration overrides exceed the record or source-count limit",
|
||||
}}
|
||||
@@ -37,7 +68,7 @@ func prepareOverrides(base *composedDocument, sources []SourceInfo, overrides []
|
||||
}
|
||||
}
|
||||
if len(diagnostics) != 0 {
|
||||
return nil, cloneSourceInfos(sources), canonicalDiagnostics(diagnostics)
|
||||
return preparedOverrideBatch{sources: cloneSourceInfos(sources)}, canonicalDiagnostics(diagnostics)
|
||||
}
|
||||
|
||||
prepared := make([]preparedOverride, len(overrides))
|
||||
@@ -89,7 +120,7 @@ func prepareOverrides(base *composedDocument, sources []SourceInfo, overrides []
|
||||
})
|
||||
continue
|
||||
}
|
||||
if pathContainsDirective(override.Path) {
|
||||
if pathContainsDirective(override.Path) || (rejectInheritanceDirectives && pathContainsInheritanceDirective(override.Path)) {
|
||||
diagnostics = append(diagnostics, Diagnostic{
|
||||
Code: CodeOverrideDirective, Severity: SeverityError, Path: override.Path.clone(),
|
||||
Message: "configuration overrides cannot create configuration directives", Primary: location,
|
||||
@@ -106,7 +137,11 @@ func prepareOverrides(base *composedDocument, sources []SourceInfo, overrides []
|
||||
diagnostics = append(diagnostics, diagnostic)
|
||||
continue
|
||||
}
|
||||
if relative, ok := overrideDirectivePath(value, Path{}); ok {
|
||||
findDirective := overrideDirectivePath
|
||||
if rejectInheritanceDirectives {
|
||||
findDirective = overrideStructuralDirectivePath
|
||||
}
|
||||
if relative, ok := findDirective(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,
|
||||
@@ -136,10 +171,10 @@ func prepareOverrides(base *composedDocument, sources []SourceInfo, overrides []
|
||||
usedNodes += nodes
|
||||
}
|
||||
if len(diagnostics) != 0 {
|
||||
return nil, allSources, canonicalDiagnostics(diagnostics)
|
||||
return preparedOverrideBatch{sources: allSources}, canonicalDiagnostics(diagnostics)
|
||||
}
|
||||
|
||||
return prepared, allSources, nil
|
||||
return preparedOverrideBatch{overrides: prepared, sources: allSources}, nil
|
||||
}
|
||||
|
||||
func validOverrideLabel(label string) bool {
|
||||
@@ -191,6 +226,15 @@ func pathContainsDirective(path Path) bool {
|
||||
return false
|
||||
}
|
||||
|
||||
func pathContainsInheritanceDirective(path Path) bool {
|
||||
for _, segment := range path.segments {
|
||||
if segment.key == inheritanceKey {
|
||||
return true
|
||||
}
|
||||
}
|
||||
return false
|
||||
}
|
||||
|
||||
func appendOverridePath(base, relative Path) Path {
|
||||
result := base.clone()
|
||||
result.segments = append(result.segments, clonePathSegments(relative.segments, 0)...)
|
||||
@@ -198,19 +242,27 @@ func appendOverridePath(base, relative Path) Path {
|
||||
}
|
||||
|
||||
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)
|
||||
}
|
||||
|
||||
func overrideDirectivePathWithInheritance(node *document.Node, path Path, rejectInheritanceDirectives bool) (Path, bool) {
|
||||
if node.Kind == document.Mapping {
|
||||
for _, entry := range node.Mapping {
|
||||
child := path.Key(entry.Key)
|
||||
if entry.Key == directiveKey {
|
||||
if entry.Key == directiveKey || (rejectInheritanceDirectives && entry.Key == inheritanceKey) {
|
||||
return child, true
|
||||
}
|
||||
if found, ok := overrideDirectivePath(entry.Value, child); ok {
|
||||
if found, ok := overrideDirectivePathWithInheritance(entry.Value, child, rejectInheritanceDirectives); ok {
|
||||
return found, true
|
||||
}
|
||||
}
|
||||
} else if node.Kind == document.Sequence {
|
||||
for index, child := range node.Sequence {
|
||||
if found, ok := overrideDirectivePath(child, path.Index(index)); ok {
|
||||
if found, ok := overrideDirectivePathWithInheritance(child, path.Index(index), rejectInheritanceDirectives); ok {
|
||||
return found, true
|
||||
}
|
||||
}
|
||||
|
||||
Reference in New Issue
Block a user