Extract patterned glob entry preparation
This commit is contained in:
@@ -56,45 +56,13 @@ func selectGlobImportCandidates(access *filesystemAccess, basePath string, spec
|
||||
continue
|
||||
}
|
||||
for _, entry := range entries {
|
||||
matched, err := path.Match(segment, entry.Name())
|
||||
if err != nil {
|
||||
return importSelection{}, []Diagnostic{*importSelectionDiagnostic(site, CodeImportInvalid, "import glob pattern is invalid")}
|
||||
candidate, selected, diagnostic := prepareGlobEntry(access, basePath, parent, entry, segment, last, policy)
|
||||
if diagnostic != nil {
|
||||
return importSelection{}, []Diagnostic{*diagnostic}
|
||||
}
|
||||
if !matched || !policy.hidden && strings.HasPrefix(entry.Name(), ".") {
|
||||
continue
|
||||
if selected {
|
||||
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)
|
||||
@@ -123,6 +91,50 @@ func selectGlobImportCandidates(access *filesystemAccess, basePath string, spec
|
||||
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) {
|
||||
if !access.contains(candidatePath) || !access.contains(accessPath) {
|
||||
return selectedImportCandidate{}, false, []Diagnostic{*importSelectionDiagnostic(site, CodeImportOutsideRoot, "glob traversal is outside the configuration root")}
|
||||
|
||||
Reference in New Issue
Block a user