ic-mops 1.1.2 → 1.2.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 +9 -0
- package/bundle/cli.tgz +0 -0
- package/cli.ts +65 -9
- package/commands/install/install-local-dep.ts +9 -2
- package/commands/maintainer.ts +105 -0
- package/commands/owner.ts +105 -0
- package/commands/replica.ts +38 -9
- package/commands/test/test.ts +18 -1
- package/commands/watch/parseDfxJson.ts +2 -2
- package/declarations/main/main.did +44 -23
- package/declarations/main/main.did.d.ts +45 -22
- package/declarations/main/main.did.js +55 -27
- package/dist/cli.js +55 -8
- package/dist/commands/install/install-local-dep.js +6 -1
- package/dist/commands/maintainer.d.ts +3 -0
- package/dist/commands/maintainer.js +88 -0
- package/dist/commands/owner.d.ts +3 -0
- package/dist/commands/owner.js +88 -0
- package/dist/commands/replica.d.ts +3 -2
- package/dist/commands/replica.js +34 -7
- package/dist/commands/test/test.d.ts +2 -1
- package/dist/commands/test/test.js +14 -0
- package/dist/commands/watch/parseDfxJson.js +2 -2
- package/dist/declarations/main/main.did +44 -23
- package/dist/declarations/main/main.did.d.ts +45 -22
- package/dist/declarations/main/main.did.js +55 -27
- package/dist/package.json +1 -1
- package/dist/resolve-packages.js +6 -2
- package/package.json +1 -1
- package/resolve-packages.ts +6 -2
- package/commands/transfer-ownership.ts +0 -45
- package/dist/commands/transfer-ownership.d.ts +0 -1
- package/dist/commands/transfer-ownership.js +0 -38
package/CHANGELOG.md
CHANGED
|
@@ -1,5 +1,14 @@
|
|
|
1
1
|
# Mops CLI Changelog
|
|
2
2
|
|
|
3
|
+
## 1.2.0
|
|
4
|
+
- Removed `mops transfer-ownership` command
|
|
5
|
+
- Added `mops owner` command to manage package owners ([docs](https://docs.mops.one/cli/mops-owner))
|
|
6
|
+
- Added `mops maintainers` command to manage package maintainers ([docs](https://docs.mops.one/cli/mops-maintainers))
|
|
7
|
+
- Added experimental support for pocket-ic replica that comes with dfx in `mops test` command ([docs](https://docs.mops.one/cli/mops-test#--replica))
|
|
8
|
+
- Added flag `--verbose` to `mops test` command to show replica logs
|
|
9
|
+
- Fixed bug where `mops watch` would fail if dfx.json did not exist
|
|
10
|
+
- Fixed bug with local dependencies without `mops.toml` file
|
|
11
|
+
|
|
3
12
|
## 1.1.2
|
|
4
13
|
- Fixed `{MOPS_ENV}` substitution in local package path
|
|
5
14
|
|
package/bundle/cli.tgz
CHANGED
|
Binary file
|
package/cli.ts
CHANGED
|
@@ -21,12 +21,13 @@ import {sync} from './commands/sync.js';
|
|
|
21
21
|
import {outdated} from './commands/outdated.js';
|
|
22
22
|
import {update} from './commands/update.js';
|
|
23
23
|
import {bench} from './commands/bench.js';
|
|
24
|
-
import {transferOwnership} from './commands/transfer-ownership.js';
|
|
25
24
|
import {toolchain} from './commands/toolchain/index.js';
|
|
26
25
|
import {Tool} from './types.js';
|
|
27
26
|
import * as self from './commands/self.js';
|
|
28
27
|
import {resolvePackages} from './resolve-packages.js';
|
|
29
28
|
import {watch} from './commands/watch/watch.js';
|
|
29
|
+
import {addOwner, printOwners, removeOwner} from './commands/owner.js';
|
|
30
|
+
import {addMaintainer, printMaintainers, removeMaintainer} from './commands/maintainer.js';
|
|
30
31
|
|
|
31
32
|
declare global {
|
|
32
33
|
// eslint-disable-next-line no-var
|
|
@@ -214,6 +215,7 @@ program
|
|
|
214
215
|
.addOption(new Option('--mode <mode>', 'Test mode').choices(['interpreter', 'wasi', 'replica']).default('interpreter'))
|
|
215
216
|
.addOption(new Option('--replica <replica>', 'Which replica to use to run tests in replica mode').choices(['dfx', 'pocket-ic']))
|
|
216
217
|
.option('-w, --watch', 'Enable watch mode')
|
|
218
|
+
.option('--verbose', 'Verbose output')
|
|
217
219
|
.action(async (filter, options) => {
|
|
218
220
|
checkConfigFile(true);
|
|
219
221
|
await installAll({silent: true, lock: 'ignore', installFromLockFile: true});
|
|
@@ -289,6 +291,68 @@ userCommand
|
|
|
289
291
|
|
|
290
292
|
program.addCommand(userCommand);
|
|
291
293
|
|
|
294
|
+
// mops owner *
|
|
295
|
+
const ownerCommand = new Command('owner').description('Package owner management');
|
|
296
|
+
|
|
297
|
+
// mops owner list
|
|
298
|
+
ownerCommand
|
|
299
|
+
.command('list')
|
|
300
|
+
.description('List package owners')
|
|
301
|
+
.action(async () => {
|
|
302
|
+
await printOwners();
|
|
303
|
+
});
|
|
304
|
+
|
|
305
|
+
// mops owner add
|
|
306
|
+
ownerCommand
|
|
307
|
+
.command('add <principal>')
|
|
308
|
+
.description('Add package owner')
|
|
309
|
+
.addOption(new Option('--yes', 'Do not ask for confirmation'))
|
|
310
|
+
.action(async (data, options) => {
|
|
311
|
+
await addOwner(data, options.yes);
|
|
312
|
+
});
|
|
313
|
+
|
|
314
|
+
// mops owner remove
|
|
315
|
+
ownerCommand
|
|
316
|
+
.command('remove <principal>')
|
|
317
|
+
.description('Remove package owner')
|
|
318
|
+
.addOption(new Option('--yes', 'Do not ask for confirmation'))
|
|
319
|
+
.action(async (data, options) => {
|
|
320
|
+
await removeOwner(data, options.yes);
|
|
321
|
+
});
|
|
322
|
+
|
|
323
|
+
program.addCommand(ownerCommand);
|
|
324
|
+
|
|
325
|
+
// mops maintainer *
|
|
326
|
+
const maintainerCommand = new Command('maintainer').description('Package maintainer management');
|
|
327
|
+
|
|
328
|
+
// mops maintainer list
|
|
329
|
+
maintainerCommand
|
|
330
|
+
.command('list')
|
|
331
|
+
.description('List package maintainers')
|
|
332
|
+
.action(async () => {
|
|
333
|
+
await printMaintainers();
|
|
334
|
+
});
|
|
335
|
+
|
|
336
|
+
// mops maintainer add
|
|
337
|
+
maintainerCommand
|
|
338
|
+
.command('add <principal>')
|
|
339
|
+
.description('Add package maintainer')
|
|
340
|
+
.addOption(new Option('--yes', 'Do not ask for confirmation'))
|
|
341
|
+
.action(async (data, options) => {
|
|
342
|
+
await addMaintainer(data, options.yes);
|
|
343
|
+
});
|
|
344
|
+
|
|
345
|
+
// mops maintainer remove
|
|
346
|
+
maintainerCommand
|
|
347
|
+
.command('remove <principal>')
|
|
348
|
+
.description('Remove package maintainer')
|
|
349
|
+
.addOption(new Option('--yes', 'Do not ask for confirmation'))
|
|
350
|
+
.action(async (data, options) => {
|
|
351
|
+
await removeMaintainer(data, options.yes);
|
|
352
|
+
});
|
|
353
|
+
|
|
354
|
+
program.addCommand(maintainerCommand);
|
|
355
|
+
|
|
292
356
|
// bump
|
|
293
357
|
program
|
|
294
358
|
.command('bump [major|minor|patch]')
|
|
@@ -323,14 +387,6 @@ program
|
|
|
323
387
|
await update(pkg, options);
|
|
324
388
|
});
|
|
325
389
|
|
|
326
|
-
// transfer-ownership
|
|
327
|
-
program
|
|
328
|
-
.command('transfer-ownership [to-principal]')
|
|
329
|
-
.description('Transfer ownership of the current package to another principal')
|
|
330
|
-
.action(async (toPrincipal) => {
|
|
331
|
-
await transferOwnership(toPrincipal);
|
|
332
|
-
});
|
|
333
|
-
|
|
334
390
|
// toolchain
|
|
335
391
|
const toolchainCommand = new Command('toolchain').description('Toolchain management');
|
|
336
392
|
|
|
@@ -1,5 +1,6 @@
|
|
|
1
1
|
import process from 'node:process';
|
|
2
2
|
import path from 'node:path';
|
|
3
|
+
import {existsSync} from 'node:fs';
|
|
3
4
|
import {createLogUpdate} from 'log-update';
|
|
4
5
|
import {getRootDir, readConfig} from '../../mops.js';
|
|
5
6
|
import {installDeps} from './install-deps.js';
|
|
@@ -28,10 +29,16 @@ export async function installLocalDep(pkg : string, pkgPath = '', {verbose, sile
|
|
|
28
29
|
// install dependencies
|
|
29
30
|
if (!ignoreTransitive) {
|
|
30
31
|
let dir = path.resolve(getRootDir(), pkgPath).replaceAll('{MOPS_ENV}', process.env.MOPS_ENV || 'local');
|
|
31
|
-
let
|
|
32
|
+
let mopsToml = path.join(dir, 'mops.toml');
|
|
33
|
+
|
|
34
|
+
if (!existsSync(mopsToml)) {
|
|
35
|
+
return true;
|
|
36
|
+
}
|
|
37
|
+
|
|
38
|
+
let config = readConfig(mopsToml);
|
|
32
39
|
return installDeps(Object.values(config.dependencies || {}), {silent, verbose}, pkgPath);
|
|
33
40
|
}
|
|
34
41
|
else {
|
|
35
42
|
return true;
|
|
36
43
|
}
|
|
37
|
-
}
|
|
44
|
+
}
|
|
@@ -0,0 +1,105 @@
|
|
|
1
|
+
import process from 'node:process';
|
|
2
|
+
import chalk from 'chalk';
|
|
3
|
+
import {checkConfigFile, getIdentity, readConfig} from '../mops.js';
|
|
4
|
+
import {mainActor} from '../api/actors.js';
|
|
5
|
+
import {Principal} from '@dfinity/principal';
|
|
6
|
+
import prompts from 'prompts';
|
|
7
|
+
|
|
8
|
+
export async function printMaintainers() {
|
|
9
|
+
if (!checkConfigFile()) {
|
|
10
|
+
return;
|
|
11
|
+
}
|
|
12
|
+
|
|
13
|
+
let config = readConfig();
|
|
14
|
+
let actor = await mainActor();
|
|
15
|
+
|
|
16
|
+
let maintainers = await actor.getPackageMaintainers(config.package?.name || '');
|
|
17
|
+
console.log(`Maintainers of package ${chalk.bold(config.package?.name)}:`);
|
|
18
|
+
for (let maintainer of maintainers) {
|
|
19
|
+
console.log(maintainer.toText());
|
|
20
|
+
}
|
|
21
|
+
}
|
|
22
|
+
|
|
23
|
+
export async function addMaintainer(maintainer : string, yes = false) {
|
|
24
|
+
if (!checkConfigFile()) {
|
|
25
|
+
return;
|
|
26
|
+
}
|
|
27
|
+
|
|
28
|
+
let config = readConfig();
|
|
29
|
+
let principal = Principal.fromText(maintainer);
|
|
30
|
+
|
|
31
|
+
if (!yes) {
|
|
32
|
+
let promptsConfig = {
|
|
33
|
+
onCancel() {
|
|
34
|
+
console.log('aborted');
|
|
35
|
+
process.exit(0);
|
|
36
|
+
},
|
|
37
|
+
};
|
|
38
|
+
|
|
39
|
+
let {confirm} = await prompts({
|
|
40
|
+
type: 'confirm',
|
|
41
|
+
name: 'confirm',
|
|
42
|
+
message: `Are you sure you want to add maintainer ${chalk.yellow(maintainer)} to ${chalk.yellow(config.package?.name)} package?`,
|
|
43
|
+
initial: true,
|
|
44
|
+
}, promptsConfig);
|
|
45
|
+
|
|
46
|
+
if (!confirm) {
|
|
47
|
+
return;
|
|
48
|
+
}
|
|
49
|
+
}
|
|
50
|
+
|
|
51
|
+
let identity = await getIdentity();
|
|
52
|
+
let actor = await mainActor(identity);
|
|
53
|
+
|
|
54
|
+
let res = await actor.addMaintainer(config.package?.name || '', principal);
|
|
55
|
+
if ('ok' in res) {
|
|
56
|
+
console.log(chalk.green('Success!'));
|
|
57
|
+
console.log(`Added maintainer ${chalk.bold(maintainer)} to package ${chalk.bold(config.package?.name)}`);
|
|
58
|
+
}
|
|
59
|
+
else {
|
|
60
|
+
console.error(chalk.red('Error: ') + res.err);
|
|
61
|
+
process.exit(1);
|
|
62
|
+
}
|
|
63
|
+
}
|
|
64
|
+
|
|
65
|
+
export async function removeMaintainer(maintainer : string, yes = false) {
|
|
66
|
+
if (!checkConfigFile()) {
|
|
67
|
+
return;
|
|
68
|
+
}
|
|
69
|
+
|
|
70
|
+
let config = readConfig();
|
|
71
|
+
let principal = Principal.fromText(maintainer);
|
|
72
|
+
|
|
73
|
+
if (!yes) {
|
|
74
|
+
let promptsConfig = {
|
|
75
|
+
onCancel() {
|
|
76
|
+
console.log('aborted');
|
|
77
|
+
process.exit(0);
|
|
78
|
+
},
|
|
79
|
+
};
|
|
80
|
+
|
|
81
|
+
let {confirm} = await prompts({
|
|
82
|
+
type: 'confirm',
|
|
83
|
+
name: 'confirm',
|
|
84
|
+
message: `Are you sure you want to remove maintainer ${chalk.red(maintainer)} from ${chalk.red(config.package?.name)} package?`,
|
|
85
|
+
initial: true,
|
|
86
|
+
}, promptsConfig);
|
|
87
|
+
|
|
88
|
+
if (!confirm) {
|
|
89
|
+
return;
|
|
90
|
+
}
|
|
91
|
+
}
|
|
92
|
+
|
|
93
|
+
let identity = await getIdentity();
|
|
94
|
+
let actor = await mainActor(identity);
|
|
95
|
+
|
|
96
|
+
let res = await actor.removeMaintainer(config.package?.name || '', principal);
|
|
97
|
+
if ('ok' in res) {
|
|
98
|
+
console.log(chalk.green('Success!'));
|
|
99
|
+
console.log(`Removed maintainer ${chalk.bold(maintainer)} from package ${chalk.bold(config.package?.name)}`);
|
|
100
|
+
}
|
|
101
|
+
else {
|
|
102
|
+
console.error(chalk.red('Error: ') + res.err);
|
|
103
|
+
process.exit(1);
|
|
104
|
+
}
|
|
105
|
+
}
|
|
@@ -0,0 +1,105 @@
|
|
|
1
|
+
import process from 'node:process';
|
|
2
|
+
import chalk from 'chalk';
|
|
3
|
+
import {checkConfigFile, getIdentity, readConfig} from '../mops.js';
|
|
4
|
+
import {mainActor} from '../api/actors.js';
|
|
5
|
+
import {Principal} from '@dfinity/principal';
|
|
6
|
+
import prompts from 'prompts';
|
|
7
|
+
|
|
8
|
+
export async function printOwners() {
|
|
9
|
+
if (!checkConfigFile()) {
|
|
10
|
+
return;
|
|
11
|
+
}
|
|
12
|
+
|
|
13
|
+
let config = readConfig();
|
|
14
|
+
let actor = await mainActor();
|
|
15
|
+
|
|
16
|
+
let owners = await actor.getPackageOwners(config.package?.name || '');
|
|
17
|
+
console.log(`Owners of package ${chalk.bold(config.package?.name)}:`);
|
|
18
|
+
for (let owner of owners) {
|
|
19
|
+
console.log(owner.toText());
|
|
20
|
+
}
|
|
21
|
+
}
|
|
22
|
+
|
|
23
|
+
export async function addOwner(owner : string, yes = false) {
|
|
24
|
+
if (!checkConfigFile()) {
|
|
25
|
+
return;
|
|
26
|
+
}
|
|
27
|
+
|
|
28
|
+
let config = readConfig();
|
|
29
|
+
let principal = Principal.fromText(owner);
|
|
30
|
+
|
|
31
|
+
if (!yes) {
|
|
32
|
+
let promptsConfig = {
|
|
33
|
+
onCancel() {
|
|
34
|
+
console.log('aborted');
|
|
35
|
+
process.exit(0);
|
|
36
|
+
},
|
|
37
|
+
};
|
|
38
|
+
|
|
39
|
+
let {confirm} = await prompts({
|
|
40
|
+
type: 'confirm',
|
|
41
|
+
name: 'confirm',
|
|
42
|
+
message: `Are you sure you want to add owner ${chalk.yellow(owner)} to ${chalk.yellow(config.package?.name)} package?`,
|
|
43
|
+
initial: true,
|
|
44
|
+
}, promptsConfig);
|
|
45
|
+
|
|
46
|
+
if (!confirm) {
|
|
47
|
+
return;
|
|
48
|
+
}
|
|
49
|
+
}
|
|
50
|
+
|
|
51
|
+
let identity = await getIdentity();
|
|
52
|
+
let actor = await mainActor(identity);
|
|
53
|
+
|
|
54
|
+
let res = await actor.addOwner(config.package?.name || '', principal);
|
|
55
|
+
if ('ok' in res) {
|
|
56
|
+
console.log(chalk.green('Success!'));
|
|
57
|
+
console.log(`Added owner ${chalk.bold(owner)} to package ${chalk.bold(config.package?.name)}`);
|
|
58
|
+
}
|
|
59
|
+
else {
|
|
60
|
+
console.error(chalk.red('Error: ') + res.err);
|
|
61
|
+
process.exit(1);
|
|
62
|
+
}
|
|
63
|
+
}
|
|
64
|
+
|
|
65
|
+
export async function removeOwner(owner : string, yes = false) {
|
|
66
|
+
if (!checkConfigFile()) {
|
|
67
|
+
return;
|
|
68
|
+
}
|
|
69
|
+
|
|
70
|
+
let config = readConfig();
|
|
71
|
+
let principal = Principal.fromText(owner);
|
|
72
|
+
|
|
73
|
+
if (!yes) {
|
|
74
|
+
let promptsConfig = {
|
|
75
|
+
onCancel() {
|
|
76
|
+
console.log('aborted');
|
|
77
|
+
process.exit(0);
|
|
78
|
+
},
|
|
79
|
+
};
|
|
80
|
+
|
|
81
|
+
let {confirm} = await prompts({
|
|
82
|
+
type: 'confirm',
|
|
83
|
+
name: 'confirm',
|
|
84
|
+
message: `Are you sure you want to remove owner ${chalk.red(owner)} from ${chalk.red(config.package?.name)} package?`,
|
|
85
|
+
initial: true,
|
|
86
|
+
}, promptsConfig);
|
|
87
|
+
|
|
88
|
+
if (!confirm) {
|
|
89
|
+
return;
|
|
90
|
+
}
|
|
91
|
+
}
|
|
92
|
+
|
|
93
|
+
let identity = await getIdentity();
|
|
94
|
+
let actor = await mainActor(identity);
|
|
95
|
+
|
|
96
|
+
let res = await actor.removeOwner(config.package?.name || '', principal);
|
|
97
|
+
if ('ok' in res) {
|
|
98
|
+
console.log(chalk.green('Success!'));
|
|
99
|
+
console.log(`Removed owner ${chalk.bold(owner)} from package ${chalk.bold(config.package?.name)}`);
|
|
100
|
+
}
|
|
101
|
+
else {
|
|
102
|
+
console.error(chalk.red('Error: ') + res.err);
|
|
103
|
+
process.exit(1);
|
|
104
|
+
}
|
|
105
|
+
}
|
package/commands/replica.ts
CHANGED
|
@@ -8,19 +8,21 @@ import {spawn as spawnAsync} from 'promisify-child-process';
|
|
|
8
8
|
import {IDL} from '@dfinity/candid';
|
|
9
9
|
import {Actor, HttpAgent} from '@dfinity/agent';
|
|
10
10
|
import {PocketIc, PocketIcServer} from 'pic-ic';
|
|
11
|
+
import chalk from 'chalk';
|
|
11
12
|
|
|
12
13
|
import {readConfig} from '../mops.js';
|
|
13
14
|
import {toolchain} from './toolchain/index.js';
|
|
15
|
+
import {getDfxVersion} from '../helpers/get-dfx-version.js';
|
|
14
16
|
|
|
15
17
|
type StartOptions = {
|
|
16
|
-
type ?: 'dfx' | 'pocket-ic';
|
|
18
|
+
type ?: 'dfx' | 'pocket-ic' | 'dfx-pocket-ic';
|
|
17
19
|
dir ?: string;
|
|
18
20
|
verbose ?: boolean;
|
|
19
21
|
silent ?: boolean;
|
|
20
22
|
};
|
|
21
23
|
|
|
22
24
|
export class Replica {
|
|
23
|
-
type : 'dfx' | 'pocket-ic' = 'dfx';
|
|
25
|
+
type : 'dfx' | 'pocket-ic' | 'dfx-pocket-ic' = 'dfx';
|
|
24
26
|
verbose = false;
|
|
25
27
|
canisters : Record<string, {cwd : string; canisterId : string; actor : any; stream : PassThrough;}> = {};
|
|
26
28
|
pocketIcServer ?: PocketIcServer;
|
|
@@ -36,20 +38,33 @@ export class Replica {
|
|
|
36
38
|
|
|
37
39
|
silent || console.log(`Starting ${this.type} replica...`);
|
|
38
40
|
|
|
39
|
-
if (this.type
|
|
41
|
+
if (this.type === 'dfx' || this.type === 'dfx-pocket-ic') {
|
|
40
42
|
fs.mkdirSync(this.dir, {recursive: true});
|
|
41
43
|
fs.writeFileSync(path.join(this.dir, 'dfx.json'), JSON.stringify(this.dfxJson(''), null, 2));
|
|
42
44
|
fs.writeFileSync(path.join(this.dir, 'canister.did'), 'service : { runTests: () -> (); }');
|
|
43
45
|
|
|
44
46
|
await this.stop();
|
|
45
47
|
|
|
46
|
-
this.dfxProcess = spawn('dfx', ['start', '
|
|
48
|
+
this.dfxProcess = spawn('dfx', ['start', this.type === 'dfx-pocket-ic' ? '--pocketic' : '', '--clean', (this.verbose ? '' : '-qqqq'), '--artificial-delay', '0'].filter(x => x).flat(), {cwd: this.dir});
|
|
47
49
|
|
|
48
50
|
// process canister logs
|
|
49
51
|
this._attachCanisterLogHandler(this.dfxProcess);
|
|
50
52
|
|
|
51
53
|
this.dfxProcess.stdout.on('data', (data) => {
|
|
52
|
-
|
|
54
|
+
if (this.verbose) {
|
|
55
|
+
console.log('DFX:', data.toString());
|
|
56
|
+
}
|
|
57
|
+
});
|
|
58
|
+
|
|
59
|
+
this.dfxProcess.stderr.on('data', (data) => {
|
|
60
|
+
if (this.verbose) {
|
|
61
|
+
console.error('DFX:', data.toString());
|
|
62
|
+
}
|
|
63
|
+
if (data.toString().includes('Failed to bind socket to')) {
|
|
64
|
+
console.error(chalk.red(data.toString()));
|
|
65
|
+
console.log('Please try again after some time');
|
|
66
|
+
process.exit(11);
|
|
67
|
+
}
|
|
53
68
|
});
|
|
54
69
|
|
|
55
70
|
// await for dfx to start
|
|
@@ -115,9 +130,22 @@ export class Replica {
|
|
|
115
130
|
}
|
|
116
131
|
|
|
117
132
|
async stop(sigint = false) {
|
|
118
|
-
if (this.type
|
|
119
|
-
this.dfxProcess
|
|
120
|
-
|
|
133
|
+
if (this.type === 'dfx' || this.type === 'dfx-pocket-ic') {
|
|
134
|
+
if (this.dfxProcess) {
|
|
135
|
+
this.dfxProcess.kill();
|
|
136
|
+
// give replica some time to stop
|
|
137
|
+
await new Promise((resolve) => {
|
|
138
|
+
setTimeout(resolve, 1000);
|
|
139
|
+
});
|
|
140
|
+
}
|
|
141
|
+
|
|
142
|
+
// if (!this.dfxProcess) {
|
|
143
|
+
// try {
|
|
144
|
+
// execSync('dfx killall', {cwd: this.dir, timeout: 3_000, stdio: ['pipe', this.verbose ? 'inherit' : 'ignore', 'pipe']});
|
|
145
|
+
// execSync('dfx stop' + (this.verbose ? '' : ' -qqqq'), {cwd: this.dir, timeout: 10_000, stdio: ['pipe', this.verbose ? 'inherit' : 'ignore', 'pipe']});
|
|
146
|
+
// }
|
|
147
|
+
// catch {}
|
|
148
|
+
// }
|
|
121
149
|
}
|
|
122
150
|
else if (this.pocketIc && this.pocketIcServer) {
|
|
123
151
|
if (!sigint) {
|
|
@@ -128,7 +156,7 @@ export class Replica {
|
|
|
128
156
|
}
|
|
129
157
|
|
|
130
158
|
async deploy(name : string, wasm : string, idlFactory : IDL.InterfaceFactory, cwd : string = process.cwd(), signal ?: AbortSignal) {
|
|
131
|
-
if (this.type === 'dfx') {
|
|
159
|
+
if (this.type === 'dfx' || this.type === 'dfx-pocket-ic') {
|
|
132
160
|
// prepare dfx.json for current canister
|
|
133
161
|
let dfxJson = path.join(this.dir, 'dfx.json');
|
|
134
162
|
|
|
@@ -253,6 +281,7 @@ export class Replica {
|
|
|
253
281
|
return {
|
|
254
282
|
version: 1,
|
|
255
283
|
canisters,
|
|
284
|
+
dfx: getDfxVersion(),
|
|
256
285
|
defaults: {
|
|
257
286
|
build: {
|
|
258
287
|
packtool: 'mops sources',
|
package/commands/test/test.ts
CHANGED
|
@@ -8,6 +8,7 @@ import chalk from 'chalk';
|
|
|
8
8
|
import {globSync} from 'glob';
|
|
9
9
|
import chokidar from 'chokidar';
|
|
10
10
|
import debounce from 'debounce';
|
|
11
|
+
import {SemVer} from 'semver';
|
|
11
12
|
|
|
12
13
|
import {sources} from '../sources.js';
|
|
13
14
|
import {getRootDir, readConfig} from '../../mops.js';
|
|
@@ -25,6 +26,7 @@ import {Replica} from '../replica.js';
|
|
|
25
26
|
import {ActorMethod} from '@dfinity/agent';
|
|
26
27
|
import {PassThrough, Readable} from 'node:stream';
|
|
27
28
|
import {TestMode} from '../../types.js';
|
|
29
|
+
import {getDfxVersion} from '../../helpers/get-dfx-version.js';
|
|
28
30
|
|
|
29
31
|
let ignore = [
|
|
30
32
|
'**/node_modules/**',
|
|
@@ -39,13 +41,14 @@ let globConfig = {
|
|
|
39
41
|
};
|
|
40
42
|
|
|
41
43
|
type ReporterName = 'verbose' | 'files' | 'compact' | 'silent';
|
|
42
|
-
type ReplicaName = 'dfx' | 'pocket-ic';
|
|
44
|
+
type ReplicaName = 'dfx' | 'pocket-ic' | 'dfx-pocket-ic';
|
|
43
45
|
|
|
44
46
|
type TestOptions = {
|
|
45
47
|
watch : boolean;
|
|
46
48
|
reporter : ReporterName;
|
|
47
49
|
mode : TestMode;
|
|
48
50
|
replica : ReplicaName;
|
|
51
|
+
verbose : boolean;
|
|
49
52
|
};
|
|
50
53
|
|
|
51
54
|
|
|
@@ -66,7 +69,20 @@ export async function test(filter = '', options : Partial<TestOptions> = {}) {
|
|
|
66
69
|
let rootDir = getRootDir();
|
|
67
70
|
|
|
68
71
|
let replicaType = options.replica ?? (config.toolchain?.['pocket-ic'] ? 'pocket-ic' : 'dfx' as ReplicaName);
|
|
72
|
+
|
|
73
|
+
if (replicaType === 'pocket-ic' && !config.toolchain?.['pocket-ic']) {
|
|
74
|
+
let dfxVersion = getDfxVersion();
|
|
75
|
+
if (!dfxVersion || new SemVer(dfxVersion).compare('0.24.1') < 0) {
|
|
76
|
+
console.log(chalk.red('Please update dfx to the version >=0.24.1 or specify pocket-ic version in mops.toml'));
|
|
77
|
+
process.exit(1);
|
|
78
|
+
}
|
|
79
|
+
else {
|
|
80
|
+
replicaType = 'dfx-pocket-ic';
|
|
81
|
+
}
|
|
82
|
+
}
|
|
83
|
+
|
|
69
84
|
replica.type = replicaType;
|
|
85
|
+
replica.verbose = !!options.verbose;
|
|
70
86
|
|
|
71
87
|
if (options.watch) {
|
|
72
88
|
replica.ttl = 60 * 15; // 15 minutes
|
|
@@ -202,6 +218,7 @@ export async function testWithReporter(reporterName : ReporterName | Reporter |
|
|
|
202
218
|
let testTempDir = path.join(getRootDir(), '.mops/.test/');
|
|
203
219
|
replica.dir = testTempDir;
|
|
204
220
|
|
|
221
|
+
fs.rmSync(testTempDir, {recursive: true, force: true});
|
|
205
222
|
fs.mkdirSync(testTempDir, {recursive: true});
|
|
206
223
|
|
|
207
224
|
await parallel(os.cpus().length, files, async (file : string) => {
|
|
@@ -51,14 +51,14 @@ function readDfxJson() : DfxConfig | Record<string, never> {
|
|
|
51
51
|
|
|
52
52
|
export function getMotokoCanisters() : Record<string, string> {
|
|
53
53
|
let dfxJson = readDfxJson();
|
|
54
|
-
return Object.fromEntries(Object.entries(dfxJson.canisters)
|
|
54
|
+
return Object.fromEntries(Object.entries(dfxJson.canisters || {})
|
|
55
55
|
.filter(([_, canister]) => canister.type === 'motoko')
|
|
56
56
|
.map(([name, canister]) => [name, canister.main ?? '']));
|
|
57
57
|
}
|
|
58
58
|
|
|
59
59
|
export function getMotokoCanistersWithDeclarations() : Record<string, string> {
|
|
60
60
|
let dfxJson = readDfxJson();
|
|
61
|
-
return Object.fromEntries(Object.entries(dfxJson.canisters)
|
|
61
|
+
return Object.fromEntries(Object.entries(dfxJson.canisters || {})
|
|
62
62
|
.filter(([_, canister]) => canister.type === 'motoko' && canister.declarations)
|
|
63
63
|
.map(([name, canister]) => [name, canister.main ?? '']));
|
|
64
64
|
}
|