Files
sfdupes/TODO.md
sneak e0d578a707 Specify persistent SQLite scan database in README; plan in TODO.md
scan will maintain a persistent database of file signatures
(default /var/lib/sfdupes/db.sqlite, overridable via
SFDUPES_DATABASE) that survives between runs; rescans hash only new
or changed files (mtime/size) and remove records for vanished files,
so scan can be cronned daily. report and trees will read the
database instead of a scan stream.
2026-07-24 02:54:08 +07:00

117 lines
5.5 KiB
Markdown

# Workflow
- branch (from `main`)
- do the work in Next Step
- move Next Step to the top of Completed Steps
- move the top item of Future Steps into Next Step
- commit (`TODO.md` changes in the same commit as the work)
- merge to `main` if the branch is not protected, otherwise open a PR
- push
# Status
- pre-1.0
# Next Step
- persistent scan database (branch `persistent-database`): `scan`
maintains a SQLite database that survives between runs so it can be
cronned daily; `report` and `trees` read the database instead of a
scan stream. Database path defaults to `/var/lib/sfdupes/db.sqlite`,
overridable via `SFDUPES_DATABASE`. Plan:
- [x] update `README.md` (the authoritative spec) for the database:
new Database section, revised `scan`/`report`/`trees` modes,
dependency list (`modernc.org/sqlite`, pure Go, cgo stays
disabled), exit codes, smoke test with incremental steps
- [ ] add `modernc.org/sqlite` (hash-pinned via `go.sum`)
- [ ] `db.go`: path resolution (`SFDUPES_DATABASE` env, default
`/var/lib/sfdupes/db.sqlite`), open/create with WAL +
busy-timeout pragmas and `PRAGMA user_version` schema check,
`files` table (path BLOB primary key, size, mtime, head,
tail), load-all-rows, and single-transaction apply of
upserts/deletes
- [ ] `scan.go`: resolve operands to absolute paths; diff stat
results against loaded rows (reuse hashes when size matches
and mtime is not newer); hash only new/changed files; delete
rows under the scanned operands not successfully processed;
leave rows outside the operands untouched; new summary line
(added/updated/removed/unchanged/skipped); "update" progress
pass for the database write
- [ ] `report.go`/`trees.go`: read records from the database (no
positional args, no stream parsing); drop the NUL-stream
parser and malformed-record handling
- [ ] `main.go`: updated usage strings; `report`/`trees` take no
args (usage error otherwise)
- [ ] tests: db open/env-override/schema tests; incremental scan
tests (add, mtime update, delete, unchanged-hash-reuse,
out-of-scope rows untouched, error paths); rework pipeline
test to go through the database; keep walk/stat/hash/grouping
unit tests
- [ ] `.gitignore`: local `*.sqlite` artifacts
- [ ] `make check`, `make docker`, and the README smoke test pass
# Completed Steps
- add the `origin` remote (`git@git.eeqj.de:sneak/sfdupes.git`), tag
`v0.0.1`, and push `main` plus tags (2026-07-23)
- `scan` CLI rework (2026-07-23, branch `scan-required-paths`): required
`PATH...` operands via cobra flags replacing the `/srv` `-root`
default; new `-x`/`--one-file-system` flag (GNU convention) to stop
at filesystem boundaries, which are crossed by default
- bring the repo into full policy compliance (2026-07-23, branch
`repo-policy-compliance`; checklist below)
- `git init` with README-only first commit; code baseline committed on
`main` (2026-07-22)
- implement `scan`, `report`, and `trees` subcommands (pre-git history)
# Future Steps
- convert Makefile targets to scripts-to-rule-them-all `script/`
entrypoints like the other managed repos
- possible later features (explicitly out of scope per README):
full-content verification of candidates, removal-script helpers
# Repo Policy Compliance
Audited 2026-07-22 against `REPO_POLICIES.md` (2026-07-06), the existing
repo checklist, and the Go styleguide. Code is already gofmt-clean, so no
standalone formatting commit is needed.
- [x] `.gitignore` missing — the compiled `sfdupes` binary and
`files.dat` sit untracked in the tree; needs OS/editor/Go
artifacts plus secrets patterns
- [x] `.editorconfig` missing
- [x] `LICENSE` missing and README has no License section (MIT assumed
from house convention — user to confirm)
- [x] `REPO_POLICIES.md` missing from repo root
- [x] `.golangci.yml` missing (install canonical copy); code must then
pass `make lint` (150 findings fixed; `make lint` is clean)
- [x] `Makefile` lacks required targets `test`, `lint`, `fmt`,
`fmt-check`, `docker`, `hooks`; `check` currently depends on
`build`, which writes the binary (`make check` must not modify
files)
- [x] no tests — `go test ./...` has nothing to run; policy requires
real tests with a 30-second timeout and the conditional `-v`
rerun pattern (suite covers parsing, grouping, digests,
suppression, hashing, and the scan pipeline; 64% coverage)
- [x] `Dockerfile` missing — Go multistage with hash-pinned images:
fail-fast lint stage, build stage running `make check`
- [x] `.dockerignore` missing
- [x] `.gitea/workflows/check.yml` missing (`docker build .` on push,
checkout action pinned by commit SHA)
- [x] README lacks required sections: Description first line
(name/purpose/category/license/author), Getting Started,
Rationale, TODO, License, Author
- [x] README non-goal "no git repository setup and no CI" is stale now
that the repo is under git with CI
- [x] pre-commit hook not installed (`make hooks` once the target
exists)
Accepted divergences (no action):
- flat single-package layout with `.go` files in the repo root — fine
for a small single-binary tool per the Go styleguide; the tracker
audit agrees
- `go test` runs without `-race` — the repo mandates `CGO_ENABLED=0`
(pure-Go builds) and the race detector requires cgo