ic-mops 1.5.0 → 1.6.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 +7 -0
- package/bundle/cli.tgz +0 -0
- package/commands/bench.ts +95 -20
- package/commands/toolchain/index.ts +5 -2
- package/dist/commands/bench.js +76 -19
- package/dist/commands/toolchain/index.js +5 -2
- package/dist/package.json +1 -1
- package/package.json +1 -1
package/CHANGELOG.md
CHANGED
|
@@ -1,5 +1,12 @@
|
|
|
1
1
|
# Mops CLI Changelog
|
|
2
2
|
|
|
3
|
+
## 1.6.0
|
|
4
|
+
- Add support for `.bash_profile` and `.zprofile` files to `mops toolchain init` command
|
|
5
|
+
|
|
6
|
+
## 1.5.1
|
|
7
|
+
- Collapsible output of `mops bench` in a CI environment
|
|
8
|
+
- Fix regression in `mops bench` without `dfx.json` file (by @rvanasa)
|
|
9
|
+
|
|
3
10
|
## 1.5.0
|
|
4
11
|
- Compile benchmarks with `--release` flag by default
|
|
5
12
|
- Respect `profile` field in `dfx.json` for benchmarks
|
package/bundle/cli.tgz
CHANGED
|
Binary file
|
package/commands/bench.ts
CHANGED
|
@@ -67,7 +67,7 @@ export async function bench(filter = '', optionsArg : Partial<BenchOptions> = {}
|
|
|
67
67
|
compare: false,
|
|
68
68
|
verbose: false,
|
|
69
69
|
silent: false,
|
|
70
|
-
profile: dfxJson
|
|
70
|
+
profile: dfxJson?.profile || 'Release',
|
|
71
71
|
};
|
|
72
72
|
|
|
73
73
|
let options : BenchOptions = {...defaultOptions, ...optionsArg};
|
|
@@ -125,7 +125,7 @@ export async function bench(filter = '', optionsArg : Partial<BenchOptions> = {}
|
|
|
125
125
|
fs.rmSync(benchDir, {recursive: true, force: true});
|
|
126
126
|
fs.mkdirSync(benchDir, {recursive: true});
|
|
127
127
|
|
|
128
|
-
if (!options.silent) {
|
|
128
|
+
if (!options.silent && !process.env.CI) {
|
|
129
129
|
console.log('Benchmark files:');
|
|
130
130
|
for (let file of files) {
|
|
131
131
|
console.log(chalk.gray(`• ${absToRel(file)}`));
|
|
@@ -183,6 +183,57 @@ export async function bench(filter = '', optionsArg : Partial<BenchOptions> = {}
|
|
|
183
183
|
return benchResults;
|
|
184
184
|
}
|
|
185
185
|
|
|
186
|
+
function computeDiff(
|
|
187
|
+
results : Map<string, BenchResult>,
|
|
188
|
+
prevResults : Map<string, BenchResult> | undefined,
|
|
189
|
+
rows : string[],
|
|
190
|
+
cols : string[],
|
|
191
|
+
metric : keyof BenchResult,
|
|
192
|
+
) : number {
|
|
193
|
+
let diff = 0;
|
|
194
|
+
let count = 0;
|
|
195
|
+
|
|
196
|
+
for (let [_rowIndex, row] of rows.entries()) {
|
|
197
|
+
for (let [_colIndex, col] of cols.entries()) {
|
|
198
|
+
let res = results.get(`${row}:${col}`);
|
|
199
|
+
if (res && prevResults) {
|
|
200
|
+
let prevRes = prevResults.get(`${row}:${col}`);
|
|
201
|
+
if (prevRes) {
|
|
202
|
+
let denom = Number(prevRes[metric]);
|
|
203
|
+
let numerator = Number(res[metric]) - denom;
|
|
204
|
+
let percent = 0;
|
|
205
|
+
if (denom !== 0) {
|
|
206
|
+
percent = (numerator / denom) * 100;
|
|
207
|
+
}
|
|
208
|
+
if (!Number.isFinite(percent)) {
|
|
209
|
+
percent = 0;
|
|
210
|
+
}
|
|
211
|
+
diff += percent;
|
|
212
|
+
count++;
|
|
213
|
+
}
|
|
214
|
+
}
|
|
215
|
+
}
|
|
216
|
+
}
|
|
217
|
+
|
|
218
|
+
return count > 0 ? diff / count : 0;
|
|
219
|
+
}
|
|
220
|
+
|
|
221
|
+
function computeDiffAll(
|
|
222
|
+
currentResults : Map<string, BenchResult>,
|
|
223
|
+
prevResults : Map<string, BenchResult> | undefined,
|
|
224
|
+
rows : string[],
|
|
225
|
+
cols : string[],
|
|
226
|
+
) : number {
|
|
227
|
+
let metrics : (keyof BenchResult)[] = ['instructions', 'rts_heap_size', 'rts_logical_stable_memory_size', 'rts_reclaimed'];
|
|
228
|
+
let diff = 0;
|
|
229
|
+
|
|
230
|
+
for (let metric of metrics) {
|
|
231
|
+
diff += computeDiff(currentResults, prevResults, rows, cols, metric);
|
|
232
|
+
}
|
|
233
|
+
|
|
234
|
+
return diff;
|
|
235
|
+
}
|
|
236
|
+
|
|
186
237
|
function getMocArgs(options : BenchOptions) : string {
|
|
187
238
|
let args = '';
|
|
188
239
|
|
|
@@ -273,6 +324,19 @@ async function runBenchFile(file : string, options : BenchOptions, replica : Ben
|
|
|
273
324
|
return filesize(n, {standard: 'iec', round: 2});
|
|
274
325
|
};
|
|
275
326
|
|
|
327
|
+
let colorizePercent = (percent : number, wrapInParens = false) : string => {
|
|
328
|
+
let sign = percent > 0 ? '+' : '';
|
|
329
|
+
let percentText = percent == 0 ? '0%' : sign + percent.toFixed(2) + '%';
|
|
330
|
+
let color : keyof typeof chalk = percent == 0 ? 'gray' : (percent > 0 ? 'red' : 'green');
|
|
331
|
+
let parens = wrapInParens ? ['(', ')'] : ['', ''];
|
|
332
|
+
if (process.env.CI) {
|
|
333
|
+
return `$${parens[0]}{\\color{${color}}${percentText.replace('%', '\\\\%')}}${parens[1]}$`;
|
|
334
|
+
}
|
|
335
|
+
else {
|
|
336
|
+
return `${parens[0]}${chalk[color](percentText)}${parens[1]}`;
|
|
337
|
+
}
|
|
338
|
+
};
|
|
339
|
+
|
|
276
340
|
let getTable = (prop : keyof BenchResult) : string => {
|
|
277
341
|
let resArr = [['', ...schema.cols]];
|
|
278
342
|
let allZero = true;
|
|
@@ -296,15 +360,7 @@ async function runBenchFile(file : string, options : BenchOptions, replica : Ben
|
|
|
296
360
|
if (Object.is(percent, NaN)) {
|
|
297
361
|
percent = 0;
|
|
298
362
|
}
|
|
299
|
-
|
|
300
|
-
let percentText = percent == 0 ? '0%' : sign + percent.toFixed(2) + '%';
|
|
301
|
-
let color : keyof typeof chalk = percent == 0 ? 'gray' : (percent > 0 ? 'red' : 'green');
|
|
302
|
-
if (process.env.CI) {
|
|
303
|
-
diff = ` $({\\color{${color}}${percentText.replace('%', '\\\\%')}})$`;
|
|
304
|
-
}
|
|
305
|
-
else {
|
|
306
|
-
diff = ` (${chalk[color](percentText)})`;
|
|
307
|
-
}
|
|
363
|
+
diff = ' ' + colorizePercent(percent, true);
|
|
308
364
|
}
|
|
309
365
|
else {
|
|
310
366
|
diff = chalk.yellow(' (no previous results)');
|
|
@@ -345,14 +401,33 @@ async function runBenchFile(file : string, options : BenchOptions, replica : Ben
|
|
|
345
401
|
let logUpdate = createLogUpdate(process.stdout, {showCursor: true});
|
|
346
402
|
|
|
347
403
|
let getOutput = () => {
|
|
348
|
-
|
|
349
|
-
|
|
350
|
-
|
|
351
|
-
|
|
352
|
-
|
|
353
|
-
|
|
354
|
-
|
|
355
|
-
|
|
404
|
+
if (process.env.CI) {
|
|
405
|
+
return [
|
|
406
|
+
'\n<details>',
|
|
407
|
+
`\n<summary>${absToRel(file)} ${colorizePercent(computeDiffAll(results, prevResults, schema.rows, schema.cols), true).replace('\\\\%', '\\%')}</summary>`,
|
|
408
|
+
`\n${process.env.CI ? `### ${schema.name}` : chalk.bold(schema.name)}`,
|
|
409
|
+
`${schema.description ? '\n' + (process.env.CI ? `_${schema.description}_` : chalk.gray(schema.description)) : ''}`,
|
|
410
|
+
`\n\nInstructions: ${colorizePercent(computeDiff(results, prevResults, schema.rows, schema.cols, 'instructions'), false)}`,
|
|
411
|
+
`Heap: ${colorizePercent(computeDiff(results, prevResults, schema.rows, schema.cols, 'rts_heap_size'), false)}`,
|
|
412
|
+
`Stable Memory: ${colorizePercent(computeDiff(results, prevResults, schema.rows, schema.cols, 'rts_logical_stable_memory_size'), false)}`,
|
|
413
|
+
`Garbage Collection: ${colorizePercent(computeDiff(results, prevResults, schema.rows, schema.cols, 'rts_reclaimed'), false)}`,
|
|
414
|
+
`\n\n**Instructions**\n\n${getTable('instructions')}`,
|
|
415
|
+
`\n\n**Heap**\n\n${getTable('rts_heap_size')}`,
|
|
416
|
+
`\n\n**Garbage Collection**\n\n${getTable('rts_reclaimed')}`,
|
|
417
|
+
`${getTable('rts_logical_stable_memory_size') ? `\n\n**Stable Memory**\n\n${getTable('rts_logical_stable_memory_size')}` : ''}`,
|
|
418
|
+
'\n</details>',
|
|
419
|
+
].join('\n');
|
|
420
|
+
}
|
|
421
|
+
else {
|
|
422
|
+
return `
|
|
423
|
+
\n${chalk.bold(schema.name)}
|
|
424
|
+
${schema.description ? '\n' + chalk.gray(schema.description) : ''}
|
|
425
|
+
\n\n${chalk.blue('Instructions')}\n\n${getTable('instructions')}
|
|
426
|
+
\n\n${chalk.blue('Heap')}\n\n${getTable('rts_heap_size')}
|
|
427
|
+
\n\n${chalk.blue('Garbage Collection')}\n\n${getTable('rts_reclaimed')}
|
|
428
|
+
${getTable('rts_logical_stable_memory_size') ? `\n\n${chalk.blue('Stable Memory')}\n\n${getTable('rts_logical_stable_memory_size')}` : ''}
|
|
429
|
+
`;
|
|
430
|
+
}
|
|
356
431
|
};
|
|
357
432
|
|
|
358
433
|
let canUpdateLog = !process.env.CI && !options.silent && terminalSize().rows > getOutput().split('\n').length;
|
|
@@ -445,4 +520,4 @@ async function runBenchFile(file : string, options : BenchOptions, replica : Ben
|
|
|
445
520
|
['rts_reclaimed', reclaimedCells],
|
|
446
521
|
],
|
|
447
522
|
};
|
|
448
|
-
}
|
|
523
|
+
}
|
|
@@ -79,13 +79,16 @@ async function init({reset = false, silent = false} = {}) {
|
|
|
79
79
|
|
|
80
80
|
let zshrc = path.join(os.homedir(), '.zshrc');
|
|
81
81
|
let bashrc = path.join(os.homedir(), '.bashrc');
|
|
82
|
+
let bashProfile = path.join(os.homedir(), '.bash_profile');
|
|
83
|
+
let zprofile = path.join(os.homedir(), '.zprofile');
|
|
82
84
|
|
|
83
|
-
let shellConfigFiles = [bashrc, zshrc, process.env.GITHUB_ENV || ''].map(x => x).filter((file) => {
|
|
85
|
+
let shellConfigFiles = [bashrc, zshrc, bashProfile, zprofile, process.env.GITHUB_ENV || ''].map(x => x).filter((file) => {
|
|
84
86
|
return fs.existsSync(file);
|
|
85
87
|
});
|
|
86
88
|
|
|
87
89
|
if (shellConfigFiles.length === 0) {
|
|
88
|
-
console.error('Shell config files not found:
|
|
90
|
+
console.error('Shell config files not found: .bashrc, .zshrc, .bash_profile, .zprofile');
|
|
91
|
+
console.log('TIP: You can add "export DFX_MOC_PATH=moc-wrapper" to your shell config file manually to initialize Mops toolchain');
|
|
89
92
|
process.exit(1);
|
|
90
93
|
}
|
|
91
94
|
|
package/dist/commands/bench.js
CHANGED
|
@@ -43,7 +43,7 @@ export async function bench(filter = '', optionsArg = {}) {
|
|
|
43
43
|
compare: false,
|
|
44
44
|
verbose: false,
|
|
45
45
|
silent: false,
|
|
46
|
-
profile: dfxJson
|
|
46
|
+
profile: dfxJson?.profile || 'Release',
|
|
47
47
|
};
|
|
48
48
|
let options = { ...defaultOptions, ...optionsArg };
|
|
49
49
|
let replicaType = options.replica ?? (config.toolchain?.['pocket-ic'] ? 'pocket-ic' : 'dfx');
|
|
@@ -90,7 +90,7 @@ export async function bench(filter = '', optionsArg = {}) {
|
|
|
90
90
|
let benchDir = `${getRootDir()}/.mops/.bench/`;
|
|
91
91
|
fs.rmSync(benchDir, { recursive: true, force: true });
|
|
92
92
|
fs.mkdirSync(benchDir, { recursive: true });
|
|
93
|
-
if (!options.silent) {
|
|
93
|
+
if (!options.silent && !process.env.CI) {
|
|
94
94
|
console.log('Benchmark files:');
|
|
95
95
|
for (let file of files) {
|
|
96
96
|
console.log(chalk.gray(`• ${absToRel(file)}`));
|
|
@@ -139,6 +139,40 @@ export async function bench(filter = '', optionsArg = {}) {
|
|
|
139
139
|
fs.rmSync(benchDir, { recursive: true, force: true });
|
|
140
140
|
return benchResults;
|
|
141
141
|
}
|
|
142
|
+
function computeDiff(results, prevResults, rows, cols, metric) {
|
|
143
|
+
let diff = 0;
|
|
144
|
+
let count = 0;
|
|
145
|
+
for (let [_rowIndex, row] of rows.entries()) {
|
|
146
|
+
for (let [_colIndex, col] of cols.entries()) {
|
|
147
|
+
let res = results.get(`${row}:${col}`);
|
|
148
|
+
if (res && prevResults) {
|
|
149
|
+
let prevRes = prevResults.get(`${row}:${col}`);
|
|
150
|
+
if (prevRes) {
|
|
151
|
+
let denom = Number(prevRes[metric]);
|
|
152
|
+
let numerator = Number(res[metric]) - denom;
|
|
153
|
+
let percent = 0;
|
|
154
|
+
if (denom !== 0) {
|
|
155
|
+
percent = (numerator / denom) * 100;
|
|
156
|
+
}
|
|
157
|
+
if (!Number.isFinite(percent)) {
|
|
158
|
+
percent = 0;
|
|
159
|
+
}
|
|
160
|
+
diff += percent;
|
|
161
|
+
count++;
|
|
162
|
+
}
|
|
163
|
+
}
|
|
164
|
+
}
|
|
165
|
+
}
|
|
166
|
+
return count > 0 ? diff / count : 0;
|
|
167
|
+
}
|
|
168
|
+
function computeDiffAll(currentResults, prevResults, rows, cols) {
|
|
169
|
+
let metrics = ['instructions', 'rts_heap_size', 'rts_logical_stable_memory_size', 'rts_reclaimed'];
|
|
170
|
+
let diff = 0;
|
|
171
|
+
for (let metric of metrics) {
|
|
172
|
+
diff += computeDiff(currentResults, prevResults, rows, cols, metric);
|
|
173
|
+
}
|
|
174
|
+
return diff;
|
|
175
|
+
}
|
|
142
176
|
function getMocArgs(options) {
|
|
143
177
|
let args = '';
|
|
144
178
|
if (options.forceGc) {
|
|
@@ -211,6 +245,18 @@ async function runBenchFile(file, options, replica) {
|
|
|
211
245
|
let formatSize = (n) => {
|
|
212
246
|
return filesize(n, { standard: 'iec', round: 2 });
|
|
213
247
|
};
|
|
248
|
+
let colorizePercent = (percent, wrapInParens = false) => {
|
|
249
|
+
let sign = percent > 0 ? '+' : '';
|
|
250
|
+
let percentText = percent == 0 ? '0%' : sign + percent.toFixed(2) + '%';
|
|
251
|
+
let color = percent == 0 ? 'gray' : (percent > 0 ? 'red' : 'green');
|
|
252
|
+
let parens = wrapInParens ? ['(', ')'] : ['', ''];
|
|
253
|
+
if (process.env.CI) {
|
|
254
|
+
return `$${parens[0]}{\\color{${color}}${percentText.replace('%', '\\\\%')}}${parens[1]}$`;
|
|
255
|
+
}
|
|
256
|
+
else {
|
|
257
|
+
return `${parens[0]}${chalk[color](percentText)}${parens[1]}`;
|
|
258
|
+
}
|
|
259
|
+
};
|
|
214
260
|
let getTable = (prop) => {
|
|
215
261
|
let resArr = [['', ...schema.cols]];
|
|
216
262
|
let allZero = true;
|
|
@@ -231,15 +277,7 @@ async function runBenchFile(file, options, replica) {
|
|
|
231
277
|
if (Object.is(percent, NaN)) {
|
|
232
278
|
percent = 0;
|
|
233
279
|
}
|
|
234
|
-
|
|
235
|
-
let percentText = percent == 0 ? '0%' : sign + percent.toFixed(2) + '%';
|
|
236
|
-
let color = percent == 0 ? 'gray' : (percent > 0 ? 'red' : 'green');
|
|
237
|
-
if (process.env.CI) {
|
|
238
|
-
diff = ` $({\\color{${color}}${percentText.replace('%', '\\\\%')}})$`;
|
|
239
|
-
}
|
|
240
|
-
else {
|
|
241
|
-
diff = ` (${chalk[color](percentText)})`;
|
|
242
|
-
}
|
|
280
|
+
diff = ' ' + colorizePercent(percent, true);
|
|
243
281
|
}
|
|
244
282
|
else {
|
|
245
283
|
diff = chalk.yellow(' (no previous results)');
|
|
@@ -275,14 +313,33 @@ async function runBenchFile(file, options, replica) {
|
|
|
275
313
|
};
|
|
276
314
|
let logUpdate = createLogUpdate(process.stdout, { showCursor: true });
|
|
277
315
|
let getOutput = () => {
|
|
278
|
-
|
|
279
|
-
|
|
280
|
-
|
|
281
|
-
|
|
282
|
-
|
|
283
|
-
|
|
284
|
-
|
|
285
|
-
|
|
316
|
+
if (process.env.CI) {
|
|
317
|
+
return [
|
|
318
|
+
'\n<details>',
|
|
319
|
+
`\n<summary>${absToRel(file)} ${colorizePercent(computeDiffAll(results, prevResults, schema.rows, schema.cols), true).replace('\\\\%', '\\%')}</summary>`,
|
|
320
|
+
`\n${process.env.CI ? `### ${schema.name}` : chalk.bold(schema.name)}`,
|
|
321
|
+
`${schema.description ? '\n' + (process.env.CI ? `_${schema.description}_` : chalk.gray(schema.description)) : ''}`,
|
|
322
|
+
`\n\nInstructions: ${colorizePercent(computeDiff(results, prevResults, schema.rows, schema.cols, 'instructions'), false)}`,
|
|
323
|
+
`Heap: ${colorizePercent(computeDiff(results, prevResults, schema.rows, schema.cols, 'rts_heap_size'), false)}`,
|
|
324
|
+
`Stable Memory: ${colorizePercent(computeDiff(results, prevResults, schema.rows, schema.cols, 'rts_logical_stable_memory_size'), false)}`,
|
|
325
|
+
`Garbage Collection: ${colorizePercent(computeDiff(results, prevResults, schema.rows, schema.cols, 'rts_reclaimed'), false)}`,
|
|
326
|
+
`\n\n**Instructions**\n\n${getTable('instructions')}`,
|
|
327
|
+
`\n\n**Heap**\n\n${getTable('rts_heap_size')}`,
|
|
328
|
+
`\n\n**Garbage Collection**\n\n${getTable('rts_reclaimed')}`,
|
|
329
|
+
`${getTable('rts_logical_stable_memory_size') ? `\n\n**Stable Memory**\n\n${getTable('rts_logical_stable_memory_size')}` : ''}`,
|
|
330
|
+
'\n</details>',
|
|
331
|
+
].join('\n');
|
|
332
|
+
}
|
|
333
|
+
else {
|
|
334
|
+
return `
|
|
335
|
+
\n${chalk.bold(schema.name)}
|
|
336
|
+
${schema.description ? '\n' + chalk.gray(schema.description) : ''}
|
|
337
|
+
\n\n${chalk.blue('Instructions')}\n\n${getTable('instructions')}
|
|
338
|
+
\n\n${chalk.blue('Heap')}\n\n${getTable('rts_heap_size')}
|
|
339
|
+
\n\n${chalk.blue('Garbage Collection')}\n\n${getTable('rts_reclaimed')}
|
|
340
|
+
${getTable('rts_logical_stable_memory_size') ? `\n\n${chalk.blue('Stable Memory')}\n\n${getTable('rts_logical_stable_memory_size')}` : ''}
|
|
341
|
+
`;
|
|
342
|
+
}
|
|
286
343
|
};
|
|
287
344
|
let canUpdateLog = !process.env.CI && !options.silent && terminalSize().rows > getOutput().split('\n').length;
|
|
288
345
|
let log = () => {
|
|
@@ -71,11 +71,14 @@ async function init({ reset = false, silent = false } = {}) {
|
|
|
71
71
|
catch { }
|
|
72
72
|
let zshrc = path.join(os.homedir(), '.zshrc');
|
|
73
73
|
let bashrc = path.join(os.homedir(), '.bashrc');
|
|
74
|
-
let
|
|
74
|
+
let bashProfile = path.join(os.homedir(), '.bash_profile');
|
|
75
|
+
let zprofile = path.join(os.homedir(), '.zprofile');
|
|
76
|
+
let shellConfigFiles = [bashrc, zshrc, bashProfile, zprofile, process.env.GITHUB_ENV || ''].map(x => x).filter((file) => {
|
|
75
77
|
return fs.existsSync(file);
|
|
76
78
|
});
|
|
77
79
|
if (shellConfigFiles.length === 0) {
|
|
78
|
-
console.error('Shell config files not found:
|
|
80
|
+
console.error('Shell config files not found: .bashrc, .zshrc, .bash_profile, .zprofile');
|
|
81
|
+
console.log('TIP: You can add "export DFX_MOC_PATH=moc-wrapper" to your shell config file manually to initialize Mops toolchain');
|
|
79
82
|
process.exit(1);
|
|
80
83
|
}
|
|
81
84
|
// update all existing shell config files
|
package/dist/package.json
CHANGED