Count import depth only for selected sources
This commit is contained in:
@@ -400,10 +400,6 @@ func (s *importTraversal) walkDeclarations(basePath string, declarations []impor
|
||||
site := spec.fieldSites["placement"]
|
||||
return []Diagnostic{{Code: CodeImportInvalid, Severity: SeverityError, Path: site.path.clone(), Message: "sequence-item placement requires a nonempty destination", Primary: cloneLocation(&site.location)}}
|
||||
}
|
||||
if depth+1 > s.limits.depth {
|
||||
location := spec.location
|
||||
return []Diagnostic{importDiagnostic(CodeImportLimitExceeded, "configuration exceeds the active import-depth limit", &location)}
|
||||
}
|
||||
policies[index] = policy
|
||||
}
|
||||
for index, spec := range declarations {
|
||||
@@ -478,6 +474,9 @@ func (s *importTraversal) visitPath(candidate selectedImportCandidate, spec impo
|
||||
if !s.access.contains(canonical) {
|
||||
return []Diagnostic{importDiagnostic(CodeImportOutsideRoot, "import target resolves outside the configuration root", &location)}
|
||||
}
|
||||
if depth > s.limits.depth {
|
||||
return []Diagnostic{importDiagnostic(CodeImportLimitExceeded, "configuration exceeds the active import-depth limit", &location)}
|
||||
}
|
||||
|
||||
currentRoute := s.currentRoute(location)
|
||||
identity := s.access.identity(canonical)
|
||||
|
||||
@@ -1149,6 +1149,48 @@ func TestImportTraversalEnforcesPrivateBudgets(t *testing.T) {
|
||||
}
|
||||
}
|
||||
|
||||
func TestImportDepthBudgetCountsSelectedEdges(t *testing.T) {
|
||||
for _, test := range []struct {
|
||||
name, declaration string
|
||||
code Code
|
||||
}{
|
||||
{name: "no declaration"},
|
||||
{name: "empty paths", declaration: "path: []"},
|
||||
{name: "required empty paths", declaration: "path: []\n required: true"},
|
||||
{name: "missing path", declaration: "path: absent.yml"},
|
||||
{name: "missing directory", declaration: "dir: absent"},
|
||||
{name: "missing glob", declaration: "glob: 'absent/*.yml'"},
|
||||
{name: "selected path", declaration: "path: parts/next.yml", code: CodeImportLimitExceeded},
|
||||
{name: "selected directory", declaration: "dir: parts", code: CodeImportLimitExceeded},
|
||||
{name: "selected glob", declaration: "glob: 'parts/*.yml'", code: CodeImportLimitExceeded},
|
||||
{name: "invalid empty declaration", declaration: "dir: []\n depth: 1", code: CodeImportInvalid},
|
||||
{name: "invalid absent glob", declaration: "glob: '['", code: CodeImportInvalid},
|
||||
} {
|
||||
t.Run(test.name, func(t *testing.T) {
|
||||
directory := t.TempDir()
|
||||
mainPath := writeImportFile(t, directory, "main.yml", "configkit: {imports: [{path: leaf.yml}]}\n")
|
||||
leaf := "end: true\n"
|
||||
if test.declaration != "" {
|
||||
leaf += "configkit:\n imports:\n - " + test.declaration + "\n"
|
||||
}
|
||||
writeImportFile(t, directory, "leaf.yml", leaf)
|
||||
writeImportFile(t, directory, "parts/next.yml", "next: true\n")
|
||||
limits := defaultImportLimits()
|
||||
limits.depth = 1
|
||||
composed, sources, diagnostics := loadImportedDocuments(File(mainPath), nil, parseImportMain(t, mainPath), nil, limits)
|
||||
if test.code != "" {
|
||||
if len(diagnostics) != 1 || diagnostics[0].Code != test.code {
|
||||
t.Fatalf("diagnostics = %#v, want %s", diagnostics, test.code)
|
||||
}
|
||||
return
|
||||
}
|
||||
if len(diagnostics) != 0 || composed == nil || len(sources) != 2 {
|
||||
t.Fatalf("depth-boundary composition: sources=%#v diagnostics=%#v", sources, diagnostics)
|
||||
}
|
||||
})
|
||||
}
|
||||
}
|
||||
|
||||
func TestImportTraversalAcceptsExactPrivateBudgets(t *testing.T) {
|
||||
directory := t.TempDir()
|
||||
mainPath := writeImportFile(t, directory, "main.yml", "configkit: {imports: [{path: imported.yml}]}\n")
|
||||
|
||||
Reference in New Issue
Block a user