scanrule

package
v0.53.0 Latest Latest
Warning

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

Go to latest
Published: Oct 7, 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