ic-mops 1.4.0-pre.0 → 1.5.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 -1
- package/README.md +12 -4
- package/bundle/cli.tgz +0 -0
- package/cli.ts +6 -0
- package/commands/bench-replica.ts +14 -10
- package/commands/bench.ts +106 -29
- package/commands/init.ts +3 -2
- package/commands/replica.ts +2 -2
- package/commands/template.ts +3 -3
- package/commands/watch/parseDfxJson.ts +2 -1
- package/dist/cli.js +5 -0
- package/dist/commands/bench-replica.d.ts +3 -2
- package/dist/commands/bench-replica.js +11 -7
- package/dist/commands/bench.d.ts +3 -1
- package/dist/commands/bench.js +90 -27
- package/dist/commands/init.js +3 -2
- package/dist/commands/replica.js +2 -2
- package/dist/commands/template.js +3 -3
- package/dist/commands/watch/parseDfxJson.d.ts +41 -0
- package/dist/commands/watch/parseDfxJson.js +1 -1
- package/dist/package.json +22 -21
- package/dist/pem.d.ts +1 -1
- package/package.json +22 -21
package/CHANGELOG.md
CHANGED
|
@@ -1,9 +1,27 @@
|
|
|
1
1
|
# Mops CLI Changelog
|
|
2
2
|
|
|
3
|
+
## 1.5.0
|
|
4
|
+
- Compile benchmarks with `--release` flag by default
|
|
5
|
+
- Respect `profile` field in `dfx.json` for benchmarks
|
|
6
|
+
|
|
7
|
+
## 1.4.0
|
|
8
|
+
- Update `mops bench` command output:
|
|
9
|
+
- Print only final results if benchmarks run in a CI environment or there is no vertical space to progressively print the results
|
|
10
|
+
- Hide "Stable Memory" table if it has no data
|
|
11
|
+
- Hide verbose output when running in a CI environment ("Starting replica...", "Running simple.bench.mo...", etc.)
|
|
12
|
+
- Add LaTeX colors to the diffs when running in a CI environment with `--compare` flag
|
|
13
|
+
- CLI now fails if excess arguments are passed to it
|
|
14
|
+
|
|
15
|
+
## 1.3.0
|
|
16
|
+
- Show error on `mops install <pkg>` command. Use `mops add <pkg>` instead.
|
|
17
|
+
- Added support for pocket-ic replica that comes with dfx in `mops bench` command. To activate it, remove `pocket-ic` from `mops.toml` and run `mops bench --replica pocket-ic`. Requires dfx 0.24.1 or higher.
|
|
18
|
+
- `mops init` now pre-fills package name with current directory name in kebab-case
|
|
19
|
+
- Updated non-major npm dependencies
|
|
20
|
+
|
|
3
21
|
## 1.2.0
|
|
4
22
|
- Removed `mops transfer-ownership` command
|
|
5
23
|
- Added `mops owner` command to manage package owners ([docs](https://docs.mops.one/cli/mops-owner))
|
|
6
|
-
- Added `mops
|
|
24
|
+
- Added `mops maintainer` command to manage package maintainers ([docs](https://docs.mops.one/cli/mops-maintainer))
|
|
7
25
|
- 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
26
|
- Added flag `--verbose` to `mops test` command to show replica logs
|
|
9
27
|
- Fixed bug where `mops watch` would fail if dfx.json did not exist
|
package/README.md
CHANGED
|
@@ -2,7 +2,10 @@
|
|
|
2
2
|
|
|
3
3
|
Mops is a package manager for the Motoko programming language.
|
|
4
4
|
|
|
5
|
-
|
|
5
|
+
- [Motoko Package Registry](https://mops.one)
|
|
6
|
+
- [Documentation](https://docs.mops.one)
|
|
7
|
+
- [Blog](https://blog.mops.one)
|
|
8
|
+
- [CLI](https://cli.mops.one)
|
|
6
9
|
|
|
7
10
|
## Setup
|
|
8
11
|
|
|
@@ -12,6 +15,10 @@ See https://mops.one
|
|
|
12
15
|
|
|
13
16
|
### 2. Install CLI tool
|
|
14
17
|
```
|
|
18
|
+
curl -fsSL cli.mops.one/install.sh | sh
|
|
19
|
+
```
|
|
20
|
+
or
|
|
21
|
+
```
|
|
15
22
|
npm i -g ic-mops
|
|
16
23
|
```
|
|
17
24
|
|
|
@@ -33,8 +40,6 @@ Add `mops` as a packtool to your `dfx.json`
|
|
|
33
40
|
### 2. Initialize
|
|
34
41
|
Run this command in the root directory of your project (where is `dfx.json` placed)
|
|
35
42
|
|
|
36
|
-
If there are Vessel config files, mops will migrate packages from `vessel.dhall` to `mops.toml`
|
|
37
|
-
|
|
38
43
|
```
|
|
39
44
|
mops init
|
|
40
45
|
```
|
|
@@ -110,4 +115,7 @@ Publish package to the mops registry!
|
|
|
110
115
|
|
|
111
116
|
```
|
|
112
117
|
mops publish
|
|
113
|
-
```
|
|
118
|
+
```
|
|
119
|
+
|
|
120
|
+
------------
|
|
121
|
+
*Built for the [Supernova Hackathon](https://dfinity.org/supernova/)*
|
package/bundle/cli.tgz
CHANGED
|
Binary file
|
package/cli.ts
CHANGED
|
@@ -2,6 +2,7 @@ import process from 'node:process';
|
|
|
2
2
|
import fs from 'node:fs';
|
|
3
3
|
import events from 'node:events';
|
|
4
4
|
import {Command, Argument, Option} from 'commander';
|
|
5
|
+
import chalk from 'chalk';
|
|
5
6
|
|
|
6
7
|
import {init} from './commands/init.js';
|
|
7
8
|
import {publish} from './commands/publish.js';
|
|
@@ -98,6 +99,11 @@ program
|
|
|
98
99
|
.option('--verbose')
|
|
99
100
|
.addOption(new Option('--lock <action>', 'Lockfile action').choices(['check', 'update', 'ignore']))
|
|
100
101
|
.action(async (options) => {
|
|
102
|
+
if (process.argv.at(-1) !== 'install') {
|
|
103
|
+
console.log(`${chalk.red('Error:')} ${chalk.yellow('mops install')} command installs all dependencies.\nUse ${chalk.green(`mops add ${process.argv.at(-1)}`)} instead.`);
|
|
104
|
+
process.exit(1);
|
|
105
|
+
}
|
|
106
|
+
|
|
101
107
|
if (!checkConfigFile()) {
|
|
102
108
|
process.exit(1);
|
|
103
109
|
}
|
|
@@ -7,33 +7,36 @@ import {PocketIc, PocketIcServer} from 'pic-ic';
|
|
|
7
7
|
import {getRootDir, readConfig} from '../mops.js';
|
|
8
8
|
import {createActor, idlFactory} from '../declarations/bench/index.js';
|
|
9
9
|
import {toolchain} from './toolchain/index.js';
|
|
10
|
+
import {getDfxVersion} from '../helpers/get-dfx-version.js';
|
|
10
11
|
|
|
11
12
|
export class BenchReplica {
|
|
12
|
-
type : 'dfx' | 'pocket-ic';
|
|
13
|
+
type : 'dfx' | 'pocket-ic' | 'dfx-pocket-ic';
|
|
13
14
|
verbose = false;
|
|
14
15
|
canisters : Record<string, {cwd : string; canisterId : string; actor : any;}> = {};
|
|
15
16
|
pocketIcServer ?: PocketIcServer;
|
|
16
17
|
pocketIc ?: PocketIc;
|
|
17
18
|
|
|
18
|
-
constructor(type : 'dfx' | 'pocket-ic', verbose = false) {
|
|
19
|
+
constructor(type : 'dfx' | 'pocket-ic' | 'dfx-pocket-ic', verbose = false) {
|
|
19
20
|
this.type = type;
|
|
20
21
|
this.verbose = verbose;
|
|
21
22
|
}
|
|
22
23
|
|
|
23
24
|
async start({silent = false} = {}) {
|
|
24
|
-
|
|
25
|
+
if (!process.env.CI && !silent) {
|
|
26
|
+
console.log(`Starting ${this.type} replica...`);
|
|
27
|
+
}
|
|
25
28
|
|
|
26
|
-
if (this.type == 'dfx') {
|
|
29
|
+
if (this.type == 'dfx' || this.type === 'dfx-pocket-ic') {
|
|
27
30
|
await this.stop();
|
|
28
31
|
let dir = path.join(getRootDir(), '.mops/.bench');
|
|
29
32
|
fs.writeFileSync(path.join(dir, 'dfx.json'), JSON.stringify(this.dfxJson(''), null, 2));
|
|
30
|
-
execSync('dfx start --background --clean --artificial-delay 0' + (this.verbose ? '' : ' -qqqq'), {cwd: dir, stdio: ['inherit', this.verbose ? 'inherit' : 'ignore', 'inherit']});
|
|
33
|
+
execSync('dfx start --background --clean --artificial-delay 0' + (this.type === 'dfx-pocket-ic' ? ' --pocketic' : '') + (this.verbose ? '' : ' -qqqq'), {cwd: dir, stdio: ['inherit', this.verbose ? 'inherit' : 'ignore', 'inherit']});
|
|
31
34
|
}
|
|
32
35
|
else {
|
|
33
36
|
let pocketIcBin = await toolchain.bin('pocket-ic');
|
|
34
37
|
let config = readConfig();
|
|
35
|
-
if (config.toolchain?.['pocket-ic'] !== '
|
|
36
|
-
console.error('Current Mops CLI only supports pocket-ic
|
|
38
|
+
if (config.toolchain?.['pocket-ic'] !== '4.0.0') {
|
|
39
|
+
console.error('Current Mops CLI only supports pocket-ic 4.0.0');
|
|
37
40
|
process.exit(1);
|
|
38
41
|
}
|
|
39
42
|
this.pocketIcServer = await PocketIcServer.start({
|
|
@@ -44,7 +47,7 @@ export class BenchReplica {
|
|
|
44
47
|
}
|
|
45
48
|
|
|
46
49
|
async stop() {
|
|
47
|
-
if (this.type == 'dfx') {
|
|
50
|
+
if (this.type == 'dfx' || this.type === 'dfx-pocket-ic') {
|
|
48
51
|
let dir = path.join(getRootDir(), '.mops/.bench');
|
|
49
52
|
execSync('dfx stop' + (this.verbose ? '' : ' -qqqq'), {cwd: dir, stdio: ['pipe', this.verbose ? 'inherit' : 'ignore', 'pipe']});
|
|
50
53
|
}
|
|
@@ -55,7 +58,7 @@ export class BenchReplica {
|
|
|
55
58
|
}
|
|
56
59
|
|
|
57
60
|
async deploy(name : string, wasm : string, cwd : string = process.cwd()) {
|
|
58
|
-
if (this.type === 'dfx') {
|
|
61
|
+
if (this.type === 'dfx' || this.type === 'dfx-pocket-ic') {
|
|
59
62
|
await execaCommand(`dfx deploy ${name} --mode reinstall --yes --identity anonymous`, {cwd, stdio: this.verbose ? 'pipe' : ['pipe', 'ignore', 'pipe']});
|
|
60
63
|
let canisterId = execSync(`dfx canister id ${name}`, {cwd}).toString().trim();
|
|
61
64
|
let actor = await createActor(canisterId, {
|
|
@@ -96,6 +99,7 @@ export class BenchReplica {
|
|
|
96
99
|
return {
|
|
97
100
|
version: 1,
|
|
98
101
|
canisters,
|
|
102
|
+
dfx: getDfxVersion(),
|
|
99
103
|
defaults: {
|
|
100
104
|
build: {
|
|
101
105
|
packtool: 'mops sources',
|
|
@@ -109,4 +113,4 @@ export class BenchReplica {
|
|
|
109
113
|
},
|
|
110
114
|
};
|
|
111
115
|
}
|
|
112
|
-
}
|
|
116
|
+
}
|
package/commands/bench.ts
CHANGED
|
@@ -5,11 +5,14 @@ import os from 'node:os';
|
|
|
5
5
|
import chalk from 'chalk';
|
|
6
6
|
import {globSync} from 'glob';
|
|
7
7
|
import {markdownTable} from 'markdown-table';
|
|
8
|
-
import
|
|
8
|
+
import {createLogUpdate} from 'log-update';
|
|
9
9
|
import {execaCommand} from 'execa';
|
|
10
10
|
import stringWidth from 'string-width';
|
|
11
|
+
import {filesize} from 'filesize';
|
|
12
|
+
import terminalSize from 'terminal-size';
|
|
13
|
+
import {SemVer} from 'semver';
|
|
11
14
|
|
|
12
|
-
import {getRootDir, readConfig} from '../mops.js';
|
|
15
|
+
import {getRootDir, readConfig, readDfxJson} from '../mops.js';
|
|
13
16
|
import {parallel} from '../parallel.js';
|
|
14
17
|
import {absToRel} from './test/utils.js';
|
|
15
18
|
import {getMocVersion} from '../helpers/get-moc-version.js';
|
|
@@ -20,7 +23,8 @@ import {sources} from './sources.js';
|
|
|
20
23
|
import {Benchmark, Benchmarks} from '../declarations/main/main.did.js';
|
|
21
24
|
import {BenchResult, _SERVICE} from '../declarations/bench/bench.did.js';
|
|
22
25
|
import {BenchReplica} from './bench-replica.js';
|
|
23
|
-
|
|
26
|
+
|
|
27
|
+
type ReplicaName = 'dfx' | 'pocket-ic' | 'dfx-pocket-ic';
|
|
24
28
|
|
|
25
29
|
let ignore = [
|
|
26
30
|
'**/node_modules/**',
|
|
@@ -35,7 +39,7 @@ let globConfig = {
|
|
|
35
39
|
};
|
|
36
40
|
|
|
37
41
|
type BenchOptions = {
|
|
38
|
-
replica :
|
|
42
|
+
replica : ReplicaName,
|
|
39
43
|
replicaVersion : string,
|
|
40
44
|
compiler : 'moc',
|
|
41
45
|
compilerVersion : string,
|
|
@@ -45,11 +49,12 @@ type BenchOptions = {
|
|
|
45
49
|
compare : boolean,
|
|
46
50
|
verbose : boolean,
|
|
47
51
|
silent : boolean,
|
|
48
|
-
|
|
52
|
+
profile : 'Debug' | 'Release',
|
|
49
53
|
};
|
|
50
54
|
|
|
51
55
|
export async function bench(filter = '', optionsArg : Partial<BenchOptions> = {}) : Promise<Benchmarks> {
|
|
52
56
|
let config = readConfig();
|
|
57
|
+
let dfxJson = readDfxJson();
|
|
53
58
|
|
|
54
59
|
let defaultOptions : BenchOptions = {
|
|
55
60
|
replica: config.toolchain?.['pocket-ic'] ? 'pocket-ic' : 'dfx',
|
|
@@ -62,20 +67,39 @@ export async function bench(filter = '', optionsArg : Partial<BenchOptions> = {}
|
|
|
62
67
|
compare: false,
|
|
63
68
|
verbose: false,
|
|
64
69
|
silent: false,
|
|
70
|
+
profile: dfxJson.profile || 'Release',
|
|
65
71
|
};
|
|
66
72
|
|
|
67
73
|
let options : BenchOptions = {...defaultOptions, ...optionsArg};
|
|
68
74
|
|
|
69
|
-
|
|
75
|
+
let replicaType = options.replica ?? (config.toolchain?.['pocket-ic'] ? 'pocket-ic' : 'dfx' as ReplicaName);
|
|
76
|
+
if (replicaType === 'pocket-ic' && !config.toolchain?.['pocket-ic']) {
|
|
77
|
+
let dfxVersion = getDfxVersion();
|
|
78
|
+
if (!dfxVersion || new SemVer(dfxVersion).compare('0.24.1') < 0) {
|
|
79
|
+
console.log(chalk.red('Please update dfx to the version >=0.24.1 or specify pocket-ic version in mops.toml'));
|
|
80
|
+
process.exit(1);
|
|
81
|
+
}
|
|
82
|
+
else {
|
|
83
|
+
replicaType = 'dfx-pocket-ic';
|
|
84
|
+
}
|
|
85
|
+
}
|
|
86
|
+
|
|
87
|
+
options.replica = replicaType;
|
|
88
|
+
|
|
89
|
+
if (process.env.CI) {
|
|
90
|
+
console.log('# Benchmark Results\n\n');
|
|
91
|
+
}
|
|
92
|
+
|
|
93
|
+
if (replicaType == 'dfx') {
|
|
70
94
|
options.replicaVersion = getDfxVersion();
|
|
71
95
|
}
|
|
72
|
-
else if (
|
|
96
|
+
else if (replicaType == 'pocket-ic') {
|
|
73
97
|
options.replicaVersion = config.toolchain?.['pocket-ic'] || '';
|
|
74
98
|
}
|
|
75
99
|
|
|
76
100
|
options.verbose && console.log(options);
|
|
77
101
|
|
|
78
|
-
let replica = new BenchReplica(
|
|
102
|
+
let replica = new BenchReplica(replicaType, options.verbose);
|
|
79
103
|
|
|
80
104
|
let rootDir = getRootDir();
|
|
81
105
|
let globStr = '**/bench?(mark)/**/*.bench.mo';
|
|
@@ -106,14 +130,19 @@ export async function bench(filter = '', optionsArg : Partial<BenchOptions> = {}
|
|
|
106
130
|
for (let file of files) {
|
|
107
131
|
console.log(chalk.gray(`• ${absToRel(file)}`));
|
|
108
132
|
}
|
|
109
|
-
|
|
110
|
-
|
|
111
|
-
|
|
133
|
+
if (!process.env.CI) {
|
|
134
|
+
console.log('');
|
|
135
|
+
console.log('='.repeat(50));
|
|
136
|
+
console.log('');
|
|
137
|
+
}
|
|
112
138
|
}
|
|
113
139
|
|
|
114
140
|
await replica.start({silent: options.silent});
|
|
115
141
|
|
|
116
|
-
|
|
142
|
+
if (!process.env.CI && !options.silent) {
|
|
143
|
+
console.log('Deploying canisters...');
|
|
144
|
+
}
|
|
145
|
+
|
|
117
146
|
await parallel(os.cpus().length, files, async (file : string) => {
|
|
118
147
|
try {
|
|
119
148
|
await deployBenchFile(file, options, replica);
|
|
@@ -128,8 +157,8 @@ export async function bench(filter = '', optionsArg : Partial<BenchOptions> = {}
|
|
|
128
157
|
let benchResults : Benchmarks = [];
|
|
129
158
|
|
|
130
159
|
await parallel(1, files, async (file : string) => {
|
|
131
|
-
if (!options.silent) {
|
|
132
|
-
console.log('\n' + '
|
|
160
|
+
if (!options.silent && !process.env.CI) {
|
|
161
|
+
console.log('\n' + '-'.repeat(50));
|
|
133
162
|
console.log(`\nRunning ${chalk.gray(absToRel(file))}...`);
|
|
134
163
|
console.log('');
|
|
135
164
|
}
|
|
@@ -144,7 +173,9 @@ export async function bench(filter = '', optionsArg : Partial<BenchOptions> = {}
|
|
|
144
173
|
}
|
|
145
174
|
});
|
|
146
175
|
|
|
147
|
-
|
|
176
|
+
if (!process.env.CI && !options.silent) {
|
|
177
|
+
console.log('Stopping replica...');
|
|
178
|
+
}
|
|
148
179
|
await replica.stop();
|
|
149
180
|
|
|
150
181
|
fs.rmSync(benchDir, {recursive: true, force: true});
|
|
@@ -154,12 +185,22 @@ export async function bench(filter = '', optionsArg : Partial<BenchOptions> = {}
|
|
|
154
185
|
|
|
155
186
|
function getMocArgs(options : BenchOptions) : string {
|
|
156
187
|
let args = '';
|
|
188
|
+
|
|
157
189
|
if (options.forceGc) {
|
|
158
190
|
args += ' --force-gc';
|
|
159
191
|
}
|
|
192
|
+
|
|
160
193
|
if (options.gc) {
|
|
161
194
|
args += ` --${options.gc}-gc`;
|
|
162
195
|
}
|
|
196
|
+
|
|
197
|
+
if (options.profile === 'Debug') {
|
|
198
|
+
args += ' --debug';
|
|
199
|
+
}
|
|
200
|
+
else if (options.profile === 'Release') {
|
|
201
|
+
args += ' --release';
|
|
202
|
+
}
|
|
203
|
+
|
|
163
204
|
return args;
|
|
164
205
|
}
|
|
165
206
|
|
|
@@ -234,6 +275,7 @@ async function runBenchFile(file : string, options : BenchOptions, replica : Ben
|
|
|
234
275
|
|
|
235
276
|
let getTable = (prop : keyof BenchResult) : string => {
|
|
236
277
|
let resArr = [['', ...schema.cols]];
|
|
278
|
+
let allZero = true;
|
|
237
279
|
|
|
238
280
|
for (let [_rowIndex, row] of schema.rows.entries()) {
|
|
239
281
|
let curRow = [row];
|
|
@@ -241,6 +283,9 @@ async function runBenchFile(file : string, options : BenchOptions, replica : Ben
|
|
|
241
283
|
for (let [_colIndex, col] of schema.cols.entries()) {
|
|
242
284
|
let res = results.get(`${row}:${col}`);
|
|
243
285
|
if (res) {
|
|
286
|
+
if (res[prop] != 0n) {
|
|
287
|
+
allZero = false;
|
|
288
|
+
}
|
|
244
289
|
|
|
245
290
|
// compare with previous results
|
|
246
291
|
let diff = '';
|
|
@@ -248,10 +293,18 @@ async function runBenchFile(file : string, options : BenchOptions, replica : Ben
|
|
|
248
293
|
let prevRes = prevResults.get(`${row}:${col}`);
|
|
249
294
|
if (prevRes) {
|
|
250
295
|
let percent = (Number(res[prop]) - Number(prevRes[prop])) / Number(prevRes[prop]) * 100;
|
|
296
|
+
if (Object.is(percent, NaN)) {
|
|
297
|
+
percent = 0;
|
|
298
|
+
}
|
|
251
299
|
let sign = percent > 0 ? '+' : '';
|
|
252
300
|
let percentText = percent == 0 ? '0%' : sign + percent.toFixed(2) + '%';
|
|
253
301
|
let color : keyof typeof chalk = percent == 0 ? 'gray' : (percent > 0 ? 'red' : 'green');
|
|
254
|
-
|
|
302
|
+
if (process.env.CI) {
|
|
303
|
+
diff = ` $({\\color{${color}}${percentText.replace('%', '\\\\%')}})$`;
|
|
304
|
+
}
|
|
305
|
+
else {
|
|
306
|
+
diff = ` (${chalk[color](percentText)})`;
|
|
307
|
+
}
|
|
255
308
|
}
|
|
256
309
|
else {
|
|
257
310
|
diff = chalk.yellow(' (no previous results)');
|
|
@@ -278,25 +331,47 @@ async function runBenchFile(file : string, options : BenchOptions, replica : Ben
|
|
|
278
331
|
resArr.push(curRow);
|
|
279
332
|
}
|
|
280
333
|
|
|
334
|
+
// don't show Stable Memory table if all values are 0
|
|
335
|
+
if (allZero && prop == 'rts_logical_stable_memory_size') {
|
|
336
|
+
return '';
|
|
337
|
+
}
|
|
338
|
+
|
|
281
339
|
return markdownTable(resArr, {
|
|
282
340
|
align: ['l', ...'r'.repeat(schema.cols.length)],
|
|
283
341
|
stringLength: stringWidth,
|
|
284
342
|
});
|
|
285
343
|
};
|
|
286
344
|
|
|
287
|
-
let
|
|
288
|
-
|
|
289
|
-
|
|
290
|
-
|
|
345
|
+
let logUpdate = createLogUpdate(process.stdout, {showCursor: true});
|
|
346
|
+
|
|
347
|
+
let getOutput = () => {
|
|
348
|
+
return `
|
|
349
|
+
\n${process.env.CI ? `## ${schema.name}` : chalk.bold(schema.name)}
|
|
350
|
+
${schema.description ? '\n' + (process.env.CI ? `_${schema.description}_` : chalk.gray(schema.description)) : ''}
|
|
291
351
|
\n\n${chalk.blue('Instructions')}\n\n${getTable('instructions')}
|
|
292
352
|
\n\n${chalk.blue('Heap')}\n\n${getTable('rts_heap_size')}
|
|
293
|
-
\n\n${chalk.blue('Stable Memory')}\n\n${getTable('rts_logical_stable_memory_size')}
|
|
294
353
|
\n\n${chalk.blue('Garbage Collection')}\n\n${getTable('rts_reclaimed')}
|
|
295
|
-
|
|
354
|
+
${getTable('rts_logical_stable_memory_size') ? `\n\n${chalk.blue('Stable Memory')}\n\n${getTable('rts_logical_stable_memory_size')}` : ''}
|
|
355
|
+
`;
|
|
296
356
|
};
|
|
297
357
|
|
|
298
|
-
|
|
299
|
-
|
|
358
|
+
let canUpdateLog = !process.env.CI && !options.silent && terminalSize().rows > getOutput().split('\n').length;
|
|
359
|
+
|
|
360
|
+
let log = () => {
|
|
361
|
+
if (options.silent) {
|
|
362
|
+
return;
|
|
363
|
+
}
|
|
364
|
+
let output = getOutput();
|
|
365
|
+
if (process.env.CI || terminalSize().rows <= output.split('\n').length) {
|
|
366
|
+
console.log(output);
|
|
367
|
+
}
|
|
368
|
+
else {
|
|
369
|
+
logUpdate(output);
|
|
370
|
+
}
|
|
371
|
+
};
|
|
372
|
+
|
|
373
|
+
if (canUpdateLog) {
|
|
374
|
+
log();
|
|
300
375
|
}
|
|
301
376
|
|
|
302
377
|
// run all cells
|
|
@@ -314,16 +389,18 @@ async function runBenchFile(file : string, options : BenchOptions, replica : Ben
|
|
|
314
389
|
// @ts-ignore
|
|
315
390
|
reclaimedCells[rowIndex][colIndex] = res.rts_reclaimed;
|
|
316
391
|
|
|
317
|
-
if (
|
|
318
|
-
|
|
392
|
+
if (canUpdateLog) {
|
|
393
|
+
log();
|
|
319
394
|
}
|
|
320
395
|
}
|
|
321
396
|
}
|
|
322
397
|
|
|
323
|
-
if (
|
|
324
|
-
|
|
398
|
+
if (canUpdateLog) {
|
|
399
|
+
logUpdate.done();
|
|
400
|
+
}
|
|
401
|
+
else {
|
|
402
|
+
log();
|
|
325
403
|
}
|
|
326
|
-
logUpdate.done();
|
|
327
404
|
|
|
328
405
|
// save results
|
|
329
406
|
if (options.save) {
|
package/commands/init.ts
CHANGED
|
@@ -11,6 +11,7 @@ import {installAll} from './install/install-all.js';
|
|
|
11
11
|
import {VesselConfig, readVesselConfig} from '../vessel.js';
|
|
12
12
|
import {Config, Dependencies} from '../types.js';
|
|
13
13
|
import {template} from './template.js';
|
|
14
|
+
import {kebabCase} from 'change-case';
|
|
14
15
|
|
|
15
16
|
export async function init({yes = false} = {}) {
|
|
16
17
|
let configFile = path.join(process.cwd(), 'mops.toml');
|
|
@@ -88,7 +89,7 @@ export async function init({yes = false} = {}) {
|
|
|
88
89
|
type: 'text',
|
|
89
90
|
name: 'name',
|
|
90
91
|
message: 'Enter package name:',
|
|
91
|
-
initial:
|
|
92
|
+
initial: kebabCase(path.basename(process.cwd())),
|
|
92
93
|
},
|
|
93
94
|
{
|
|
94
95
|
type: 'text',
|
|
@@ -133,7 +134,7 @@ export async function init({yes = false} = {}) {
|
|
|
133
134
|
], promptsConfig);
|
|
134
135
|
|
|
135
136
|
config.package = {
|
|
136
|
-
name: (res.name || '').trim(),
|
|
137
|
+
name: kebabCase((res.name || '').trim()),
|
|
137
138
|
version: '1.0.0',
|
|
138
139
|
description: (res.description || '').trim(),
|
|
139
140
|
repository: (res.repository || '').trim(),
|
package/commands/replica.ts
CHANGED
|
@@ -87,8 +87,8 @@ export class Replica {
|
|
|
87
87
|
|
|
88
88
|
// eslint-disable-next-line
|
|
89
89
|
let config = readConfig();
|
|
90
|
-
if (config.toolchain?.['pocket-ic'] !== '
|
|
91
|
-
console.error('Current Mops CLI only supports pocket-ic
|
|
90
|
+
if (config.toolchain?.['pocket-ic'] !== '4.0.0') {
|
|
91
|
+
console.error('Current Mops CLI only supports pocket-ic 4.0.0');
|
|
92
92
|
process.exit(1);
|
|
93
93
|
}
|
|
94
94
|
|
package/commands/template.ts
CHANGED
|
@@ -2,7 +2,7 @@ import fs from 'node:fs';
|
|
|
2
2
|
import path from 'node:path';
|
|
3
3
|
import chalk from 'chalk';
|
|
4
4
|
import prompts from 'prompts';
|
|
5
|
-
import
|
|
5
|
+
import {kebabCase, pascalCase} from 'change-case';
|
|
6
6
|
import {getRootDir, readConfig} from '../mops.js';
|
|
7
7
|
import {copyTemplateFileSync} from '../templates.js';
|
|
8
8
|
|
|
@@ -99,8 +99,8 @@ export async function template(templateName ?: string, options : any = {}) {
|
|
|
99
99
|
let data = fs.readFileSync(dest).toString();
|
|
100
100
|
data = data.replace(/<year>/g, new Date().getFullYear().toString());
|
|
101
101
|
if (config.package?.name) {
|
|
102
|
-
data = data.replace(/<name>/g, config.package.name);
|
|
103
|
-
data = data.replace(/<import-name>/g,
|
|
102
|
+
data = data.replace(/<name>/g, kebabCase(config.package.name));
|
|
103
|
+
data = data.replace(/<import-name>/g, pascalCase(config.package.name));
|
|
104
104
|
}
|
|
105
105
|
fs.writeFileSync(dest, data);
|
|
106
106
|
|
|
@@ -5,6 +5,7 @@ import {getRootDir} from '../../mops.js';
|
|
|
5
5
|
type DfxConfig = {
|
|
6
6
|
$schema : string;
|
|
7
7
|
version : number;
|
|
8
|
+
profile : 'Debug' | 'Release';
|
|
8
9
|
canisters : {
|
|
9
10
|
[key : string] : {
|
|
10
11
|
type : 'motoko' | 'assets';
|
|
@@ -41,7 +42,7 @@ type DfxConfig = {
|
|
|
41
42
|
};
|
|
42
43
|
};
|
|
43
44
|
|
|
44
|
-
function readDfxJson() : DfxConfig | Record<string, never> {
|
|
45
|
+
export function readDfxJson() : DfxConfig | Record<string, never> {
|
|
45
46
|
let dfxJsonPath = path.resolve(getRootDir(), 'dfx.json');
|
|
46
47
|
if (!existsSync(dfxJsonPath)) {
|
|
47
48
|
return {};
|
package/dist/cli.js
CHANGED
|
@@ -2,6 +2,7 @@ import process from 'node:process';
|
|
|
2
2
|
import fs from 'node:fs';
|
|
3
3
|
import events from 'node:events';
|
|
4
4
|
import { Command, Argument, Option } from 'commander';
|
|
5
|
+
import chalk from 'chalk';
|
|
5
6
|
import { init } from './commands/init.js';
|
|
6
7
|
import { publish } from './commands/publish.js';
|
|
7
8
|
import { sources } from './commands/sources.js';
|
|
@@ -80,6 +81,10 @@ program
|
|
|
80
81
|
.option('--verbose')
|
|
81
82
|
.addOption(new Option('--lock <action>', 'Lockfile action').choices(['check', 'update', 'ignore']))
|
|
82
83
|
.action(async (options) => {
|
|
84
|
+
if (process.argv.at(-1) !== 'install') {
|
|
85
|
+
console.log(`${chalk.red('Error:')} ${chalk.yellow('mops install')} command installs all dependencies.\nUse ${chalk.green(`mops add ${process.argv.at(-1)}`)} instead.`);
|
|
86
|
+
process.exit(1);
|
|
87
|
+
}
|
|
83
88
|
if (!checkConfigFile()) {
|
|
84
89
|
process.exit(1);
|
|
85
90
|
}
|
|
@@ -1,6 +1,6 @@
|
|
|
1
1
|
import { PocketIc, PocketIcServer } from 'pic-ic';
|
|
2
2
|
export declare class BenchReplica {
|
|
3
|
-
type: 'dfx' | 'pocket-ic';
|
|
3
|
+
type: 'dfx' | 'pocket-ic' | 'dfx-pocket-ic';
|
|
4
4
|
verbose: boolean;
|
|
5
5
|
canisters: Record<string, {
|
|
6
6
|
cwd: string;
|
|
@@ -9,7 +9,7 @@ export declare class BenchReplica {
|
|
|
9
9
|
}>;
|
|
10
10
|
pocketIcServer?: PocketIcServer;
|
|
11
11
|
pocketIc?: PocketIc;
|
|
12
|
-
constructor(type: 'dfx' | 'pocket-ic', verbose?: boolean);
|
|
12
|
+
constructor(type: 'dfx' | 'pocket-ic' | 'dfx-pocket-ic', verbose?: boolean);
|
|
13
13
|
start({ silent }?: {
|
|
14
14
|
silent?: boolean | undefined;
|
|
15
15
|
}): Promise<void>;
|
|
@@ -20,6 +20,7 @@ export declare class BenchReplica {
|
|
|
20
20
|
dfxJson(canisterName: string): {
|
|
21
21
|
version: number;
|
|
22
22
|
canisters: Record<string, any>;
|
|
23
|
+
dfx: string;
|
|
23
24
|
defaults: {
|
|
24
25
|
build: {
|
|
25
26
|
packtool: string;
|
|
@@ -7,6 +7,7 @@ import { PocketIc, PocketIcServer } from 'pic-ic';
|
|
|
7
7
|
import { getRootDir, readConfig } from '../mops.js';
|
|
8
8
|
import { createActor, idlFactory } from '../declarations/bench/index.js';
|
|
9
9
|
import { toolchain } from './toolchain/index.js';
|
|
10
|
+
import { getDfxVersion } from '../helpers/get-dfx-version.js';
|
|
10
11
|
export class BenchReplica {
|
|
11
12
|
constructor(type, verbose = false) {
|
|
12
13
|
this.verbose = false;
|
|
@@ -15,18 +16,20 @@ export class BenchReplica {
|
|
|
15
16
|
this.verbose = verbose;
|
|
16
17
|
}
|
|
17
18
|
async start({ silent = false } = {}) {
|
|
18
|
-
|
|
19
|
-
|
|
19
|
+
if (!process.env.CI && !silent) {
|
|
20
|
+
console.log(`Starting ${this.type} replica...`);
|
|
21
|
+
}
|
|
22
|
+
if (this.type == 'dfx' || this.type === 'dfx-pocket-ic') {
|
|
20
23
|
await this.stop();
|
|
21
24
|
let dir = path.join(getRootDir(), '.mops/.bench');
|
|
22
25
|
fs.writeFileSync(path.join(dir, 'dfx.json'), JSON.stringify(this.dfxJson(''), null, 2));
|
|
23
|
-
execSync('dfx start --background --clean --artificial-delay 0' + (this.verbose ? '' : ' -qqqq'), { cwd: dir, stdio: ['inherit', this.verbose ? 'inherit' : 'ignore', 'inherit'] });
|
|
26
|
+
execSync('dfx start --background --clean --artificial-delay 0' + (this.type === 'dfx-pocket-ic' ? ' --pocketic' : '') + (this.verbose ? '' : ' -qqqq'), { cwd: dir, stdio: ['inherit', this.verbose ? 'inherit' : 'ignore', 'inherit'] });
|
|
24
27
|
}
|
|
25
28
|
else {
|
|
26
29
|
let pocketIcBin = await toolchain.bin('pocket-ic');
|
|
27
30
|
let config = readConfig();
|
|
28
|
-
if (config.toolchain?.['pocket-ic'] !== '
|
|
29
|
-
console.error('Current Mops CLI only supports pocket-ic
|
|
31
|
+
if (config.toolchain?.['pocket-ic'] !== '4.0.0') {
|
|
32
|
+
console.error('Current Mops CLI only supports pocket-ic 4.0.0');
|
|
30
33
|
process.exit(1);
|
|
31
34
|
}
|
|
32
35
|
this.pocketIcServer = await PocketIcServer.start({
|
|
@@ -36,7 +39,7 @@ export class BenchReplica {
|
|
|
36
39
|
}
|
|
37
40
|
}
|
|
38
41
|
async stop() {
|
|
39
|
-
if (this.type == 'dfx') {
|
|
42
|
+
if (this.type == 'dfx' || this.type === 'dfx-pocket-ic') {
|
|
40
43
|
let dir = path.join(getRootDir(), '.mops/.bench');
|
|
41
44
|
execSync('dfx stop' + (this.verbose ? '' : ' -qqqq'), { cwd: dir, stdio: ['pipe', this.verbose ? 'inherit' : 'ignore', 'pipe'] });
|
|
42
45
|
}
|
|
@@ -46,7 +49,7 @@ export class BenchReplica {
|
|
|
46
49
|
}
|
|
47
50
|
}
|
|
48
51
|
async deploy(name, wasm, cwd = process.cwd()) {
|
|
49
|
-
if (this.type === 'dfx') {
|
|
52
|
+
if (this.type === 'dfx' || this.type === 'dfx-pocket-ic') {
|
|
50
53
|
await execaCommand(`dfx deploy ${name} --mode reinstall --yes --identity anonymous`, { cwd, stdio: this.verbose ? 'pipe' : ['pipe', 'ignore', 'pipe'] });
|
|
51
54
|
let canisterId = execSync(`dfx canister id ${name}`, { cwd }).toString().trim();
|
|
52
55
|
let actor = await createActor(canisterId, {
|
|
@@ -83,6 +86,7 @@ export class BenchReplica {
|
|
|
83
86
|
return {
|
|
84
87
|
version: 1,
|
|
85
88
|
canisters,
|
|
89
|
+
dfx: getDfxVersion(),
|
|
86
90
|
defaults: {
|
|
87
91
|
build: {
|
|
88
92
|
packtool: 'mops sources',
|
package/dist/commands/bench.d.ts
CHANGED
|
@@ -1,6 +1,7 @@
|
|
|
1
1
|
import { Benchmarks } from '../declarations/main/main.did.js';
|
|
2
|
+
type ReplicaName = 'dfx' | 'pocket-ic' | 'dfx-pocket-ic';
|
|
2
3
|
type BenchOptions = {
|
|
3
|
-
replica:
|
|
4
|
+
replica: ReplicaName;
|
|
4
5
|
replicaVersion: string;
|
|
5
6
|
compiler: 'moc';
|
|
6
7
|
compilerVersion: string;
|
|
@@ -10,6 +11,7 @@ type BenchOptions = {
|
|
|
10
11
|
compare: boolean;
|
|
11
12
|
verbose: boolean;
|
|
12
13
|
silent: boolean;
|
|
14
|
+
profile: 'Debug' | 'Release';
|
|
13
15
|
};
|
|
14
16
|
export declare function bench(filter?: string, optionsArg?: Partial<BenchOptions>): Promise<Benchmarks>;
|
|
15
17
|
export {};
|
package/dist/commands/bench.js
CHANGED
|
@@ -5,10 +5,13 @@ import os from 'node:os';
|
|
|
5
5
|
import chalk from 'chalk';
|
|
6
6
|
import { globSync } from 'glob';
|
|
7
7
|
import { markdownTable } from 'markdown-table';
|
|
8
|
-
import
|
|
8
|
+
import { createLogUpdate } from 'log-update';
|
|
9
9
|
import { execaCommand } from 'execa';
|
|
10
10
|
import stringWidth from 'string-width';
|
|
11
|
-
import {
|
|
11
|
+
import { filesize } from 'filesize';
|
|
12
|
+
import terminalSize from 'terminal-size';
|
|
13
|
+
import { SemVer } from 'semver';
|
|
14
|
+
import { getRootDir, readConfig, readDfxJson } from '../mops.js';
|
|
12
15
|
import { parallel } from '../parallel.js';
|
|
13
16
|
import { absToRel } from './test/utils.js';
|
|
14
17
|
import { getMocVersion } from '../helpers/get-moc-version.js';
|
|
@@ -16,7 +19,6 @@ import { getDfxVersion } from '../helpers/get-dfx-version.js';
|
|
|
16
19
|
import { getMocPath } from '../helpers/get-moc-path.js';
|
|
17
20
|
import { sources } from './sources.js';
|
|
18
21
|
import { BenchReplica } from './bench-replica.js';
|
|
19
|
-
import { filesize } from 'filesize';
|
|
20
22
|
let ignore = [
|
|
21
23
|
'**/node_modules/**',
|
|
22
24
|
'**/.mops/**',
|
|
@@ -29,6 +31,7 @@ let globConfig = {
|
|
|
29
31
|
};
|
|
30
32
|
export async function bench(filter = '', optionsArg = {}) {
|
|
31
33
|
let config = readConfig();
|
|
34
|
+
let dfxJson = readDfxJson();
|
|
32
35
|
let defaultOptions = {
|
|
33
36
|
replica: config.toolchain?.['pocket-ic'] ? 'pocket-ic' : 'dfx',
|
|
34
37
|
replicaVersion: '',
|
|
@@ -40,16 +43,32 @@ export async function bench(filter = '', optionsArg = {}) {
|
|
|
40
43
|
compare: false,
|
|
41
44
|
verbose: false,
|
|
42
45
|
silent: false,
|
|
46
|
+
profile: dfxJson.profile || 'Release',
|
|
43
47
|
};
|
|
44
48
|
let options = { ...defaultOptions, ...optionsArg };
|
|
45
|
-
|
|
49
|
+
let replicaType = options.replica ?? (config.toolchain?.['pocket-ic'] ? 'pocket-ic' : 'dfx');
|
|
50
|
+
if (replicaType === 'pocket-ic' && !config.toolchain?.['pocket-ic']) {
|
|
51
|
+
let dfxVersion = getDfxVersion();
|
|
52
|
+
if (!dfxVersion || new SemVer(dfxVersion).compare('0.24.1') < 0) {
|
|
53
|
+
console.log(chalk.red('Please update dfx to the version >=0.24.1 or specify pocket-ic version in mops.toml'));
|
|
54
|
+
process.exit(1);
|
|
55
|
+
}
|
|
56
|
+
else {
|
|
57
|
+
replicaType = 'dfx-pocket-ic';
|
|
58
|
+
}
|
|
59
|
+
}
|
|
60
|
+
options.replica = replicaType;
|
|
61
|
+
if (process.env.CI) {
|
|
62
|
+
console.log('# Benchmark Results\n\n');
|
|
63
|
+
}
|
|
64
|
+
if (replicaType == 'dfx') {
|
|
46
65
|
options.replicaVersion = getDfxVersion();
|
|
47
66
|
}
|
|
48
|
-
else if (
|
|
67
|
+
else if (replicaType == 'pocket-ic') {
|
|
49
68
|
options.replicaVersion = config.toolchain?.['pocket-ic'] || '';
|
|
50
69
|
}
|
|
51
70
|
options.verbose && console.log(options);
|
|
52
|
-
let replica = new BenchReplica(
|
|
71
|
+
let replica = new BenchReplica(replicaType, options.verbose);
|
|
53
72
|
let rootDir = getRootDir();
|
|
54
73
|
let globStr = '**/bench?(mark)/**/*.bench.mo';
|
|
55
74
|
if (filter) {
|
|
@@ -76,12 +95,16 @@ export async function bench(filter = '', optionsArg = {}) {
|
|
|
76
95
|
for (let file of files) {
|
|
77
96
|
console.log(chalk.gray(`• ${absToRel(file)}`));
|
|
78
97
|
}
|
|
79
|
-
|
|
80
|
-
|
|
81
|
-
|
|
98
|
+
if (!process.env.CI) {
|
|
99
|
+
console.log('');
|
|
100
|
+
console.log('='.repeat(50));
|
|
101
|
+
console.log('');
|
|
102
|
+
}
|
|
82
103
|
}
|
|
83
104
|
await replica.start({ silent: options.silent });
|
|
84
|
-
|
|
105
|
+
if (!process.env.CI && !options.silent) {
|
|
106
|
+
console.log('Deploying canisters...');
|
|
107
|
+
}
|
|
85
108
|
await parallel(os.cpus().length, files, async (file) => {
|
|
86
109
|
try {
|
|
87
110
|
await deployBenchFile(file, options, replica);
|
|
@@ -94,8 +117,8 @@ export async function bench(filter = '', optionsArg = {}) {
|
|
|
94
117
|
});
|
|
95
118
|
let benchResults = [];
|
|
96
119
|
await parallel(1, files, async (file) => {
|
|
97
|
-
if (!options.silent) {
|
|
98
|
-
console.log('\n' + '
|
|
120
|
+
if (!options.silent && !process.env.CI) {
|
|
121
|
+
console.log('\n' + '-'.repeat(50));
|
|
99
122
|
console.log(`\nRunning ${chalk.gray(absToRel(file))}...`);
|
|
100
123
|
console.log('');
|
|
101
124
|
}
|
|
@@ -109,7 +132,9 @@ export async function bench(filter = '', optionsArg = {}) {
|
|
|
109
132
|
throw err;
|
|
110
133
|
}
|
|
111
134
|
});
|
|
112
|
-
|
|
135
|
+
if (!process.env.CI && !options.silent) {
|
|
136
|
+
console.log('Stopping replica...');
|
|
137
|
+
}
|
|
113
138
|
await replica.stop();
|
|
114
139
|
fs.rmSync(benchDir, { recursive: true, force: true });
|
|
115
140
|
return benchResults;
|
|
@@ -122,6 +147,12 @@ function getMocArgs(options) {
|
|
|
122
147
|
if (options.gc) {
|
|
123
148
|
args += ` --${options.gc}-gc`;
|
|
124
149
|
}
|
|
150
|
+
if (options.profile === 'Debug') {
|
|
151
|
+
args += ' --debug';
|
|
152
|
+
}
|
|
153
|
+
else if (options.profile === 'Release') {
|
|
154
|
+
args += ' --release';
|
|
155
|
+
}
|
|
125
156
|
return args;
|
|
126
157
|
}
|
|
127
158
|
async function deployBenchFile(file, options, replica) {
|
|
@@ -182,21 +213,33 @@ async function runBenchFile(file, options, replica) {
|
|
|
182
213
|
};
|
|
183
214
|
let getTable = (prop) => {
|
|
184
215
|
let resArr = [['', ...schema.cols]];
|
|
216
|
+
let allZero = true;
|
|
185
217
|
for (let [_rowIndex, row] of schema.rows.entries()) {
|
|
186
218
|
let curRow = [row];
|
|
187
219
|
for (let [_colIndex, col] of schema.cols.entries()) {
|
|
188
220
|
let res = results.get(`${row}:${col}`);
|
|
189
221
|
if (res) {
|
|
222
|
+
if (res[prop] != 0n) {
|
|
223
|
+
allZero = false;
|
|
224
|
+
}
|
|
190
225
|
// compare with previous results
|
|
191
226
|
let diff = '';
|
|
192
227
|
if (options.compare && prevResults) {
|
|
193
228
|
let prevRes = prevResults.get(`${row}:${col}`);
|
|
194
229
|
if (prevRes) {
|
|
195
230
|
let percent = (Number(res[prop]) - Number(prevRes[prop])) / Number(prevRes[prop]) * 100;
|
|
231
|
+
if (Object.is(percent, NaN)) {
|
|
232
|
+
percent = 0;
|
|
233
|
+
}
|
|
196
234
|
let sign = percent > 0 ? '+' : '';
|
|
197
235
|
let percentText = percent == 0 ? '0%' : sign + percent.toFixed(2) + '%';
|
|
198
236
|
let color = percent == 0 ? 'gray' : (percent > 0 ? 'red' : 'green');
|
|
199
|
-
|
|
237
|
+
if (process.env.CI) {
|
|
238
|
+
diff = ` $({\\color{${color}}${percentText.replace('%', '\\\\%')}})$`;
|
|
239
|
+
}
|
|
240
|
+
else {
|
|
241
|
+
diff = ` (${chalk[color](percentText)})`;
|
|
242
|
+
}
|
|
200
243
|
}
|
|
201
244
|
else {
|
|
202
245
|
diff = chalk.yellow(' (no previous results)');
|
|
@@ -221,23 +264,41 @@ async function runBenchFile(file, options, replica) {
|
|
|
221
264
|
}
|
|
222
265
|
resArr.push(curRow);
|
|
223
266
|
}
|
|
267
|
+
// don't show Stable Memory table if all values are 0
|
|
268
|
+
if (allZero && prop == 'rts_logical_stable_memory_size') {
|
|
269
|
+
return '';
|
|
270
|
+
}
|
|
224
271
|
return markdownTable(resArr, {
|
|
225
272
|
align: ['l', ...'r'.repeat(schema.cols.length)],
|
|
226
273
|
stringLength: stringWidth,
|
|
227
274
|
});
|
|
228
275
|
};
|
|
229
|
-
let
|
|
230
|
-
|
|
231
|
-
|
|
232
|
-
${
|
|
276
|
+
let logUpdate = createLogUpdate(process.stdout, { showCursor: true });
|
|
277
|
+
let getOutput = () => {
|
|
278
|
+
return `
|
|
279
|
+
\n${process.env.CI ? `## ${schema.name}` : chalk.bold(schema.name)}
|
|
280
|
+
${schema.description ? '\n' + (process.env.CI ? `_${schema.description}_` : chalk.gray(schema.description)) : ''}
|
|
233
281
|
\n\n${chalk.blue('Instructions')}\n\n${getTable('instructions')}
|
|
234
282
|
\n\n${chalk.blue('Heap')}\n\n${getTable('rts_heap_size')}
|
|
235
|
-
\n\n${chalk.blue('Stable Memory')}\n\n${getTable('rts_logical_stable_memory_size')}
|
|
236
283
|
\n\n${chalk.blue('Garbage Collection')}\n\n${getTable('rts_reclaimed')}
|
|
237
|
-
|
|
284
|
+
${getTable('rts_logical_stable_memory_size') ? `\n\n${chalk.blue('Stable Memory')}\n\n${getTable('rts_logical_stable_memory_size')}` : ''}
|
|
285
|
+
`;
|
|
238
286
|
};
|
|
239
|
-
|
|
240
|
-
|
|
287
|
+
let canUpdateLog = !process.env.CI && !options.silent && terminalSize().rows > getOutput().split('\n').length;
|
|
288
|
+
let log = () => {
|
|
289
|
+
if (options.silent) {
|
|
290
|
+
return;
|
|
291
|
+
}
|
|
292
|
+
let output = getOutput();
|
|
293
|
+
if (process.env.CI || terminalSize().rows <= output.split('\n').length) {
|
|
294
|
+
console.log(output);
|
|
295
|
+
}
|
|
296
|
+
else {
|
|
297
|
+
logUpdate(output);
|
|
298
|
+
}
|
|
299
|
+
};
|
|
300
|
+
if (canUpdateLog) {
|
|
301
|
+
log();
|
|
241
302
|
}
|
|
242
303
|
// run all cells
|
|
243
304
|
for (let [rowIndex, row] of schema.rows.entries()) {
|
|
@@ -252,15 +313,17 @@ async function runBenchFile(file, options, replica) {
|
|
|
252
313
|
logicalStableMemoryCells[rowIndex][colIndex] = res.rts_logical_stable_memory_size;
|
|
253
314
|
// @ts-ignore
|
|
254
315
|
reclaimedCells[rowIndex][colIndex] = res.rts_reclaimed;
|
|
255
|
-
if (
|
|
256
|
-
|
|
316
|
+
if (canUpdateLog) {
|
|
317
|
+
log();
|
|
257
318
|
}
|
|
258
319
|
}
|
|
259
320
|
}
|
|
260
|
-
if (
|
|
261
|
-
|
|
321
|
+
if (canUpdateLog) {
|
|
322
|
+
logUpdate.done();
|
|
323
|
+
}
|
|
324
|
+
else {
|
|
325
|
+
log();
|
|
262
326
|
}
|
|
263
|
-
logUpdate.done();
|
|
264
327
|
// save results
|
|
265
328
|
if (options.save) {
|
|
266
329
|
console.log(`Saving results to ${chalk.gray(absToRel(resultsJsonFile))}`);
|
package/dist/commands/init.js
CHANGED
|
@@ -9,6 +9,7 @@ import { mainActor } from '../api/actors.js';
|
|
|
9
9
|
import { installAll } from './install/install-all.js';
|
|
10
10
|
import { readVesselConfig } from '../vessel.js';
|
|
11
11
|
import { template } from './template.js';
|
|
12
|
+
import { kebabCase } from 'change-case';
|
|
12
13
|
export async function init({ yes = false } = {}) {
|
|
13
14
|
let configFile = path.join(process.cwd(), 'mops.toml');
|
|
14
15
|
let exists = existsSync(configFile);
|
|
@@ -73,7 +74,7 @@ export async function init({ yes = false } = {}) {
|
|
|
73
74
|
type: 'text',
|
|
74
75
|
name: 'name',
|
|
75
76
|
message: 'Enter package name:',
|
|
76
|
-
initial:
|
|
77
|
+
initial: kebabCase(path.basename(process.cwd())),
|
|
77
78
|
},
|
|
78
79
|
{
|
|
79
80
|
type: 'text',
|
|
@@ -117,7 +118,7 @@ export async function init({ yes = false } = {}) {
|
|
|
117
118
|
},
|
|
118
119
|
], promptsConfig);
|
|
119
120
|
config.package = {
|
|
120
|
-
name: (res.name || '').trim(),
|
|
121
|
+
name: kebabCase((res.name || '').trim()),
|
|
121
122
|
version: '1.0.0',
|
|
122
123
|
description: (res.description || '').trim(),
|
|
123
124
|
repository: (res.repository || '').trim(),
|
package/dist/commands/replica.js
CHANGED
|
@@ -65,8 +65,8 @@ export class Replica {
|
|
|
65
65
|
let pocketIcBin = await toolchain.bin('pocket-ic');
|
|
66
66
|
// eslint-disable-next-line
|
|
67
67
|
let config = readConfig();
|
|
68
|
-
if (config.toolchain?.['pocket-ic'] !== '
|
|
69
|
-
console.error('Current Mops CLI only supports pocket-ic
|
|
68
|
+
if (config.toolchain?.['pocket-ic'] !== '4.0.0') {
|
|
69
|
+
console.error('Current Mops CLI only supports pocket-ic 4.0.0');
|
|
70
70
|
process.exit(1);
|
|
71
71
|
}
|
|
72
72
|
this.pocketIcServer = await PocketIcServer.start({
|
|
@@ -2,7 +2,7 @@ import fs from 'node:fs';
|
|
|
2
2
|
import path from 'node:path';
|
|
3
3
|
import chalk from 'chalk';
|
|
4
4
|
import prompts from 'prompts';
|
|
5
|
-
import
|
|
5
|
+
import { kebabCase, pascalCase } from 'change-case';
|
|
6
6
|
import { getRootDir, readConfig } from '../mops.js';
|
|
7
7
|
import { copyTemplateFileSync } from '../templates.js';
|
|
8
8
|
export async function template(templateName, options = {}) {
|
|
@@ -93,8 +93,8 @@ export async function template(templateName, options = {}) {
|
|
|
93
93
|
let data = fs.readFileSync(dest).toString();
|
|
94
94
|
data = data.replace(/<year>/g, new Date().getFullYear().toString());
|
|
95
95
|
if (config.package?.name) {
|
|
96
|
-
data = data.replace(/<name>/g, config.package.name);
|
|
97
|
-
data = data.replace(/<import-name>/g,
|
|
96
|
+
data = data.replace(/<name>/g, kebabCase(config.package.name));
|
|
97
|
+
data = data.replace(/<import-name>/g, pascalCase(config.package.name));
|
|
98
98
|
}
|
|
99
99
|
fs.writeFileSync(dest, data);
|
|
100
100
|
console.log(chalk.green('Created'), path.relative(getRootDir(), 'README.md'));
|
|
@@ -1,2 +1,43 @@
|
|
|
1
|
+
type DfxConfig = {
|
|
2
|
+
$schema: string;
|
|
3
|
+
version: number;
|
|
4
|
+
profile: 'Debug' | 'Release';
|
|
5
|
+
canisters: {
|
|
6
|
+
[key: string]: {
|
|
7
|
+
type: 'motoko' | 'assets';
|
|
8
|
+
main?: string;
|
|
9
|
+
specified_id?: string;
|
|
10
|
+
declarations?: {
|
|
11
|
+
output: string;
|
|
12
|
+
node_compatibility: boolean;
|
|
13
|
+
};
|
|
14
|
+
build?: string[];
|
|
15
|
+
frontend?: {
|
|
16
|
+
entrypoint: string;
|
|
17
|
+
};
|
|
18
|
+
source?: string[];
|
|
19
|
+
remote?: {
|
|
20
|
+
id: {
|
|
21
|
+
ic: string;
|
|
22
|
+
staging: string;
|
|
23
|
+
};
|
|
24
|
+
};
|
|
25
|
+
};
|
|
26
|
+
};
|
|
27
|
+
defaults: {
|
|
28
|
+
build: {
|
|
29
|
+
packtool: string;
|
|
30
|
+
};
|
|
31
|
+
};
|
|
32
|
+
dfx: string;
|
|
33
|
+
networks: {
|
|
34
|
+
[key: string]: {
|
|
35
|
+
type: string;
|
|
36
|
+
providers: string[];
|
|
37
|
+
};
|
|
38
|
+
};
|
|
39
|
+
};
|
|
40
|
+
export declare function readDfxJson(): DfxConfig | Record<string, never>;
|
|
1
41
|
export declare function getMotokoCanisters(): Record<string, string>;
|
|
2
42
|
export declare function getMotokoCanistersWithDeclarations(): Record<string, string>;
|
|
43
|
+
export {};
|
|
@@ -1,7 +1,7 @@
|
|
|
1
1
|
import { existsSync, readFileSync } from 'node:fs';
|
|
2
2
|
import path from 'node:path';
|
|
3
3
|
import { getRootDir } from '../../mops.js';
|
|
4
|
-
function readDfxJson() {
|
|
4
|
+
export function readDfxJson() {
|
|
5
5
|
let dfxJsonPath = path.resolve(getRootDir(), 'dfx.json');
|
|
6
6
|
if (!existsSync(dfxJsonPath)) {
|
|
7
7
|
return {};
|
package/dist/package.json
CHANGED
|
@@ -1,6 +1,6 @@
|
|
|
1
1
|
{
|
|
2
2
|
"name": "ic-mops",
|
|
3
|
-
"version": "1.
|
|
3
|
+
"version": "1.5.0",
|
|
4
4
|
"type": "module",
|
|
5
5
|
"bin": {
|
|
6
6
|
"mops": "bin/mops.js",
|
|
@@ -28,20 +28,20 @@
|
|
|
28
28
|
"node": ">=18.0.0"
|
|
29
29
|
},
|
|
30
30
|
"dependencies": {
|
|
31
|
-
"@dfinity/agent": "2.
|
|
32
|
-
"@dfinity/candid": "2.
|
|
33
|
-
"@dfinity/identity": "2.
|
|
34
|
-
"@dfinity/identity-secp256k1": "2.
|
|
35
|
-
"@dfinity/principal": "2.
|
|
31
|
+
"@dfinity/agent": "2.3.0",
|
|
32
|
+
"@dfinity/candid": "2.3.0",
|
|
33
|
+
"@dfinity/identity": "2.3.0",
|
|
34
|
+
"@dfinity/identity-secp256k1": "2.3.0",
|
|
35
|
+
"@dfinity/principal": "2.3.0",
|
|
36
36
|
"@iarna/toml": "2.2.5",
|
|
37
|
-
"@noble/hashes": "1.
|
|
37
|
+
"@noble/hashes": "1.7.1",
|
|
38
38
|
"as-table": "1.0.55",
|
|
39
39
|
"buffer": "6.0.3",
|
|
40
40
|
"cacheable-request": "12.0.1",
|
|
41
|
-
"
|
|
42
|
-
"
|
|
41
|
+
"chalk": "5.4.1",
|
|
42
|
+
"change-case": "5.4.4",
|
|
43
43
|
"chokidar": "3.6.0",
|
|
44
|
-
"commander": "
|
|
44
|
+
"commander": "13.1.0",
|
|
45
45
|
"debounce": "2.1.1",
|
|
46
46
|
"decomp-tarxz": "0.1.1",
|
|
47
47
|
"decompress": "4.2.1",
|
|
@@ -51,25 +51,26 @@
|
|
|
51
51
|
"filesize": "10.1.6",
|
|
52
52
|
"fs-extra": "11.2.0",
|
|
53
53
|
"get-folder-size": "5.0.0",
|
|
54
|
-
"glob": "11.0.
|
|
54
|
+
"glob": "11.0.1",
|
|
55
55
|
"globby": "14.0.2",
|
|
56
|
-
"got": "14.4.
|
|
56
|
+
"got": "14.4.6",
|
|
57
57
|
"log-update": "6.1.0",
|
|
58
|
-
"markdown-table": "3.0.
|
|
59
|
-
"mdast-util-from-markdown": "2.0.
|
|
60
|
-
"mdast-util-to-markdown": "2.1.
|
|
58
|
+
"markdown-table": "3.0.4",
|
|
59
|
+
"mdast-util-from-markdown": "2.0.2",
|
|
60
|
+
"mdast-util-to-markdown": "2.1.2",
|
|
61
61
|
"minimatch": "10.0.1",
|
|
62
62
|
"ncp": "2.0.0",
|
|
63
63
|
"node-fetch": "3.3.2",
|
|
64
64
|
"octokit": "3.1.2",
|
|
65
65
|
"pem-file": "1.0.1",
|
|
66
|
-
"pic-ic": "0.
|
|
66
|
+
"pic-ic": "0.5.3",
|
|
67
67
|
"promisify-child-process": "4.1.2",
|
|
68
68
|
"prompts": "2.4.2",
|
|
69
|
-
"semver": "7.
|
|
69
|
+
"semver": "7.7.1",
|
|
70
70
|
"stream-to-promise": "3.0.0",
|
|
71
71
|
"string-width": "7.2.0",
|
|
72
|
-
"tar": "7.4.3"
|
|
72
|
+
"tar": "7.4.3",
|
|
73
|
+
"terminal-size": "4.0.0"
|
|
73
74
|
},
|
|
74
75
|
"devDependencies": {
|
|
75
76
|
"@tsconfig/strictest": "2.0.5",
|
|
@@ -78,7 +79,7 @@
|
|
|
78
79
|
"@types/fs-extra": "11.0.4",
|
|
79
80
|
"@types/glob": "8.1.0",
|
|
80
81
|
"@types/ncp": "2.0.8",
|
|
81
|
-
"@types/node": "22.
|
|
82
|
+
"@types/node": "22.13.4",
|
|
82
83
|
"@types/prompts": "2.4.9",
|
|
83
84
|
"@types/semver": "7.5.8",
|
|
84
85
|
"@types/stream-to-promise": "2.2.4",
|
|
@@ -86,7 +87,7 @@
|
|
|
86
87
|
"bun": "1.1.27",
|
|
87
88
|
"esbuild": "0.23.1",
|
|
88
89
|
"eslint": "8.57.0",
|
|
89
|
-
"tsx": "4.19.
|
|
90
|
-
"typescript": "5.
|
|
90
|
+
"tsx": "4.19.2",
|
|
91
|
+
"typescript": "5.7.3"
|
|
91
92
|
}
|
|
92
93
|
}
|
package/dist/pem.d.ts
CHANGED
|
@@ -2,4 +2,4 @@ import { Buffer } from 'node:buffer';
|
|
|
2
2
|
import { Ed25519KeyIdentity } from '@dfinity/identity';
|
|
3
3
|
import { Secp256k1KeyIdentity } from '@dfinity/identity-secp256k1';
|
|
4
4
|
export declare function decodeFile(file: string, password?: string): Secp256k1KeyIdentity | Ed25519KeyIdentity;
|
|
5
|
-
export declare function encrypt(buffer: Buffer, password: string): Buffer
|
|
5
|
+
export declare function encrypt(buffer: Buffer, password: string): Buffer<ArrayBuffer>;
|
package/package.json
CHANGED
|
@@ -1,6 +1,6 @@
|
|
|
1
1
|
{
|
|
2
2
|
"name": "ic-mops",
|
|
3
|
-
"version": "1.
|
|
3
|
+
"version": "1.5.0",
|
|
4
4
|
"type": "module",
|
|
5
5
|
"bin": {
|
|
6
6
|
"mops": "dist/bin/mops.js",
|
|
@@ -44,20 +44,20 @@
|
|
|
44
44
|
"esbuild": "esbuild"
|
|
45
45
|
},
|
|
46
46
|
"dependencies": {
|
|
47
|
-
"@dfinity/agent": "2.
|
|
48
|
-
"@dfinity/candid": "2.
|
|
49
|
-
"@dfinity/identity": "2.
|
|
50
|
-
"@dfinity/identity-secp256k1": "2.
|
|
51
|
-
"@dfinity/principal": "2.
|
|
47
|
+
"@dfinity/agent": "2.3.0",
|
|
48
|
+
"@dfinity/candid": "2.3.0",
|
|
49
|
+
"@dfinity/identity": "2.3.0",
|
|
50
|
+
"@dfinity/identity-secp256k1": "2.3.0",
|
|
51
|
+
"@dfinity/principal": "2.3.0",
|
|
52
52
|
"@iarna/toml": "2.2.5",
|
|
53
|
-
"@noble/hashes": "1.
|
|
53
|
+
"@noble/hashes": "1.7.1",
|
|
54
54
|
"as-table": "1.0.55",
|
|
55
55
|
"buffer": "6.0.3",
|
|
56
56
|
"cacheable-request": "12.0.1",
|
|
57
|
-
"
|
|
58
|
-
"
|
|
57
|
+
"chalk": "5.4.1",
|
|
58
|
+
"change-case": "5.4.4",
|
|
59
59
|
"chokidar": "3.6.0",
|
|
60
|
-
"commander": "
|
|
60
|
+
"commander": "13.1.0",
|
|
61
61
|
"debounce": "2.1.1",
|
|
62
62
|
"decomp-tarxz": "0.1.1",
|
|
63
63
|
"decompress": "4.2.1",
|
|
@@ -67,25 +67,26 @@
|
|
|
67
67
|
"filesize": "10.1.6",
|
|
68
68
|
"fs-extra": "11.2.0",
|
|
69
69
|
"get-folder-size": "5.0.0",
|
|
70
|
-
"glob": "11.0.
|
|
70
|
+
"glob": "11.0.1",
|
|
71
71
|
"globby": "14.0.2",
|
|
72
|
-
"got": "14.4.
|
|
72
|
+
"got": "14.4.6",
|
|
73
73
|
"log-update": "6.1.0",
|
|
74
|
-
"markdown-table": "3.0.
|
|
75
|
-
"mdast-util-from-markdown": "2.0.
|
|
76
|
-
"mdast-util-to-markdown": "2.1.
|
|
74
|
+
"markdown-table": "3.0.4",
|
|
75
|
+
"mdast-util-from-markdown": "2.0.2",
|
|
76
|
+
"mdast-util-to-markdown": "2.1.2",
|
|
77
77
|
"minimatch": "10.0.1",
|
|
78
78
|
"ncp": "2.0.0",
|
|
79
79
|
"node-fetch": "3.3.2",
|
|
80
80
|
"octokit": "3.1.2",
|
|
81
81
|
"pem-file": "1.0.1",
|
|
82
|
-
"pic-ic": "0.
|
|
82
|
+
"pic-ic": "0.5.3",
|
|
83
83
|
"promisify-child-process": "4.1.2",
|
|
84
84
|
"prompts": "2.4.2",
|
|
85
|
-
"semver": "7.
|
|
85
|
+
"semver": "7.7.1",
|
|
86
86
|
"stream-to-promise": "3.0.0",
|
|
87
87
|
"string-width": "7.2.0",
|
|
88
|
-
"tar": "7.4.3"
|
|
88
|
+
"tar": "7.4.3",
|
|
89
|
+
"terminal-size": "4.0.0"
|
|
89
90
|
},
|
|
90
91
|
"devDependencies": {
|
|
91
92
|
"@tsconfig/strictest": "2.0.5",
|
|
@@ -94,7 +95,7 @@
|
|
|
94
95
|
"@types/fs-extra": "11.0.4",
|
|
95
96
|
"@types/glob": "8.1.0",
|
|
96
97
|
"@types/ncp": "2.0.8",
|
|
97
|
-
"@types/node": "22.
|
|
98
|
+
"@types/node": "22.13.4",
|
|
98
99
|
"@types/prompts": "2.4.9",
|
|
99
100
|
"@types/semver": "7.5.8",
|
|
100
101
|
"@types/stream-to-promise": "2.2.4",
|
|
@@ -102,7 +103,7 @@
|
|
|
102
103
|
"bun": "1.1.27",
|
|
103
104
|
"esbuild": "0.23.1",
|
|
104
105
|
"eslint": "8.57.0",
|
|
105
|
-
"tsx": "4.19.
|
|
106
|
-
"typescript": "5.
|
|
106
|
+
"tsx": "4.19.2",
|
|
107
|
+
"typescript": "5.7.3"
|
|
107
108
|
}
|
|
108
109
|
}
|