Extract patterned glob entry preparation
This commit is contained in:
@@ -1,6 +1,6 @@
|
|||||||
# Import Discovery And Facade Simplification Implementation Plan
|
# Import Discovery And Facade Simplification Implementation Plan
|
||||||
|
|
||||||
Status: not started.
|
Status: in progress.
|
||||||
Baseline: `bb5540b62e382106d59678e2edb7655acfd5c960`.
|
Baseline: `bb5540b62e382106d59678e2edb7655acfd5c960`.
|
||||||
Audience: a Luna coding agent implementing the stages sequentially.
|
Audience: a Luna coding agent implementing the stages sequentially.
|
||||||
|
|
||||||
@@ -76,7 +76,8 @@ acceptance criteria.
|
|||||||
## Stage 1 — Extract Patterned Glob Entry Preparation
|
## Stage 1 — Extract Patterned Glob Entry Preparation
|
||||||
|
|
||||||
Finding: **C03**. Owners: `internal/engine/glob.go`, existing glob selection,
|
Finding: **C03**. Owners: `internal/engine/glob.go`, existing glob selection,
|
||||||
link, and directory failure tests. Status: **not started**.
|
link, and directory failure tests. Status: **complete**. Validation passed:
|
||||||
|
`env GOTOOLCHAIN=local GOPROXY=off GOTELEMETRY=off go test ./internal/engine -run 'Glob|Directory|Link|Filesystem|Resource'` and `git diff --check`.
|
||||||
|
|
||||||
1. Add `prepareGlobEntry` beside the selector. Take the filesystem access,
|
1. Add `prepareGlobEntry` beside the selector. Take the filesystem access,
|
||||||
base path, parent `selectedImportCandidate`, `fs.DirEntry`, pattern segment,
|
base path, parent `selectedImportCandidate`, `fs.DirEntry`, pattern segment,
|
||||||
|
|||||||
@@ -56,45 +56,13 @@ func selectGlobImportCandidates(access *filesystemAccess, basePath string, spec
|
|||||||
continue
|
continue
|
||||||
}
|
}
|
||||||
for _, entry := range entries {
|
for _, entry := range entries {
|
||||||
matched, err := path.Match(segment, entry.Name())
|
candidate, selected, diagnostic := prepareGlobEntry(access, basePath, parent, entry, segment, last, policy)
|
||||||
if err != nil {
|
if diagnostic != nil {
|
||||||
return importSelection{}, []Diagnostic{*importSelectionDiagnostic(site, CodeImportInvalid, "import glob pattern is invalid")}
|
return importSelection{}, []Diagnostic{*diagnostic}
|
||||||
}
|
}
|
||||||
if !matched || !policy.hidden && strings.HasPrefix(entry.Name(), ".") {
|
if selected {
|
||||||
continue
|
nextByPath[candidate.path] = candidate
|
||||||
}
|
}
|
||||||
accessPath := access.join(parent.accessPath, entry.Name())
|
|
||||||
lexicalPath := access.join(parent.path, entry.Name())
|
|
||||||
if !access.contains(accessPath) || !access.contains(lexicalPath) {
|
|
||||||
return importSelection{}, []Diagnostic{*importSelectionDiagnostic(site, CodeImportOutsideRoot, "glob traversal is outside the configuration root")}
|
|
||||||
}
|
|
||||||
target, err := access.importEntryTarget(accessPath, entry, policy.follow)
|
|
||||||
if err != nil {
|
|
||||||
return importSelection{}, []Diagnostic{globCandidateDiagnostic(err, site.location, "glob match could not be inspected")}
|
|
||||||
}
|
|
||||||
if target.symlink && !policy.follow {
|
|
||||||
continue
|
|
||||||
}
|
|
||||||
if !last && !target.dir {
|
|
||||||
continue
|
|
||||||
}
|
|
||||||
physicalPath := target.identity
|
|
||||||
// Native source identity and relative imports use the namespace
|
|
||||||
// spelling; resolved link identities belong only to discovery.
|
|
||||||
if access.native != nil {
|
|
||||||
physicalPath = accessPath
|
|
||||||
}
|
|
||||||
if physicalPath == "" {
|
|
||||||
physicalPath, err = access.canonical(accessPath)
|
|
||||||
if err != nil {
|
|
||||||
return importSelection{}, []Diagnostic{globFilesystemDiagnostic(err, "glob match could not be canonicalized", site.location)}
|
|
||||||
}
|
|
||||||
}
|
|
||||||
candidate := selectedImportCandidate{
|
|
||||||
path: normalizedImportCandidatePath(access, lexicalPath), accessPath: physicalPath,
|
|
||||||
label: relativeImportLabel(access, basePath, lexicalPath), site: site,
|
|
||||||
}
|
|
||||||
nextByPath[candidate.path] = candidate
|
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
candidates = candidatesFromMap(nextByPath)
|
candidates = candidatesFromMap(nextByPath)
|
||||||
@@ -123,6 +91,50 @@ func selectGlobImportCandidates(access *filesystemAccess, basePath string, spec
|
|||||||
return selection, nil
|
return selection, nil
|
||||||
}
|
}
|
||||||
|
|
||||||
|
func prepareGlobEntry(access *filesystemAccess, basePath string, parent selectedImportCandidate, entry fs.DirEntry, pattern string, last bool, policy resolvedImportPolicy) (selectedImportCandidate, bool, *Diagnostic) {
|
||||||
|
name := entry.Name()
|
||||||
|
matched, err := path.Match(pattern, name)
|
||||||
|
if err != nil {
|
||||||
|
return selectedImportCandidate{}, false, importSelectionDiagnostic(parent.site, CodeImportInvalid, "import glob pattern is invalid")
|
||||||
|
}
|
||||||
|
if !matched || !policy.hidden && strings.HasPrefix(name, ".") {
|
||||||
|
return selectedImportCandidate{}, false, nil
|
||||||
|
}
|
||||||
|
|
||||||
|
accessPath := access.join(parent.accessPath, name)
|
||||||
|
lexicalPath := access.join(parent.path, name)
|
||||||
|
if !access.contains(accessPath) || !access.contains(lexicalPath) {
|
||||||
|
return selectedImportCandidate{}, false, importSelectionDiagnostic(parent.site, CodeImportOutsideRoot, "glob traversal is outside the configuration root")
|
||||||
|
}
|
||||||
|
target, err := access.importEntryTarget(accessPath, entry, policy.follow)
|
||||||
|
if err != nil {
|
||||||
|
diagnostic := globCandidateDiagnostic(err, parent.site.location, "glob match could not be inspected")
|
||||||
|
return selectedImportCandidate{}, false, &diagnostic
|
||||||
|
}
|
||||||
|
if target.symlink && !policy.follow || !last && !target.dir {
|
||||||
|
return selectedImportCandidate{}, false, nil
|
||||||
|
}
|
||||||
|
|
||||||
|
physicalPath := target.identity
|
||||||
|
// Native source identity and relative imports use the namespace spelling;
|
||||||
|
// resolved link identities belong only to discovery.
|
||||||
|
if access.native != nil {
|
||||||
|
physicalPath = accessPath
|
||||||
|
}
|
||||||
|
if physicalPath == "" {
|
||||||
|
physicalPath, err = access.canonical(accessPath)
|
||||||
|
if err != nil {
|
||||||
|
diagnostic := globFilesystemDiagnostic(err, "glob match could not be canonicalized", parent.site.location)
|
||||||
|
return selectedImportCandidate{}, false, &diagnostic
|
||||||
|
}
|
||||||
|
}
|
||||||
|
|
||||||
|
return selectedImportCandidate{
|
||||||
|
path: normalizedImportCandidatePath(access, lexicalPath), accessPath: physicalPath,
|
||||||
|
label: relativeImportLabel(access, basePath, lexicalPath), site: parent.site,
|
||||||
|
}, true, nil
|
||||||
|
}
|
||||||
|
|
||||||
func explicitGlobCandidate(access *filesystemAccess, basePath, candidatePath, accessPath string, site importFieldSite, last bool) (selectedImportCandidate, bool, []Diagnostic) {
|
func explicitGlobCandidate(access *filesystemAccess, basePath, candidatePath, accessPath string, site importFieldSite, last bool) (selectedImportCandidate, bool, []Diagnostic) {
|
||||||
if !access.contains(candidatePath) || !access.contains(accessPath) {
|
if !access.contains(candidatePath) || !access.contains(accessPath) {
|
||||||
return selectedImportCandidate{}, false, []Diagnostic{*importSelectionDiagnostic(site, CodeImportOutsideRoot, "glob traversal is outside the configuration root")}
|
return selectedImportCandidate{}, false, []Diagnostic{*importSelectionDiagnostic(site, CodeImportOutsideRoot, "glob traversal is outside the configuration root")}
|
||||||
|
|||||||
Reference in New Issue
Block a user