Documentation
¶
Overview ¶
Package fsroot provides scoped filesystem roots.
All provider I/O flows through the Root interface, confining reads and writes to a directory tree. Three implementations serve the three lifecycles: confined roots for execution, read-only roots for planning, and writable unconfined roots for tests.
Index ¶
Constants ¶
This section is empty.
Variables ¶
This section is empty.
Functions ¶
This section is empty.
Types ¶
type Path ¶
type Path struct {
// contains filtered or unexported fields
}
Path holds both root-relative and absolute forms of a filesystem path.
Created through Root.NewPath to guarantee both fields are populated. The root field records which root directory Rel is relative to (matching os.Root.Name). Abs is derived as filepath.Join(root, rel) and is not serialized.
noinspection GoMixedReceiverTypes
func NewPath ¶
NewPath creates a Path from a root directory and a root-relative path.
Abs is derived via filepath.Join. Rel is stored in canonical slash form regardless of the input's separators — rel is the half that serializes, and equal logical paths must produce equal document bytes on every platform (the same rule the Merkle-root digest follows). Intended for tests and deserialization.
Parameters:
- `root`: the root directory that `rel` is relative to (matches os.Root.Name).
- `rel`: the root-relative path; any separator form.
Returns:
- `Path`: the constructed path, with `rel` canonicalized to slash form.
func (Path) Abs ¶
Abs returns the absolute path used for unconfined I/O, URIs, display, and logging.
Returns:
- `string`: the absolute path.
func (Path) MarshalJSON ¶
MarshalJSON serializes the canonical form {root, rel}. Abs is derived on deserialization.
Returns:
- `[]byte`: the JSON encoding of the {root, rel} form.
- `error`: any error returned by json.Marshal.
func (Path) MarshalYAML ¶
MarshalYAML serializes the canonical form {root, rel}. Abs is derived on deserialization.
Returns:
- `any`: the {root, rel} form for the YAML encoder to serialize.
- `error`: always nil; present to satisfy the yaml.Marshaler interface.
func (Path) Rel ¶
Rel returns the root-relative path used for confined I/O.
Always canonical slash form, on every platform: rel is the half that serializes, so equal logical paths produce equal document bytes and checksums everywhere, and it feeds io/fs APIs whose contract requires slash paths. Convert with filepath.FromSlash only where an OS-native rel is genuinely needed; direct filesystem I/O flows through Path.Abs, which stays OS-native.
Returns:
- `string`: the root-relative path, slash-separated.
func (Path) Root ¶
Root returns the root directory path that Rel is relative to. Matches os.Root.Name.
Returns:
- `string`: the root directory path.
func (*Path) UnmarshalJSON ¶
UnmarshalJSON deserializes {root, rel} and derives Abs.
Pointer receiver is required by the json.Unmarshaler contract — the method must mutate the receiver to populate fields from the JSON bytes. All other Path methods use value receivers since Path is an immutable value type.
Implementation note: A pointer receiver is required by the json.Unmarshaler contract. The method mutates the receiver in place to populate `root`, `rel`, and `abs` from the encoded document, so a value receiver would fill a discarded copy.
This is the deliberate exception to Path's value-receiver convention. The getters and the Marshal methods use value receivers so the value type Path — not just *Path — satisfies json.Marshaler / yaml.Marshaler and its accessors stay callable on non-addressable values (map elements, function returns). Unmarshaling always targets an addressable variable (json.Unmarshal(data, &p)), so the pointer receiver is safe. The resulting value/pointer mix is intentional, which is why the mixed-receivers inspection is suppressed.
Parameters:
- `data`: the JSON bytes to decode.
Returns:
- `error`: non-nil if the JSON is malformed.
func (*Path) UnmarshalYAML ¶
UnmarshalYAML deserializes {root, rel} and derives Abs.
Implementation note: A pointer receiver is required by the json.Unmarshaler contract. The method mutates the receiver in place to populate `root`, `rel`, and `abs` from the encoded document, so a value receiver would fill a discarded copy.
This is the deliberate exception to Path's value-receiver convention. The getters and the Marshal methods use value receivers so the value type Path — not just *Path — satisfies json.Marshaler / yaml.Marshaler and its accessors stay callable on non-addressable values (map elements, function returns). Unmarshaling always targets an addressable variable (json.Unmarshal(data, &p)), so the pointer receiver is safe. The resulting value/pointer mix is intentional, which is why the mixed-receivers inspection is suppressed.
Parameters:
- `value`: the YAML node to decode.
Returns:
- `error`: non-nil if the YAML is malformed.
type Root ¶
type Root interface {
Close() error
FS() fs.FS
Lstat(p Path) (fs.FileInfo, error)
MkdirAll(p Path, perm os.FileMode) error
Name() string
NewPath(path string) Path
Open(p Path) (*os.File, error)
OpenFile(p Path, flag int, perm os.FileMode) (*os.File, error)
ReadFile(p Path) ([]byte, error)
Readlink(p Path) (string, error)
Remove(p Path) error
Rename(oldPath, newPath Path) error
Stat(p Path) (fs.FileInfo, error)
Symlink(target string, link Path) error
WriteFile(p Path, data []byte, perm os.FileMode) error
}
Root provides scoped filesystem operations. All path arguments are Path values created through Root.NewPath.
Three concrete implementations provide different access modes:
- OpenConfined wraps *os.Root for OS-enforced confinement (execution)
- OpenUnconfined delegates to os.* for unconfined read-only access (planning)
- OpenWritableUnconfined delegates to os.* for unconfined read-write access (testing)
func OpenConfined ¶
OpenConfined opens an OS-enforced confined Root at dir.
Parameters:
- `dir`: the directory to confine all I/O within.
Returns:
- `Root`: a confined root backed by *os.Root.
- `error`: any error from os.OpenRoot.
func OpenUnconfined ¶
OpenUnconfined creates a read-only Root at dir. Write operations return [errReadOnly].
Parameters:
- `dir`: the base directory for all path resolution.
Returns:
- `Root`: a read-only, unconfined root.
func OpenWritableUnconfined ¶
OpenWritableUnconfined creates a read-write Root at dir without OS-level confinement.
Parameters:
- `dir`: the base directory for all path resolution.
Returns:
- `Root`: a read-write, unconfined root.