Add selected profile overlays
This commit is contained in:
42
load.go
42
load.go
@@ -17,8 +17,8 @@ type Definition[T any] struct {
|
||||
}
|
||||
|
||||
// Options contains the application definition and per-load input selections.
|
||||
// Imports enables explicit path and glob imports; later precedence layers remain
|
||||
// unavailable until their owning features are implemented.
|
||||
// Imports enables explicit path and glob imports; Profile selects one fixed profile
|
||||
// overlay. Explicit overrides remain unavailable until implemented.
|
||||
type Options[T any] struct {
|
||||
Definition Definition[T]
|
||||
Imports bool
|
||||
@@ -94,9 +94,9 @@ func (r *Result[T]) Diagnostics() []Diagnostic {
|
||||
return cloneDiagnostics(r.diagnostics)
|
||||
}
|
||||
|
||||
// Load parses and strictly decodes zero or one selected source plus explicitly
|
||||
// enabled imports. It accepts at most one Options value and returns no result when
|
||||
// any error is reported.
|
||||
// Load parses and strictly decodes zero or one selected source, explicitly enabled
|
||||
// imports, and one selected profile. It accepts at most one Options value and
|
||||
// returns no result when any error is reported.
|
||||
func Load[T any](source Source, supplied ...Options[T]) (*Result[T], error) {
|
||||
accumulator := diagnosticAccumulator{}
|
||||
options, diagnostics := selectOptions(source, supplied)
|
||||
@@ -127,7 +127,7 @@ func Load[T any](source Source, supplied ...Options[T]) (*Result[T], error) {
|
||||
if parsed.source != nil {
|
||||
accumulator.sources = append(accumulator.sources, *parsed.source)
|
||||
}
|
||||
if options.Filesystem != nil {
|
||||
if options.Filesystem != nil && !activeProfile(options.Profile) {
|
||||
if diagnostic := validateFilesystemContext(source, options.Filesystem, parsed); diagnostic != nil {
|
||||
accumulator.add(*diagnostic)
|
||||
return nil, accumulator.loadError()
|
||||
@@ -153,6 +153,26 @@ func Load[T any](source Source, supplied ...Options[T]) (*Result[T], error) {
|
||||
if hasErrors(versionDiagnostics) {
|
||||
return nil, accumulator.loadError()
|
||||
}
|
||||
if activeProfile(options.Profile) {
|
||||
if composition == nil {
|
||||
composition, diagnostics = composeDocuments(inputDocument)
|
||||
if len(diagnostics) != 0 {
|
||||
accumulator.add(diagnostics...)
|
||||
return nil, accumulator.loadError()
|
||||
}
|
||||
composition.inputBytes = parsed.bytes
|
||||
composition.inputNodes = countInputNodes(parsed.document)
|
||||
}
|
||||
composition, accumulator.sources, diagnostics = loadProfileDocument(
|
||||
source, options.Filesystem, parsed, composition, accumulator.sources,
|
||||
options.Profile, options.Definition.Version, defaultImportLimits(),
|
||||
)
|
||||
if len(diagnostics) != 0 {
|
||||
accumulator.add(diagnostics...)
|
||||
return nil, accumulator.loadError()
|
||||
}
|
||||
inputDocument = composition.root
|
||||
}
|
||||
|
||||
defaults := reflect.Zero(reflect.TypeFor[T]())
|
||||
if options.Definition.Defaults != nil {
|
||||
@@ -171,6 +191,9 @@ func Load[T any](source Source, supplied ...Options[T]) (*Result[T], error) {
|
||||
|
||||
configuration := decoded.value.Interface().(T)
|
||||
metadata := metadataFromDecoded(decoded)
|
||||
if composition != nil {
|
||||
applyOverlayMetadata(&metadata, composition.overlays)
|
||||
}
|
||||
final := decoded.final
|
||||
var resolutionSnapshots []resolutionSnapshot
|
||||
if options.Definition.Resolve != nil {
|
||||
@@ -213,8 +236,8 @@ func selectOptions[T any](source Source, supplied []Options[T]) (Options[T], []D
|
||||
if definition.Secret != nil {
|
||||
diagnostics = append(diagnostics, optionDiagnostic(CodeOptionsUnavailable, "dynamic secret classification is not available in this release boundary"))
|
||||
}
|
||||
if options.Profile != "" && options.Profile != "default" {
|
||||
diagnostics = append(diagnostics, optionDiagnostic(CodeOptionsUnavailable, "configuration profiles are not available in this release boundary"))
|
||||
if !validProfileName(options.Profile) {
|
||||
diagnostics = append(diagnostics, optionDiagnostic(CodeOptionsInvalid, "profile name must contain only ASCII letters, digits, underscore, or hyphen"))
|
||||
}
|
||||
if options.Filesystem != nil {
|
||||
diagnostics = append(diagnostics, filesystemOptionDiagnostics(source, options.Filesystem)...)
|
||||
@@ -228,6 +251,9 @@ func selectOptions[T any](source Source, supplied []Options[T]) (Options[T], []D
|
||||
if source.kind == sourceNone && options.Profile != "" && options.Profile != "default" {
|
||||
diagnostics = append(diagnostics, optionDiagnostic(CodeOptionsInvalid, "NoSource cannot select an active profile"))
|
||||
}
|
||||
if options.Filesystem == nil && (source.kind == sourceBytes || source.kind == sourceReader) && (options.Imports || activeProfile(options.Profile)) {
|
||||
diagnostics = append(diagnostics, optionDiagnostic(CodeOptionsInvalid, "byte and reader imports or profiles require filesystem context"))
|
||||
}
|
||||
if definition.Version != nil {
|
||||
if !definition.Version.Path.valid() {
|
||||
diagnostics = append(diagnostics, optionDiagnostic(CodeOptionsInvalid, "schema-version path is invalid"))
|
||||
|
||||
Reference in New Issue
Block a user