1
0
Эх сурвалжийг харах

Add the PR record for go-readability

Co-Authored-By: Claude Opus 5.5 <noreply@anthropic.com>
Claude 1 цаг өмнө
parent
commit
69923afd2b

+ 100 - 0
pull-requests/go-readability/go-readability.md

@@ -0,0 +1,100 @@
+# Go readability
+
+Branch: `go-readability` → `main`
+
+PR 10 of the review fixes plan (`docs/review-fixes-plan.md`), a readability PR: no behaviour change, no version change. It was done after PR 11; the two touch different files.
+
+## What changed
+
+Four commits, one per area:
+
+1. **`Service.state` split into named helpers (R3, R4).**
+   - **The helpers:** `state()` in `internal/app/app.go` used `p`, `v`, `q`, `f`, `m` and `st` across a 58-line function. It now builds the `State` from four helpers:
+     - `limits()`;
+     - `missingSources(proj)`, the pool files export could not copy;
+     - `padState(proj, slot, missing)`;
+     - `sequenceStates(proj)`.
+   
+     They use names such as `proj`, `view` and `seq`.
+   - **The rename:** `Service.edit` becomes `apply`.
+2. **Clearer names and notes in `xpj` and `project` (R4, R6).**
+   - **Renames, with the comments that mention them:**
+
+     | Was | Now | What it does |
+     | --- | --- | --- |
+     | `xpj.wrap` | `wrapErr` | Prefixes JSON errors with `xpj:`. |
+     | `project.wrap` | `fromFile` | Builds a `Project` from a decoded file. |
+     | `project.edit` (type) | `setter` | Applies several `Set`s and keeps the first error. |
+
+     Together with `apply`, no two things share a name any more.
+   - **`uniqueFile`:** it kept taken file names and sample names in one map, told apart by a `"\x00"` suffix. Now it uses two maps, `takenFiles` and `takenNames`, and its comment says both kinds of name are kept unique.
+   - **The BPM check:** `!(bpm >= MinBPM && bpm <= MaxBPM)` now has a comment saying it is written that way so NaN, for which every comparison is false, is refused.
+3. **`main()` reads as a list of steps (R5).**
+   - `main()` in `main.go` goes from 96 lines to 12. It calls four new functions, each keeping the comment that was there:
+     - `newApp`: the application options and the panic handler;
+     - `newWindow`: the hidden window, sized and shown once the screens are known;
+     - `guardClose`: the unsaved-changes guard;
+     - `handleFileDrops`: the file-drop handler.
+   - The steps run in the same order as before.
+4. **The CLI's flags each have a named parse function (R5).**
+   - **Parsing:** `init()` in `cmd/mpckit-cli/main.go` was 104 lines of closures. Each flag now has its own function: `parsePadOp`, `parseTuneOp`, `parseMuteOp`, `parseClearOp`, `parseCopyOp`, `parseMoveOp`, `parseSwapOp`, `parseSeqOp` and `parseRmseqOp`. `init()` registers them from a nine-row table.
+   - **`main()`:** it was 62 lines, over the plan's 60. It now hands opening the project to `openProject` and exporting to `write`.
+   - **Unchanged:** flag names, usage text, error messages and output.
+
+**Longest functions** in `main.go`, `cmd/mpckit-cli/main.go` and `internal/app/app.go`:
+
+| | Longest | Next |
+| --- | --- | --- |
+| Before (`main`) | CLI `init` 104 lines | `main()` 96, CLI `main` 62, `state` 58 |
+| Now | 28 lines: `padState`, `parseSeqOp` and the CLI `main` | `newApp` and `openProject`, 25 each |
+
+## Notes
+
+- **Name choices.** I used the plan's names: `wrapErr`, `fromFile`, `apply` and `setter`.
+  - **New in the CLI:** a function type for one flag's change to the project, which I named `opFunc`, beside the existing `op` and `opFlag`. I avoided calling it `edit`, which this PR removes as a name elsewhere.
+  - **The two CLI helpers:** `openProject` and `write`.
+- **Two small changes in how the CLI's parse functions are written, with the same result:**
+  - `-clear` and `-rmseq` used to return a function together with the error. They now return nil on error. `flag` never stored the function when there was an error, so nothing a user sees changes.
+  - `-tune`'s long out-of-range message is now split across two lines of source; the text is the same.
+- **Not changed:** what each function does, the order of `main()`'s steps, and the tests. `load_test.go` changes only for the `fromFile` rename.
+
+## Testing
+
+**On the server, every command with `GOTOOLCHAIN=go1.27.4`:**
+- `go test ./...` passes. No test was removed or loosened; one renamed call and comment in `load_test.go`.
+- `go vet ./...` (also with `GOOS=windows`) and `staticcheck ./...` are clean.
+- `govulncheck ./...`: "No vulnerabilities found."
+- In `frontend`: `npm ci`, `npm run check` (0 errors, 0 warnings), `npm run build` and `npm run format:check` pass. The frontend is unchanged.
+- `wails3 build` builds and the app starts under Xvfb.
+
+**"No behaviour change", checked against `main` before the first commit:**
+- **Exports are byte-identical.** I ran `go run ./cmd/mpckit-cli -load testdata/device/DemoFile.xpj -out <dir>` on `main` and after the last commit. `cmp` finds the two `DemoFile.xpj` identical, and `diff -r` finds the data folders identical.
+- **`go run ./cmd/mpckit-cli -h`** prints exactly the same text.
+- **22 CLI runs give the same results.** Two runs use every flag (one exports to a folder, one to a zip). The rest are 15 bad flag values, an existing export with and without `-force`, a stray argument, both `-out` and `-zip`, and no `-name`. For each run I compared stdout, stderr, exit code, the exported files, and the zip's entries and their contents (the zip itself stores its write time).
+- **The State the window gets is byte-identical.** A scratch test, not committed, wrote the full `State` JSON after loading DemoFile, ten edits, two refused edits, loading a copy with a missing WAV, and the refused export.
+- **No bound method changed:** `TestBoundMethods` passes untouched, and `frontend/bindings` did not change.
+
+**On the laptop (PowerShell, in the repo).** This changes the window set-up in `main.go`, so watch the window size, the close prompt and file drop in particular:
+1. `git fetch; git checkout go-readability`
+2. `go test ./...`: all `ok`.
+3. `go run ./cmd/mpckit-cli -h`: the same usage text as before.
+4. `wails3 dev`. The window opens at the usual size, centred, with nothing scrolling.
+5. **About:** open About and check the version and links. Close it with Escape.
+6. **Pads tab:** load `testdata\device\DemoFile.xpj`.
+   - Click pads to hear them. The pad panel shows names and files.
+   - Change a tune and a mute group.
+   - Drop a WAV onto an empty pad: it is assigned. Drop a non-WAV file: "Only WAV files can be assigned to a pad." shows.
+   - Move/Copy to pad: the picker opens. Drag A1 onto A5: the notes warning shows; Cancel.
+7. **Sequences tab:**
+   - Select Intro and Sequence 02.
+   - Change a name and a BPM.
+   - Set Sequence 02 to 1 bar: the "Shorten…" dialog shows; Cancel.
+   - Add a sequence in B5, then remove it: the "Remove…" dialog shows.
+8. **Export:**
+   - Export to a new folder.
+   - Export there again and Cancel at "Replace existing files?".
+   - Export a zip.
+9. **Missing file:** load a copy of DemoFile with one WAV removed. The missing badge and the footer warning show, and export is disabled.
+10. **New and close:**
+    - New, with unsaved changes: the confirm dialog shows.
+    - Make a change, then close the window: "Close without exporting?" shows. Cancel keeps the app open; confirming closes it.