Documentation
¶
Overview ¶
Package sourceload provides file-finding and load-stack tracking for locating source files across virtual filesystems.
The package is focused on file-path traversal, file loading, and load-stack management — isolated from Scheme evaluation concerns.
Index ¶
Constants ¶
This section is empty.
Variables ¶
var ErrNotFound = werr.NewStaticError("sourceload: file not found")
ErrNotFound is returned when no matching file can be located across all provided search directories.
Functions ¶
func Walk ¶
func Walk(fsys fs.FS, searchDirs []string, accept func(name string) bool, fn func(relPath string)) error
Walk traverses fsys under each search directory, calling fn for every file where accept returns true. Hidden directories (name starting with ".") are skipped. Non-existent directories are silently skipped. Other root-level errors (permission, I/O) are propagated.
accept receives the filename (not the full path). fn receives the slash-separated path relative to the search directory.
No "." fallback — only walks directories explicitly provided. No deduplication — caller handles domain-specific identity. Per-directory errors are accumulated via errors.Join and returned alongside partial results. Individual file-level errors within a directory are skipped (best-effort enumeration).
func WithLoadStack ¶
WithLoadStack returns a context carrying stack as the active per-load-chain load stack. Library loading installs a private stack here so that concurrent SRFI-18 thread loads resolve their (include …) directives against their own directory instead of a single mutable LoadStack shared on the root namespace. The stack threads down the synchronous load → compile → include call chain via context, but context does NOT cross the SRFI-18 goroutine boundary (each thread sub-context starts from its own context), so its Push/Pop stay confined to one goroutine and need no cross-thread synchronization — exactly the property that makes the shared-namespace stack unsafe under concurrency.
Types ¶
type Finder ¶
type Finder struct {
// contains filtered or unexported fields
}
Finder locates files within an fs.FS by searching an ordered list of directories. It supports an optional LoadStack for current-directory-relative resolution and an optional canonicalize function applied to resolved paths.
func NewFinder ¶
func NewFinder(fsys fs.FS, searchDirs []string, opts ...FinderOption) *Finder
NewFinder constructs a Finder that searches fsys in the given directories. It panics if fsys is nil.
func (*Finder) Candidates ¶ added in v1.20.0
Candidates returns the ordered paths Open would try for name, in search order, with invalid fs paths dropped. It touches the filesystem not at all, so a caller can put an authorization gate ahead of every access to a candidate rather than behind the first one.
Returns nil for an empty name.
func (*Finder) Open ¶
Open searches for the named path and returns an open file, the resolved path, and nil on success. It returns ErrNotFound when no match is found.
Search order:
- stack.CurrentDir() — if stack is non-nil, CurrentDir is non-empty, and is not "."
- Each searchDir provided to NewFinder, in order
- FS root "."
The returned path goes through canonicalize (if set) before being returned. Returns ErrNotFound immediately for an empty path argument.
Open is the composition of Candidates and OpenCandidate. A caller that must authorize a candidate before touching it uses those two directly, so that the gate sits visibly between them; there is still one implementation of each half.
func (*Finder) OpenCandidate ¶ added in v1.20.0
OpenCandidate stats then opens one already-chosen candidate, returning the resolved path (canonicalize applied, if set).
Errors are returned raw so a caller can classify them: errors.Is(err, fs.ErrNotExist) is "keep searching", anything else is a hard failure that must not be mistaken for absence.
type FinderOption ¶
type FinderOption func(*Finder)
FinderOption is a functional option for Finder.
func WithCanonicalize ¶
func WithCanonicalize(fn func(string) string) FinderOption
WithCanonicalize sets a path transformation applied to every resolved path before it is returned from Open. It does not affect which file is opened — only the returned path string.
func WithStack ¶
func WithStack(s *LoadStack) FinderOption
WithStack attaches a LoadStack to the Finder. When set, the directory of the currently-loading file is searched first (before explicit searchDirs).
type LoadStack ¶
type LoadStack struct {
// contains filtered or unexported fields
}
LoadStack tracks the chain of source files currently being loaded. Each Push records the path of a file being processed; Pop removes it when loading is complete. The stack enables directory-relative resolution of include paths — the current file's directory is the base for includes.
All methods are safe for concurrent use.
func LoadStackFromContext ¶
LoadStackFromContext returns the per-load-chain LoadStack carried on ctx, or nil when none has been installed (the top-level, non-library-load case, where the shared per-namespace stack remains the source of the current load directory).
func NewLoadStack ¶
func NewLoadStack() *LoadStack
NewLoadStack returns an empty LoadStack with pre-allocated capacity.
func (*LoadStack) Current ¶
Current returns the path at the top of the stack, or "" if the stack is empty.
func (*LoadStack) CurrentDir ¶
CurrentDir returns the directory component of the top path using slash-separated semantics (path.Dir, not filepath.Dir). Returns "" if the stack is empty.
func (*LoadStack) Paths ¶ added in v1.20.0
Paths returns a copy of the stack's paths, outermost first. It exists so a derived stack can be seeded from an existing one without sharing its storage: Engine.ContextWithLoadPath hands back a context carrying its OWN stack, so a caller cannot leak a push into the context it was given.