|
1 | 1 | import { describe, expect, jest, test } from "@jest/globals"; |
2 | | -import { existsSync, rmSync } from "node:fs"; |
| 2 | +import { existsSync, readFileSync, rmSync, writeFileSync } from "node:fs"; |
3 | 3 | import path from "path"; |
4 | 4 | import { cli } from "./helpers"; |
5 | 5 |
|
@@ -92,4 +92,40 @@ describe("install", () => { |
92 | 92 | rmSync(path.join(cwd, ".mops"), { recursive: true, force: true }); |
93 | 93 | } |
94 | 94 | }); |
| 95 | + |
| 96 | + // Regression: `install --lock update` used to early-return if mops.toml's |
| 97 | + // deps hash was unchanged, even when the lockfile's per-file hashes were |
| 98 | + // stale/corrupt. The subsequent checkLockFile would then fail and exit 1, |
| 99 | + // so `--lock update` could never recover a broken lock — the only escape |
| 100 | + // was `rm mops.lock`. See issue #514. |
| 101 | + test("--lock update rewrites a lockfile with a corrupt file hash", async () => { |
| 102 | + const cwd = path.join(import.meta.dirname, "install/success"); |
| 103 | + const lockFile = path.join(cwd, "mops.lock"); |
| 104 | + rmSync(lockFile, { force: true }); |
| 105 | + try { |
| 106 | + const first = await cli(["install"], { cwd, env: { CI: undefined } }); |
| 107 | + expect(first.exitCode).toBe(0); |
| 108 | + expect(existsSync(lockFile)).toBe(true); |
| 109 | + |
| 110 | + const bad = |
| 111 | + "BAD0000000000000000000000000000000000000000000000000000000000BAD"; |
| 112 | + const original = readFileSync(lockFile, "utf8"); |
| 113 | + const corrupted = original.replace( |
| 114 | + /"core@1\.0\.0\/mops\.toml":\s*"[0-9a-f]{64}"/, |
| 115 | + `"core@1.0.0/mops.toml": "${bad}"`, |
| 116 | + ); |
| 117 | + expect(corrupted).not.toBe(original); |
| 118 | + writeFileSync(lockFile, corrupted); |
| 119 | + |
| 120 | + const result = await cli(["install", "--lock", "update"], { |
| 121 | + cwd, |
| 122 | + env: { CI: undefined }, |
| 123 | + }); |
| 124 | + expect(result.exitCode).toBe(0); |
| 125 | + expect(readFileSync(lockFile, "utf8")).not.toContain(bad); |
| 126 | + } finally { |
| 127 | + rmSync(lockFile, { force: true }); |
| 128 | + rmSync(path.join(cwd, ".mops"), { recursive: true, force: true }); |
| 129 | + } |
| 130 | + }); |
95 | 131 | }); |
0 commit comments