sneak 7f75f2ee72
All checks were successful
check / check (push) Successful in 35s
Clear all golangci-lint findings and make the CI build green (closes #1)
Fix every golangci-lint finding under the repo's standard .golangci.yml
(from ~192 down to 0 under the pinned v2.10.1) without changing program
behavior:

- gochecknoglobals: replace the verbose/quiet/exclude* package globals with
  an options struct threaded through the command implementations.
- err113: introduce package-level sentinel errors and wrap them with %w.
- errcheck: check or explicitly discard every previously unchecked error
  (bar.Add/Finish, deferred Close, verbose writes).
- forbidigo: route verbose output through os.Stdout instead of fmt.Print*.
- noinlineerr / wsl_v5 / nlreturn / gofmt: split inline error checks and
  normalize whitespace.
- complexity (cyclop/gocognit/nestif): extract small behavior-preserving
  helpers (runOverPaths, countAndBar, walkSkip, clearOne, checkOne,
  missingChecksum, reportCheck).
- mnd/lll/nonamedreturns/revive/modernize/nilnil: named constants, wrapped
  lines, unnamed returns, doc comments, SplitSeq, non-(nil,nil) returns.
- paralleltest/thelper: mark tests parallel (now race-safe with no shared
  globals) and add t.Helper(); probe the real xattr key so the guard is
  accurate.

Also make the tests actually runnable in CI rather than skipping:

- move the xattr keys into the user.* namespace (user.berlin.sneak.app.*),
  which Linux requires for regular-file xattrs; macOS treats the whole
  string as an opaque name, so behavior is unchanged there.
- run the Docker builder's checks as an unprivileged user so the permission
  tests are meaningful (root bypasses file mode bits).
2026-07-27 00:55:46 +07:00
2025-05-08 13:26:05 -07:00

attrsum is a Go 1.22 command-line utility that adds, updates, verifies, and clears per-file file content checksums stored in extended attributes (xattrs) on macOS (APFS) and Linux, released under the WTFPL v2.

Original release 2025-05-08.

Current version 1.0 (2025-05-08).


Getting Started — Quick Build

# prerequisites: Go 1.22+
git clone https://git.eeqj.de/sneak/attrsum.git
cd attrsum
go build -o attrsum .

Install

go install git.eeqj.de/sneak/attrsum@latest   # into GOPATH/bin or $(go env GOBIN)

Semantic Versioning 2.0.0 is used for tags.


Usage

# add checksum & timestamp xattrs to every regular file under one or more paths
attrsum sum add DIR1 DIR2 file.txt

# update checksum only when file mtime is newer than stored sumtime
attrsum sum update DIR1 DIR2

# verify checksums, stop on first error
attrsum check DIR1 DIR2

# verify every file, reporting each result, keep going after errors
attrsum -v check --continue DIR1 DIR2

# remove checksum & timestamp xattrs
attrsum clear DIR1 DIR2

# read paths from stdin (use - as argument)
find /data -name "*.jpg" | attrsum sum add -

# quiet mode (suppress progress bar and summary)
attrsum -q sum add DIR
xattr key meaning
user.berlin.sneak.app.attrsum.checksum base-58 multihash (sha2-256)
user.berlin.sneak.app.attrsum.sumtime RFC 3339 timestamp of checksum

Flags:

  • -v, --verbose — per-file log output
  • -q, --quiet — suppress all output except errors (no progress bar or summary)
  • --exclude PATTERN — skip paths matching rsync/Doublestar glob
  • --exclude-dotfiles — skip any path component that starts with .

All commands display a progress bar with ETA and print a summary report to stderr on completion (unless --quiet is specified).

attrsum never follows symlinks and skips non-regular files (sockets, devices, …).


Why?

Apple APFS and Linux ext3/ext4 store no per-file content checksums, so silent data corruption can pass unnoticed. attrsum keeps a portable checksum inside each files xattrs, providing integrity verification that travels with the file itself—no external database required. Now you can trust a USB stick didn't eat your data.


TODO

Future improvements under consideration:

  • Dry-run mode (--dry-run, -n) — show what would be done without making changes
  • JSON output (--json) — machine-readable output for scripting and integration
  • Parallel processing (-j N) — use multiple goroutines for faster checksumming on large trees
  • Exit code documentation — formalize and document exit codes for scripting

Contributing


Community & Support

Bug tracker and wiki are in the Gitea repo linked above.

No formal Code of Conduct; be excellent to each other.


License

Everything is permitted. See WTFPL v2.

Description
No description provided
Readme 120 KiB
Languages
Go 74.9%
Shell 18.1%
Dockerfile 4.3%
Makefile 2.7%