golazy.dev golazy.dev / lazyfs Index | Files

package lazyfs

import "golazy.dev/lazyfs"

Package lazyfs combines multiple read-only filesystems into one layered filesystem.

Add layers from lowest to highest precedence. Higher files replace lower files, while directories merge:

files := lazyfs.New()
if err := files.Add(frameworkFS,
	lazyfs.Name("framework"),
	lazyfs.Owner("golazy.dev"),
); err != nil {
	return err
}
if err := files.Add(appFS,
	lazyfs.Name("application"),
	lazyfs.Owner("example.com/myapp"),
); err != nil {
	return err
}
if err := files.Seal(); err != nil {
	return err
}

data, err := fs.ReadFile(files, "views/layout.html.tpl")
if err != nil {
	return err
}
// data comes from appFS when both layers contain this path.

resolution, err := files.Resolve("views/layout.html.tpl")
if err != nil {
	return err
}
// resolution.Winner identifies the application layer.

Filesystems are added from lowest to highest precedence. Add is safe to call concurrently while a stack is being assembled. Seal prevents later changes once initialization is complete. Reads take a snapshot of the current stack, so they are safe both during assembly and after sealing.

Files in higher layers replace files or directories at the same path. Directories in higher layers merge their entries with directories from lower layers, with each child following the same precedence rules. Mount exposes a filesystem below a path prefix without copying its contents.

Variables

var ErrSealed

ErrSealed is returned when a layer is added to a sealed filesystem.

var ErrSealed = errors.New("lazyfs: filesystem is sealed")

Functions

func Mount

Mount returns a filesystem that exposes files beneath prefix. Parent directories needed to reach prefix are synthesized without copying files.

func Mount(prefix string, files fs.FS) (fs.FS, error)

Types

type AddOption

AddOption configures metadata for an added layer.

type AddOption interface {
	// contains filtered or unexported methods
}
func Name

Name assigns a stable, human-readable name to a layer. Non-empty names must be unique within one filesystem.

func Name(name string) AddOption
func Owner

Owner records the package or add-on that contributed a layer.

func Owner(owner string) AddOption

type FS

FS is a concurrency-safe layered filesystem. The last filesystem added has the highest precedence.

type FS struct {
	// contains filtered or unexported fields
}
func New

New returns an empty layered filesystem.

func New() *FS
func (files *FS) Add

Add adds files as the new highest-precedence layer.

func (files *FS) Add(fsys fs.FS, options ...AddOption) error
func (files *FS) Glob

Glob implements fs.GlobFS.

func (files *FS) Glob(pattern string) ([]string, error)
func (files *FS) Layers

Layers returns layer metadata ordered from lowest to highest precedence.

func (files *FS) Layers() []Layer
func (files *FS) Lstat

Lstat implements fs.ReadLinkFS.

func (files *FS) Lstat(name string) (fs.FileInfo, error)
func (files *FS) Open

Open implements fs.FS.

func (files *FS) Open(name string) (fs.File, error)
func (files *FS) ReadDir

ReadDir implements fs.ReadDirFS.

func (files *FS) ReadDir(name string) ([]fs.DirEntry, error)
func (files *FS) ReadFile

ReadFile implements fs.ReadFileFS.

func (files *FS) ReadFile(name string) ([]byte, error)
func (files *FS) Resolve

Resolve reports the winning and shadowed layers for name.

func (files *FS) Resolve(name string) (Resolution, error)
func (files *FS) Seal

Seal prevents later additions. Calling Seal more than once is safe.

func (files *FS) Seal() error
func (files *FS) Sealed

Sealed reports whether Seal has been called.

func (files *FS) Sealed() bool
func (files *FS) Stat

Stat implements fs.StatFS.

func (files *FS) Stat(name string) (fs.FileInfo, error)
func (files *FS) Sub

Sub implements fs.SubFS. The returned filesystem is a sealed snapshot that preserves the source layer metadata.

func (files *FS) Sub(dir string) (fs.FS, error)

type Layer

Layer describes one filesystem in a layered stack. Index zero is the lowest precedence layer.

type Layer struct {
	Index	int
	Name	string
	Owner	string
}

type Resolution

Resolution describes which layer wins for a path and which lower layers are shadowed. Candidates are ordered from highest to lowest precedence, so the first candidate is also Winner.

type Resolution struct {
	Path		string
	Winner		Candidate
	Candidates	[]Candidate
}