Expose sequence placement controls in the public API

This commit is contained in:
2026-10-16 19:23:43 +00:00
parent c19825620c
commit adef16ccdd
13 changed files with 573 additions and 55 deletions

View File

@@ -51,13 +51,14 @@ type importTraversal struct {
rule *VersionRule
versionState *sourceVersionState
scope acquisitionScope
itemScope bool
itemPrefix Path
sources []SourceInfo
active map[resourceIdentity]int
visited map[resourceIdentity]importRoute
stack []importRoute
scope acquisitionScope
itemScope bool
itemPrefix Path
itemFallback Path
sources []SourceInfo
active map[resourceIdentity]int
visited map[resourceIdentity]importRoute
stack []importRoute
}
func loadImportedDocuments(source Source, context *FilesystemContext, main parsedSource, rule *VersionRule, limits importLimits) (*composedDocument, []SourceInfo, []Diagnostic) {
@@ -135,9 +136,6 @@ func loadImportedWithAccessTrackedAndProcessingPolicy(access *filesystemAccess,
mainInfo := cloneSourceInfo(*main.source)
mainInfo.Destination = destination.clone()
mainIsItem := main.source.placementMode == placementModeSequenceItem
if mainIsItem {
mainInfo.destinationUnresolved = true
}
if mainPath != "" {
mainInfo.Path = mainPath
}
@@ -161,6 +159,7 @@ func loadImportedWithAccessTrackedAndProcessingPolicy(access *filesystemAccess,
if mainIsItem {
state.itemScope = true
state.itemPrefix = destination.clone()
state.itemFallback = destination.clone()
state.scope.destination = Path{}
state.sources[0] = cloneSourceInfo(mainInfo)
}
@@ -394,7 +393,10 @@ func (s *importTraversal) visitPath(basePath string, declaration importDeclarati
if declaration.placement == placementModeSequenceItem {
info.placementMode = placementModeSequenceItem
}
info.destinationUnresolved = s.itemScope || declaration.placement == placementModeSequenceItem
// A source's own item placement still has an exact sequence-container
// destination. Only an unresolved enclosing item index makes the path a
// fallback container for this snapshot.
info.destinationUnresolved = s.itemScope
if kind == SourceKindFilesystem {
info.namespace = s.access.token
}
@@ -484,18 +486,21 @@ func (s *importTraversal) sourceDestination(destination Path) Path {
if !s.itemScope {
return destination.clone()
}
return appendDestination(s.itemPrefix, destination)
// Until the enclosing item receives its assigned index, only the collection
// container is exact. Keep the local suffix in the acquisition projection.
return s.itemFallback.clone()
}
func (s *importTraversal) visitItemSource(canonical string, declaration importDeclaration, destination, relativeDestination Path, depth int, info SourceInfo, body *document.Node, declarations []importDeclaration, processing *sourceVersionProcessingResult) []Diagnostic {
parentScope := s.scope
parentItemScope, parentPrefix := s.itemScope, s.itemPrefix
parentItemScope, parentPrefix, parentFallback := s.itemScope, s.itemPrefix, s.itemFallback
s.scope = acquisitionScope{}
s.itemScope = true
if parentItemScope {
s.itemPrefix = appendDestination(parentPrefix, destination)
} else {
s.itemPrefix = destination.clone()
s.itemFallback = destination.clone()
}
s.scope.contributions = append(s.scope.contributions, acquiredContribution{
source: cloneSourceInfo(info), payload: body, document: body,
@@ -503,7 +508,7 @@ func (s *importTraversal) visitItemSource(canonical string, declaration importDe
})
diagnostics := s.walkDeclarations(s.access.dir(canonical), declarations, depth, Path{})
itemScope := s.scope
s.scope, s.itemScope, s.itemPrefix = parentScope, parentItemScope, parentPrefix
s.scope, s.itemScope, s.itemPrefix, s.itemFallback = parentScope, parentItemScope, parentPrefix, parentFallback
if len(diagnostics) != 0 {
return diagnostics
}