ic-mops 2.13.2 → 2.14.0
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.
- package/CHANGELOG.md +19 -0
- package/bun.lock +24 -12
- package/bundle/cli.tgz +0 -0
- package/cache.ts +101 -20
- package/cli.ts +40 -14
- package/commands/available-updates.ts +4 -2
- package/commands/bench.ts +3 -0
- package/commands/check.ts +11 -0
- package/commands/init.ts +15 -2
- package/commands/install/install-mops-dep.ts +14 -9
- package/commands/install/sync-local-cache.ts +7 -1
- package/commands/lint.ts +11 -0
- package/commands/outdated.ts +5 -2
- package/commands/publish.ts +0 -1
- package/commands/test/test.ts +14 -0
- package/commands/update.ts +3 -2
- package/commands/watch/tester.ts +5 -1
- package/dist/cache.d.ts +3 -0
- package/dist/cache.js +98 -18
- package/dist/cli.js +16 -12
- package/dist/commands/available-updates.d.ts +1 -1
- package/dist/commands/available-updates.js +4 -1
- package/dist/commands/bench.js +2 -0
- package/dist/commands/check.js +7 -0
- package/dist/commands/init.js +9 -2
- package/dist/commands/install/install-mops-dep.js +12 -9
- package/dist/commands/install/sync-local-cache.js +2 -1
- package/dist/commands/lint.js +7 -0
- package/dist/commands/outdated.d.ts +2 -1
- package/dist/commands/outdated.js +2 -2
- package/dist/commands/publish.js +0 -1
- package/dist/commands/test/test.d.ts +1 -1
- package/dist/commands/test/test.js +10 -5
- package/dist/commands/update.d.ts +2 -1
- package/dist/commands/update.js +2 -2
- package/dist/commands/watch/tester.js +4 -1
- package/dist/helpers/autofix-motoko.d.ts +1 -1
- package/dist/helpers/autofix-motoko.js +3 -0
- package/dist/helpers/deprecate-dfx-replica.d.ts +2 -0
- package/dist/helpers/deprecate-dfx-replica.js +20 -0
- package/dist/helpers/fix-lock.d.ts +1 -0
- package/dist/helpers/fix-lock.js +93 -0
- package/dist/integrity.d.ts +2 -2
- package/dist/integrity.js +22 -6
- package/dist/mops.js +1 -1
- package/dist/package.json +3 -3
- package/dist/tests/check-fix.test.js +40 -0
- package/dist/tests/cli.test.js +136 -1
- package/dist/vessel.js +21 -13
- package/dist/wasm/pkg/nodejs/package.json +1 -1
- package/dist/wasm/pkg/nodejs/wasm_bg.wasm +0 -0
- package/dist/wasm/pkg/web/package.json +1 -1
- package/dist/wasm/pkg/web/wasm_bg.wasm +0 -0
- package/helpers/autofix-motoko.ts +4 -1
- package/helpers/deprecate-dfx-replica.ts +32 -0
- package/helpers/fix-lock.ts +101 -0
- package/integrity.ts +30 -9
- package/mops.ts +1 -1
- package/package.json +3 -3
- package/tests/check-fix.test.ts +46 -0
- package/tests/cli.test.ts +180 -1
- package/tests/install/update-bound-patch/mops.toml +2 -0
- package/vessel.ts +31 -14
- package/wasm/pkg/nodejs/package.json +1 -1
- package/wasm/pkg/nodejs/wasm_bg.wasm +0 -0
- package/wasm/pkg/web/package.json +1 -1
- package/wasm/pkg/web/wasm_bg.wasm +0 -0
package/commands/lint.ts
CHANGED
|
@@ -11,6 +11,7 @@ import {
|
|
|
11
11
|
readConfig,
|
|
12
12
|
} from "../mops.js";
|
|
13
13
|
import { resolvePackages } from "../resolve-packages.js";
|
|
14
|
+
import { withFixLock } from "../helpers/fix-lock.js";
|
|
14
15
|
import { toolchain } from "./toolchain/index.js";
|
|
15
16
|
import { MOTOKO_GLOB_CONFIG } from "../constants.js";
|
|
16
17
|
import { existsSync } from "node:fs";
|
|
@@ -174,6 +175,16 @@ async function runLintoko(
|
|
|
174
175
|
export async function lint(
|
|
175
176
|
filter: string | undefined,
|
|
176
177
|
options: Partial<LintOptions>,
|
|
178
|
+
): Promise<void> {
|
|
179
|
+
if (options.fix) {
|
|
180
|
+
return withFixLock(() => lintImpl(filter, options));
|
|
181
|
+
}
|
|
182
|
+
return lintImpl(filter, options);
|
|
183
|
+
}
|
|
184
|
+
|
|
185
|
+
async function lintImpl(
|
|
186
|
+
filter: string | undefined,
|
|
187
|
+
options: Partial<LintOptions>,
|
|
177
188
|
): Promise<void> {
|
|
178
189
|
let config = readConfig();
|
|
179
190
|
let rootDir = getRootDir();
|
package/commands/outdated.ts
CHANGED
|
@@ -3,7 +3,10 @@ import { checkConfigFile, readConfig } from "../mops.js";
|
|
|
3
3
|
import { getAvailableUpdates } from "./available-updates.js";
|
|
4
4
|
import { getDepName, getDepPinnedVersion } from "../helpers/get-dep-name.js";
|
|
5
5
|
|
|
6
|
-
export async function outdated({
|
|
6
|
+
export async function outdated({
|
|
7
|
+
major,
|
|
8
|
+
patch,
|
|
9
|
+
}: { major?: boolean; patch?: boolean } = {}) {
|
|
7
10
|
if (!checkConfigFile()) {
|
|
8
11
|
return;
|
|
9
12
|
}
|
|
@@ -12,7 +15,7 @@ export async function outdated({ major }: { major?: boolean } = {}) {
|
|
|
12
15
|
let available = await getAvailableUpdates(
|
|
13
16
|
config,
|
|
14
17
|
undefined,
|
|
15
|
-
major ? "major" : "caret",
|
|
18
|
+
major ? "major" : patch ? "patch" : "caret",
|
|
16
19
|
);
|
|
17
20
|
|
|
18
21
|
if (available.length === 0) {
|
package/commands/publish.ts
CHANGED
package/commands/test/test.ts
CHANGED
|
@@ -32,6 +32,7 @@ import { toolchain } from "../toolchain/index.js";
|
|
|
32
32
|
import { Replica } from "../replica.js";
|
|
33
33
|
import { TestMode } from "../../types.js";
|
|
34
34
|
import { getDfxVersion } from "../../helpers/get-dfx-version.js";
|
|
35
|
+
import { warnIfDfxReplica } from "../../helpers/deprecate-dfx-replica.js";
|
|
35
36
|
import { MOTOKO_GLOB_CONFIG, MOTOKO_IGNORE_PATTERNS } from "../../constants.js";
|
|
36
37
|
|
|
37
38
|
type ReporterName = "verbose" | "files" | "compact" | "silent";
|
|
@@ -79,6 +80,8 @@ export async function test(filter = "", options: Partial<TestOptions> = {}) {
|
|
|
79
80
|
}
|
|
80
81
|
}
|
|
81
82
|
|
|
83
|
+
let explicitReplica = options.replica === "dfx";
|
|
84
|
+
|
|
82
85
|
replica.type = replicaType;
|
|
83
86
|
replica.verbose = !!options.verbose;
|
|
84
87
|
|
|
@@ -124,6 +127,7 @@ export async function test(filter = "", options: Partial<TestOptions> = {}) {
|
|
|
124
127
|
replicaType,
|
|
125
128
|
true,
|
|
126
129
|
controller.signal,
|
|
130
|
+
explicitReplica,
|
|
127
131
|
);
|
|
128
132
|
await curRun;
|
|
129
133
|
|
|
@@ -150,6 +154,9 @@ export async function test(filter = "", options: Partial<TestOptions> = {}) {
|
|
|
150
154
|
filter,
|
|
151
155
|
options.mode,
|
|
152
156
|
replicaType,
|
|
157
|
+
false,
|
|
158
|
+
undefined,
|
|
159
|
+
explicitReplica,
|
|
153
160
|
);
|
|
154
161
|
if (!passed) {
|
|
155
162
|
process.exit(1);
|
|
@@ -167,6 +174,7 @@ async function runAll(
|
|
|
167
174
|
replicaType: ReplicaName,
|
|
168
175
|
watch = false,
|
|
169
176
|
signal?: AbortSignal,
|
|
177
|
+
explicitReplica = false,
|
|
170
178
|
): Promise<boolean> {
|
|
171
179
|
let done = await testWithReporter(
|
|
172
180
|
reporterName,
|
|
@@ -175,6 +183,7 @@ async function runAll(
|
|
|
175
183
|
replicaType,
|
|
176
184
|
watch,
|
|
177
185
|
signal,
|
|
186
|
+
explicitReplica,
|
|
178
187
|
);
|
|
179
188
|
return done;
|
|
180
189
|
}
|
|
@@ -186,6 +195,7 @@ export async function testWithReporter(
|
|
|
186
195
|
replicaType: ReplicaName,
|
|
187
196
|
watch = false,
|
|
188
197
|
signal?: AbortSignal,
|
|
198
|
+
explicitReplica = false,
|
|
189
199
|
): Promise<boolean> {
|
|
190
200
|
let rootDir = getRootDir();
|
|
191
201
|
let files: string[] = [];
|
|
@@ -261,6 +271,10 @@ export async function testWithReporter(
|
|
|
261
271
|
let hasWasiTests = filesWithMode.some(({ mode }) => mode === "wasi");
|
|
262
272
|
let hasReplicaTests = filesWithMode.some(({ mode }) => mode === "replica");
|
|
263
273
|
|
|
274
|
+
if (hasReplicaTests) {
|
|
275
|
+
warnIfDfxReplica(replicaType, explicitReplica);
|
|
276
|
+
}
|
|
277
|
+
|
|
264
278
|
// prepare wasmtime path
|
|
265
279
|
if (hasWasiTests && !wasmtimePath) {
|
|
266
280
|
// ensure wasmtime is installed or specified in config
|
package/commands/update.ts
CHANGED
|
@@ -15,11 +15,12 @@ type UpdateOptions = {
|
|
|
15
15
|
dev?: boolean;
|
|
16
16
|
lock?: "update" | "ignore";
|
|
17
17
|
major?: boolean;
|
|
18
|
+
patch?: boolean;
|
|
18
19
|
};
|
|
19
20
|
|
|
20
21
|
export async function update(
|
|
21
22
|
pkg?: string,
|
|
22
|
-
{ lock, major }: UpdateOptions = {},
|
|
23
|
+
{ lock, major, patch }: UpdateOptions = {},
|
|
23
24
|
) {
|
|
24
25
|
if (!checkConfigFile()) {
|
|
25
26
|
return;
|
|
@@ -66,7 +67,7 @@ export async function update(
|
|
|
66
67
|
let available = await getAvailableUpdates(
|
|
67
68
|
config,
|
|
68
69
|
pkg,
|
|
69
|
-
major ? "major" : "caret",
|
|
70
|
+
major ? "major" : patch ? "patch" : "caret",
|
|
70
71
|
);
|
|
71
72
|
|
|
72
73
|
if (available.length === 0) {
|
package/commands/watch/tester.ts
CHANGED
|
@@ -3,6 +3,7 @@ import { readConfig } from "../../mops.js";
|
|
|
3
3
|
import { ErrorChecker } from "./error-checker.js";
|
|
4
4
|
import { testWithReporter } from "../test/test.js";
|
|
5
5
|
import { SilentReporter } from "../test/reporters/silent-reporter.js";
|
|
6
|
+
import { type ReplicaName } from "../../helpers/deprecate-dfx-replica.js";
|
|
6
7
|
|
|
7
8
|
export class Tester {
|
|
8
9
|
verbose = false;
|
|
@@ -53,12 +54,15 @@ export class Tester {
|
|
|
53
54
|
this.controller = new AbortController();
|
|
54
55
|
|
|
55
56
|
let config = readConfig();
|
|
57
|
+
let replicaType: ReplicaName = config.toolchain?.["pocket-ic"]
|
|
58
|
+
? "pocket-ic"
|
|
59
|
+
: "dfx";
|
|
56
60
|
|
|
57
61
|
this.currentRun = testWithReporter(
|
|
58
62
|
this.reporter,
|
|
59
63
|
"",
|
|
60
64
|
"interpreter",
|
|
61
|
-
|
|
65
|
+
replicaType,
|
|
62
66
|
true,
|
|
63
67
|
this.controller.signal,
|
|
64
68
|
);
|
package/dist/cache.d.ts
CHANGED
|
@@ -1,3 +1,6 @@
|
|
|
1
|
+
export declare function createStagingDir(dest: string): string;
|
|
2
|
+
export declare function commitStagingDir(staging: string, dest: string): boolean;
|
|
3
|
+
export declare function sweepStaleStagingDirs(): void;
|
|
1
4
|
export declare let show: () => string;
|
|
2
5
|
export declare let getDepCacheDir: (cacheName: string) => string;
|
|
3
6
|
export declare let isDepCached: (cacheName: string) => boolean;
|
package/dist/cache.js
CHANGED
|
@@ -8,6 +8,72 @@ let getGlobalCacheDir = () => {
|
|
|
8
8
|
let network = getNetwork();
|
|
9
9
|
return path.join(globalCacheDir, network === "ic" ? "" : network);
|
|
10
10
|
};
|
|
11
|
+
// Cache writes stage into a sibling `<dest>/../.staging-<rand>` and atomic-
|
|
12
|
+
// rename onto `dest` so concurrent processes never observe a partial cache.
|
|
13
|
+
const STAGING_PREFIX = ".staging-";
|
|
14
|
+
export function createStagingDir(dest) {
|
|
15
|
+
let parent = path.dirname(dest);
|
|
16
|
+
fs.mkdirSync(parent, { recursive: true });
|
|
17
|
+
return fs.mkdtempSync(path.join(parent, STAGING_PREFIX));
|
|
18
|
+
}
|
|
19
|
+
// Returns false if another process committed first (race lost) — `staging`
|
|
20
|
+
// is removed and the existing `dest` is left intact. We only swallow
|
|
21
|
+
// `EPERM` (Windows) when `dest` exists; otherwise it's likely AV / open
|
|
22
|
+
// handles and bubbles up.
|
|
23
|
+
export function commitStagingDir(staging, dest) {
|
|
24
|
+
try {
|
|
25
|
+
fs.renameSync(staging, dest);
|
|
26
|
+
return true;
|
|
27
|
+
}
|
|
28
|
+
catch (err) {
|
|
29
|
+
let raceLost = (err.code === "ENOTEMPTY" ||
|
|
30
|
+
err.code === "EEXIST" ||
|
|
31
|
+
err.code === "EPERM") &&
|
|
32
|
+
fs.existsSync(dest);
|
|
33
|
+
if (raceLost) {
|
|
34
|
+
fs.rmSync(staging, { recursive: true, force: true });
|
|
35
|
+
return false;
|
|
36
|
+
}
|
|
37
|
+
throw err;
|
|
38
|
+
}
|
|
39
|
+
}
|
|
40
|
+
// Sweep leftover `.staging-*` from interrupted runs. Mtime cutoff avoids
|
|
41
|
+
// clobbering siblings that are mid-staging right now. Runs at most once
|
|
42
|
+
// per process.
|
|
43
|
+
const STAGING_STALE_MS = 60 * 60 * 1000;
|
|
44
|
+
let swept = false;
|
|
45
|
+
export function sweepStaleStagingDirs() {
|
|
46
|
+
if (swept) {
|
|
47
|
+
return;
|
|
48
|
+
}
|
|
49
|
+
swept = true;
|
|
50
|
+
let cutoff = Date.now() - STAGING_STALE_MS;
|
|
51
|
+
let parents = [
|
|
52
|
+
path.join(getGlobalCacheDir(), "packages"),
|
|
53
|
+
path.join(getGlobalCacheDir(), "packages", "_github"),
|
|
54
|
+
path.join(getRootDir(), ".mops"),
|
|
55
|
+
path.join(getRootDir(), ".mops", "_github"),
|
|
56
|
+
];
|
|
57
|
+
for (let parent of parents) {
|
|
58
|
+
if (!fs.existsSync(parent)) {
|
|
59
|
+
continue;
|
|
60
|
+
}
|
|
61
|
+
for (let entry of fs.readdirSync(parent)) {
|
|
62
|
+
if (!entry.startsWith(STAGING_PREFIX)) {
|
|
63
|
+
continue;
|
|
64
|
+
}
|
|
65
|
+
let full = path.join(parent, entry);
|
|
66
|
+
try {
|
|
67
|
+
if (fs.statSync(full).mtimeMs < cutoff) {
|
|
68
|
+
fs.rmSync(full, { recursive: true, force: true });
|
|
69
|
+
}
|
|
70
|
+
}
|
|
71
|
+
catch {
|
|
72
|
+
// raced with another sweeper; ignore
|
|
73
|
+
}
|
|
74
|
+
}
|
|
75
|
+
}
|
|
76
|
+
}
|
|
11
77
|
export let show = () => {
|
|
12
78
|
return getGlobalCacheDir();
|
|
13
79
|
};
|
|
@@ -32,29 +98,43 @@ export function getGithubDepCacheName(name, repo) {
|
|
|
32
98
|
return (`_github/${name}#${branch.replaceAll("/", "___")}` +
|
|
33
99
|
(commitHash ? `@${commitHash}` : ""));
|
|
34
100
|
}
|
|
35
|
-
export let addCache = (cacheName, source) => {
|
|
101
|
+
export let addCache = async (cacheName, source) => {
|
|
36
102
|
let dest = path.join(getGlobalCacheDir(), "packages", cacheName);
|
|
37
|
-
|
|
38
|
-
|
|
39
|
-
|
|
40
|
-
|
|
41
|
-
|
|
42
|
-
|
|
43
|
-
|
|
103
|
+
let staging = createStagingDir(dest);
|
|
104
|
+
try {
|
|
105
|
+
await new Promise((resolve, reject) => {
|
|
106
|
+
ncp.ncp(source, staging, { stopOnErr: true }, (err) => {
|
|
107
|
+
if (err) {
|
|
108
|
+
reject(err);
|
|
109
|
+
}
|
|
110
|
+
resolve();
|
|
111
|
+
});
|
|
44
112
|
});
|
|
45
|
-
|
|
113
|
+
commitStagingDir(staging, dest);
|
|
114
|
+
}
|
|
115
|
+
catch (err) {
|
|
116
|
+
fs.rmSync(staging, { recursive: true, force: true });
|
|
117
|
+
throw err;
|
|
118
|
+
}
|
|
46
119
|
};
|
|
47
|
-
export let copyCache = (cacheName, dest) => {
|
|
120
|
+
export let copyCache = async (cacheName, dest) => {
|
|
48
121
|
let source = path.join(getGlobalCacheDir(), "packages", cacheName);
|
|
49
|
-
|
|
50
|
-
|
|
51
|
-
|
|
52
|
-
|
|
53
|
-
|
|
54
|
-
|
|
55
|
-
|
|
122
|
+
let staging = createStagingDir(dest);
|
|
123
|
+
try {
|
|
124
|
+
await new Promise((resolve, reject) => {
|
|
125
|
+
ncp.ncp(source, staging, { stopOnErr: true }, (err) => {
|
|
126
|
+
if (err) {
|
|
127
|
+
reject(err);
|
|
128
|
+
}
|
|
129
|
+
resolve();
|
|
130
|
+
});
|
|
56
131
|
});
|
|
57
|
-
|
|
132
|
+
commitStagingDir(staging, dest);
|
|
133
|
+
}
|
|
134
|
+
catch (err) {
|
|
135
|
+
fs.rmSync(staging, { recursive: true, force: true });
|
|
136
|
+
throw err;
|
|
137
|
+
}
|
|
58
138
|
};
|
|
59
139
|
export let cacheSize = async () => {
|
|
60
140
|
let dir = path.join(getGlobalCacheDir());
|
package/dist/cli.js
CHANGED
|
@@ -327,7 +327,7 @@ program
|
|
|
327
327
|
.addOption(new Option("--mode <mode>", "Test mode")
|
|
328
328
|
.choices(["interpreter", "wasi", "replica"])
|
|
329
329
|
.default("interpreter"))
|
|
330
|
-
.addOption(new Option("--replica <replica>", "Which replica to use to run tests in replica mode").choices(["dfx", "pocket-ic"]))
|
|
330
|
+
.addOption(new Option("--replica <replica>", "Which replica to use to run tests in replica mode (`dfx` is deprecated; prefer `pocket-ic`)").choices(["dfx", "pocket-ic"]))
|
|
331
331
|
.option("-w, --watch", "Enable watch mode")
|
|
332
332
|
.option("--verbose", "Verbose output")
|
|
333
333
|
.action(async (filter, options) => {
|
|
@@ -343,7 +343,7 @@ program
|
|
|
343
343
|
program
|
|
344
344
|
.command("bench [filter]")
|
|
345
345
|
.description("Run benchmarks")
|
|
346
|
-
.addOption(new Option("--replica <replica>", "Which replica to use to run benchmarks").choices(["dfx", "pocket-ic"]))
|
|
346
|
+
.addOption(new Option("--replica <replica>", "Which replica to use to run benchmarks (`dfx` is deprecated; prefer `pocket-ic`)").choices(["dfx", "pocket-ic"]))
|
|
347
347
|
.addOption(new Option("--gc <gc>", "Garbage collector")
|
|
348
348
|
.choices(["copying", "compacting", "generational", "incremental"])
|
|
349
349
|
.default("copying"))
|
|
@@ -491,16 +491,18 @@ program
|
|
|
491
491
|
// outdated
|
|
492
492
|
program
|
|
493
493
|
.command("outdated")
|
|
494
|
-
.description("Print outdated dependencies
|
|
495
|
-
.addOption(new Option("--major", "Allow updates that cross the caret bound (major versions, or for 0.x.y packages, minor versions)"))
|
|
494
|
+
.description("Print outdated dependencies in mops.toml within the caret bound (does not cross major versions, or pre-1.0 minor versions)")
|
|
495
|
+
.addOption(new Option("--major", "Allow updates that cross the caret bound (major versions, or for 0.x.y packages, minor versions)").conflicts("patch"))
|
|
496
|
+
.addOption(new Option("--patch", "Restrict updates to patch versions only (e.g. 1.2.3 -> 1.2.4, never 1.2.3 -> 1.3.0)"))
|
|
496
497
|
.action(async (options) => {
|
|
497
498
|
await outdated(options);
|
|
498
499
|
});
|
|
499
500
|
// update
|
|
500
501
|
program
|
|
501
502
|
.command("update [pkg]")
|
|
502
|
-
.description("Update dependencies
|
|
503
|
-
.addOption(new Option("--major", "Allow updates that cross the caret bound (major versions, or for 0.x.y packages, minor versions)"))
|
|
503
|
+
.description("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)")
|
|
504
|
+
.addOption(new Option("--major", "Allow updates that cross the caret bound (major versions, or for 0.x.y packages, minor versions)").conflicts("patch"))
|
|
505
|
+
.addOption(new Option("--patch", "Restrict updates to patch versions only (e.g. 1.2.3 -> 1.2.4, never 1.2.3 -> 1.3.0)"))
|
|
504
506
|
.addOption(new Option("--lock <action>", "Lockfile action").choices([
|
|
505
507
|
"update",
|
|
506
508
|
"ignore",
|
|
@@ -509,7 +511,9 @@ program
|
|
|
509
511
|
await update(pkg, options);
|
|
510
512
|
});
|
|
511
513
|
// toolchain
|
|
512
|
-
const toolchainCommand = new Command("toolchain")
|
|
514
|
+
const toolchainCommand = new Command("toolchain")
|
|
515
|
+
.description(`Toolchain management for ${TOOLCHAINS.map((s) => `"${s}"`).join(", ")}`)
|
|
516
|
+
.showHelpAfterError();
|
|
513
517
|
toolchainCommand
|
|
514
518
|
.command("init")
|
|
515
519
|
.description("One-time initialization of toolchain management")
|
|
@@ -525,8 +529,8 @@ toolchainCommand
|
|
|
525
529
|
toolchainCommand
|
|
526
530
|
.command("use")
|
|
527
531
|
.description("Install specified tool version and update mops.toml")
|
|
528
|
-
.addArgument(new Argument("<tool>").choices(TOOLCHAINS))
|
|
529
|
-
.addArgument(new Argument("[version]"))
|
|
532
|
+
.addArgument(new Argument("<tool>", "tool to install").choices(TOOLCHAINS))
|
|
533
|
+
.addArgument(new Argument("[version]", "version to install (defaults to interactive picker)"))
|
|
530
534
|
.action(async (tool, version) => {
|
|
531
535
|
if (!checkConfigFile()) {
|
|
532
536
|
process.exit(1);
|
|
@@ -536,7 +540,7 @@ toolchainCommand
|
|
|
536
540
|
toolchainCommand
|
|
537
541
|
.command("update")
|
|
538
542
|
.description("Update specified tool or all tools to the latest version and update mops.toml")
|
|
539
|
-
.addArgument(new Argument("[tool]").choices(TOOLCHAINS))
|
|
543
|
+
.addArgument(new Argument("[tool]", "tool to update (defaults to all configured tools)").choices(TOOLCHAINS))
|
|
540
544
|
.action(async (tool) => {
|
|
541
545
|
if (!checkConfigFile()) {
|
|
542
546
|
process.exit(1);
|
|
@@ -545,8 +549,8 @@ toolchainCommand
|
|
|
545
549
|
});
|
|
546
550
|
toolchainCommand
|
|
547
551
|
.command("bin")
|
|
548
|
-
.description(
|
|
549
|
-
.addArgument(new Argument("<tool>").choices(TOOLCHAINS))
|
|
552
|
+
.description("Get path to the tool binary")
|
|
553
|
+
.addArgument(new Argument("<tool>", "tool to look up").choices(TOOLCHAINS))
|
|
550
554
|
.addOption(new Option("--fallback", "Fallback to the moc that comes with dfx if moc is not specified in the [toolchain] section"))
|
|
551
555
|
.action(async (tool, options) => {
|
|
552
556
|
let bin = await toolchain.bin(tool, options);
|
|
@@ -1,3 +1,3 @@
|
|
|
1
1
|
import { Config } from "../types.js";
|
|
2
|
-
export type UpdateBound = "caret" | "major";
|
|
2
|
+
export type UpdateBound = "patch" | "caret" | "major";
|
|
3
3
|
export declare function getAvailableUpdates(config: Config, pkg?: string, bound?: UpdateBound): Promise<Array<[string, string, string]>>;
|
|
@@ -29,7 +29,10 @@ export async function getAvailableUpdates(config, pkg, bound = "caret") {
|
|
|
29
29
|
let semverPart = { major: null };
|
|
30
30
|
let name = getDepName(dep.name);
|
|
31
31
|
let pinnedVersion = getDepPinnedVersion(dep.name);
|
|
32
|
-
if (
|
|
32
|
+
if (bound === "patch") {
|
|
33
|
+
semverPart = { patch: null };
|
|
34
|
+
}
|
|
35
|
+
else if (pinnedVersion) {
|
|
33
36
|
semverPart =
|
|
34
37
|
pinnedVersion.split(".").length === 1
|
|
35
38
|
? { minor: null }
|
package/dist/commands/bench.js
CHANGED
|
@@ -16,6 +16,7 @@ import { parallel } from "../parallel.js";
|
|
|
16
16
|
import { absToRel } from "./test/utils.js";
|
|
17
17
|
import { getMocVersion } from "../helpers/get-moc-version.js";
|
|
18
18
|
import { getDfxVersion } from "../helpers/get-dfx-version.js";
|
|
19
|
+
import { warnIfDfxReplica } from "../helpers/deprecate-dfx-replica.js";
|
|
19
20
|
import { getMocPath } from "../helpers/get-moc-path.js";
|
|
20
21
|
import { sources } from "./sources.js";
|
|
21
22
|
import { MOTOKO_GLOB_CONFIG } from "../constants.js";
|
|
@@ -59,6 +60,7 @@ export async function bench(filter = "", optionsArg = {}) {
|
|
|
59
60
|
else if (replicaType == "pocket-ic") {
|
|
60
61
|
options.replicaVersion = config.toolchain?.["pocket-ic"] || "";
|
|
61
62
|
}
|
|
63
|
+
warnIfDfxReplica(replicaType, optionsArg.replica === "dfx");
|
|
62
64
|
options.verbose && console.log(options);
|
|
63
65
|
let replica = new BenchReplica(replicaType, options.verbose);
|
|
64
66
|
let rootDir = getRootDir();
|
package/dist/commands/check.js
CHANGED
|
@@ -4,6 +4,7 @@ import { execa } from "execa";
|
|
|
4
4
|
import { cliError } from "../error.js";
|
|
5
5
|
import { getGlobalMocArgs, getRootDir, readConfig, resolveConfigPath, } from "../mops.js";
|
|
6
6
|
import { autofixMotoko } from "../helpers/autofix-motoko.js";
|
|
7
|
+
import { withFixLock } from "../helpers/fix-lock.js";
|
|
7
8
|
import { getMocSemVer } from "../helpers/get-moc-version.js";
|
|
8
9
|
import { filterCanisters, looksLikeFile, resolveCanisterConfigs, validateCanisterArgs, } from "../helpers/resolve-canisters.js";
|
|
9
10
|
import { prepareMigrationArgs } from "../helpers/migrations.js";
|
|
@@ -42,6 +43,12 @@ function logAutofixResult(fixResult, verbose) {
|
|
|
42
43
|
}
|
|
43
44
|
}
|
|
44
45
|
export async function check(args, options = {}) {
|
|
46
|
+
if (options.fix) {
|
|
47
|
+
return withFixLock(() => checkImpl(args, options));
|
|
48
|
+
}
|
|
49
|
+
return checkImpl(args, options);
|
|
50
|
+
}
|
|
51
|
+
async function checkImpl(args, options = {}) {
|
|
45
52
|
const config = readConfig();
|
|
46
53
|
const canisters = resolveCanisterConfigs(config);
|
|
47
54
|
const hasCanisters = Object.keys(canisters).length > 0;
|
package/dist/commands/init.js
CHANGED
|
@@ -19,6 +19,14 @@ export async function init({ yes = false } = {}) {
|
|
|
19
19
|
}
|
|
20
20
|
console.log("Initializing...");
|
|
21
21
|
let config = {};
|
|
22
|
+
let vesselFile = path.join(process.cwd(), "vessel.dhall");
|
|
23
|
+
let vesselExists = existsSync(vesselFile);
|
|
24
|
+
// Warn before the --yes early-return so scripted/CI users get the heads-up
|
|
25
|
+
// even though `mops init --yes` skips the vessel migration entirely.
|
|
26
|
+
if (vesselExists) {
|
|
27
|
+
console.warn(chalk.yellow("WARN: vessel.dhall auto-migration is deprecated and will be removed in mops v3. " +
|
|
28
|
+
"Before then, copy your dependencies into mops.toml manually and delete vessel.dhall / package-set.dhall."));
|
|
29
|
+
}
|
|
22
30
|
if (yes) {
|
|
23
31
|
await applyInit({
|
|
24
32
|
type: "project",
|
|
@@ -30,9 +38,8 @@ export async function init({ yes = false } = {}) {
|
|
|
30
38
|
return;
|
|
31
39
|
}
|
|
32
40
|
// migrate from vessel
|
|
33
|
-
let vesselFile = path.join(process.cwd(), "vessel.dhall");
|
|
34
41
|
let vesselConfig = { dependencies: [], "dev-dependencies": [] };
|
|
35
|
-
if (
|
|
42
|
+
if (vesselExists) {
|
|
36
43
|
console.log("Reading vessel.dhall file");
|
|
37
44
|
let res = await readVesselConfig(process.cwd(), { cache: false });
|
|
38
45
|
if (res) {
|
|
@@ -4,12 +4,11 @@ import path from "node:path";
|
|
|
4
4
|
import { Buffer } from "node:buffer";
|
|
5
5
|
import { createLogUpdate } from "log-update";
|
|
6
6
|
import chalk from "chalk";
|
|
7
|
-
import { deleteSync } from "del";
|
|
8
7
|
import { checkConfigFile, progressBar, readConfig } from "../../mops.js";
|
|
9
8
|
import { getHighestVersion } from "../../api/getHighestVersion.js";
|
|
10
9
|
import { storageActor } from "../../api/actors.js";
|
|
11
10
|
import { parallel } from "../../parallel.js";
|
|
12
|
-
import { getDepCacheDir, getMopsDepCacheName, isDepCached, } from "../../cache.js";
|
|
11
|
+
import { commitStagingDir, createStagingDir, getDepCacheDir, getMopsDepCacheName, isDepCached, sweepStaleStagingDirs, } from "../../cache.js";
|
|
13
12
|
import { downloadFile, getPackageFilesInfo, } from "../../api/downloadPackageFiles.js";
|
|
14
13
|
import { installDeps } from "./install-deps.js";
|
|
15
14
|
import { getDepName } from "../../helpers/get-dep-name.js";
|
|
@@ -37,6 +36,7 @@ export async function installMopsDep(pkg, version = "", { verbose, silent, dep,
|
|
|
37
36
|
}
|
|
38
37
|
version = versionRes.ok;
|
|
39
38
|
}
|
|
39
|
+
sweepStaleStagingDirs();
|
|
40
40
|
let cacheName = getMopsDepCacheName(depName, version);
|
|
41
41
|
let cacheDir = getDepCacheDir(cacheName);
|
|
42
42
|
// global cache hit
|
|
@@ -60,24 +60,27 @@ export async function installMopsDep(pkg, version = "", { verbose, silent, dep,
|
|
|
60
60
|
filesData.set(path, data);
|
|
61
61
|
progress();
|
|
62
62
|
});
|
|
63
|
+
let stagingDir = createStagingDir(cacheDir);
|
|
63
64
|
let onSigInt = () => {
|
|
64
|
-
|
|
65
|
-
process.exit();
|
|
65
|
+
fs.rmSync(stagingDir, { recursive: true, force: true });
|
|
66
|
+
process.exit(130);
|
|
66
67
|
};
|
|
67
68
|
process.on("SIGINT", onSigInt);
|
|
68
|
-
// write files to global cache
|
|
69
69
|
try {
|
|
70
70
|
await Promise.all(Array.from(filesData.entries()).map(async ([filePath, data]) => {
|
|
71
|
-
await fs.promises.mkdir(path.join(
|
|
72
|
-
await fs.promises.writeFile(path.join(
|
|
71
|
+
await fs.promises.mkdir(path.join(stagingDir, path.dirname(filePath)), { recursive: true });
|
|
72
|
+
await fs.promises.writeFile(path.join(stagingDir, filePath), Buffer.from(data));
|
|
73
73
|
}));
|
|
74
|
+
commitStagingDir(stagingDir, cacheDir);
|
|
74
75
|
}
|
|
75
76
|
catch (err) {
|
|
76
77
|
console.error(chalk.red("Error: ") + err);
|
|
77
|
-
|
|
78
|
+
fs.rmSync(stagingDir, { recursive: true, force: true });
|
|
78
79
|
return false;
|
|
79
80
|
}
|
|
80
|
-
|
|
81
|
+
finally {
|
|
82
|
+
process.off("SIGINT", onSigInt);
|
|
83
|
+
}
|
|
81
84
|
}
|
|
82
85
|
catch (err) {
|
|
83
86
|
console.error(chalk.red("Error: ") + err);
|
|
@@ -1,9 +1,10 @@
|
|
|
1
1
|
import fs from "node:fs";
|
|
2
2
|
import path from "node:path";
|
|
3
|
-
import { copyCache, getDepCacheName } from "../../cache.js";
|
|
3
|
+
import { copyCache, getDepCacheName, sweepStaleStagingDirs, } from "../../cache.js";
|
|
4
4
|
import { getDependencyType, getRootDir } from "../../mops.js";
|
|
5
5
|
import { resolvePackages } from "../../resolve-packages.js";
|
|
6
6
|
export async function syncLocalCache({ verbose = false } = {}) {
|
|
7
|
+
sweepStaleStagingDirs();
|
|
7
8
|
let resolvedPackages = await resolvePackages();
|
|
8
9
|
let rootDir = getRootDir();
|
|
9
10
|
verbose && console.log("Syncing local cache...");
|
package/dist/commands/lint.js
CHANGED
|
@@ -5,6 +5,7 @@ import path from "node:path";
|
|
|
5
5
|
import { cliError } from "../error.js";
|
|
6
6
|
import { formatDir, formatGithubDir, getDependencyType, getRootDir, readConfig, } from "../mops.js";
|
|
7
7
|
import { resolvePackages } from "../resolve-packages.js";
|
|
8
|
+
import { withFixLock } from "../helpers/fix-lock.js";
|
|
8
9
|
import { toolchain } from "./toolchain/index.js";
|
|
9
10
|
import { MOTOKO_GLOB_CONFIG } from "../constants.js";
|
|
10
11
|
import { existsSync } from "node:fs";
|
|
@@ -109,6 +110,12 @@ async function runLintoko(lintokoBinPath, rootDir, args, options, label) {
|
|
|
109
110
|
}
|
|
110
111
|
}
|
|
111
112
|
export async function lint(filter, options) {
|
|
113
|
+
if (options.fix) {
|
|
114
|
+
return withFixLock(() => lintImpl(filter, options));
|
|
115
|
+
}
|
|
116
|
+
return lintImpl(filter, options);
|
|
117
|
+
}
|
|
118
|
+
async function lintImpl(filter, options) {
|
|
112
119
|
let config = readConfig();
|
|
113
120
|
let rootDir = getRootDir();
|
|
114
121
|
let lintokoBinPath = config.toolchain?.lintoko
|
|
@@ -2,12 +2,12 @@ import chalk from "chalk";
|
|
|
2
2
|
import { checkConfigFile, readConfig } from "../mops.js";
|
|
3
3
|
import { getAvailableUpdates } from "./available-updates.js";
|
|
4
4
|
import { getDepName, getDepPinnedVersion } from "../helpers/get-dep-name.js";
|
|
5
|
-
export async function outdated({ major } = {}) {
|
|
5
|
+
export async function outdated({ major, patch, } = {}) {
|
|
6
6
|
if (!checkConfigFile()) {
|
|
7
7
|
return;
|
|
8
8
|
}
|
|
9
9
|
let config = readConfig();
|
|
10
|
-
let available = await getAvailableUpdates(config, undefined, major ? "major" : "caret");
|
|
10
|
+
let available = await getAvailableUpdates(config, undefined, major ? "major" : patch ? "patch" : "caret");
|
|
11
11
|
if (available.length === 0) {
|
|
12
12
|
console.log(chalk.green("All dependencies are up to date!"));
|
|
13
13
|
}
|
package/dist/commands/publish.js
CHANGED
|
@@ -256,7 +256,6 @@ export async function publish(options = {}) {
|
|
|
256
256
|
console.log("Running benchmarks...");
|
|
257
257
|
try {
|
|
258
258
|
benchmarks = await bench("", {
|
|
259
|
-
replica: config.toolchain?.["pocket-ic"] ? "pocket-ic" : "dfx",
|
|
260
259
|
gc: "copying",
|
|
261
260
|
forceGc: true,
|
|
262
261
|
silent: true,
|
|
@@ -10,5 +10,5 @@ type TestOptions = {
|
|
|
10
10
|
verbose: boolean;
|
|
11
11
|
};
|
|
12
12
|
export declare function test(filter?: string, options?: Partial<TestOptions>): Promise<void>;
|
|
13
|
-
export declare function testWithReporter(reporterName: ReporterName | Reporter | undefined, filter: string | undefined, defaultMode: TestMode | undefined, replicaType: ReplicaName, watch?: boolean, signal?: AbortSignal): Promise<boolean>;
|
|
13
|
+
export declare function testWithReporter(reporterName: ReporterName | Reporter | undefined, filter: string | undefined, defaultMode: TestMode | undefined, replicaType: ReplicaName, watch?: boolean, signal?: AbortSignal, explicitReplica?: boolean): Promise<boolean>;
|
|
14
14
|
export {};
|