mirror of
https://github.com/kuhyx/wake-alarm.git
synced 2026-11-10 19:07:03 +01:00
Remove done file-length TODO
Co-Authored-By: Claude Opus 5.5 (1M context) <noreply@anthropic.com>
This commit is contained in:
parent
fd65c454e3
commit
a51a67e2fe
@ -1,112 +0,0 @@
|
||||
# Refactor TODO — enforce the 250-line file cap
|
||||
|
||||
> **This file is a ready-to-use prompt.** Paste it to Claude, or open this repo
|
||||
> and say "do refactor_claude_todo". It is self-contained: everything needed to
|
||||
> execute is below. Generated 2026-08-14 from a measured survey of every repo.
|
||||
|
||||
## Goal
|
||||
|
||||
Every file in this repo must be **at most 250 lines** — source, tests, and
|
||||
prose (`.md`/`.txt`/`.rst`/`.tex`) alike — and must **stay** that way forever,
|
||||
enforced by a gate that fails the commit, not by a note anyone can ignore.
|
||||
|
||||
Why: a file that cannot be read in one piece forces re-reads and partial edits,
|
||||
which is the single largest avoidable cost in an LLM-assisted workflow. Aim by
|
||||
churn, not size alone — refactoring pays where code is read and changed often
|
||||
(Fowler, _refactoring economic benefit_).
|
||||
|
||||
## Scope in this repo
|
||||
|
||||
- **18 files** currently exceed 250 lines (of 73 eligible files).
|
||||
- **6,553 lines** sit in violation; longest file is **478 lines**.
|
||||
|
||||
Exempt (do NOT split these):
|
||||
|
||||
- generated files — `*.g.dart`, `*.freezed.dart`, `*.gr.dart`, `**/l10n/generated/**`,
|
||||
anything with a `GENERATED` header
|
||||
- markup — `.html`, `.css`, `.scss`
|
||||
- data files — `.json`, `.yaml`, `.csv`, wordlists and other data-ish `.txt`
|
||||
(mean line length under 25 chars)
|
||||
|
||||
## Violations, highest ROI first
|
||||
|
||||
ROI = lines x commits in the last year. Work top-down; a long file nobody edits
|
||||
has near-zero payoff and should not be first.
|
||||
|
||||
| lines | commits/yr | kind | file |
|
||||
| ----: | ---------: | :--- | :------------------------------------- |
|
||||
| 478 | 15 | code | `wake_alarm/_alarm.py` |
|
||||
| 438 | 12 | code | `wake_alarm/tests/test_alarm_part2.py` |
|
||||
| 435 | 12 | code | `wake_alarm/tests/test_alarm.py` |
|
||||
| 358 | 8 | code | `wake_alarm/tests/test_alarm_part3.py` |
|
||||
| 457 | 4 | code | `wake_alarm/tests/test_alarm_sinks.py` |
|
||||
| 283 | 6 | code | `wake_alarm/tests/test_alarm_part4.py` |
|
||||
| 329 | 4 | code | `wake_alarm/_alarm_view.py` |
|
||||
| 405 | 3 | code | `wake_alarm/_audio.py` |
|
||||
| 386 | 3 | code | `wake_alarm/tests/test_sync.py` |
|
||||
| 371 | 3 | code | `wake_alarm/_sync.py` |
|
||||
| 317 | 3 | code | `wake_alarm/_escape_flow.py` |
|
||||
| 314 | 3 | code | `wake_alarm/tests/test_state.py` |
|
||||
| 420 | 2 | code | `wake_alarm/tests/test_alarm_audio.py` |
|
||||
| 351 | 2 | code | `wake_alarm/tests/test_smart_plug.py` |
|
||||
| 341 | 2 | code | `wake_alarm/_sinks.py` |
|
||||
|
||||
_(3 further files over 250 lines not listed — re-run the survey for the full set.)_
|
||||
|
||||
## How to split
|
||||
|
||||
- **Python** — extract cohesive helpers into sibling modules; keep the public
|
||||
API and imports stable.
|
||||
- **Shell** — split into `lib/*.sh` sourced by a thin entry script. Keep
|
||||
`set -euo pipefail` in each.
|
||||
- **Dart / TypeScript** — extract widgets/components into their own files.
|
||||
- **Tests** — split by test-group into sibling files
|
||||
(`foo.test.ts` -> `foo.parsing.test.ts`, `foo.render.test.ts`). Coverage must
|
||||
not drop.
|
||||
- **Docs** — split into topic files under `docs/` with an index. For an
|
||||
oversized `CLAUDE.md`, move detail into referenced docs so the
|
||||
always-loaded part shrinks.
|
||||
|
||||
**Do not** game the cap: no one-lining, no deleting tests, no moving code into
|
||||
an exempt extension, no `# noqa`-style suppressions.
|
||||
|
||||
## Make it permanent (required — this is the point)
|
||||
|
||||
A refactor without a gate silently regrows. Before this task is done:
|
||||
|
||||
1. Wire the shared gate `~/src/utils/scripts/check_file_length.sh` into this repo's
|
||||
`.pre-commit-config.yaml` as a local hook. If the repo has no pre-commit
|
||||
config, add a minimal one.
|
||||
2. The hook checks **files in the commit** (not the whole tree), so unrelated
|
||||
commits never break, and it **fails** — exit 1, not a warning.
|
||||
3. No baseline file and no allowlist. Those are suppressions.
|
||||
4. If this repo has CI (`.github/workflows`), add the same check there so it
|
||||
also fails on push.
|
||||
|
||||
## Done condition
|
||||
|
||||
- `bash ~/src/utils/scripts/check_file_length.sh --all` from this repo root exits 0.
|
||||
- The repo's own test suite and coverage bar are still green.
|
||||
- `pre-commit run --files <changed files>` passes.
|
||||
- A deliberately over-250-line test file, staged, makes `git commit` **fail**.
|
||||
- For a deployed daemon/app: the entry point still actually runs.
|
||||
|
||||
## Verify
|
||||
|
||||
Run the suite, then the alarm entry point. The phone_app companion needs `phone-deploy` verification if touched.
|
||||
|
||||
## Why this sat untouched (added 2026-08-24)
|
||||
|
||||
This repo ran a LOCAL `scripts/check_file_length.py` with `MAX_LINES = 500`,
|
||||
under a hook named "Max file length (500 lines)". It reported "gated" while
|
||||
permitting files every other repo rejects -- so the cap looked enforced and
|
||||
nothing ever failed. The hook now delegates to the shared 250-line gate in
|
||||
`~/src/utils`, which reports 17 real violations.
|
||||
|
||||
Done condition is now an exit code, not a count:
|
||||
|
||||
```
|
||||
bash scripts/check_file_length.sh --all # must exit 0
|
||||
```
|
||||
|
||||
REMOVE ME AFTER FINISH
|
||||
Loading…
Reference in New Issue
Block a user