Help us shape the future of Go! Take the 2026 Go Developer Survey

scanrule

package
v0.56.0 Latest Latest
Warning

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

Go to latest
Published: Oct 11, 2026 License: MIT Imports: 7 Imported by: 0

Documentation

Overview

Package scanrule is the ONE answer to "does the scan walk this path of this storage?" (issue #44).

Two things say no, and they are composed here rather than beside each other:

  • filex's own trees — the trash, the version history, the thumbnail cache (syspath.Sealed). Always, on every storage; nobody configures them.
  • the storage's own exclusions: glob patterns an operator writes into the storage's `scan_exclude` setting (storage.ScanExcludeKey) for the parts of a big existing tree filex has no business cataloguing — `.git`, `.snapshots`, a download client's `incomplete/`, `*.tmp`.

The third thing a walk turns away — named pipes, sockets and device nodes — never reaches this far: the local driver drops them from its listing (internal/regfile), so a walk cannot even see one to ask about it.

⚠⚠ Scan-only, and deliberately so. A path this package excludes is not walked, catalogued, indexed, thumbnailed or virus-scanned, and the fsnotify watcher does not watch it. It is NOT hidden: it is still on the storage, and everything that reads the storage directly — the file protocols (WebDAV, SFTP, FTP, NFS, S3), the AI/MCP tools, a public folder share, an archive download, a copy — still sees it. Nor are the byte-moving walks (copy, move, delete, archive) taught to skip it, and they must never be: a folder move that copied everything but the excluded part and then deleted the source would delete the excluded part. So this is a cost control, not an access control, and the storage form's help text says exactly that.

⚠ filex's own names are outside the operator's reach: a pattern never matches anything syspath.Hidden (`.filex-open` working copies, `.keepdir`) nor an encrypted folder's marker (e2e.MarkerName). `.*` is the pattern people write first, and it would otherwise take both away from the catalogue — the desktop's "open with" round trip and every encrypted folder's lock screen read their rows there.

Index

Constants

View Source
const (
	MaxPatterns      = 200
	MaxPatternLength = 512
)

Limits on what one storage may configure — a textarea, not a database.

Variables

View Source
var ErrInvalid = errors.New("invalid scan exclusion")

ErrInvalid wraps every reason a pattern is refused.

Functions

This section is empty.

Types

type InvalidError

type InvalidError struct {
	// Pattern is the line as written; empty when the setting as a whole was
	// refused (too many patterns).
	Pattern string
	Problem Problem
	// contains filtered or unexported fields
}

InvalidError is a refused setting: which pattern, which rule it broke, and an English detail for logs and API callers. errors.Is(err, ErrInvalid) finds it.

func (*InvalidError) Error

func (e *InvalidError) Error() string

func (*InvalidError) Unwrap

func (e *InvalidError) Unwrap() error

type Problem

type Problem string

Problem says which rule a refused pattern broke. The admin API turns it into a sentence in the reader's language (`server.storage.scan_exclude_*`), so the three are the whole list a translator sees.

const (
	// ProblemSyntax: not a pattern filex can use — `!`, `..`, a broken
	// character class, a NUL byte, a value that is not text.
	ProblemSyntax Problem = "syntax"
	// ProblemEverything: it matches every name there is, so it would leave
	// the storage empty.
	ProblemEverything Problem = "everything"
	// ProblemLimit: more than MaxPatterns patterns, or one longer than
	// MaxPatternLength.
	ProblemLimit Problem = "limit"
)

type Rule

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

Rule is one storage's scan rule. The zero value and a nil *Rule are both valid and exclude nothing of the operator's: only filex's own trees.

func FromConfig

func FromConfig(cfg map[string]any) (*Rule, error)

FromConfig reads a storage config map's scan exclusions. A missing or empty setting is a rule that excludes nothing.

func Parse

func Parse(v any) (*Rule, error)

Parse reads the setting's value: a string, one pattern per line (what the storage form sends), or a list of strings (what an API caller may send). Blank lines and lines starting with `#` are skipped.

func (*Rule) Empty

func (r *Rule) Empty() bool

Empty reports whether the rule has no patterns of the operator's.

func (*Rule) Excluded

func (r *Rule) Excluded(rel string) bool

Excluded reports whether the storage's own patterns match rel or a folder above it. filex's own names never are (see the package comment).

func (*Rule) Patterns

func (r *Rule) Patterns() []string

Patterns returns the patterns as written, in order. A copy.

func (*Rule) Skips

func (r *Rule) Skips(rel string) bool

Skips reports whether the scan must not walk rel: it is inside filex's own trees, or the storage's exclusions match it or a folder above it. Every walk that catalogues asks this one question — the full scan, the one-pass prefetch, a folder rescan, the copy mirror, the fsnotify watcher — and so does the delete pass, which must never judge a row the walk cannot see.

Jump to

Keyboard shortcuts

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