filesystem

package
v0.40.0 Latest Latest
Warning

This package is not in the latest version of its module.

Go to latest
Published: Nov 13, 2026 License: MIT Imports: 28 Imported by: 0

Documentation

Overview

Package filesystem provides Scriptling's filesystem extension libraries: os and os.path, pathlib, glob, fs, shutil, tempfile, zipfile, tarfile, scriptling.grep, scriptling.find and scriptling.sed. Every library checks paths against the allowed paths it is registered with (nil allows all, an empty slice denies all). The package also exports a plain-Go API (Grep, Find, SedReplace, EditFile, ...) that needs no interpreter.

Index

Constants

View Source
const (
	OSLibraryName       = "os"
	OSPathLibraryName   = "os.path"
	PathlibLibraryName  = "pathlib"
	GlobLibraryName     = "glob"
	FSLibraryName       = "fs"
	ShutilLibraryName   = "shutil"
	TempfileLibraryName = "tempfile"
	ZipfileLibraryName  = "zipfile"
	TarfileLibraryName  = "tarfile"
	GrepLibraryName     = "scriptling.grep"
	FindLibraryName     = "scriptling.find"
	SedLibraryName      = "scriptling.sed"
)

Library names.

Variables

View Source
var ErrPathNotAllowed = fssecurity.ErrPathNotAllowed

ErrPathNotAllowed is returned when a requested path falls outside the AllowedPaths configured on the options struct.

View Source
var ErrSearchNotFound = errors.New("search text not found")

ErrSearchNotFound is returned by EditFile when the search text does not appear in the file at all.

View Source
var ErrSearchNotUnique = errors.New("search text matched multiple times")

ErrSearchNotUnique is returned by EditFile when the search text appears more than once. The caller should provide more surrounding context to disambiguate.

Functions

func EditFile

func EditFile(ctx context.Context, path, search, replace string) (int, error)

EditFile performs a targeted search-and-replace on a single file: it finds the exact `search` text, verifies it appears exactly once, and replaces it with `replace`. The modification is written atomically (temp file + rename), matching sed's in-place edit semantics.

Unlike SedReplace (which replaces every occurrence line-by-line), EditFile operates on the full file content and requires the match to be unique — the gold standard for coding-agent edits where "replace all" is dangerous.

search and replace may span multiple lines. Returns the number of bytes written.

func Find

func Find(ctx context.Context, root string, opts FindOptions) ([]string, error)

Find returns the paths under root that match the given filters. It uses the same concurrent walker as scriptling.find. Paths are returned in arbitrary order. The root itself is never included in the result.

func NewFindLibrary

func NewFindLibrary(config fssecurity.Config) *object.Library

NewFindLibrary creates a new scriptling.find library with the given configuration.

func NewGlobLibrary

func NewGlobLibrary(config fssecurity.Config) *object.Library

NewGlobLibrary creates a new Glob library with the given configuration.

func NewGrepLibrary

func NewGrepLibrary(config fssecurity.Config) *object.Library

NewGrepLibrary creates a new scriptling.grep library with the given configuration.

func NewOSLibrary

func NewOSLibrary(config fssecurity.Config) (*object.Library, *object.Library)

NewOSLibrary creates a new OS library with the given configuration. The returned libraries are for "os" and "os.path". Prefer using RegisterOS which handles registration automatically.

func NewPathlibLibrary

func NewPathlibLibrary(config fssecurity.Config) *object.Library

NewPathlibLibrary creates a new Pathlib library with the given configuration.

func NewSedLibrary

func NewSedLibrary(config fssecurity.Config) *object.Library

NewSedLibrary creates a new scriptling.sed library with the given configuration.

func NewShutilLibrary

func NewShutilLibrary(config fssecurity.Config) *object.Library

NewShutilLibrary creates a new shutil library with the given configuration.

func NewTarfileLibrary

func NewTarfileLibrary(config fssecurity.Config) *object.Library

func NewTempfileLibrary

func NewTempfileLibrary(config fssecurity.Config) *object.Library

NewTempfileLibrary creates a new tempfile library with the given configuration.

func NewZipfileLibrary

func NewZipfileLibrary(config fssecurity.Config) *object.Library

func RegisterAll

func RegisterAll(registrar object.LibraryRegistrar, allowedPaths []string)

RegisterAll registers every filesystem library (os and os.path, pathlib, glob, fs, shutil, tempfile, zipfile, tarfile, scriptling.grep, scriptling.find and scriptling.sed), all restricted to allowedPaths.

func RegisterFS

func RegisterFS(registrar object.LibraryRegistrar, allowedPaths []string)

func RegisterFind

func RegisterFind(registrar object.LibraryRegistrar, allowedPaths []string)

RegisterFind registers the scriptling.find library with a Scriptling instance. If allowedPaths is nil, all paths are allowed. If non-nil, all find operations are restricted to those directories (same semantics as RegisterGrep).

func RegisterGlob

func RegisterGlob(registrar object.LibraryRegistrar, allowedPaths []string)

RegisterGlob registers the glob library with a Scriptling instance. If allowedPaths is empty or nil, all paths are allowed (no restrictions). If allowedPaths contains paths, all glob operations are restricted to those directories.

SECURITY: When running untrusted scripts, ALWAYS provide allowedPaths to restrict file system access. The security checks prevent: - Reading files outside allowed directories - Path traversal attacks (../../../etc/passwd) - Symlink attacks (symlinks pointing outside allowed dirs)

Example:

No restrictions - full filesystem access (DANGEROUS for untrusted code)
filesystem.RegisterGlob(s, nil)

Restricted to specific directories (SECURE)
filesystem.RegisterGlob(s, []string{"/tmp/sandbox", "/home/user/data"})

func RegisterGrep

func RegisterGrep(registrar object.LibraryRegistrar, allowedPaths []string)

RegisterGrep registers the scriptling.grep library with a Scriptling instance. If allowedPaths is nil, all paths are allowed. If non-nil, operations are restricted to those directories (same semantics as RegisterOS).

func RegisterOS

func RegisterOS(registrar object.LibraryRegistrar, allowedPaths []string)

RegisterOS registers the os and os.path libraries with a Scriptling instance. If allowedPaths is empty or nil, all paths are allowed (no restrictions). If allowedPaths contains paths, all file operations are restricted to those directories.

SECURITY: When running untrusted scripts, ALWAYS provide allowedPaths to restrict file system access. The security checks prevent: - Reading/writing files outside allowed directories - Path traversal attacks (../../../etc/passwd) - Symlink attacks (symlinks pointing outside allowed dirs)

Example:

No restrictions - full filesystem access (DANGEROUS for untrusted code)
filesystem.RegisterOS(s, nil)

Restricted to specific directories (SECURE)
filesystem.RegisterOS(s, []string{"/tmp/sandbox", "/home/user/data"})

func RegisterPathlib

func RegisterPathlib(registrar object.LibraryRegistrar, allowedPaths []string)

RegisterPathlib registers the pathlib library with a Scriptling instance.

func RegisterSed

func RegisterSed(registrar object.LibraryRegistrar, allowedPaths []string)

RegisterSed registers the scriptling.sed library with a Scriptling instance. If allowedPaths is nil, all paths are allowed. If non-nil, operations are restricted to those directories (same semantics as RegisterOS).

func RegisterShutil

func RegisterShutil(registrar object.LibraryRegistrar, allowedPaths []string)

RegisterShutil registers the shutil library with a Scriptling instance.

func RegisterTarfile

func RegisterTarfile(registrar object.LibraryRegistrar, allowedPaths []string)

func RegisterTempfile

func RegisterTempfile(registrar object.LibraryRegistrar, allowedPaths []string)

RegisterTempfile registers the tempfile library with a Scriptling instance.

func RegisterZipfile

func RegisterZipfile(registrar object.LibraryRegistrar, allowedPaths []string)

func SedReplace

func SedReplace(ctx context.Context, old, replacement, path string, opts SedOptions) (int64, error)

SedReplace replaces every occurrence of old with replacement in the file (or every matching file under the directory) at path. old is matched literally, not as a regular expression. Files are edited in place using an atomic temp-file + rename. The return value is the number of files modified.

func SedReplacePattern

func SedReplacePattern(ctx context.Context, pattern, replacement, path string, opts SedOptions) (int64, error)

SedReplacePattern is SedReplace with old interpreted as a regular expression. Capture groups may be referenced in replacement as ${1}, ${2}, or ${name}.

Types

type ExtractMatch

type ExtractMatch struct {
	File   string
	Line   int
	Text   string
	Groups []string
}

ExtractMatch is a single regex match with its capture groups, returned by SedExtract.

func SedExtract

func SedExtract(ctx context.Context, pattern, path string, opts SedOptions) ([]ExtractMatch, error)

SedExtract returns every match of pattern (a regular expression with capture groups) found in the file or directory at path. The result includes the captured groups for each match.

type FindEntry

type FindEntry struct {
	Path       string
	Size       int64
	Mtime      time.Time
	IsDir      bool
	Hash       uint64 // crc64 of file content when FindOptions.IncludeHash is set; 0 otherwise
	LinkTarget string // symlink target when the entry is a symlink; empty for regular files/dirs
	FilePerm   int    // file permission bits; populated when FindOptions.IncludeMetadata is set
}

FindEntry is a single matching entry returned by FindEntries, carrying the metadata required to decide whether the entry has changed without re-reading it. Callers comparing two trees (e.g. a sync tool diffing local and remote) can rely on Size+Mtime alone for the common case.

func FindEntries

func FindEntries(ctx context.Context, root string, opts FindOptions) ([]FindEntry, error)

FindEntries is like Find but returns FindEntry records with size, mtime, and type per match. Every matching entry is stat'd so the caller can compare trees without re-reading the bytes. Use Find instead when only the path strings are needed — Find skips the stat in the no-filter common case.

Like Find, the root itself is never included in the result, and paths are returned in arbitrary order.

type FindOptions

type FindOptions struct {
	Recursive       *bool
	Type            string
	Name            string
	MtimeMin        *float64
	MtimeMax        *float64
	SizeMin         *int64
	SizeMax         *int64
	IncludeHidden   bool
	FollowLinks     bool
	MaxDepth        int
	AllowedPaths    []string
	IncludeHash     bool // when true, every entry's file content is crc64-hashed
	IncludeSymlinks bool // when true, symlink entries are yielded with their target in LinkTarget
	IncludeMetadata bool // when true, file_perm is populated
}

FindOptions controls a find search.

Recursive is a pointer so that the zero value (nil) preserves scriptling's default of descending into subdirectories. Pass a pointer to false to keep the search non-recursive.

Type selects "any" (the zero value), "file", or "dir".

MtimeMin/MtimeMax and SizeMin/SizeMax are pointers so that a zero value is not confused with the valid bound 0; nil means the filter is inactive.

MaxDepth of 0 means unlimited.

type GlobLibraryInstance

type GlobLibraryInstance struct {
	// contains filtered or unexported fields
}

GlobLibraryInstance holds the configured Glob library instance

type GrepMatch

type GrepMatch struct {
	File string
	Line int
	Text string
}

GrepMatch is a single matching line.

func Grep

func Grep(ctx context.Context, needle, path string, opts GrepOptions) ([]GrepMatch, error)

Grep searches path for needle. When path is a directory the search runs concurrently over its files using the same bounded worker pool as scriptling.grep, respecting opts.Recursive / opts.Glob / opts.MaxSize.

needle is interpreted as a regular expression unless opts.Literal is true. Matches are returned in arbitrary order.

type GrepOptions

type GrepOptions struct {
	Literal      bool
	Recursive    bool
	IgnoreCase   bool
	FollowLinks  bool
	Glob         string
	MaxSize      int64
	AllowedPaths []string
}

GrepOptions controls a Grep search.

Literal selects literal-string matching (scriptling.grep.string) when true, versus regular-expression matching (scriptling.grep.pattern) when false.

MaxSize skips files larger than this many bytes. The zero value applies the scriptling default of 1 MiB; a negative value disables the limit.

AllowedPaths, when non-nil, restricts every searched path to the listed absolute directories (nil = no restriction, matching the interpreter default).

type PathlibLibraryInstance

type PathlibLibraryInstance struct {
	PathClass *object.Class
	// contains filtered or unexported fields
}

PathlibLibraryInstance holds the configured Pathlib library instance

type SedOptions

type SedOptions struct {
	Recursive    bool
	IgnoreCase   bool
	FollowLinks  bool
	Glob         string
	MaxSize      int64
	AllowedPaths []string
}

SedOptions controls a sed replace or extract operation. See GrepOptions for the meaning of MaxSize and AllowedPaths; the semantics are identical.

Jump to

Keyboard shortcuts

? : This menu
/ : Search site
f or F : Jump to
y or Y : Canonical URL