fsift

package module
v0.1.0 Latest Latest
Warning

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

Go to latest
Published: Jul 25, 2026 License: MPL-2.0 Imports: 6 Imported by: 0

README

fsift

Filter-driven fs.WalkDir for Go. Composable FileFilters with prune-on-descend semantics: a filter returning true on a directory skips the entire subtree.

API

ListFiles — collect all matching paths
files, err := fsift.ListFiles(ctx, os.DirFS("."),
    fsift.SkipHiddenDirs(),
    fsift.SkipHiddenFiles(),
    fsift.MaxDepth(3),
    fsift.SkipVendorDirs(),
)
Walk — iterator (range-over-func, Go 1.22+)
for path := range fsift.Walk(ctx, os.DirFS("."), fsift.SkipHiddenDirs()) {
    fmt.Println(path)
    // break stops the walk immediately
}

Context cancellation and break both terminate the walk.

FindFirst — multi-predicate first-match detection

Walks once; each predicate is removed from the active set on its first match. The walk terminates as soon as every predicate has matched (or the tree is exhausted). Returns a map from predicate index to the first matching path; absent keys mean no match was found.

gomod   := func(path string, _ fs.DirEntry) bool { return filepath.Base(path) == "go.mod" }
pkgjson := func(path string, _ fs.DirEntry) bool { return filepath.Base(path) == "package.json" }

results, err := fsift.FindFirst(ctx, os.DirFS("."), gomod, pkgjson)
// results[0] = path to first go.mod found
// results[1] = path to first package.json found

Typical use: workspace marker-file detection where one match per marker type is enough — FindFirst stops the walk the moment all types are satisfied.

Filters

Filter Description
SkipHiddenDirs() Prunes directories whose names start with .
SkipHiddenFiles() Skips files whose names start with .
MaxDepth(n) Prunes directories at depth ≥ n (root = depth 0)
SkipVendorDirs(extra...) Prunes node_modules, target, vendor, dist, .venv; variadic extra names extend the set

Hidden-file detection is OS-aware (Unix dotfiles, Windows FILE_ATTRIBUTE_HIDDEN).

Custom filter
goFiles := func(path string, d fs.DirEntry) bool {
    return !d.IsDir() && filepath.Ext(path) != ".go"
}
files, err := fsift.ListFiles(ctx, os.DirFS("."), goFiles)

Filter returns true to skip. For directories, true prunes the subtree.

Documentation

Overview

Package fsift provides filter-driven fs.WalkDir helpers: composable FileFilters, single-pass file discovery, and a filtered fs.FS decorator that applies those filters transparently to any consumer of the wrapped FS.

Index

Constants

This section is empty.

Variables

This section is empty.

Functions

func Filtered

func Filtered(base fs.FS, filters ...FileFilter) fs.FS

Filtered returns base wrapped so ReadDir omits any entry a filter skips, applying the same prune-on-descend semantics as ListFiles: skipping a directory hides its whole subtree. Filters receive each entry's path relative to the FS root. Open is left untouched, so a caller holding an exact path can still read a file inside a pruned directory.

func FindFirst

func FindFirst(ctx context.Context, dirFS fs.FS, predicates ...FileFilter) (map[int]string, error)

FindFirst walks dirFS applying filters and, for each file yielded, tests it against each predicate. When a predicate matches its first file, it is removed from the active set and its match is recorded. The walk terminates as soon as every predicate has been satisfied. Returns a map from predicate index to the first matching path; predicates with no match are absent.

Typical use: detect workspace marker files (go.mod, package.json, Cargo.toml) in a single walk — one match per marker type stops further searching for that type, and the walk ends when all types are found.

func ListFiles

func ListFiles(ctx context.Context, dirFS fs.FS, filters ...FileFilter) ([]string, error)

ListFiles walks dirFS and returns the paths of all regular files that pass every filter. Filters are applied with the prune-on-descend semantics described on FileFilter: a filter returning true for a directory skips the entire subtree. ctx cancellation is honoured — the walk stops and the collected results so far are returned alongside the context error.

func Walk

func Walk(ctx context.Context, dirFS fs.FS, filters ...FileFilter) iter.Seq[string]

Walk returns an iterator over file paths in dirFS, applying filters with the same semantics as ListFiles: a filter returning true on a directory prunes the subtree (fs.SkipDir); a filter returning true on a file skips that file. The iterator honours ctx — if the context is cancelled the walk stops and the cancellation error is swallowed (the caller controls the loop via break).

Types

type FileFilter

type FileFilter func(path string, d fs.DirEntry) bool

FileFilter is a predicate over a filesystem entry. Returning true on a directory prunes the subtree (equivalent to fs.SkipDir); returning true on a regular file skips that file.

func MaxDepth

func MaxDepth(maxDepth int) FileFilter

MaxDepth returns a FileFilter that prunes directories deeper than n levels from the walk root. Depth is counted as the number of path separators in the directory's path relative to the root (the root itself is depth 0). Files at depth n are still visited; only descending past depth n is blocked.

func SkipGlobs

func SkipGlobs(patterns ...string) FileFilter

SkipGlobs returns a FileFilter that skips any entry whose base name matches one of the shell patterns (path.Match syntax: *, ?, [set]). It applies to files and directories alike, so SkipGlobs("node_modules", "*.gen.go") prunes the node_modules subtree and skips generated files. A malformed pattern never matches.

func SkipHiddenDirs

func SkipHiddenDirs() FileFilter

SkipHiddenDirs returns a FileFilter that prunes hidden directories (names starting with '.').

func SkipHiddenFiles

func SkipHiddenFiles() FileFilter

SkipHiddenFiles returns a FileFilter that skips hidden files (names starting with '.').

func SkipVendorDirs

func SkipVendorDirs(extra ...string) FileFilter

SkipVendorDirs returns a FileFilter that prunes common vendor/build output directories: node_modules, target, vendor, dist, .venv, plus any additional names supplied by the caller.

Jump to

Keyboard shortcuts

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