Define main-relative input options

This commit is contained in:
2026-11-09 18:42:09 +00:00
parent ae0c94d3c6
commit 0a136063da
6 changed files with 89 additions and 6 deletions

View File

@@ -7,10 +7,16 @@ type Input struct {
Source Source
Imports bool
Filesystem *FilesystemContext
MainRelative *MainRelativeContext
Destination Path
PlacementMode PlacementMode
}
type MainRelativeContext struct {
Fallback *FilesystemContext
RequireBase bool
}
// Underlay contains strictly composed contributions at one precedence tier.
type Underlay struct{ Inputs []Input }
@@ -22,6 +28,7 @@ type LayeredOptions[T any] struct {
Underlays []Underlay
Overlay string
OverlayFilesystem *FilesystemContext
OverlayFallback *FilesystemContext
Overrides []Override
}
@@ -37,13 +44,14 @@ func LoadLayered[T any](main Input, secrets SecretBinding, supplied ...LayeredOp
}
request := loadRequest[T]{
main: loadInput{
source: main.Source, imports: main.Imports, filesystem: main.Filesystem,
source: main.Source, imports: main.Imports, filesystem: main.Filesystem, mainRelative: main.MainRelative,
destination: main.Destination.clone(), placementMode: main.PlacementMode,
},
definition: options.Definition, sourceVersionMode: options.SourceVersionMode,
importDefaults: options.ImportDefaults,
overlay: options.Overlay,
overlayFilesystem: options.OverlayFilesystem,
overlayFallback: options.OverlayFallback,
overrides: append([]Override(nil), options.Overrides...),
underlays: make([]loadGroup, len(options.Underlays)),
}
@@ -51,7 +59,7 @@ func LoadLayered[T any](main Input, secrets SecretBinding, supplied ...LayeredOp
request.underlays[index].inputs = make([]loadInput, len(underlay.Inputs))
for inputIndex, input := range underlay.Inputs {
request.underlays[index].inputs[inputIndex] = loadInput{
source: input.Source, imports: input.Imports, filesystem: input.Filesystem,
source: input.Source, imports: input.Imports, filesystem: input.Filesystem, mainRelative: input.MainRelative,
destination: input.Destination.clone(), placementMode: input.PlacementMode,
}
}

View File

@@ -16,6 +16,7 @@ type loadRequest[T any] struct {
effectiveVersion *VersionRule
overlay string
overlayFilesystem *FilesystemContext
overlayFallback *FilesystemContext
overrides []Override
ordinary bool
}
@@ -31,6 +32,7 @@ type loadInput struct {
source Source
imports bool
filesystem *FilesystemContext
mainRelative *MainRelativeContext
destination Path
placementMode PlacementMode
}
@@ -57,6 +59,9 @@ func loadGroupedWithSecretLookupLimit[T any](request loadRequest[T], secrets Sec
request.importDefaults = defaults
request.sequencePolicy = policy
request.definition.sequenceIdentityRegistrations = nil
if request.main.mainRelative != nil && request.main.filesystem == nil {
diagnostics = append(diagnostics, optionDiagnostic(CodeOptionsInvalid, "main input cannot use main-relative context"))
}
main, mainDiagnostics := normalizeInput(request.main, "")
request.main = main
diagnostics = append(diagnostics, mainDiagnostics...)
@@ -64,6 +69,13 @@ func loadGroupedWithSecretLookupLimit[T any](request loadRequest[T], secrets Sec
for groupIndex := range request.underlays {
for inputIndex := range request.underlays[groupIndex].inputs {
input := &request.underlays[groupIndex].inputs[inputIndex]
if input.mainRelative != nil && input.filesystem == nil {
if input.source.kind == sourceFile || input.source.kind == sourceFilesystem || input.source.kind == sourceSearch {
diagnostics = append(diagnostics, optionDiagnostic(CodeOptionsInvalid, "file and search underlays cannot use main-relative context"))
} else if input.mainRelative.Fallback != nil {
diagnostics = append(diagnostics, filesystemOptionDiagnostics(Source{kind: sourceBytes}, input.mainRelative.Fallback)...)
}
}
normalized, inputDiagnostics := normalizeInput(*input, "")
*input = normalized
diagnostics = append(diagnostics, inputDiagnostics...)
@@ -71,10 +83,10 @@ func loadGroupedWithSecretLookupLimit[T any](request loadRequest[T], secrets Sec
}
diagnostics = append(diagnostics, overlayOptionDiagnostics(request.overlay)...)
if activeOverlay(request.overlay) {
if request.overlayFilesystem == nil {
diagnostics = append(diagnostics, optionDiagnostic(CodeOptionsInvalid, "selected overlay requires explicit filesystem context"))
} else {
if request.overlayFilesystem != nil {
diagnostics = append(diagnostics, filesystemOptionDiagnostics(Source{kind: sourceBytes}, request.overlayFilesystem)...)
} else if request.overlayFallback != nil {
diagnostics = append(diagnostics, filesystemOptionDiagnostics(Source{kind: sourceBytes}, request.overlayFallback)...)
}
}
if len(diagnostics) != 0 {

View File

@@ -29,7 +29,7 @@ func normalizeInput(input loadInput, ordinaryOverlay string) (loadInput, []Diagn
if input.source.kind == sourceNone && activeOverlay(ordinaryOverlay) && input.filesystem == nil {
diagnostics = append(diagnostics, optionDiagnostic(CodeOptionsInvalid, "NoSource overlays require explicit filesystem context"))
}
if input.filesystem == nil && (input.source.kind == sourceBytes || input.source.kind == sourceReader || input.source.kind == sourceMapping) && (input.imports || activeOverlay(ordinaryOverlay)) {
if input.filesystem == nil && input.mainRelative == nil && (input.source.kind == sourceBytes || input.source.kind == sourceReader || input.source.kind == sourceMapping) && (input.imports || activeOverlay(ordinaryOverlay)) {
diagnostics = append(diagnostics, optionDiagnostic(CodeOptionsInvalid, "synthetic-source imports or overlays require filesystem context"))
}
return input, canonicalDiagnostics(diagnostics)