Rename the machine configuration along with its directory
Found by the deployment to vm4006: the move renames the directory and leaves the file inside it alone, so the machine configuration ended up at `.git/werkator/.gittally.yml` — a pair of names the lookup did not expect, because it pairs directory and file name. The instance resolved empty credentials, no public URL and none of the host's build definitions, and said nothing about it. That is the exact failure this change exists to prevent, produced by the change itself. `StateDirMigration` now renames the configuration with the directory, unless one under the current name is already there. `ConfigFiles` carries `.git/werkator/.gittally.yml` as a third candidate as well, for a directory somebody moved by hand, where the migration never runs and so can rename nothing. Co-Authored-By: Claude Opus 5 <noreply@anthropic.com>
This commit is contained in:
co-authored by
Claude Opus 5
parent
8499bb7a53
commit
39dac4b51b
@@ -108,6 +108,22 @@ So that an operator who moved the directory by hand does not lose the live state
|
||||
- [StateDirMigrationTest: "leaves both alone when the current directory already exists"](../../src/test/kotlin/de/hoennig/werkator/StateDirMigrationTest.kt)
|
||||
- [StateDirMigrationTest: "does nothing where there is no pre-rename directory"](../../src/test/kotlin/de/hoennig/werkator/StateDirMigrationTest.kt)
|
||||
|
||||
#### Scenario#1.06: The machine configuration survives a directory that moved without it
|
||||
|
||||
So that the move cannot produce a pair of names its own lookup does not expect.
|
||||
|
||||
- **Given** a state directory that has moved to `.git/werkator/`
|
||||
- **and** the machine configuration inside it still named `.gittally.yml`
|
||||
- **When** the configuration is loaded
|
||||
- **Then** its settings take effect
|
||||
- **and** where the move did it, the file carries the current name afterwards
|
||||
|
||||
##### Verified by
|
||||
|
||||
- [StateDirMigrationTest: "renames the machine configuration inside the moved directory"](../../src/test/kotlin/de/hoennig/werkator/StateDirMigrationTest.kt)
|
||||
- [StateDirMigrationTest: "never overwrites a machine configuration that already carries the current name"](../../src/test/kotlin/de/hoennig/werkator/StateDirMigrationTest.kt)
|
||||
- [ConfigLoaderTest: "finds the machine config left under its old name in an already-moved directory"](../../src/test/kotlin/de/hoennig/werkator/config/ConfigLoaderTest.kt)
|
||||
|
||||
## The Solution
|
||||
|
||||
**One spelling rule.**
|
||||
@@ -120,6 +136,11 @@ This is what turns a rename into a decidable question instead of a matter of tas
|
||||
The current name wins and the old file is then ignored rather than merged — two files side by side are a half-done rename, not a layering.
|
||||
Error messages name the file that was actually read, so they never point at a file that does not exist.
|
||||
|
||||
**A move that finishes the job.**
|
||||
The deployment to vm4006 found the gap the hard way: the move renames the *directory* and leaves the file inside it alone, so the machine configuration ended up at `.git/werkator/.gittally.yml` — a pair of names the lookup did not expect.
|
||||
The instance came up with empty credentials and no host build definitions, without an error, which is the failure this PR exists to prevent.
|
||||
`StateDirMigration` now renames the configuration along with the directory, unless one under the current name is already there, and `ConfigFiles` carries the intermediate path as a third candidate for a directory somebody moved by hand.
|
||||
|
||||
**A one-time move for the state.**
|
||||
[`StateDirMigration`](../../src/main/kotlin/de/hoennig/werkator/StateDirMigration.kt) renames `.git/gittally` to `.git/werkator` from `CliRunner`, before any command resolves a path under it and therefore before the second Spring context of `server` exists.
|
||||
A fallback was rejected here: unlike a configuration, the state is written, so a fallback would have to decide on every write which of two directories wins, where a one-time move decides once and leaves a single path behind.
|
||||
|
||||
Reference in New Issue
Block a user