Repository navigation
fix(config): don't migrate a settings.json with a non-numeric version as v1 - #680
Open
eric-engberg wants to merge 1 commit into
Open
eric-engberg wants to merge 1 commit into
eric-engberg wants to merge 1 commit into
Conversation
… as v1 loadSettings treats a file as v1 only when it has no `version` key, but needsMigration/detectVersion treat any `version` that isn't a number as v1. A current config with `"version": "4"` or `"version": null` (after a hand edit, for example) therefore skipped v1 validation and then ran the v1->v2 migration anyway. That migration rebuilds the config from `lines` and the v1 fields only, so the result validated and was written back over the file: Powerline, defaultPaddingSide, minimalistMode, separators and every other v2+ setting were dropped, widget ids were regenerated, and the status line announced "ccstatusline updated to v2.0.2". needsMigration now reports no migration for a version that is present but not a number. The config then reaches schema validation, which rejects it, so it takes the existing invalid-file path: defaults in memory, the load error recorded for the warning badge and TUI banner, and the file left untouched. Import validation shares needsMigration, so an import file with a non-numeric version is now rejected instead of being reduced to its v1 fields.
This file contains hidden or bidirectional Unicode text that may be interpreted or compiled differently than what appears below. To review, open the file in an editor that reveals hidden Unicode characters.
Learn more about bidirectional Unicode characters
Sign up for free
to join this conversation on GitHub.
Already have an account?
Sign in to comment
Add this suggestion to a batch that can be applied as a single commit.This suggestion is invalid because no changes were made to the code.Suggestions cannot be applied while the pull request is closed.Suggestions cannot be applied while viewing a subset of changes.Only one suggestion per line can be applied in a batch.Add this suggestion to a batch that can be applied as a single commit.Applying suggestions on deleted lines is not supported.You must change the existing code in this line in order to create a valid suggestion.Outdated suggestions cannot be applied.This suggestion has been applied or marked resolved.Suggestions cannot be applied from pending reviews.Suggestions cannot be applied on multi-line comments.Suggestions cannot be applied while the pull request is queued to merge.Suggestion cannot be applied right now. Please check back later.
What
A
settings.jsonwhose"version"isn't a number ("4"ornull) is now treated as an invalid file, like any other: the status line shows the⚠ invalid configbadge with the default line, the TUI shows its "not in a valid format" banner, and the file is left as it is. Before, ccstatusline ran the v1 migration on it and wrote the result back, which reset most of the user's settings.Why
loadSettingsdecides a file is v1 by checking for aversionkey at all.needsMigration/detectVersiondecide bytypeof version === 'number'and call anything else v1. The two disagree for a version that's present but not a number. A current config with a quoted version, which a hand edit can produce:{ "version": "4", "lines": [...], "powerline": { "enabled": true, "theme": "nord-aurora", ... }, "defaultPaddingSide": "both", ... }skips v1 validation (it has a
versionkey) and then runs the v1→v2 migration anyway (the version isn't a number). That migration builds a fresh config fromlinesand the nine v1 fields only. The result validates, so it's written over the file:powerline: { enabled: true },minimalistMode: true), the filemainwrites back holds onlylineswith every widget id replaced by a new GUID,"version": 4, and anupdatemessage. Powerline and minimalist mode are gone, and so is every other setting the v1 format didn't have.mainleavespowerline.enabled: falseand notheme, and prints "ccstatusline updated to v2.0.2, 5hr block timer widget added" under the status line, which keeps showing for about a dozen renders.The load function's own contract says a file that fails validation is never overwritten; this input got around it.
How
needsMigrationnow returns false whenversionis present but not a number. Nothing else changes in the loader: the config goes straight to schema validation, which rejects it (versionmust be a number), and it takes the existing invalid-file path. That path keeps defaults in memory, records the load error for the badge and TUI banner, and doesn't write. Making the version a number again brings the user's settings back as they were.Unchanged:
versionkey still validate as v1 and migrate;Import uses the same
needsMigration, so importing a file with a non-numeric version is now rejected ("Invalid config format: Invalid input: expected number, received string") instead of being quietly reduced to its v1 fields in the preview.detectVersionandmigrateConfigare untouched; every caller ofmigrateConfigeither checksneedsMigrationfirst or only runs for files without aversionkey.Demo
The demo's baseline configs with
"version": 4changed to"version": "4", rendered once from sample data (scripts/payload.example.json). Each still prints the file's version and Powerline flag, renders the status line, then prints them again. stderr is hidden.Powerline: before
Powerline: after
Plain: before
Plain: after
Testing
main:config.test.ts: a file with"version": "4"and one with"version": nullload as defaults, keep the file byte-for-byte, write no backup, and set the "not in a valid format" load error;config.test.ts: an import with a string version is rejected;migrations.test.ts:needsMigrationis false for a string or null version.bun test: 2786 pass, 0 fail.bun run lintpasses.config.test.tsandmigrations.test.ts150 pass (146 existing, 4 new). The full suite under Node gives 2611 of 2764 passing. The 153 failures are in the same 17 files that fail onmain, all from spying on Node built-ins.main, and the TUI opens and exits cleanly under both;mainrewrites the file under both runtimes, and this branch renders the badge and leaves it unchanged.mainrewrites the file on launch. This branch shows the "settings.json is not in a valid format" banner and leaves the file unchanged, the same screenmainshows for any other invalid file (e.g."lines": 42).