README: drop the tooling attribution, document the entrypoints (closes #21) #40
77
README.md
77
README.md
@@ -16,9 +16,6 @@ expensive. `scan` maintains a persistent SQLite database of file
|
||||
signatures that survives between runs, so it can be run from cron and
|
||||
the reports can be generated at any time from the most recent scan.
|
||||
|
||||
This tool was created by [@sneak](https://sneak.berlin) to scratch an itch,
|
||||
using Claude Code/Fable.
|
||||
|
||||
This README is the complete and authoritative specification.
|
||||
|
||||
## Getting Started
|
||||
@@ -283,7 +280,7 @@ the workers.
|
||||
files seen this run broken down by disposition, plus skips:
|
||||
|
||||
```
|
||||
scan: 123456 files seen (1200 added, 34 updated, 56 removed, 122166 unchanged), 3 skipped
|
||||
scan: 123400 files seen (1200 added, 34 updated, 56 removed, 122166 unchanged), 3 skipped
|
||||
```
|
||||
|
||||
(`removed` counts deleted database records, which are not part of the
|
||||
@@ -443,12 +440,80 @@ Additional requirements:
|
||||
- `2`: usage error (including `scan` with no `PATH` operand and
|
||||
`report`/`trees` with any positional argument).
|
||||
|
||||
## Entrypoints
|
||||
|
||||
This repository adheres to the
|
||||
[Scripts to Rule Them All](https://github.com/github/scripts-to-rule-them-all)
|
||||
standard: the normalized executables in `script/` are the entrypoints
|
||||
for the development workflow, and the `Makefile` targets are thin
|
||||
shims that call them. Every script is POSIX `sh`, resolves the
|
||||
repository root itself so it can be run from any working directory,
|
||||
and may be invoked directly. The provided entrypoints are:
|
||||
|
||||
- `script/bootstrap` — install everything needed to build and
|
||||
develop this repository, idempotently, assuming nothing is
|
||||
present. `git`, `make`, and `go` come from the first of nix, apt,
|
||||
brew, or apk found on the host, and are presence-checked only.
|
||||
`golangci-lint` is treated differently: it is checked against the
|
||||
version pinned in the script (the version the `Dockerfile` lint
|
||||
stage runs) and reinstalled with `go install` whenever the
|
||||
installed version differs — older or newer, not merely absent —
|
||||
because a host on any other version lints against different rules
|
||||
than CI. After installing, the script verifies the pin against the
|
||||
`golangci-lint` that `PATH` actually resolves; if a different copy
|
||||
shadows the install, bootstrap fails, naming both the install
|
||||
directory and the shadowing binary, rather than reporting a
|
||||
success the gate would not honour. Ends with `go mod download`.
|
||||
- `script/setup` — make a fresh clone ready for development: runs
|
||||
`script/bootstrap`, then `script/install-precommit`.
|
||||
- `script/projectname` — print this project's name (`sfdupes`).
|
||||
Scripts that need the name call it, so they stay identical across
|
||||
repositories.
|
||||
- `script/test` — run the test suite with a 30-second timeout and
|
||||
coverage enabled, rerunning verbosely on failure so the logs show
|
||||
which test failed.
|
||||
- `script/lint` — run `golangci-lint` over the module with the
|
||||
repository's `.golangci.yml`.
|
||||
- `script/fmt` — format the Go sources in place (`gofmt -s -w`).
|
||||
Markdown is not formatted.
|
||||
- `script/fmt-check` — the read-only counterpart of `script/fmt`:
|
||||
prints any unformatted file and exits non-zero instead of writing.
|
||||
- `script/check` — run `script/test`, `script/lint`, and
|
||||
`script/fmt-check`, in that order. Modifies nothing.
|
||||
- `script/docker` — build the Docker image, tagged with the name
|
||||
from `script/projectname`. The `Dockerfile` runs the gates as
|
||||
build steps, so this is also the check a developer or reviewer
|
||||
runs by hand.
|
||||
- `script/cibuild` — build the Docker image untagged. This is what
|
||||
the Gitea workflow runs on push; because the gates run as build
|
||||
steps, a successful build implies the repository is green.
|
||||
- `script/precommit` — run by the git pre-commit hook: `go mod tidy`
|
||||
must be a no-op (a resulting change to `go.mod` or `go.sum` fails
|
||||
the commit), then `script/check`.
|
||||
- `script/install-precommit` — install the git pre-commit hook that
|
||||
runs `script/precommit`. The hook is written to the common git
|
||||
directory, so the main checkout and every worktree share it.
|
||||
|
||||
`script/docker` and `script/cibuild` both pass a freshly computed
|
||||
`CHECK_EPOCH` build argument, and the `Dockerfile`'s gate steps
|
||||
reference it. Without that, an unchanged tree lets Docker serve the
|
||||
gate layers from cache and the build exits 0 having executed no tests
|
||||
and no lint — a green it never earned. `CHECK_EPOCH` invalidates the
|
||||
gate layers on every run while leaving the pinned base images and the
|
||||
dependency layers cached.
|
||||
|
||||
## Build
|
||||
|
||||
The `Makefile` is the single source of truth for all operations:
|
||||
The `script/` entrypoints above are where the implementations live;
|
||||
the `Makefile` targets are shims onto them, except `build`, which
|
||||
carries the compile recipe:
|
||||
|
||||
- `make` / `make build` — build the `sfdupes` binary (cgo
|
||||
disabled); building is the default target.
|
||||
- `make bootstrap` — install the build and development
|
||||
dependencies.
|
||||
- `make setup` — prepare a fresh clone: `bootstrap` plus the
|
||||
pre-commit hook.
|
||||
- `make test` — run the test suite (30-second timeout; reruns with
|
||||
`-v` on failure).
|
||||
- `make lint` — run `golangci-lint` with the repo config.
|
||||
@@ -458,7 +523,7 @@ The `Makefile` is the single source of truth for all operations:
|
||||
- `make docker` — build the Docker image, which runs `make check` as
|
||||
a build stage.
|
||||
- `make hooks` — install the pre-commit hook.
|
||||
- `make clean` — remove the binary and any legacy local `files.dat`.
|
||||
- `make clean` — remove the binary.
|
||||
|
||||
### Definition of done
|
||||
|
||||
|
||||
Reference in New Issue
Block a user