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 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.profile || 'Release',
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
- let sign = percent > 0 ? '+' : '';
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
- 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)) : ''}
351
- \n\n${chalk.blue('Instructions')}\n\n${getTable('instructions')}
352
- \n\n${chalk.blue('Heap')}\n\n${getTable('rts_heap_size')}
353
- \n\n${chalk.blue('Garbage Collection')}\n\n${getTable('rts_reclaimed')}
354
- ${getTable('rts_logical_stable_memory_size') ? `\n\n${chalk.blue('Stable Memory')}\n\n${getTable('rts_logical_stable_memory_size')}` : ''}
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: ".bashrc" or ".zshrc"');
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
 
@@ -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.profile || 'Release',
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
- let sign = percent > 0 ? '+' : '';
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
- 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)) : ''}
281
- \n\n${chalk.blue('Instructions')}\n\n${getTable('instructions')}
282
- \n\n${chalk.blue('Heap')}\n\n${getTable('rts_heap_size')}
283
- \n\n${chalk.blue('Garbage Collection')}\n\n${getTable('rts_reclaimed')}
284
- ${getTable('rts_logical_stable_memory_size') ? `\n\n${chalk.blue('Stable Memory')}\n\n${getTable('rts_logical_stable_memory_size')}` : ''}
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 shellConfigFiles = [bashrc, zshrc, process.env.GITHUB_ENV || ''].map(x => x).filter((file) => {
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: ".bashrc" or ".zshrc"');
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
@@ -1,6 +1,6 @@
1
1
  {
2
2
  "name": "ic-mops",
3
- "version": "1.5.0",
3
+ "version": "1.6.0",
4
4
  "type": "module",
5
5
  "bin": {
6
6
  "mops": "bin/mops.js",
package/package.json CHANGED
@@ -1,6 +1,6 @@
1
1
  {
2
2
  "name": "ic-mops",
3
- "version": "1.5.0",
3
+ "version": "1.6.0",
4
4
  "type": "module",
5
5
  "bin": {
6
6
  "mops": "dist/bin/mops.js",