ic-mops 0.36.1 → 0.37.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/bin/moc-wrapper.sh +3 -0
- package/bin/mops.ts +3 -0
- package/cache.ts +2 -2
- package/cli.ts +61 -4
- package/commands/add.ts +3 -1
- package/commands/bench-replica.ts +5 -3
- package/commands/docs.ts +9 -6
- package/commands/install-all.ts +7 -2
- package/commands/install.ts +5 -1
- package/commands/publish.ts +2 -0
- package/commands/test/test.ts +42 -19
- package/commands/toolchain/index.ts +325 -0
- package/commands/toolchain/moc.ts +58 -0
- package/commands/toolchain/pocket-ic.ts +74 -0
- package/commands/toolchain/toolchain-utils.ts +83 -0
- package/commands/toolchain/wasmtime.ts +45 -0
- package/dist/bin/mops.d.ts +1 -1
- package/dist/cache.js +2 -2
- package/dist/cli.d.ts +0 -1
- package/dist/cli.js +52 -3
- package/dist/commands/add.js +2 -1
- package/dist/commands/bench-replica.d.ts +1 -1
- package/dist/commands/bench-replica.js +5 -3
- package/dist/commands/docs.js +9 -6
- package/dist/commands/install-all.js +5 -2
- package/dist/commands/install.js +5 -1
- package/dist/commands/publish.js +1 -0
- package/dist/commands/test/test.js +41 -19
- package/dist/commands/toolchain/index.d.ts +26 -0
- package/dist/commands/toolchain/index.js +274 -0
- package/dist/commands/toolchain/moc.d.ts +5 -1
- package/dist/commands/toolchain/moc.js +18 -6
- package/dist/commands/toolchain/mocv.js +0 -1
- package/dist/commands/toolchain/pocket-ic.d.ts +12 -0
- package/dist/commands/toolchain/pocket-ic.js +62 -0
- package/dist/commands/toolchain/toolchain-utils.d.ts +2 -2
- package/dist/commands/toolchain/toolchain-utils.js +22 -6
- package/dist/commands/toolchain/wasmtime.d.ts +5 -1
- package/dist/commands/toolchain/wasmtime.js +16 -4
- package/dist/integrity.js +40 -15
- package/dist/mops.js +2 -2
- package/dist/package.json +9 -4
- package/dist/pic-js/examples/clock/tests/clock/index.d.ts +1 -0
- package/dist/pic-js/examples/clock/tests/clock/index.js +5 -0
- package/dist/pic-js/examples/clock/tests/jest.config.d.ts +3 -0
- package/dist/pic-js/examples/clock/tests/jest.config.js +8 -0
- package/dist/pic-js/examples/clock/tests/src/clock.spec.d.ts +1 -0
- package/dist/pic-js/examples/clock/tests/src/clock.spec.js +48 -0
- package/dist/pic-js/examples/counter/tests/counter/index.d.ts +1 -0
- package/dist/pic-js/examples/counter/tests/counter/index.js +5 -0
- package/dist/pic-js/examples/counter/tests/jest.config.d.ts +3 -0
- package/dist/pic-js/examples/counter/tests/jest.config.js +8 -0
- package/dist/pic-js/examples/counter/tests/src/counter.spec.d.ts +1 -0
- package/dist/pic-js/examples/counter/tests/src/counter.spec.js +80 -0
- package/dist/pic-js/examples/todo/tests/jest.config.d.ts +3 -0
- package/dist/pic-js/examples/todo/tests/jest.config.js +8 -0
- package/dist/pic-js/examples/todo/tests/src/todo.spec.d.ts +1 -0
- package/dist/pic-js/examples/todo/tests/src/todo.spec.js +211 -0
- package/dist/pic-js/examples/todo/tests/todo/index.d.ts +1 -0
- package/dist/pic-js/examples/todo/tests/todo/index.js +5 -0
- package/dist/pic-js/packages/pic/src/error.d.ts +12 -0
- package/dist/pic-js/packages/pic/src/error.js +36 -0
- package/dist/pic-js/packages/pic/src/http-client.d.ts +15 -0
- package/dist/pic-js/packages/pic/src/http-client.js +37 -0
- package/dist/pic-js/packages/pic/src/identity.d.ts +66 -0
- package/dist/pic-js/packages/pic/src/identity.js +86 -0
- package/dist/pic-js/packages/pic/src/index.d.ts +4 -0
- package/dist/pic-js/packages/pic/src/index.js +8 -0
- package/dist/pic-js/packages/pic/src/management-canister.d.ts +30 -0
- package/dist/pic-js/packages/pic/src/management-canister.js +43 -0
- package/dist/pic-js/packages/pic/src/pocket-ic-actor.d.ts +83 -0
- package/dist/pic-js/packages/pic/src/pocket-ic-actor.js +58 -0
- package/dist/pic-js/packages/pic/src/pocket-ic-client-types.d.ts +61 -0
- package/dist/pic-js/packages/pic/src/pocket-ic-client-types.js +2 -0
- package/dist/pic-js/packages/pic/src/pocket-ic-client.d.ts +24 -0
- package/dist/pic-js/packages/pic/src/pocket-ic-client.js +123 -0
- package/dist/pic-js/packages/pic/src/pocket-ic-server.d.ts +10 -0
- package/dist/pic-js/packages/pic/src/pocket-ic-server.js +55 -0
- package/dist/pic-js/packages/pic/src/pocket-ic-types.d.ts +40 -0
- package/dist/pic-js/packages/pic/src/pocket-ic-types.js +2 -0
- package/dist/pic-js/packages/pic/src/pocket-ic.d.ts +447 -0
- package/dist/pic-js/packages/pic/src/pocket-ic.js +551 -0
- package/dist/pic-js/packages/pic/src/util/candid.d.ts +1 -0
- package/dist/pic-js/packages/pic/src/util/candid.js +7 -0
- package/dist/pic-js/packages/pic/src/util/encoding.d.ts +5 -0
- package/dist/pic-js/packages/pic/src/util/encoding.js +19 -0
- package/dist/pic-js/packages/pic/src/util/fs.d.ts +4 -0
- package/dist/pic-js/packages/pic/src/util/fs.js +29 -0
- package/dist/pic-js/packages/pic/src/util/index.d.ts +5 -0
- package/dist/pic-js/packages/pic/src/util/index.js +21 -0
- package/dist/pic-js/packages/pic/src/util/os.d.ts +4 -0
- package/dist/pic-js/packages/pic/src/util/os.js +19 -0
- package/dist/pic-js/packages/pic/src/util/poll.d.ts +5 -0
- package/dist/pic-js/packages/pic/src/util/poll.js +28 -0
- package/dist/templates/mops-test.yml +4 -4
- package/dist/types.d.ts +7 -0
- package/dist/vessel.js +5 -1
- package/global.d.ts +2 -1
- package/integrity.ts +57 -17
- package/mops.ts +3 -3
- package/package.json +9 -4
- package/templates/mops-test.yml +4 -4
- package/types.ts +10 -1
- package/vessel.ts +6 -1
- package/bun.lockb +0 -0
- package/cli-local.ts +0 -3
package/dist/cli.js
CHANGED
|
@@ -1,6 +1,5 @@
|
|
|
1
|
-
#!/usr/bin/env node
|
|
2
1
|
import fs from 'node:fs';
|
|
3
|
-
import {
|
|
2
|
+
import { Command, Argument, Option } from 'commander';
|
|
4
3
|
import chalk from 'chalk';
|
|
5
4
|
import { init } from './commands/init.js';
|
|
6
5
|
import { publish } from './commands/publish.js';
|
|
@@ -24,10 +23,12 @@ import { outdated } from './commands/outdated.js';
|
|
|
24
23
|
import { update } from './commands/update.js';
|
|
25
24
|
import { bench } from './commands/bench.js';
|
|
26
25
|
import { transferOwnership } from './commands/transfer-ownership.js';
|
|
26
|
+
import { toolchain } from './commands/toolchain/index.js';
|
|
27
27
|
let networkFile = getNetworkFile();
|
|
28
28
|
if (fs.existsSync(networkFile)) {
|
|
29
29
|
globalThis.MOPS_NETWORK = fs.readFileSync(networkFile).toString() || 'ic';
|
|
30
30
|
}
|
|
31
|
+
let program = new Command();
|
|
31
32
|
program.name('mops');
|
|
32
33
|
// --version
|
|
33
34
|
let packageJson = JSON.parse(fs.readFileSync(new URL('package.json', import.meta.url)).toString());
|
|
@@ -44,7 +45,7 @@ program
|
|
|
44
45
|
program
|
|
45
46
|
.command('add <pkg>')
|
|
46
47
|
.description('Install the package and save it to mops.toml')
|
|
47
|
-
.option('--dev')
|
|
48
|
+
.option('--dev', 'Add to [dev-dependencies] section')
|
|
48
49
|
.option('--verbose')
|
|
49
50
|
.addOption(new Option('--lock <action>', 'Lockfile action').choices(['update', 'ignore']))
|
|
50
51
|
.action(async (pkg, options) => {
|
|
@@ -83,6 +84,7 @@ program
|
|
|
83
84
|
if (!compatible) {
|
|
84
85
|
return;
|
|
85
86
|
}
|
|
87
|
+
await toolchain.ensureToolchainInited({ strict: false });
|
|
86
88
|
if (pkg) {
|
|
87
89
|
// @deprecated
|
|
88
90
|
console.log(chalk.yellow('Consider using the \'mops add\' command to install a specific package.'));
|
|
@@ -90,6 +92,7 @@ program
|
|
|
90
92
|
}
|
|
91
93
|
else {
|
|
92
94
|
await installAll(options);
|
|
95
|
+
await toolchain.installAll(options);
|
|
93
96
|
}
|
|
94
97
|
});
|
|
95
98
|
// publish
|
|
@@ -143,6 +146,7 @@ program
|
|
|
143
146
|
process.exit(1);
|
|
144
147
|
}
|
|
145
148
|
await installAll({ silent: true, lock: 'ignore' });
|
|
149
|
+
await toolchain.ensureToolchainInited({ strict: false });
|
|
146
150
|
let sourcesArr = await sources(options);
|
|
147
151
|
console.log(sourcesArr.join('\n'));
|
|
148
152
|
});
|
|
@@ -290,4 +294,49 @@ program
|
|
|
290
294
|
.action(async (toPrincipal) => {
|
|
291
295
|
await transferOwnership(toPrincipal);
|
|
292
296
|
});
|
|
297
|
+
// toolchain
|
|
298
|
+
const toolchainCommand = new Command('toolchain').description('Toolchain management');
|
|
299
|
+
toolchainCommand
|
|
300
|
+
.command('init')
|
|
301
|
+
.description('One-time initialization of toolchain management')
|
|
302
|
+
.action(async () => {
|
|
303
|
+
await toolchain.init();
|
|
304
|
+
});
|
|
305
|
+
toolchainCommand
|
|
306
|
+
.command('reset')
|
|
307
|
+
.description('Uninstall toolchain management')
|
|
308
|
+
.action(async () => {
|
|
309
|
+
await toolchain.init({ reset: true });
|
|
310
|
+
});
|
|
311
|
+
toolchainCommand
|
|
312
|
+
.command('use')
|
|
313
|
+
.description('Install specified tool version and update mops.toml')
|
|
314
|
+
.addArgument(new Argument('<tool>').choices(['moc', 'wasmtime', 'pocket-ic']))
|
|
315
|
+
.addArgument(new Argument('[version]'))
|
|
316
|
+
.action(async (tool, version) => {
|
|
317
|
+
if (!checkConfigFile()) {
|
|
318
|
+
process.exit(1);
|
|
319
|
+
}
|
|
320
|
+
await toolchain.use(tool, version);
|
|
321
|
+
});
|
|
322
|
+
toolchainCommand
|
|
323
|
+
.command('update')
|
|
324
|
+
.description('Update specified tool or all tools to the latest version and update mops.toml')
|
|
325
|
+
.addArgument(new Argument('[tool]').choices(['moc', 'wasmtime', 'pocket-ic']))
|
|
326
|
+
.action(async (tool) => {
|
|
327
|
+
if (!checkConfigFile()) {
|
|
328
|
+
process.exit(1);
|
|
329
|
+
}
|
|
330
|
+
await toolchain.update(tool);
|
|
331
|
+
});
|
|
332
|
+
toolchainCommand
|
|
333
|
+
.command('bin')
|
|
334
|
+
.description('Get path to the tool binary\n<tool> can be one of "moc", "wasmtime", "pocket-ic"')
|
|
335
|
+
.addArgument(new Argument('<tool>').choices(['moc', 'wasmtime', 'pocket-ic']))
|
|
336
|
+
.addOption(new Option('--fallback', 'Fallback to the moc that comes with dfx if moc is not specified in the [toolchain] section'))
|
|
337
|
+
.action(async (tool, options) => {
|
|
338
|
+
let bin = await toolchain.bin(tool, options);
|
|
339
|
+
console.log(bin);
|
|
340
|
+
});
|
|
341
|
+
program.addCommand(toolchainCommand);
|
|
293
342
|
program.parse();
|
package/dist/commands/add.js
CHANGED
|
@@ -1,6 +1,6 @@
|
|
|
1
1
|
import path from 'node:path';
|
|
2
2
|
import chalk from 'chalk';
|
|
3
|
-
import
|
|
3
|
+
import { createLogUpdate } from 'log-update';
|
|
4
4
|
import { checkConfigFile, getGithubCommit, parseGithubURL, readConfig, writeConfig } from '../mops.js';
|
|
5
5
|
import { getHighestVersion } from '../api/getHighestVersion.js';
|
|
6
6
|
import { installFromGithub } from '../vessel.js';
|
|
@@ -91,6 +91,7 @@ export async function add(name, { verbose = false, dev = false, lock } = {}, asN
|
|
|
91
91
|
throw Error(`Invalid config file: [${depsProp}] not found`);
|
|
92
92
|
}
|
|
93
93
|
writeConfig(config);
|
|
94
|
+
let logUpdate = createLogUpdate(process.stdout, { showCursor: true });
|
|
94
95
|
if (lock !== 'ignore') {
|
|
95
96
|
logUpdate('Checking integrity...');
|
|
96
97
|
}
|
|
@@ -2,9 +2,10 @@ import { execSync } from 'node:child_process';
|
|
|
2
2
|
import path from 'node:path';
|
|
3
3
|
import fs from 'node:fs';
|
|
4
4
|
import { execaCommand } from 'execa';
|
|
5
|
-
import { PocketIc } from '
|
|
5
|
+
import { PocketIc } from 'pic-ic';
|
|
6
6
|
import { getRootDir } from '../mops.js';
|
|
7
7
|
import { createActor, idlFactory } from '../declarations/bench/index.js';
|
|
8
|
+
import { toolchain } from './toolchain/index.js';
|
|
8
9
|
export class BenchReplica {
|
|
9
10
|
constructor(type, verbose = false) {
|
|
10
11
|
this.verbose = false;
|
|
@@ -21,7 +22,8 @@ export class BenchReplica {
|
|
|
21
22
|
execSync('dfx start --background --clean --artificial-delay 0' + (this.verbose ? '' : ' -qqqq'), { cwd: dir, stdio: ['inherit', this.verbose ? 'inherit' : 'ignore', 'inherit'] });
|
|
22
23
|
}
|
|
23
24
|
else {
|
|
24
|
-
|
|
25
|
+
let pocketIcBin = await toolchain.bin('pocket-ic');
|
|
26
|
+
this.pocketIc = await PocketIc.create(pocketIcBin);
|
|
25
27
|
}
|
|
26
28
|
}
|
|
27
29
|
async stop() {
|
|
@@ -30,7 +32,7 @@ export class BenchReplica {
|
|
|
30
32
|
execSync('dfx stop' + (this.verbose ? '' : ' -qqqq'), { cwd: dir, stdio: ['pipe', this.verbose ? 'inherit' : 'ignore', 'pipe'] });
|
|
31
33
|
}
|
|
32
34
|
else if (this.pocketIc) {
|
|
33
|
-
this.pocketIc.tearDown();
|
|
35
|
+
await this.pocketIc.tearDown();
|
|
34
36
|
}
|
|
35
37
|
}
|
|
36
38
|
async deploy(name, wasm, cwd = process.cwd()) {
|
package/dist/commands/docs.js
CHANGED
|
@@ -1,4 +1,4 @@
|
|
|
1
|
-
import { spawn
|
|
1
|
+
import { spawn } from 'node:child_process';
|
|
2
2
|
import fs from 'node:fs';
|
|
3
3
|
import path from 'node:path';
|
|
4
4
|
import chalk from 'chalk';
|
|
@@ -7,22 +7,25 @@ import { deleteSync } from 'del';
|
|
|
7
7
|
import tar from 'tar';
|
|
8
8
|
import streamToPromise from 'stream-to-promise';
|
|
9
9
|
import { getRootDir } from '../mops.js';
|
|
10
|
-
|
|
10
|
+
import { toolchain } from './toolchain/index.js';
|
|
11
|
+
let moDocPath;
|
|
11
12
|
export async function docs({ silent = false } = {}) {
|
|
12
13
|
let rootDir = getRootDir();
|
|
13
14
|
let docsDir = path.join(rootDir, '.mops/.docs');
|
|
14
15
|
let docsDirRelative = path.relative(process.cwd(), docsDir);
|
|
15
16
|
deleteSync([docsDir], { force: true });
|
|
16
|
-
// detect mocv
|
|
17
|
+
// detect mocv (legacy)
|
|
17
18
|
if (process.env.DFX_MOC_PATH && process.env.DFX_MOC_PATH.includes('mocv/versions')) {
|
|
18
|
-
|
|
19
|
+
moDocPath = process.env.DFX_MOC_PATH.replace(/\/moc$/, '/mo-doc');
|
|
19
20
|
}
|
|
20
21
|
else {
|
|
21
|
-
|
|
22
|
+
// fallbacks to dfx moc if not specified in config
|
|
23
|
+
let mocPath = await toolchain.bin('moc');
|
|
24
|
+
moDocPath = mocPath.replace(/\/moc$/, '/mo-doc');
|
|
22
25
|
}
|
|
23
26
|
// generate docs
|
|
24
27
|
await new Promise((resolve) => {
|
|
25
|
-
let proc = spawn(
|
|
28
|
+
let proc = spawn(moDocPath, [`--source=${path.join(rootDir, 'src')}`, `--output=${docsDirRelative}`, '--format=adoc']);
|
|
26
29
|
// stdout
|
|
27
30
|
proc.stdout.on('data', (data) => {
|
|
28
31
|
let text = data.toString().trim();
|
|
@@ -1,5 +1,6 @@
|
|
|
1
1
|
import chalk from 'chalk';
|
|
2
|
-
|
|
2
|
+
// eslint-disable-next-line @typescript-eslint/no-unused-vars
|
|
3
|
+
import { createLogUpdate } from 'log-update';
|
|
3
4
|
import { checkConfigFile, readConfig } from '../mops.js';
|
|
4
5
|
import { install } from './install.js';
|
|
5
6
|
import { installFromGithub } from '../vessel.js';
|
|
@@ -26,6 +27,8 @@ export async function installAll({ verbose = false, silent = false, lock } = {})
|
|
|
26
27
|
installedPackages = { ...installedPackages, ...res };
|
|
27
28
|
}
|
|
28
29
|
}
|
|
30
|
+
let logUpdate = createLogUpdate(process.stdout, { showCursor: true });
|
|
31
|
+
// let logUpdate = l;
|
|
29
32
|
if (!silent && lock !== 'ignore') {
|
|
30
33
|
logUpdate('Checking integrity...');
|
|
31
34
|
}
|
|
@@ -35,6 +38,6 @@ export async function installAll({ verbose = false, silent = false, lock } = {})
|
|
|
35
38
|
]);
|
|
36
39
|
if (!silent) {
|
|
37
40
|
logUpdate.clear();
|
|
38
|
-
console.log(chalk.green('
|
|
41
|
+
console.log(chalk.green('Packages installed'));
|
|
39
42
|
}
|
|
40
43
|
}
|
package/dist/commands/install.js
CHANGED
|
@@ -1,6 +1,6 @@
|
|
|
1
1
|
import path from 'node:path';
|
|
2
2
|
import fs from 'node:fs';
|
|
3
|
-
import
|
|
3
|
+
import { createLogUpdate } from 'log-update';
|
|
4
4
|
import chalk from 'chalk';
|
|
5
5
|
import { checkConfigFile, formatDir, progressBar, readConfig } from '../mops.js';
|
|
6
6
|
import { getHighestVersion } from '../api/getHighestVersion.js';
|
|
@@ -13,6 +13,7 @@ export async function install(pkg, version = '', { verbose = false, silent = fal
|
|
|
13
13
|
if (!checkConfigFile()) {
|
|
14
14
|
return false;
|
|
15
15
|
}
|
|
16
|
+
let logUpdate = createLogUpdate(process.stdout, { showCursor: true });
|
|
16
17
|
// progress
|
|
17
18
|
let total = Infinity;
|
|
18
19
|
let step = 0;
|
|
@@ -75,6 +76,9 @@ export async function install(pkg, version = '', { verbose = false, silent = fal
|
|
|
75
76
|
if (verbose) {
|
|
76
77
|
silent || logUpdate.done();
|
|
77
78
|
}
|
|
79
|
+
else {
|
|
80
|
+
logUpdate.clear();
|
|
81
|
+
}
|
|
78
82
|
// install dependencies
|
|
79
83
|
let ok = true;
|
|
80
84
|
let config = readConfig(path.join(dir, 'mops.toml'));
|
package/dist/commands/publish.js
CHANGED
|
@@ -289,6 +289,7 @@ export async function publish(options = {}) {
|
|
|
289
289
|
fs.rmSync(path.join(rootDir, '.mops/.docs'), { force: true, recursive: true });
|
|
290
290
|
// finish
|
|
291
291
|
progress();
|
|
292
|
+
logUpdate.done();
|
|
292
293
|
let res = await actor.finishPublish(puiblishingId);
|
|
293
294
|
if ('err' in res) {
|
|
294
295
|
console.log(chalk.red('Error: ') + res.err);
|
|
@@ -1,4 +1,4 @@
|
|
|
1
|
-
import { spawn
|
|
1
|
+
import { spawn } from 'node:child_process';
|
|
2
2
|
import path from 'node:path';
|
|
3
3
|
import fs from 'node:fs';
|
|
4
4
|
import os from 'node:os';
|
|
@@ -7,7 +7,7 @@ import { globSync } from 'glob';
|
|
|
7
7
|
import chokidar from 'chokidar';
|
|
8
8
|
import debounce from 'debounce';
|
|
9
9
|
import { sources } from '../sources.js';
|
|
10
|
-
import { getRootDir } from '../../mops.js';
|
|
10
|
+
import { getRootDir, readConfig } from '../../mops.js';
|
|
11
11
|
import { parallel } from '../../parallel.js';
|
|
12
12
|
import { MMF1 } from './mmf1.js';
|
|
13
13
|
import { absToRel } from './utils.js';
|
|
@@ -15,6 +15,7 @@ import { VerboseReporter } from './reporters/verbose-reporter.js';
|
|
|
15
15
|
import { FilesReporter } from './reporters/files-reporter.js';
|
|
16
16
|
import { CompactReporter } from './reporters/compact-reporter.js';
|
|
17
17
|
import { SilentReporter } from './reporters/silent-reporter.js';
|
|
18
|
+
import { toolchain } from '../toolchain/index.js';
|
|
18
19
|
let ignore = [
|
|
19
20
|
'**/node_modules/**',
|
|
20
21
|
'**/.mops/**',
|
|
@@ -57,7 +58,8 @@ export async function test(filter = '', { watch = false, reporter = 'verbose', m
|
|
|
57
58
|
}
|
|
58
59
|
}
|
|
59
60
|
}
|
|
60
|
-
let mocPath =
|
|
61
|
+
let mocPath = '';
|
|
62
|
+
let wasmtimePath = '';
|
|
61
63
|
export async function runAll(reporterName = 'verbose', filter = '', mode = 'interpreter') {
|
|
62
64
|
let reporter;
|
|
63
65
|
if (reporterName == 'compact') {
|
|
@@ -99,19 +101,29 @@ export async function testWithReporter(reporter, filter = '', mode = 'interprete
|
|
|
99
101
|
return false;
|
|
100
102
|
}
|
|
101
103
|
reporter.addFiles(files);
|
|
104
|
+
let config = readConfig();
|
|
102
105
|
let sourcesArr = await sources();
|
|
103
106
|
if (!mocPath) {
|
|
104
|
-
mocPath =
|
|
107
|
+
mocPath = await toolchain.bin('moc');
|
|
105
108
|
}
|
|
106
109
|
let wasmDir = `${getRootDir()}/.mops/.test/`;
|
|
107
110
|
fs.mkdirSync(wasmDir, { recursive: true });
|
|
108
111
|
await parallel(os.cpus().length, files, async (file) => {
|
|
109
112
|
let mmf = new MMF1('store', absToRel(file));
|
|
110
113
|
let wasiMode = mode === 'wasi' || fs.readFileSync(file, 'utf8').startsWith('// @testmode wasi');
|
|
111
|
-
|
|
112
|
-
|
|
113
|
-
|
|
114
|
+
if (wasiMode && !wasmtimePath) {
|
|
115
|
+
// ensure wasmtime is installed or specified in config
|
|
116
|
+
if (config.toolchain?.wasmtime) {
|
|
117
|
+
wasmtimePath = await toolchain.bin('wasmtime');
|
|
118
|
+
}
|
|
119
|
+
// fallback wasmtime to global binary if not specified in config (legacy)
|
|
120
|
+
else {
|
|
121
|
+
wasmtimePath = 'wasmtime';
|
|
122
|
+
console.log(chalk.yellow('Warning:'), 'Wasmtime is not specified in config. Using global binary "wasmtime". This will be removed in the future.');
|
|
123
|
+
console.log(`Run ${chalk.green('mops toolchain use wasmtime')} or add ${chalk.green('wasmtime = "<version>"')} in mops.toml to avoid breaking changes with future versions of mops.`);
|
|
114
124
|
}
|
|
125
|
+
}
|
|
126
|
+
let promise = new Promise((resolve) => {
|
|
115
127
|
let mocArgs = ['--hide-warnings', '--error-detail=2', ...sourcesArr.join(' ').split(' '), file].filter(x => x);
|
|
116
128
|
// build and run wasm
|
|
117
129
|
if (wasiMode) {
|
|
@@ -123,18 +135,28 @@ export async function testWithReporter(reporter, filter = '', mode = 'interprete
|
|
|
123
135
|
return;
|
|
124
136
|
}
|
|
125
137
|
// run
|
|
126
|
-
let
|
|
127
|
-
|
|
128
|
-
|
|
129
|
-
|
|
130
|
-
|
|
131
|
-
|
|
132
|
-
|
|
133
|
-
|
|
134
|
-
|
|
135
|
-
|
|
136
|
-
|
|
137
|
-
}
|
|
138
|
+
let wasmtimeArgs = [];
|
|
139
|
+
if (config.toolchain?.wasmtime && config.toolchain?.wasmtime >= '14.0.0') {
|
|
140
|
+
wasmtimeArgs = [
|
|
141
|
+
'-S', 'preview2=n',
|
|
142
|
+
'-C', 'cache=n',
|
|
143
|
+
'-W', 'bulk-memory',
|
|
144
|
+
'-W', 'multi-memory',
|
|
145
|
+
'-W', 'max-wasm-stack=2000000',
|
|
146
|
+
'-W', 'nan-canonicalization=y',
|
|
147
|
+
wasmFile,
|
|
148
|
+
];
|
|
149
|
+
}
|
|
150
|
+
else {
|
|
151
|
+
wasmtimeArgs = [
|
|
152
|
+
'--max-wasm-stack=2000000',
|
|
153
|
+
'--enable-cranelift-nan-canonicalization',
|
|
154
|
+
'--wasm-features',
|
|
155
|
+
'multi-memory,bulk-memory',
|
|
156
|
+
wasmFile,
|
|
157
|
+
];
|
|
158
|
+
}
|
|
159
|
+
let proc = spawn(wasmtimePath, wasmtimeArgs);
|
|
138
160
|
await pipeMMF(proc, mmf);
|
|
139
161
|
}).finally(() => {
|
|
140
162
|
fs.rmSync(wasmFile, { force: true });
|
|
@@ -0,0 +1,26 @@
|
|
|
1
|
+
import { Tool } from '../../types.js';
|
|
2
|
+
declare function ensureToolchainInited({ strict }?: {
|
|
3
|
+
strict?: boolean | undefined;
|
|
4
|
+
}): Promise<boolean>;
|
|
5
|
+
declare function init({ reset, silent }?: {
|
|
6
|
+
reset?: boolean | undefined;
|
|
7
|
+
silent?: boolean | undefined;
|
|
8
|
+
}): Promise<void>;
|
|
9
|
+
declare function installAll({ silent, verbose }?: {
|
|
10
|
+
silent?: boolean | undefined;
|
|
11
|
+
verbose?: boolean | undefined;
|
|
12
|
+
}): Promise<void>;
|
|
13
|
+
declare function use(tool: Tool, version?: string): Promise<void>;
|
|
14
|
+
declare function update(tool?: Tool): Promise<void>;
|
|
15
|
+
declare function bin(tool: Tool, { fallback }?: {
|
|
16
|
+
fallback?: boolean | undefined;
|
|
17
|
+
}): Promise<string>;
|
|
18
|
+
export declare let toolchain: {
|
|
19
|
+
init: typeof init;
|
|
20
|
+
use: typeof use;
|
|
21
|
+
update: typeof update;
|
|
22
|
+
bin: typeof bin;
|
|
23
|
+
installAll: typeof installAll;
|
|
24
|
+
ensureToolchainInited: typeof ensureToolchainInited;
|
|
25
|
+
};
|
|
26
|
+
export {};
|
|
@@ -0,0 +1,274 @@
|
|
|
1
|
+
import path from 'node:path';
|
|
2
|
+
import fs from 'node:fs';
|
|
3
|
+
import os from 'node:os';
|
|
4
|
+
import { execSync } from 'node:child_process';
|
|
5
|
+
import chalk from 'chalk';
|
|
6
|
+
import prompts from 'prompts';
|
|
7
|
+
import { createLogUpdate } from 'log-update';
|
|
8
|
+
import { checkConfigFile, getClosestConfigFile, getRootDir, globalCacheDir, readConfig, writeConfig } from '../../mops.js';
|
|
9
|
+
import * as moc from './moc.js';
|
|
10
|
+
import * as pocketIc from './pocket-ic.js';
|
|
11
|
+
import * as wasmtime from './wasmtime.js';
|
|
12
|
+
function getToolUtils(tool) {
|
|
13
|
+
if (tool === 'moc') {
|
|
14
|
+
return moc;
|
|
15
|
+
}
|
|
16
|
+
else if (tool === 'pocket-ic') {
|
|
17
|
+
return pocketIc;
|
|
18
|
+
}
|
|
19
|
+
else if (tool === 'wasmtime') {
|
|
20
|
+
return wasmtime;
|
|
21
|
+
}
|
|
22
|
+
else {
|
|
23
|
+
console.error(`Unknown tool '${tool}'`);
|
|
24
|
+
process.exit(1);
|
|
25
|
+
}
|
|
26
|
+
}
|
|
27
|
+
async function ensureToolchainInited({ strict = true } = {}) {
|
|
28
|
+
// auto init in CI
|
|
29
|
+
if (process.env.CI) {
|
|
30
|
+
await init({ silent: true });
|
|
31
|
+
return true;
|
|
32
|
+
}
|
|
33
|
+
// for non-stict perform check only if dfx.json exists and moc is listed in [toolchain] section
|
|
34
|
+
let rootDir = getRootDir();
|
|
35
|
+
let config = readConfig();
|
|
36
|
+
if (!strict && (!config.toolchain?.moc || rootDir && !fs.existsSync(path.join(rootDir, 'dfx.json')))) {
|
|
37
|
+
return true;
|
|
38
|
+
}
|
|
39
|
+
try {
|
|
40
|
+
let res = execSync('which moc-wrapper').toString().trim();
|
|
41
|
+
if (res && process.env.DFX_MOC_PATH === 'moc-wrapper') {
|
|
42
|
+
return true;
|
|
43
|
+
}
|
|
44
|
+
}
|
|
45
|
+
catch { }
|
|
46
|
+
console.error('Toolchain management is not initialized. Run "mops toolchain init"');
|
|
47
|
+
process.exit(1);
|
|
48
|
+
}
|
|
49
|
+
// update shell config files to set DFX_MOC_PATH to moc-wrapper
|
|
50
|
+
async function init({ reset = false, silent = false } = {}) {
|
|
51
|
+
if (process.platform == 'win32') {
|
|
52
|
+
console.error('Windows is not supported. Please use WSL');
|
|
53
|
+
process.exit(1);
|
|
54
|
+
}
|
|
55
|
+
try {
|
|
56
|
+
let res = execSync('which mocv').toString().trim();
|
|
57
|
+
if (res) {
|
|
58
|
+
console.error('Mops is not compatible with mocv. Please uninstall mocv and try again.');
|
|
59
|
+
console.log('Steps to uninstall mocv:');
|
|
60
|
+
console.log('1. Run "mocv reset"');
|
|
61
|
+
console.log('2. Run "npm uninstall -g mocv"');
|
|
62
|
+
process.exit(1);
|
|
63
|
+
}
|
|
64
|
+
}
|
|
65
|
+
catch { }
|
|
66
|
+
let zshrc = path.join(os.homedir(), '.zshrc');
|
|
67
|
+
let bashrc = path.join(os.homedir(), '.bashrc');
|
|
68
|
+
let shellConfigFiles = [bashrc, zshrc, process.env.GITHUB_ENV || ''].map(x => x).filter((file) => {
|
|
69
|
+
return fs.existsSync(file);
|
|
70
|
+
});
|
|
71
|
+
if (shellConfigFiles.length === 0) {
|
|
72
|
+
console.error('Shell config files not found: ".bashrc" or ".zshrc"');
|
|
73
|
+
process.exit(1);
|
|
74
|
+
}
|
|
75
|
+
// update all existing shell config files
|
|
76
|
+
for (let shellConfigFile of shellConfigFiles) {
|
|
77
|
+
let text = fs.readFileSync(shellConfigFile).toString();
|
|
78
|
+
let setDfxMocPathLine = '\nexport DFX_MOC_PATH=moc-wrapper';
|
|
79
|
+
let newLines = [
|
|
80
|
+
setDfxMocPathLine,
|
|
81
|
+
];
|
|
82
|
+
let oldLines = [
|
|
83
|
+
// legacy mocv lines
|
|
84
|
+
`\nexport DFX_MOC_PATH=${path.join(path.join(os.homedir(), '.cache/mocv'), 'versions/current')}/moc`,
|
|
85
|
+
'\nexport DFX_MOC_PATH="$HOME/.cache/mocv/versions/current/moc"',
|
|
86
|
+
// new
|
|
87
|
+
setDfxMocPathLine,
|
|
88
|
+
];
|
|
89
|
+
// remove old lines
|
|
90
|
+
for (let oldLine of oldLines) {
|
|
91
|
+
text = text.replace(oldLine, '');
|
|
92
|
+
}
|
|
93
|
+
if (text.endsWith('\n\n')) {
|
|
94
|
+
text = text.trimEnd() + '\n';
|
|
95
|
+
}
|
|
96
|
+
// insert new lines
|
|
97
|
+
if (!reset) {
|
|
98
|
+
if (!text.endsWith('\n')) {
|
|
99
|
+
text += '\n';
|
|
100
|
+
}
|
|
101
|
+
for (let newLine of newLines) {
|
|
102
|
+
if (shellConfigFile === process.env.GITHUB_ENV) {
|
|
103
|
+
newLine = newLine.replace('export ', '');
|
|
104
|
+
}
|
|
105
|
+
text += newLine;
|
|
106
|
+
}
|
|
107
|
+
text += '\n';
|
|
108
|
+
}
|
|
109
|
+
fs.writeFileSync(shellConfigFile, text);
|
|
110
|
+
}
|
|
111
|
+
if (!silent) {
|
|
112
|
+
console.log(chalk.green('Success!'));
|
|
113
|
+
console.log('Restart terminal to apply changes');
|
|
114
|
+
}
|
|
115
|
+
}
|
|
116
|
+
async function download(tool, version, { silent = false, verbose = false } = {}) {
|
|
117
|
+
let toolUtils = getToolUtils(tool);
|
|
118
|
+
await toolUtils.download(version, { silent, verbose });
|
|
119
|
+
}
|
|
120
|
+
async function installAll({ silent = false, verbose = false } = {}) {
|
|
121
|
+
let config = readConfig();
|
|
122
|
+
if (!config.toolchain) {
|
|
123
|
+
return;
|
|
124
|
+
}
|
|
125
|
+
let logUpdate = createLogUpdate(process.stdout, { showCursor: true });
|
|
126
|
+
let log = (...args) => {
|
|
127
|
+
if (silent) {
|
|
128
|
+
return;
|
|
129
|
+
}
|
|
130
|
+
if (verbose) {
|
|
131
|
+
console.log(...args);
|
|
132
|
+
}
|
|
133
|
+
else {
|
|
134
|
+
logUpdate(...args);
|
|
135
|
+
}
|
|
136
|
+
};
|
|
137
|
+
log('Installing toolchain...');
|
|
138
|
+
if (config.toolchain?.moc) {
|
|
139
|
+
log('Installing moc', config.toolchain.moc);
|
|
140
|
+
await download('moc', config.toolchain.moc, { verbose });
|
|
141
|
+
}
|
|
142
|
+
if (config.toolchain?.wasmtime) {
|
|
143
|
+
log('Installing wasmtime', config.toolchain.wasmtime);
|
|
144
|
+
await download('wasmtime', config.toolchain.wasmtime, { verbose });
|
|
145
|
+
}
|
|
146
|
+
if (config.toolchain?.['pocket-ic']) {
|
|
147
|
+
log('Installing pocket-ic', config.toolchain['pocket-ic']);
|
|
148
|
+
await download('pocket-ic', config.toolchain['pocket-ic'], { verbose });
|
|
149
|
+
}
|
|
150
|
+
if (!silent) {
|
|
151
|
+
logUpdate.clear();
|
|
152
|
+
console.log(chalk.green('Toolchain installed'));
|
|
153
|
+
}
|
|
154
|
+
}
|
|
155
|
+
async function promptVersion(tool) {
|
|
156
|
+
let config = readConfig();
|
|
157
|
+
config.toolchain = config.toolchain || {};
|
|
158
|
+
let current = config.toolchain[tool];
|
|
159
|
+
let toolUtils = getToolUtils(tool);
|
|
160
|
+
let releases = await toolUtils.getReleases();
|
|
161
|
+
let versions = releases.map((item) => item.tag_name);
|
|
162
|
+
let currentIndex = versions.indexOf(current);
|
|
163
|
+
let res = await prompts({
|
|
164
|
+
type: 'select',
|
|
165
|
+
name: 'version',
|
|
166
|
+
message: `Select ${tool} version`,
|
|
167
|
+
choices: releases.map((release, i) => {
|
|
168
|
+
let date = new Date(release.published_at).toLocaleDateString(undefined, { year: 'numeric', month: 'short', day: 'numeric' });
|
|
169
|
+
return {
|
|
170
|
+
title: release.tag_name + chalk.gray(` ${date}${currentIndex === i ? chalk.italic(' (current)') : ''}`),
|
|
171
|
+
value: release.tag_name,
|
|
172
|
+
};
|
|
173
|
+
}),
|
|
174
|
+
initial: currentIndex == -1 ? 0 : currentIndex,
|
|
175
|
+
});
|
|
176
|
+
return res.version;
|
|
177
|
+
}
|
|
178
|
+
// download binary and set version in mops.toml
|
|
179
|
+
async function use(tool, version) {
|
|
180
|
+
if (tool === 'moc') {
|
|
181
|
+
await ensureToolchainInited();
|
|
182
|
+
}
|
|
183
|
+
if (!version) {
|
|
184
|
+
version = await promptVersion(tool);
|
|
185
|
+
}
|
|
186
|
+
if (!version) {
|
|
187
|
+
return;
|
|
188
|
+
}
|
|
189
|
+
if (version === 'latest') {
|
|
190
|
+
version = await getToolUtils(tool).getLatestReleaseTag();
|
|
191
|
+
}
|
|
192
|
+
await download(tool, version);
|
|
193
|
+
let config = readConfig();
|
|
194
|
+
config.toolchain = config.toolchain || {};
|
|
195
|
+
let oldVersion = config.toolchain[tool];
|
|
196
|
+
config.toolchain[tool] = version;
|
|
197
|
+
writeConfig(config);
|
|
198
|
+
if (oldVersion === version) {
|
|
199
|
+
console.log((`${tool} ${version} is already installed`));
|
|
200
|
+
}
|
|
201
|
+
else {
|
|
202
|
+
console.log(chalk.green(`Installed ${tool} ${version}`));
|
|
203
|
+
}
|
|
204
|
+
}
|
|
205
|
+
// download latest binary and set version in mops.toml
|
|
206
|
+
async function update(tool) {
|
|
207
|
+
if (tool === 'moc') {
|
|
208
|
+
await ensureToolchainInited();
|
|
209
|
+
}
|
|
210
|
+
let config = readConfig();
|
|
211
|
+
config.toolchain = config.toolchain || {};
|
|
212
|
+
let tools = tool ? [tool] : Object.keys(config.toolchain);
|
|
213
|
+
for (let tool of tools) {
|
|
214
|
+
if (!config.toolchain[tool]) {
|
|
215
|
+
console.error(`Tool '${tool}' is not defined in [toolchain] section in mops.toml`);
|
|
216
|
+
process.exit(1);
|
|
217
|
+
}
|
|
218
|
+
let toolUtils = getToolUtils(tool);
|
|
219
|
+
let version = await toolUtils.getLatestReleaseTag();
|
|
220
|
+
await download(tool, version);
|
|
221
|
+
let oldVersion = config.toolchain[tool];
|
|
222
|
+
config.toolchain[tool] = version;
|
|
223
|
+
writeConfig(config);
|
|
224
|
+
if (oldVersion === version) {
|
|
225
|
+
console.log((`Latest ${tool} ${version} is already installed`));
|
|
226
|
+
}
|
|
227
|
+
else {
|
|
228
|
+
console.log(chalk.green(`Installed ${tool} ${version}`));
|
|
229
|
+
}
|
|
230
|
+
}
|
|
231
|
+
}
|
|
232
|
+
// return current version from mops.toml
|
|
233
|
+
async function bin(tool, { fallback = false } = {}) {
|
|
234
|
+
let hasConfig = getClosestConfigFile();
|
|
235
|
+
// fallback to dfx moc
|
|
236
|
+
if (!hasConfig) {
|
|
237
|
+
if (tool === 'moc' && fallback) {
|
|
238
|
+
return execSync('dfx cache show').toString().trim() + '/moc';
|
|
239
|
+
}
|
|
240
|
+
checkConfigFile();
|
|
241
|
+
process.exit(1);
|
|
242
|
+
}
|
|
243
|
+
let config = readConfig();
|
|
244
|
+
let version = config.toolchain?.[tool];
|
|
245
|
+
if (version) {
|
|
246
|
+
if (tool === 'moc') {
|
|
247
|
+
await ensureToolchainInited();
|
|
248
|
+
}
|
|
249
|
+
await download(tool, version, { silent: true });
|
|
250
|
+
if (tool === 'moc') {
|
|
251
|
+
return path.join(globalCacheDir, 'moc', version, tool);
|
|
252
|
+
}
|
|
253
|
+
else {
|
|
254
|
+
return path.join(globalCacheDir, tool, version, tool);
|
|
255
|
+
}
|
|
256
|
+
}
|
|
257
|
+
else {
|
|
258
|
+
// fallback to dfx moc
|
|
259
|
+
if (tool === 'moc' && fallback) {
|
|
260
|
+
return execSync('dfx cache show').toString().trim() + '/moc';
|
|
261
|
+
}
|
|
262
|
+
console.error(`Tool '${tool}' is not defined in [toolchain] section in mops.toml`);
|
|
263
|
+
console.log(`Run ${chalk.green(`mops toolchain use ${tool}`)} to install it`);
|
|
264
|
+
process.exit(1);
|
|
265
|
+
}
|
|
266
|
+
}
|
|
267
|
+
export let toolchain = {
|
|
268
|
+
init,
|
|
269
|
+
use,
|
|
270
|
+
update,
|
|
271
|
+
bin,
|
|
272
|
+
installAll,
|
|
273
|
+
ensureToolchainInited,
|
|
274
|
+
};
|
|
@@ -1,4 +1,8 @@
|
|
|
1
|
+
export declare let repo: string;
|
|
2
|
+
export declare let getLatestReleaseTag: () => Promise<string>;
|
|
3
|
+
export declare let getReleases: () => Promise<any>;
|
|
1
4
|
export declare let isCached: (version: string) => boolean;
|
|
2
|
-
export declare let download: (version: string, { silent }?: {
|
|
5
|
+
export declare let download: (version: string, { silent, verbose }?: {
|
|
3
6
|
silent?: boolean | undefined;
|
|
7
|
+
verbose?: boolean | undefined;
|
|
4
8
|
}) => Promise<void>;
|