ic-mops 2.13.2 → 2.14.1

This diff represents the content of publicly available package versions that have been released to one of the supported registries. The information contained in this diff is provided for informational purposes only and reflects changes between package versions as they appear in their respective public registries.
Files changed (70) hide show
  1. package/CHANGELOG.md +22 -0
  2. package/bun.lock +24 -12
  3. package/bundle/cli.tgz +0 -0
  4. package/cache.ts +101 -20
  5. package/cli.ts +40 -14
  6. package/commands/available-updates.ts +4 -2
  7. package/commands/bench.ts +3 -0
  8. package/commands/check.ts +33 -22
  9. package/commands/init.ts +15 -2
  10. package/commands/install/install-mops-dep.ts +14 -9
  11. package/commands/install/sync-local-cache.ts +7 -1
  12. package/commands/lint.ts +11 -0
  13. package/commands/outdated.ts +5 -2
  14. package/commands/publish.ts +0 -1
  15. package/commands/test/test.ts +14 -0
  16. package/commands/update.ts +3 -2
  17. package/commands/watch/tester.ts +5 -1
  18. package/dist/cache.d.ts +3 -0
  19. package/dist/cache.js +98 -18
  20. package/dist/cli.js +16 -12
  21. package/dist/commands/available-updates.d.ts +1 -1
  22. package/dist/commands/available-updates.js +4 -1
  23. package/dist/commands/bench.js +2 -0
  24. package/dist/commands/check.js +27 -18
  25. package/dist/commands/init.js +9 -2
  26. package/dist/commands/install/install-mops-dep.js +12 -9
  27. package/dist/commands/install/sync-local-cache.js +2 -1
  28. package/dist/commands/lint.js +7 -0
  29. package/dist/commands/outdated.d.ts +2 -1
  30. package/dist/commands/outdated.js +2 -2
  31. package/dist/commands/publish.js +0 -1
  32. package/dist/commands/test/test.d.ts +1 -1
  33. package/dist/commands/test/test.js +10 -5
  34. package/dist/commands/update.d.ts +2 -1
  35. package/dist/commands/update.js +2 -2
  36. package/dist/commands/watch/tester.js +4 -1
  37. package/dist/helpers/autofix-motoko.d.ts +1 -1
  38. package/dist/helpers/autofix-motoko.js +10 -8
  39. package/dist/helpers/deprecate-dfx-replica.d.ts +2 -0
  40. package/dist/helpers/deprecate-dfx-replica.js +20 -0
  41. package/dist/helpers/fix-lock.d.ts +1 -0
  42. package/dist/helpers/fix-lock.js +93 -0
  43. package/dist/integrity.d.ts +2 -2
  44. package/dist/integrity.js +22 -6
  45. package/dist/mops.js +1 -1
  46. package/dist/package.json +3 -3
  47. package/dist/tests/check-fix.test.js +40 -0
  48. package/dist/tests/check.test.js +6 -0
  49. package/dist/tests/cli.test.js +136 -1
  50. package/dist/vessel.js +21 -13
  51. package/dist/wasm/pkg/nodejs/package.json +1 -1
  52. package/dist/wasm/pkg/nodejs/wasm_bg.wasm +0 -0
  53. package/dist/wasm/pkg/web/package.json +1 -1
  54. package/dist/wasm/pkg/web/wasm_bg.wasm +0 -0
  55. package/helpers/autofix-motoko.ts +16 -14
  56. package/helpers/deprecate-dfx-replica.ts +32 -0
  57. package/helpers/fix-lock.ts +101 -0
  58. package/integrity.ts +30 -9
  59. package/mops.ts +1 -1
  60. package/package.json +3 -3
  61. package/tests/__snapshots__/check.test.ts.snap +17 -4
  62. package/tests/check-fix.test.ts +46 -0
  63. package/tests/check.test.ts +11 -0
  64. package/tests/cli.test.ts +180 -1
  65. package/tests/install/update-bound-patch/mops.toml +2 -0
  66. package/vessel.ts +31 -14
  67. package/wasm/pkg/nodejs/package.json +1 -1
  68. package/wasm/pkg/nodejs/wasm_bg.wasm +0 -0
  69. package/wasm/pkg/web/package.json +1 -1
  70. package/wasm/pkg/web/wasm_bg.wasm +0 -0
package/CHANGELOG.md CHANGED
@@ -2,6 +2,28 @@
2
2
 
3
3
  ## Next
4
4
 
5
+ ## 2.14.1
6
+ - Speed up `mops check <files...>` (e.g. `mops check src/**/*.mo`) on packages with many files. Previously each file was checked in its own `moc` invocation, so every shared transitive import was re-parsed and re-type-checked once per file. All files are now passed to a single `moc --check` call, which loads and type-checks each import only once — on motoko-core (53 files) this drops a full check from ~27s to ~1.6s. The per-file `✓` confirmations now print only when the whole check passes.
7
+
8
+ ## 2.14.0
9
+ - Fix `mops check --fix` crashing with `TypeError: Cannot read properties of undefined (reading 'split')` when `moc` produces no output (e.g. it fails to spawn or is killed by the OOM killer in a memory-constrained container). The autofix pass now treats missing `moc` output as "no fixes to apply" and lets the regular check report the real failure, instead of aborting the whole command with an unhandled exception.
10
+
11
+ - Fix `mops check --fix` and `mops lint --fix` corrupting source files when two `mops` processes run concurrently in the same project (e.g. two coding agents on the same checkout). Concurrent runs could apply stale `moc` byte offsets to a sibling's already-mutated file, leaving source like `let nat = identity` (with the type-arg and call dropped) or `list.sortInPlace(` with an unclosed paren. `--fix` invocations now acquire a project-root advisory lock at `.mops/fix.lock` and serialize, cargo-style ("Waiting for another `mops --fix` run to finish..."). Read-only `mops check` and `mops lint` are unchanged.
12
+
13
+ - Deprecate the `dfx` replica in `mops bench`, `mops test --mode replica`, and `mops watch`. Behavior is unchanged — `--replica dfx`, the implicit `dfx` fallback when no `[toolchain.pocket-ic]` is set, and the dfx-bundled PocketIC fallback all still work — but each now prints a warning. Run `mops toolchain use pocket-ic <version>` to silence it. The `dfx` paths will be removed and the default flipped to PocketIC in mops v3 — `dfx` is being deprecated upstream and PocketIC is a better fit for benchmarks and replica tests (deterministic, in-process, no background daemon).
14
+
15
+ - `mops toolchain --help` now lists the tools mops manages (`moc`, `wasmtime`, `pocket-ic`, `lintoko`) in the top-level description instead of only mentioning them under `bin`, and `mops toolchain use` / `update` / `bin` print the available tools (via the auto-generated help) when invoked with a missing or invalid `<tool>` argument.
16
+
17
+ - Add `--patch` to `mops update` and `mops outdated` to restrict updates to patch versions only (e.g. `1.2.3 -> 1.2.4`, never `1.2.3 -> 1.3.0`). Mutually exclusive with `--major`. For pre-1.0 packages this matches the default — caret already restricts `0.x.y` to patch updates. Useful for risk-averse upgrades on packages that have hit 1.0+.
18
+
19
+ - Improve the per-file integrity-check error after `mops install --lock update`. Previously the message told users to run `mops install --lock update` — the exact command that just failed. After a regenerated lockfile, the only way a per-file hash can still mismatch is a local edit under `.mops/`, so the message now says that and suggests restoring from the global cache (delete the `.mops/<pkg>` directory and run `mops install`) or using a `repo`/`path` entry in `mops.toml` to keep custom changes.
20
+
21
+ - Deprecate the `vessel.dhall` auto-migration in `mops init`. Behavior is unchanged for now — interactive `mops init` still reads `vessel.dhall` and copies its dependencies into `mops.toml` — but a warning is printed (also under `--yes`, which still skips the migration itself), and the migration will be removed in mops v3. Before then, copy your dependencies into `mops.toml` manually and delete `vessel.dhall` / `package-set.dhall`.
22
+
23
+ - Fix `mops install` race conditions when multiple processes install into the same project (e.g. an editor watcher, fixture installers like vscode-motoko's, or CI matrix jobs sharing a global cache). Concurrent runs could observe a half-populated global cache or local `.mops/<pkg>` directory and copy zero-byte / truncated files, surfacing later as missing completions, hover data, or type-check errors. Cache writes (mops registry, GitHub installs, and project-local `.mops/`) now stage into a sibling `.staging-*` dir and atomically rename onto the canonical path. Stale staging dirs from interrupted runs are swept on the next install. The shared `.mops/_tmp/` zip download dir used by GitHub installs is also per-invocation now. If you have zero-byte files left over in your cache from a pre-fix crash, run `mops cache clean` once after upgrading.
24
+
25
+ - Replace `@iarna/toml` with `smol-toml` for parsing and writing `mops.toml` (faster, actively maintained, spec-compliant TOML parser). Config reformat behavior on `add`/`remove`/`bump`/`toolchain` is unchanged — both libraries round-trip through a plain object.
26
+
5
27
  ## 2.13.2
6
28
  - Fix race conditions when two `mops` processes run on the same project (e.g. an editor watcher and `caffeine check --fix`, or back-to-back invocations). `mops check-stable` used a shared `.mops/.check-stable/` scratch dir and `mops check`/`build`/`check-stable` used a shared `<parent>/.migrations-<canister>/` staging dir; concurrent runs would clobber each other and surface as misleading errors like `.mops/.check-stable/new.most: No such file or directory` or `EEXIST: file already exists, symlink ...`. Both directories are now per-invocation (created via `mkdtemp` and removed when the command finishes).
7
29
  - Deprecate `skipIfMissing` in `[canisters.<name>.check-stable]`. Behavior is unchanged for now, but `mops check`/`check-stable` print a warning when it is set. For initial deployments, commit a `.most` file at the configured `path` containing an empty actor (`// Version: 1.0.0\nactor { };`) instead — the stable check then runs against an empty baseline.
package/bun.lock CHANGED
@@ -5,7 +5,6 @@
5
5
  "": {
6
6
  "name": "ic-mops",
7
7
  "dependencies": {
8
- "@iarna/toml": "2.2.5",
9
8
  "@icp-sdk/core": "4.0.2",
10
9
  "@noble/hashes": "1.8.0",
11
10
  "as-table": "1.0.55",
@@ -41,7 +40,9 @@
41
40
  "prettier-plugin-motoko": "0.13.0",
42
41
  "promisify-child-process": "4.1.2",
43
42
  "prompts": "2.4.2",
43
+ "proper-lockfile": "4.1.2",
44
44
  "semver": "7.7.1",
45
+ "smol-toml": "1.6.1",
45
46
  "stream-to-promise": "3.0.0",
46
47
  "string-width": "7.2.0",
47
48
  "tar": "7.5.11",
@@ -57,6 +58,7 @@
57
58
  "@types/ncp": "2.0.8",
58
59
  "@types/node": "24.0.3",
59
60
  "@types/prompts": "2.4.9",
61
+ "@types/proper-lockfile": "4.1.4",
60
62
  "@types/semver": "7.5.8",
61
63
  "@types/stream-to-promise": "2.2.4",
62
64
  "@types/tar": "6.1.13",
@@ -246,8 +248,6 @@
246
248
 
247
249
  "@humanwhocodes/object-schema": ["@humanwhocodes/object-schema@2.0.3", "", {}, "sha512-93zYdMES/c1D69yZiKDBj0V24vqNzB/koF26KPaagAfd3P/4gUlh3Dys5ogAK+Exi9QyzlD8x/08Zt7wIKcDcA=="],
248
250
 
249
- "@iarna/toml": ["@iarna/toml@2.2.5", "", {}, "sha512-trnsAYxU3xnS1gPHPyU961coFyLkh4gAD/0zQ5mymY4yOZ+CYvsPqUbOFSw0aDM4y0tV7tiFxL/1XfXPNC6IPg=="],
250
-
251
251
  "@icp-sdk/core": ["@icp-sdk/core@4.0.2", "", { "peerDependencies": { "@dfinity/agent": "^3.2.4", "@dfinity/candid": "^3.2.4", "@dfinity/identity": "^3.2.4", "@dfinity/identity-secp256k1": "^3.2.4", "@dfinity/principal": "^3.2.4" } }, "sha512-tiNXiLbzc4+CJV2R/sk8Iw9WREZ32SmwPPvt5qYUaQDs6A8iftr03alCkVa+Frx4CKqbeVrJehsp07Ms7ZaHWA=="],
252
252
 
253
253
  "@isaacs/cliui": ["@isaacs/cliui@8.0.2", "", { "dependencies": { "string-width": "^5.1.2", "string-width-cjs": "npm:string-width@^4.2.0", "strip-ansi": "^7.0.1", "strip-ansi-cjs": "npm:strip-ansi@^6.0.1", "wrap-ansi": "^8.1.0", "wrap-ansi-cjs": "npm:wrap-ansi@^7.0.0" } }, "sha512-O8jcjabXaleOG9DQ0+ARXWZBTfnP4WNAqzuiJK7ll44AmxGKv/J2M4TPjxjY3znBCfvBXFzucm1twdyFybFqEA=="],
@@ -474,6 +474,10 @@
474
474
 
475
475
  "@types/prompts": ["@types/prompts@2.4.9", "", { "dependencies": { "@types/node": "*", "kleur": "^3.0.3" } }, "sha512-qTxFi6Buiu8+50/+3DGIWLHM6QuWsEKugJnnP6iv2Mc4ncxE4A/OJkjuVOA+5X0X1S/nq5VJRa8Lu+nwcvbrKA=="],
476
476
 
477
+ "@types/proper-lockfile": ["@types/proper-lockfile@4.1.4", "", { "dependencies": { "@types/retry": "*" } }, "sha512-uo2ABllncSqg9F1D4nugVl9v93RmjxF6LJzQLMLDdPaXCUIDPeOJ21Gbqi43xNKzBi/WQ0Q0dICqufzQbMjipQ=="],
478
+
479
+ "@types/retry": ["@types/retry@0.12.5", "", {}, "sha512-3xSjTp3v03X/lSQLkczaN9UIEwJMoMCA1+Nb5HfbJEQWogdeQIyVtTvxPXDQjZ5zws8rFQfVfRdz03ARihPJgw=="],
480
+
477
481
  "@types/semver": ["@types/semver@7.5.8", "", {}, "sha512-I8EUhyrgfLrcTkzV3TSsGyl1tSuPrEDzr0yd5m90UgNxQkyDXULk3b6MlQqTCpZpNtWe1K0hzclnZkTcLBe2UQ=="],
478
482
 
479
483
  "@types/stack-utils": ["@types/stack-utils@2.0.3", "", {}, "sha512-9aEbYZ3TbYMznPdcdr3SmIrLXwC/AKZXQeCf9Pgao5CKb8CyHuEX5jzWPTkvregvhRJHcpRO6BFoGW9ycaOkYw=="],
@@ -638,7 +642,7 @@
638
642
 
639
643
  "callsites": ["callsites@3.1.0", "", {}, "sha512-P8BjAsXvZS+VIDUI11hHCQEv74YT67YUi5JJFNWIqL235sBmjX4+qx9Muvls5ivyNENctx46xQLQ3aTuE7ssaQ=="],
640
644
 
641
- "camelcase": ["camelcase@6.3.0", "", {}, "sha512-Gmy6FhYlCY7uOElZUSbxo2UCDH8owEk996gkbrpsgGtrJLM3J7jGxl9Ic7Qwwj4ivOE5AWZWRMecDdF7hqGjFA=="],
645
+ "camelcase": ["camelcase@5.3.1", "", {}, "sha512-L28STB170nwWS63UjtlEOE3dldQApaJXZkOI1uMFfzf3rRuPegHaHesyee+YxQ+W6SvRDQV6UrdOdRiR153wJg=="],
642
646
 
643
647
  "caniuse-lite": ["caniuse-lite@1.0.30001781", "", {}, "sha512-RdwNCyMsNBftLjW6w01z8bKEvT6e/5tpPVEgtn22TiLGlstHOVecsX2KHFkD5e/vRnIE4EGzpuIODb3mtswtkw=="],
644
648
 
@@ -1332,7 +1336,7 @@
1332
1336
 
1333
1337
  "picocolors": ["picocolors@1.1.1", "", {}, "sha512-xceH2snhtb5M9liqDsmEw56le376mTZkEX/jEb/RxNFyegNul7eNslCXP9FDj/Lcu0X8KEyMceP2ntpaHrDEVA=="],
1334
1338
 
1335
- "picomatch": ["picomatch@2.3.1", "", {}, "sha512-JU3teHTNjmE2VCGFzuY8EXzCDVwEqB2a8fsIvwaStHhAWJEeVd1o1QD80CU6+ZdEXXSLbSsuLwJjkCBWqRQUVA=="],
1339
+ "picomatch": ["picomatch@4.0.3", "", {}, "sha512-5gTmgEY/sqK6gFXLIsQNH19lWb4ebPDLA4SdLP7dsWkIXHWlG66oPuVvXSGFPppYZz8ZDZq0dYYrbHfBCVUb1Q=="],
1336
1340
 
1337
1341
  "pidtree": ["pidtree@0.3.1", "", { "bin": { "pidtree": "bin/pidtree.js" } }, "sha512-qQbW94hLHEqCg7nhby4yRC7G2+jYHY4Rguc2bjw7Uug4GIJuu1tvf2uHaZv5Q8zdt+WKJ6qK1FOI6amaWUo5FA=="],
1338
1342
 
@@ -1366,6 +1370,8 @@
1366
1370
 
1367
1371
  "prompts": ["prompts@2.4.2", "", { "dependencies": { "kleur": "^3.0.3", "sisteransi": "^1.0.5" } }, "sha512-NxNv/kLguCA7p3jE8oL2aEBsrJWgAakBpgmgK6lpPWV+WuOmY6r2/zbAVnP+T8bQlA0nzHXSJSJW0Hq7ylaD2Q=="],
1368
1372
 
1373
+ "proper-lockfile": ["proper-lockfile@4.1.2", "", { "dependencies": { "graceful-fs": "^4.2.4", "retry": "^0.12.0", "signal-exit": "^3.0.2" } }, "sha512-TjNPblN4BwAWMXU8s9AEz4JmQxnD1NNL7bNOY/AKUzyamc379FWASUhc/K1pL2noVb+XmZKLL68cjzLsiOAMaA=="],
1374
+
1369
1375
  "punycode": ["punycode@2.3.1", "", {}, "sha512-vYt7UD1U9Wg6138shLtLOvdAu+8DsC/ilFtEVHcH+wydcSpNE20AfSOduf6MkRFahL5FY7X1oU7nKVZFtfq8Fg=="],
1370
1376
 
1371
1377
  "pure-rand": ["pure-rand@7.0.1", "", {}, "sha512-oTUZM/NAZS8p7ANR3SHh30kXB+zK2r2BPcEn/awJIbOvq82WoMN4p62AWWp3Hhw50G0xMsw1mhIBLqHw64EcNQ=="],
@@ -1408,6 +1414,8 @@
1408
1414
 
1409
1415
  "restore-cursor": ["restore-cursor@5.1.0", "", { "dependencies": { "onetime": "^7.0.0", "signal-exit": "^4.1.0" } }, "sha512-oMA2dcrw6u0YfxJQXm342bFKX/E4sG9rbTzO9ptUcR/e8A33cHuvStiYOwH7fszkZlZ1z/ta9AAoPk2F4qIOHA=="],
1410
1416
 
1417
+ "retry": ["retry@0.12.0", "", {}, "sha512-9LkiTwjUh6rT555DtE9rTX+BKByPfrMzEAtnlEtdEwr3Nkffwiihqe2bWADg+OQRjt9gl6ICdmB/ZFDCGAtSow=="],
1418
+
1411
1419
  "reusify": ["reusify@1.1.0", "", {}, "sha512-g6QUff04oZpHs0eG5p83rFLhHeV00ug/Yf9nZM6fLeUrPguBTkTQOdpAWWspMh55TZfVQDPaN3NQJfbVRAxdIw=="],
1412
1420
 
1413
1421
  "rexreplace": ["rexreplace@7.1.13", "", { "dependencies": { "globs": "0.1.4", "yargs": "16" }, "bin": { "rr": "bin/rexreplace.cli.min.js", "rexreplace": "bin/rexreplace.cli.js" } }, "sha512-UVdKFM4267di4rwFuDBGPlS+OAQ3NE/8SS6sdUQs++7dPpwgYAAO0a1OG85IQoge2IJUaDsvSiNnQkRwrzGH0Q=="],
@@ -1458,6 +1466,8 @@
1458
1466
 
1459
1467
  "slice-ansi": ["slice-ansi@7.1.0", "", { "dependencies": { "ansi-styles": "^6.2.1", "is-fullwidth-code-point": "^5.0.0" } }, "sha512-bSiSngZ/jWeX93BqeIAbImyTbEihizcwNjFoRUIY/T1wWQsfsm2Vw1agPKylXvQTU7iASGdHhyqRlqQzfz+Htg=="],
1460
1468
 
1469
+ "smol-toml": ["smol-toml@1.6.1", "", {}, "sha512-dWUG8F5sIIARXih1DTaQAX4SsiTXhInKf1buxdY9DIg4ZYPZK5nGM1VRIYmEbDbsHt7USo99xSLFu5Q1IqTmsg=="],
1470
+
1461
1471
  "source-map": ["source-map@0.6.1", "", {}, "sha512-UjgapumWlbMhkBgzT7Ykc5YXUT46F0iKu8SGXq0bcwP5dz/h0Plj6enJqjz1Zbq2l5WaqYnrVbwWOWMyF3F47g=="],
1462
1472
 
1463
1473
  "source-map-js": ["source-map-js@1.2.1", "", {}, "sha512-UXWMKhLOwVKb728IUtQPXxfYU+usdybtUrK/8uGE8CQMvrhOpwvzDBwj0QhSL7MQc7vIsISBG8VQ8+IDQxpfQA=="],
@@ -1688,8 +1698,6 @@
1688
1698
 
1689
1699
  "@isaacs/fs-minipass/minipass": ["minipass@7.1.2", "", {}, "sha512-qOOzS1cBTWYF4BH8fVePDBOO9iptMnGUEZwNc/cMWnTV2nVLZ7VoNWEPHkYczZA0pdoA7dl6e7FL659nX9S2aw=="],
1690
1700
 
1691
- "@istanbuljs/load-nyc-config/camelcase": ["camelcase@5.3.1", "", {}, "sha512-L28STB170nwWS63UjtlEOE3dldQApaJXZkOI1uMFfzf3rRuPegHaHesyee+YxQ+W6SvRDQV6UrdOdRiR153wJg=="],
1692
-
1693
1701
  "@istanbuljs/load-nyc-config/find-up": ["find-up@4.1.0", "", { "dependencies": { "locate-path": "^5.0.0", "path-exists": "^4.0.0" } }, "sha512-PpOwAdQ/YlXQ2vj8a3h8IipDuYRi3wceVQQGYWxNINccq40Anw7BlsEXCMbt1Zt+OLA6Fq9suIpIWD0OsnISlw=="],
1694
1702
 
1695
1703
  "@istanbuljs/load-nyc-config/js-yaml": ["js-yaml@3.14.2", "", { "dependencies": { "argparse": "^1.0.7", "esprima": "^4.0.0" }, "bin": { "js-yaml": "bin/js-yaml.js" } }, "sha512-PMSmkqxr106Xa156c2M265Z+FTrPl+oxd/rgOQy2tijQeK5TxQ43psO1ZCwhVOSdnn+RzkzlRz/eY4BgJBYVpg=="],
@@ -1750,6 +1758,8 @@
1750
1758
 
1751
1759
  "@unrs/resolver-binding-wasm32-wasi/@napi-rs/wasm-runtime": ["@napi-rs/wasm-runtime@0.2.12", "", { "dependencies": { "@emnapi/core": "^1.4.3", "@emnapi/runtime": "^1.4.3", "@tybys/wasm-util": "^0.10.0" } }, "sha512-ZVWUcfwY4E/yPitQJl481FjFo3K22D6qF0DuFH6Y/nbnE11GY5uguDxZMGXPQ8WQ0128MXQD7TnfHyK4oWoIJQ=="],
1752
1760
 
1761
+ "anymatch/picomatch": ["picomatch@2.3.1", "", {}, "sha512-JU3teHTNjmE2VCGFzuY8EXzCDVwEqB2a8fsIvwaStHhAWJEeVd1o1QD80CU6+ZdEXXSLbSsuLwJjkCBWqRQUVA=="],
1762
+
1753
1763
  "babel-jest/chalk": ["chalk@4.1.2", "", { "dependencies": { "ansi-styles": "^4.1.0", "supports-color": "^7.1.0" } }, "sha512-oKnbhFyRIXpUuez8iBMmyEa4nbj4IOQyuhc/wy9kY7/WVPcwIO9VA668Pu8RkO7+0G76SLROeyw9CpQ061i4mA=="],
1754
1764
 
1755
1765
  "babel-jest/slash": ["slash@3.0.0", "", {}, "sha512-g9Q1haeby36OSStwb4ntCGGGaKsaVSjQ68fBxoQcutl5fS1vuY18H3wSt3jFyFtrkx+Kz0V1G85A4MyAdDMi2Q=="],
@@ -1836,14 +1846,10 @@
1836
1846
 
1837
1847
  "jest-each/chalk": ["chalk@4.1.2", "", { "dependencies": { "ansi-styles": "^4.1.0", "supports-color": "^7.1.0" } }, "sha512-oKnbhFyRIXpUuez8iBMmyEa4nbj4IOQyuhc/wy9kY7/WVPcwIO9VA668Pu8RkO7+0G76SLROeyw9CpQ061i4mA=="],
1838
1848
 
1839
- "jest-haste-map/picomatch": ["picomatch@4.0.3", "", {}, "sha512-5gTmgEY/sqK6gFXLIsQNH19lWb4ebPDLA4SdLP7dsWkIXHWlG66oPuVvXSGFPppYZz8ZDZq0dYYrbHfBCVUb1Q=="],
1840
-
1841
1849
  "jest-matcher-utils/chalk": ["chalk@4.1.2", "", { "dependencies": { "ansi-styles": "^4.1.0", "supports-color": "^7.1.0" } }, "sha512-oKnbhFyRIXpUuez8iBMmyEa4nbj4IOQyuhc/wy9kY7/WVPcwIO9VA668Pu8RkO7+0G76SLROeyw9CpQ061i4mA=="],
1842
1850
 
1843
1851
  "jest-message-util/chalk": ["chalk@4.1.2", "", { "dependencies": { "ansi-styles": "^4.1.0", "supports-color": "^7.1.0" } }, "sha512-oKnbhFyRIXpUuez8iBMmyEa4nbj4IOQyuhc/wy9kY7/WVPcwIO9VA668Pu8RkO7+0G76SLROeyw9CpQ061i4mA=="],
1844
1852
 
1845
- "jest-message-util/picomatch": ["picomatch@4.0.3", "", {}, "sha512-5gTmgEY/sqK6gFXLIsQNH19lWb4ebPDLA4SdLP7dsWkIXHWlG66oPuVvXSGFPppYZz8ZDZq0dYYrbHfBCVUb1Q=="],
1846
-
1847
1853
  "jest-message-util/slash": ["slash@3.0.0", "", {}, "sha512-g9Q1haeby36OSStwb4ntCGGGaKsaVSjQ68fBxoQcutl5fS1vuY18H3wSt3jFyFtrkx+Kz0V1G85A4MyAdDMi2Q=="],
1848
1854
 
1849
1855
  "jest-resolve/chalk": ["chalk@4.1.2", "", { "dependencies": { "ansi-styles": "^4.1.0", "supports-color": "^7.1.0" } }, "sha512-oKnbhFyRIXpUuez8iBMmyEa4nbj4IOQyuhc/wy9kY7/WVPcwIO9VA668Pu8RkO7+0G76SLROeyw9CpQ061i4mA=="],
@@ -1866,7 +1872,7 @@
1866
1872
 
1867
1873
  "jest-util/chalk": ["chalk@4.1.2", "", { "dependencies": { "ansi-styles": "^4.1.0", "supports-color": "^7.1.0" } }, "sha512-oKnbhFyRIXpUuez8iBMmyEa4nbj4IOQyuhc/wy9kY7/WVPcwIO9VA668Pu8RkO7+0G76SLROeyw9CpQ061i4mA=="],
1868
1874
 
1869
- "jest-util/picomatch": ["picomatch@4.0.3", "", {}, "sha512-5gTmgEY/sqK6gFXLIsQNH19lWb4ebPDLA4SdLP7dsWkIXHWlG66oPuVvXSGFPppYZz8ZDZq0dYYrbHfBCVUb1Q=="],
1875
+ "jest-validate/camelcase": ["camelcase@6.3.0", "", {}, "sha512-Gmy6FhYlCY7uOElZUSbxo2UCDH8owEk996gkbrpsgGtrJLM3J7jGxl9Ic7Qwwj4ivOE5AWZWRMecDdF7hqGjFA=="],
1870
1876
 
1871
1877
  "jest-validate/chalk": ["chalk@4.1.2", "", { "dependencies": { "ansi-styles": "^4.1.0", "supports-color": "^7.1.0" } }, "sha512-oKnbhFyRIXpUuez8iBMmyEa4nbj4IOQyuhc/wy9kY7/WVPcwIO9VA668Pu8RkO7+0G76SLROeyw9CpQ061i4mA=="],
1872
1878
 
@@ -1884,6 +1890,8 @@
1884
1890
 
1885
1891
  "make-dir/pify": ["pify@3.0.0", "", {}, "sha512-C3FsVNH1udSEX48gGX1xfvwTWfsYWj5U+8/uK15BGzIGrKoUpghX8hWZwa/OFnakBiiVNmBvemTJR5mcy7iPcg=="],
1886
1892
 
1893
+ "micromatch/picomatch": ["picomatch@2.3.1", "", {}, "sha512-JU3teHTNjmE2VCGFzuY8EXzCDVwEqB2a8fsIvwaStHhAWJEeVd1o1QD80CU6+ZdEXXSLbSsuLwJjkCBWqRQUVA=="],
1894
+
1887
1895
  "minizlib/minipass": ["minipass@7.1.3", "", {}, "sha512-tEBHqDnIoM/1rXME1zgka9g6Q2lcoCkxHLuc7ODJ5BxbP5d4c2Z5cGgtXAku59200Cx7diuHTOYfSBD8n6mm8A=="],
1888
1896
 
1889
1897
  "normalize-package-data/semver": ["semver@5.7.2", "", { "bin": { "semver": "bin/semver" } }, "sha512-cBznnQ9KjJqU67B52RMC65CMarK2600WFnbkcaiwWq3xy/5haFJlshgnpjovMVJ+Hff49d8GEn0b87C5pDQ10g=="],
@@ -1902,12 +1910,16 @@
1902
1910
 
1903
1911
  "pretty-format/ansi-styles": ["ansi-styles@5.2.0", "", {}, "sha512-Cxwpt2SfTzTtXcfOlzGEee8O+c+MmUgGrNiBcXnuWxuFJHe6a5Hz7qwhwe5OgaSYI0IJvkLqWX1ASG+cJOkEiA=="],
1904
1912
 
1913
+ "proper-lockfile/signal-exit": ["signal-exit@3.0.7", "", {}, "sha512-wnD2ZE+l+SPC/uoS0vXeE9L1+0wuaMqKlfz9AMUo38JsyLSBWSFcHR1Rri62LZc12vLr1gb3jl7iwQhgwpAbGQ=="],
1914
+
1905
1915
  "read-pkg/path-type": ["path-type@3.0.0", "", { "dependencies": { "pify": "^3.0.0" } }, "sha512-T2ZUsdZFHgA3u4e5PfPbjd7HDDpxPnQb5jN0SrDsjNSuVXHJqtwTnWqG0B1jZrgmJ/7lj1EmVIByWt1gxGkWvg=="],
1906
1916
 
1907
1917
  "readable-stream/isarray": ["isarray@1.0.0", "", {}, "sha512-VLghIWNM6ELQzo7zwmcg0NmTVyWKYjvIeM83yjp0wRDTmUnrM678fQbcKBo6n2CJEF0szoG//ytg+TKla89ALQ=="],
1908
1918
 
1909
1919
  "readable-stream/safe-buffer": ["safe-buffer@5.1.2", "", {}, "sha512-Gd2UZBJDkXlY7GbJxfsE8/nvKkUEU1G38c1siN6QP6a9PT9MmHB8GnpscSmMJSoF8LOIrt8ud/wPtojys4G6+g=="],
1910
1920
 
1921
+ "readdirp/picomatch": ["picomatch@2.3.1", "", {}, "sha512-JU3teHTNjmE2VCGFzuY8EXzCDVwEqB2a8fsIvwaStHhAWJEeVd1o1QD80CU6+ZdEXXSLbSsuLwJjkCBWqRQUVA=="],
1922
+
1911
1923
  "resolve-cwd/resolve-from": ["resolve-from@5.0.0", "", {}, "sha512-qYg9KP24dD5qka9J47d0aVky0N+b4fTU89LN9iDnjB5waksiC49rvMB0PrUJQGoTmH50XPiqOvAjDfaijGxYZw=="],
1912
1924
 
1913
1925
  "rimraf/glob": ["glob@7.2.3", "", { "dependencies": { "fs.realpath": "^1.0.0", "inflight": "^1.0.4", "inherits": "2", "minimatch": "^3.1.1", "once": "^1.3.0", "path-is-absolute": "^1.0.0" } }, "sha512-nFR0zLpU2YCaRxwoCJvL6UvCH2JFyFVIvwTLsIf21AuHlMskA1hhTdk+LlYJtOlYt9v6dvszD2BGRqBL+iQK9Q=="],
package/bundle/cli.tgz CHANGED
Binary file
package/cache.ts CHANGED
@@ -17,6 +17,75 @@ let getGlobalCacheDir = () => {
17
17
  return path.join(globalCacheDir, network === "ic" ? "" : network);
18
18
  };
19
19
 
20
+ // Cache writes stage into a sibling `<dest>/../.staging-<rand>` and atomic-
21
+ // rename onto `dest` so concurrent processes never observe a partial cache.
22
+ const STAGING_PREFIX = ".staging-";
23
+
24
+ export function createStagingDir(dest: string): string {
25
+ let parent = path.dirname(dest);
26
+ fs.mkdirSync(parent, { recursive: true });
27
+ return fs.mkdtempSync(path.join(parent, STAGING_PREFIX));
28
+ }
29
+
30
+ // Returns false if another process committed first (race lost) — `staging`
31
+ // is removed and the existing `dest` is left intact. We only swallow
32
+ // `EPERM` (Windows) when `dest` exists; otherwise it's likely AV / open
33
+ // handles and bubbles up.
34
+ export function commitStagingDir(staging: string, dest: string): boolean {
35
+ try {
36
+ fs.renameSync(staging, dest);
37
+ return true;
38
+ } catch (err: any) {
39
+ let raceLost =
40
+ (err.code === "ENOTEMPTY" ||
41
+ err.code === "EEXIST" ||
42
+ err.code === "EPERM") &&
43
+ fs.existsSync(dest);
44
+ if (raceLost) {
45
+ fs.rmSync(staging, { recursive: true, force: true });
46
+ return false;
47
+ }
48
+ throw err;
49
+ }
50
+ }
51
+
52
+ // Sweep leftover `.staging-*` from interrupted runs. Mtime cutoff avoids
53
+ // clobbering siblings that are mid-staging right now. Runs at most once
54
+ // per process.
55
+ const STAGING_STALE_MS = 60 * 60 * 1000;
56
+ let swept = false;
57
+ export function sweepStaleStagingDirs() {
58
+ if (swept) {
59
+ return;
60
+ }
61
+ swept = true;
62
+ let cutoff = Date.now() - STAGING_STALE_MS;
63
+ let parents = [
64
+ path.join(getGlobalCacheDir(), "packages"),
65
+ path.join(getGlobalCacheDir(), "packages", "_github"),
66
+ path.join(getRootDir(), ".mops"),
67
+ path.join(getRootDir(), ".mops", "_github"),
68
+ ];
69
+ for (let parent of parents) {
70
+ if (!fs.existsSync(parent)) {
71
+ continue;
72
+ }
73
+ for (let entry of fs.readdirSync(parent)) {
74
+ if (!entry.startsWith(STAGING_PREFIX)) {
75
+ continue;
76
+ }
77
+ let full = path.join(parent, entry);
78
+ try {
79
+ if (fs.statSync(full).mtimeMs < cutoff) {
80
+ fs.rmSync(full, { recursive: true, force: true });
81
+ }
82
+ } catch {
83
+ // raced with another sweeper; ignore
84
+ }
85
+ }
86
+ }
87
+ }
88
+
20
89
  export let show = () => {
21
90
  return getGlobalCacheDir();
22
91
  };
@@ -49,32 +118,44 @@ export function getGithubDepCacheName(name: string, repo: string) {
49
118
  );
50
119
  }
51
120
 
52
- export let addCache = (cacheName: string, source: string) => {
121
+ export let addCache = async (cacheName: string, source: string) => {
53
122
  let dest = path.join(getGlobalCacheDir(), "packages", cacheName);
54
- fs.mkdirSync(dest, { recursive: true });
55
-
56
- return new Promise<void>((resolve, reject) => {
57
- ncp.ncp(source, dest, { stopOnErr: true }, (err) => {
58
- if (err) {
59
- reject(err);
60
- }
61
- resolve();
123
+ let staging = createStagingDir(dest);
124
+
125
+ try {
126
+ await new Promise<void>((resolve, reject) => {
127
+ ncp.ncp(source, staging, { stopOnErr: true }, (err) => {
128
+ if (err) {
129
+ reject(err);
130
+ }
131
+ resolve();
132
+ });
62
133
  });
63
- });
134
+ commitStagingDir(staging, dest);
135
+ } catch (err) {
136
+ fs.rmSync(staging, { recursive: true, force: true });
137
+ throw err;
138
+ }
64
139
  };
65
140
 
66
- export let copyCache = (cacheName: string, dest: string) => {
141
+ export let copyCache = async (cacheName: string, dest: string) => {
67
142
  let source = path.join(getGlobalCacheDir(), "packages", cacheName);
68
- fs.mkdirSync(dest, { recursive: true });
69
-
70
- return new Promise<void>((resolve, reject) => {
71
- ncp.ncp(source, dest, { stopOnErr: true }, (err) => {
72
- if (err) {
73
- reject(err);
74
- }
75
- resolve();
143
+ let staging = createStagingDir(dest);
144
+
145
+ try {
146
+ await new Promise<void>((resolve, reject) => {
147
+ ncp.ncp(source, staging, { stopOnErr: true }, (err) => {
148
+ if (err) {
149
+ reject(err);
150
+ }
151
+ resolve();
152
+ });
76
153
  });
77
- });
154
+ commitStagingDir(staging, dest);
155
+ } catch (err) {
156
+ fs.rmSync(staging, { recursive: true, force: true });
157
+ throw err;
158
+ }
78
159
  };
79
160
 
80
161
  export let cacheSize = async () => {
package/cli.ts CHANGED
@@ -413,7 +413,7 @@ program
413
413
  .addOption(
414
414
  new Option(
415
415
  "--replica <replica>",
416
- "Which replica to use to run tests in replica mode",
416
+ "Which replica to use to run tests in replica mode (`dfx` is deprecated; prefer `pocket-ic`)",
417
417
  ).choices(["dfx", "pocket-ic"]),
418
418
  )
419
419
  .option("-w, --watch", "Enable watch mode")
@@ -435,7 +435,7 @@ program
435
435
  .addOption(
436
436
  new Option(
437
437
  "--replica <replica>",
438
- "Which replica to use to run benchmarks",
438
+ "Which replica to use to run benchmarks (`dfx` is deprecated; prefer `pocket-ic`)",
439
439
  ).choices(["dfx", "pocket-ic"]),
440
440
  )
441
441
  .addOption(
@@ -626,11 +626,19 @@ program
626
626
  // outdated
627
627
  program
628
628
  .command("outdated")
629
- .description("Print outdated dependencies specified in mops.toml")
629
+ .description(
630
+ "Print outdated dependencies in mops.toml within the caret bound (does not cross major versions, or pre-1.0 minor versions)",
631
+ )
630
632
  .addOption(
631
633
  new Option(
632
634
  "--major",
633
635
  "Allow updates that cross the caret bound (major versions, or for 0.x.y packages, minor versions)",
636
+ ).conflicts("patch"),
637
+ )
638
+ .addOption(
639
+ new Option(
640
+ "--patch",
641
+ "Restrict updates to patch versions only (e.g. 1.2.3 -> 1.2.4, never 1.2.3 -> 1.3.0)",
634
642
  ),
635
643
  )
636
644
  .action(async (options) => {
@@ -640,11 +648,19 @@ program
640
648
  // update
641
649
  program
642
650
  .command("update [pkg]")
643
- .description("Update dependencies specified in mops.toml")
651
+ .description(
652
+ "Update dependencies in mops.toml to the highest semver-compatible version within the caret bound (does not cross major versions, or pre-1.0 minor versions)",
653
+ )
644
654
  .addOption(
645
655
  new Option(
646
656
  "--major",
647
657
  "Allow updates that cross the caret bound (major versions, or for 0.x.y packages, minor versions)",
658
+ ).conflicts("patch"),
659
+ )
660
+ .addOption(
661
+ new Option(
662
+ "--patch",
663
+ "Restrict updates to patch versions only (e.g. 1.2.3 -> 1.2.4, never 1.2.3 -> 1.3.0)",
648
664
  ),
649
665
  )
650
666
  .addOption(
@@ -658,9 +674,11 @@ program
658
674
  });
659
675
 
660
676
  // toolchain
661
- const toolchainCommand = new Command("toolchain").description(
662
- "Toolchain management",
663
- );
677
+ const toolchainCommand = new Command("toolchain")
678
+ .description(
679
+ `Toolchain management for ${TOOLCHAINS.map((s) => `"${s}"`).join(", ")}`,
680
+ )
681
+ .showHelpAfterError();
664
682
 
665
683
  toolchainCommand
666
684
  .command("init")
@@ -679,8 +697,13 @@ toolchainCommand
679
697
  toolchainCommand
680
698
  .command("use")
681
699
  .description("Install specified tool version and update mops.toml")
682
- .addArgument(new Argument("<tool>").choices(TOOLCHAINS))
683
- .addArgument(new Argument("[version]"))
700
+ .addArgument(new Argument("<tool>", "tool to install").choices(TOOLCHAINS))
701
+ .addArgument(
702
+ new Argument(
703
+ "[version]",
704
+ "version to install (defaults to interactive picker)",
705
+ ),
706
+ )
684
707
  .action(async (tool, version) => {
685
708
  if (!checkConfigFile()) {
686
709
  process.exit(1);
@@ -693,7 +716,12 @@ toolchainCommand
693
716
  .description(
694
717
  "Update specified tool or all tools to the latest version and update mops.toml",
695
718
  )
696
- .addArgument(new Argument("[tool]").choices(TOOLCHAINS))
719
+ .addArgument(
720
+ new Argument(
721
+ "[tool]",
722
+ "tool to update (defaults to all configured tools)",
723
+ ).choices(TOOLCHAINS),
724
+ )
697
725
  .action(async (tool?: Tool) => {
698
726
  if (!checkConfigFile()) {
699
727
  process.exit(1);
@@ -703,10 +731,8 @@ toolchainCommand
703
731
 
704
732
  toolchainCommand
705
733
  .command("bin")
706
- .description(
707
- `Get path to the tool binary\n<tool> can be one of ${TOOLCHAINS.map((s) => `"${s}"`).join(", ")}`,
708
- )
709
- .addArgument(new Argument("<tool>").choices(TOOLCHAINS))
734
+ .description("Get path to the tool binary")
735
+ .addArgument(new Argument("<tool>", "tool to look up").choices(TOOLCHAINS))
710
736
  .addOption(
711
737
  new Option(
712
738
  "--fallback",
@@ -6,7 +6,7 @@ import { Config } from "../types.js";
6
6
  import { getDepName, getDepPinnedVersion } from "../helpers/get-dep-name.js";
7
7
  import { SemverPart } from "../declarations/main/main.did.js";
8
8
 
9
- export type UpdateBound = "caret" | "major";
9
+ export type UpdateBound = "patch" | "caret" | "major";
10
10
 
11
11
  // [pkg, oldVersion, newVersion]
12
12
  export async function getAvailableUpdates(
@@ -45,7 +45,9 @@ export async function getAvailableUpdates(
45
45
  let semverPart: SemverPart = { major: null };
46
46
  let name = getDepName(dep.name);
47
47
  let pinnedVersion = getDepPinnedVersion(dep.name);
48
- if (pinnedVersion) {
48
+ if (bound === "patch") {
49
+ semverPart = { patch: null };
50
+ } else if (pinnedVersion) {
49
51
  semverPart =
50
52
  pinnedVersion.split(".").length === 1
51
53
  ? { minor: null }
package/commands/bench.ts CHANGED
@@ -22,6 +22,7 @@ import { parallel } from "../parallel.js";
22
22
  import { absToRel } from "./test/utils.js";
23
23
  import { getMocVersion } from "../helpers/get-moc-version.js";
24
24
  import { getDfxVersion } from "../helpers/get-dfx-version.js";
25
+ import { warnIfDfxReplica } from "../helpers/deprecate-dfx-replica.js";
25
26
  import { getMocPath } from "../helpers/get-moc-path.js";
26
27
  import { sources } from "./sources.js";
27
28
  import { MOTOKO_GLOB_CONFIG } from "../constants.js";
@@ -98,6 +99,8 @@ export async function bench(
98
99
  options.replicaVersion = config.toolchain?.["pocket-ic"] || "";
99
100
  }
100
101
 
102
+ warnIfDfxReplica(replicaType, optionsArg.replica === "dfx");
103
+
101
104
  options.verbose && console.log(options);
102
105
 
103
106
  let replica = new BenchReplica(replicaType, options.verbose);
package/commands/check.ts CHANGED
@@ -9,6 +9,7 @@ import {
9
9
  resolveConfigPath,
10
10
  } from "../mops.js";
11
11
  import { AutofixResult, autofixMotoko } from "../helpers/autofix-motoko.js";
12
+ import { withFixLock } from "../helpers/fix-lock.js";
12
13
  import { getMocSemVer } from "../helpers/get-moc-version.js";
13
14
  import {
14
15
  filterCanisters,
@@ -82,6 +83,16 @@ function logAutofixResult(
82
83
  export async function check(
83
84
  args: string[],
84
85
  options: Partial<CheckOptions> = {},
86
+ ): Promise<void> {
87
+ if (options.fix) {
88
+ return withFixLock(() => checkImpl(args, options));
89
+ }
90
+ return checkImpl(args, options);
91
+ }
92
+
93
+ async function checkImpl(
94
+ args: string[],
95
+ options: Partial<CheckOptions> = {},
85
96
  ): Promise<void> {
86
97
  const config = readConfig();
87
98
  const canisters = resolveCanisterConfigs(config);
@@ -251,30 +262,30 @@ async function checkFiles(
251
262
  logAutofixResult(fixResult, options.verbose);
252
263
  }
253
264
 
254
- for (const file of files) {
255
- try {
256
- const args = [file, ...mocArgs];
257
- if (options.verbose) {
258
- console.log(chalk.blue("check"), chalk.gray("Running moc:"));
259
- console.log(chalk.gray(mocPath, JSON.stringify(args)));
260
- }
261
-
262
- const result = await execa(mocPath, args, {
263
- stdio: "inherit",
264
- reject: false,
265
- });
265
+ // Check all files in a single moc invocation so shared transitive imports
266
+ // are chased and type-checked once, not re-checked for every file.
267
+ const args = [...files, ...mocArgs];
268
+ if (options.verbose) {
269
+ console.log(chalk.blue("check"), chalk.gray("Running moc:"));
270
+ console.log(chalk.gray(mocPath, JSON.stringify(args)));
271
+ }
266
272
 
267
- if (result.exitCode !== 0) {
268
- cliError(
269
- `✗ Check failed for file ${file} (exit code: ${result.exitCode})`,
270
- );
271
- }
273
+ try {
274
+ const result = await execa(mocPath, args, {
275
+ stdio: "inherit",
276
+ reject: false,
277
+ });
272
278
 
273
- console.log(chalk.green(`✓ ${file}`));
274
- } catch (err: any) {
275
- cliError(
276
- `Error while checking ${file}${err?.message ? `\n${err.message}` : ""}`,
277
- );
279
+ if (result.exitCode !== 0) {
280
+ cliError(`✗ Check failed (exit code: ${result.exitCode})`);
278
281
  }
282
+ } catch (err: any) {
283
+ cliError(
284
+ `Error while checking files${err?.message ? `\n${err.message}` : ""}`,
285
+ );
286
+ }
287
+
288
+ for (const file of files) {
289
+ console.log(chalk.green(`✓ ${file}`));
279
290
  }
280
291
  }
package/commands/init.ts CHANGED
@@ -25,6 +25,20 @@ export async function init({ yes = false } = {}) {
25
25
 
26
26
  let config: Config = {};
27
27
 
28
+ let vesselFile = path.join(process.cwd(), "vessel.dhall");
29
+ let vesselExists = existsSync(vesselFile);
30
+
31
+ // Warn before the --yes early-return so scripted/CI users get the heads-up
32
+ // even though `mops init --yes` skips the vessel migration entirely.
33
+ if (vesselExists) {
34
+ console.warn(
35
+ chalk.yellow(
36
+ "WARN: vessel.dhall auto-migration is deprecated and will be removed in mops v3. " +
37
+ "Before then, copy your dependencies into mops.toml manually and delete vessel.dhall / package-set.dhall.",
38
+ ),
39
+ );
40
+ }
41
+
28
42
  if (yes) {
29
43
  await applyInit({
30
44
  type: "project",
@@ -37,10 +51,9 @@ export async function init({ yes = false } = {}) {
37
51
  }
38
52
 
39
53
  // migrate from vessel
40
- let vesselFile = path.join(process.cwd(), "vessel.dhall");
41
54
  let vesselConfig: VesselConfig = { dependencies: [], "dev-dependencies": [] };
42
55
 
43
- if (existsSync(vesselFile)) {
56
+ if (vesselExists) {
44
57
  console.log("Reading vessel.dhall file");
45
58
  let res = await readVesselConfig(process.cwd(), { cache: false });
46
59
  if (res) {