Select configuration files through host rules

This commit is contained in:
2026-10-24 15:46:36 +00:00
parent 4748313105
commit 2f0900535d
3 changed files with 236 additions and 2 deletions

View File

@@ -2,6 +2,7 @@ package engine
import (
"errors"
"io/fs"
"os"
"path/filepath"
"runtime"
@@ -459,3 +460,60 @@ func filenameGroupAt(group FilenameGroup, index int, application string) string
return ""
}
}
type discoveryHostProbe struct {
evalSymlinks func(string) (string, error)
stat func(string) (fs.FileInfo, error)
}
func defaultDiscoveryHostProbe() discoveryHostProbe {
return discoveryHostProbe{evalSymlinks: filepath.EvalSymlinks, stat: os.Stat}
}
// resolveSearchSource selects one ordinary file source. A nil description leaves
// an existing source untouched; the selected file is read later by readSource.
func resolveSearchSource(source Source, description *Search, application string, required bool, helpers discoveryDirectoryHelpers, probe discoveryHostProbe) (Source, []Diagnostic) {
if description == nil {
return source, nil
}
iterator, diagnostics := newSearchCandidateIterator(*description, application, helpers)
if len(diagnostics) != 0 {
return Source{}, diagnostics
}
defaults := defaultDiscoveryHostProbe()
if probe.evalSymlinks == nil {
probe.evalSymlinks = defaults.evalSymlinks
}
if probe.stat == nil {
probe.stat = defaults.stat
}
for {
candidate, ok, err := iterator.next()
if err != nil {
if errors.Is(err, errUnixSystemPresetUnavailable) {
return Source{}, []Diagnostic{optionDiagnostic(CodeOptionsInvalid, "Unix system directory search is unavailable on this platform")}
}
return Source{}, []Diagnostic{classifySourceError(err, "")}
}
if !ok {
if required {
return Source{}, []Diagnostic{sourceDiagnostic(CodeSourceMissing, "", "required configuration search found no file")}
}
return NoSource(), nil
}
canonical, err := probe.evalSymlinks(candidate)
if err != nil {
if errors.Is(err, fs.ErrNotExist) {
continue
}
return Source{}, []Diagnostic{classifySourceError(err, "")}
}
if _, err := probe.stat(canonical); err != nil {
if errors.Is(err, fs.ErrNotExist) {
continue
}
return Source{}, []Diagnostic{classifySourceError(err, "")}
}
return File(candidate), nil
}
}