ic-mops 0.34.4 → 0.36.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.
Files changed (54) hide show
  1. package/cli.ts +11 -45
  2. package/commands/add.ts +7 -5
  3. package/commands/bench-replica.ts +99 -0
  4. package/commands/bench.ts +57 -90
  5. package/commands/install-all.ts +4 -4
  6. package/commands/remove.ts +4 -4
  7. package/commands/sync.ts +5 -5
  8. package/commands/update.ts +3 -3
  9. package/declarations/main/main.did +67 -78
  10. package/declarations/main/main.did.d.ts +72 -83
  11. package/declarations/main/main.did.js +12 -23
  12. package/dist/bin/mops.d.ts +2 -0
  13. package/dist/bin/mops.js +2 -0
  14. package/dist/cli.js +11 -44
  15. package/dist/commands/add.d.ts +2 -2
  16. package/dist/commands/add.js +6 -3
  17. package/dist/commands/bench-replica.d.ts +32 -0
  18. package/dist/commands/bench-replica.js +87 -0
  19. package/dist/commands/bench.d.ts +9 -8
  20. package/dist/commands/bench.js +44 -76
  21. package/dist/commands/install-all.d.ts +2 -2
  22. package/dist/commands/install-all.js +3 -3
  23. package/dist/commands/remove.d.ts +2 -2
  24. package/dist/commands/remove.js +3 -2
  25. package/dist/commands/sync.d.ts +2 -2
  26. package/dist/commands/sync.js +4 -4
  27. package/dist/commands/toolchain/moc.d.ts +4 -0
  28. package/dist/commands/toolchain/moc.js +36 -0
  29. package/dist/commands/toolchain/mocv.d.ts +1 -0
  30. package/dist/commands/toolchain/mocv.js +272 -0
  31. package/dist/commands/toolchain/toolchain-utils.d.ts +3 -0
  32. package/dist/commands/toolchain/toolchain-utils.js +56 -0
  33. package/dist/commands/toolchain/wasmtime.d.ts +4 -0
  34. package/dist/commands/toolchain/wasmtime.js +23 -0
  35. package/dist/commands/update.d.ts +2 -2
  36. package/dist/commands/update.js +2 -2
  37. package/dist/declarations/main/main.did +67 -78
  38. package/dist/declarations/main/main.did.d.ts +72 -83
  39. package/dist/declarations/main/main.did.js +12 -23
  40. package/dist/integrity.d.ts +2 -2
  41. package/dist/integrity.js +4 -4
  42. package/dist/moc-wrapper.d.ts +2 -0
  43. package/dist/moc-wrapper.js +8 -0
  44. package/dist/out/cli.d.ts +2 -0
  45. package/dist/out/cli.js +115242 -0
  46. package/dist/package.json +12 -4
  47. package/dist/templates/cli.d.ts +2 -0
  48. package/dist/templates/cli.js +3660 -0
  49. package/integrity.ts +5 -5
  50. package/package.json +12 -4
  51. package/dist/helpers/download-package-files.d.ts +0 -12
  52. package/dist/helpers/download-package-files.js +0 -62
  53. package/dist/helpers/resolve-version.d.ts +0 -1
  54. package/dist/helpers/resolve-version.js +0 -11
@@ -0,0 +1,87 @@
1
+ import { execSync } from 'node:child_process';
2
+ import path from 'node:path';
3
+ import fs from 'node:fs';
4
+ import { execaCommand } from 'execa';
5
+ import { PocketIc } from '@hadronous/pic';
6
+ import { getRootDir } from '../mops.js';
7
+ import { createActor, idlFactory } from '../declarations/bench/index.js';
8
+ export class BenchReplica {
9
+ constructor(type, verbose = false) {
10
+ this.verbose = false;
11
+ this.canisters = {};
12
+ this.type = type;
13
+ this.verbose = verbose;
14
+ }
15
+ async start() {
16
+ console.log(`Starting ${this.type} replica...`);
17
+ if (this.type == 'dfx') {
18
+ await this.stop();
19
+ let dir = path.join(getRootDir(), '.mops/.bench');
20
+ fs.writeFileSync(path.join(dir, 'dfx.json'), JSON.stringify(this.dfxJson(''), null, 2));
21
+ execSync('dfx start --background --clean --artificial-delay 0' + (this.verbose ? '' : ' -qqqq'), { cwd: dir, stdio: ['inherit', this.verbose ? 'inherit' : 'ignore', 'inherit'] });
22
+ }
23
+ else {
24
+ this.pocketIc = await PocketIc.create();
25
+ }
26
+ }
27
+ async stop() {
28
+ if (this.type == 'dfx') {
29
+ let dir = path.join(getRootDir(), '.mops/.bench');
30
+ execSync('dfx stop' + (this.verbose ? '' : ' -qqqq'), { cwd: dir, stdio: ['pipe', this.verbose ? 'inherit' : 'ignore', 'pipe'] });
31
+ }
32
+ else if (this.pocketIc) {
33
+ this.pocketIc.tearDown();
34
+ }
35
+ }
36
+ async deploy(name, wasm, cwd = process.cwd()) {
37
+ if (this.type === 'dfx') {
38
+ await execaCommand(`dfx deploy ${name} --mode reinstall --yes --identity anonymous`, { cwd, stdio: this.verbose ? 'pipe' : ['pipe', 'ignore', 'pipe'] });
39
+ let canisterId = execSync(`dfx canister id ${name}`, { cwd }).toString().trim();
40
+ let actor = await createActor(canisterId, {
41
+ agentOptions: {
42
+ host: 'http://127.0.0.1:4944',
43
+ },
44
+ });
45
+ this.canisters[name] = { cwd, canisterId, actor };
46
+ }
47
+ else if (this.pocketIc) {
48
+ let { canisterId, actor } = await this.pocketIc.setupCanister(idlFactory, wasm);
49
+ this.canisters[name] = {
50
+ cwd,
51
+ canisterId: canisterId.toText(),
52
+ actor,
53
+ };
54
+ }
55
+ }
56
+ getActor(name) {
57
+ return this.canisters[name]?.actor;
58
+ }
59
+ getCanisterId(name) {
60
+ return this.canisters[name]?.canisterId || '';
61
+ }
62
+ dfxJson(canisterName) {
63
+ let canisters = {};
64
+ if (canisterName) {
65
+ canisters[canisterName] = {
66
+ type: 'custom',
67
+ wasm: 'canister.wasm',
68
+ candid: 'canister.did',
69
+ };
70
+ }
71
+ return {
72
+ version: 1,
73
+ canisters,
74
+ defaults: {
75
+ build: {
76
+ packtool: 'mops sources',
77
+ },
78
+ },
79
+ networks: {
80
+ local: {
81
+ type: 'ephemeral',
82
+ bind: '127.0.0.1:4944',
83
+ },
84
+ },
85
+ };
86
+ }
87
+ }
@@ -1,11 +1,12 @@
1
1
  type BenchOptions = {
2
- dfx?: string;
3
- moc?: string;
4
- gc?: 'copying' | 'compacting' | 'generational' | 'incremental';
5
- forceGc?: boolean;
6
- save?: boolean;
7
- compare?: boolean;
8
- verbose?: boolean;
2
+ replica: 'dfx' | 'pocket-ic';
3
+ replicaVersion: string;
4
+ moc: string;
5
+ gc: 'copying' | 'compacting' | 'generational' | 'incremental';
6
+ forceGc: boolean;
7
+ save: boolean;
8
+ compare: boolean;
9
+ verbose: boolean;
9
10
  };
10
- export declare function bench(filter?: string, options?: BenchOptions): Promise<boolean>;
11
+ export declare function bench(filter?: string, optionsArg?: Partial<BenchOptions>): Promise<boolean>;
11
12
  export {};
@@ -1,4 +1,3 @@
1
- import { execSync } from 'node:child_process';
2
1
  import path from 'node:path';
3
2
  import fs from 'node:fs';
4
3
  import os from 'node:os';
@@ -6,15 +5,16 @@ import chalk from 'chalk';
6
5
  import { globSync } from 'glob';
7
6
  import { markdownTable } from 'markdown-table';
8
7
  import logUpdate from 'log-update';
8
+ import { execaCommand } from 'execa';
9
+ import stringWidth from 'string-width';
9
10
  import { getRootDir } from '../mops.js';
10
11
  import { parallel } from '../parallel.js';
11
- import { createActor } from '../declarations/bench/index.js';
12
12
  import { absToRel } from './test/utils.js';
13
13
  import { getMocVersion } from '../helpers/get-moc-version.js';
14
14
  import { getDfxVersion } from '../helpers/get-dfx-version.js';
15
15
  import { getMocPath } from '../helpers/get-moc-path.js';
16
16
  import { sources } from './sources.js';
17
- import { execaCommand } from 'execa';
17
+ import { BenchReplica } from './bench-replica.js';
18
18
  let ignore = [
19
19
  '**/node_modules/**',
20
20
  '**/.mops/**',
@@ -25,18 +25,21 @@ let globConfig = {
25
25
  nocase: true,
26
26
  ignore: ignore,
27
27
  };
28
- export async function bench(filter = '', options = {}) {
28
+ export async function bench(filter = '', optionsArg = {}) {
29
29
  let defaultOptions = {
30
+ replica: 'dfx',
30
31
  moc: getMocVersion(),
31
- dfx: getDfxVersion(),
32
- gc: 'incremental',
32
+ replicaVersion: '0.0.0',
33
+ gc: 'copying',
33
34
  forceGc: true,
34
35
  save: false,
35
36
  compare: false,
36
37
  verbose: false,
37
38
  };
38
- options = { ...defaultOptions, ...options };
39
+ let options = { ...defaultOptions, ...optionsArg };
40
+ options.replicaVersion = options.replica == 'dfx' ? getDfxVersion() : '1.0.0';
39
41
  options.verbose && console.log(options);
42
+ let replica = new BenchReplica(options.replica, options.verbose);
40
43
  let rootDir = getRootDir();
41
44
  let globStr = '**/bench?(mark)/**/*.bench.mo';
42
45
  if (filter) {
@@ -63,16 +66,15 @@ export async function bench(filter = '', options = {}) {
63
66
  console.log('');
64
67
  console.log('='.repeat(50));
65
68
  console.log('');
66
- console.log('Starting dfx replica...');
67
- startDfx(options.verbose);
69
+ await replica.start();
68
70
  console.log('Deploying canisters...');
69
71
  await parallel(os.cpus().length, files, async (file) => {
70
72
  try {
71
- await deployBenchFile(file, options);
73
+ await deployBenchFile(file, options, replica);
72
74
  }
73
75
  catch (err) {
74
- console.error('Unexpected error. Stopping dfx replica...');
75
- stopDfx(options.verbose);
76
+ console.error('Unexpected error. Stopping replica...');
77
+ await replica.stop();
76
78
  throw err;
77
79
  }
78
80
  });
@@ -81,16 +83,16 @@ export async function bench(filter = '', options = {}) {
81
83
  console.log(`\nRunning ${chalk.gray(absToRel(file))}...`);
82
84
  console.log('');
83
85
  try {
84
- await runBenchFile(file, options);
86
+ await runBenchFile(file, options, replica);
85
87
  }
86
88
  catch (err) {
87
- console.error('Unexpected error. Stopping dfx replica...');
88
- stopDfx(options.verbose);
89
+ console.error('Unexpected error. Stopping replica...');
90
+ await replica.stop();
89
91
  throw err;
90
92
  }
91
93
  });
92
- console.log('Stopping dfx replica...');
93
- stopDfx(options.verbose);
94
+ console.log('Stopping replica...');
95
+ await replica.stop();
94
96
  fs.rmSync(benchDir, { recursive: true, force: true });
95
97
  return true;
96
98
  }
@@ -104,49 +106,13 @@ function getMocArgs(options) {
104
106
  }
105
107
  return args;
106
108
  }
107
- function dfxJson(canisterName, options = {}) {
108
- options || console.log(options);
109
- let canisters = {};
110
- if (canisterName) {
111
- canisters[canisterName] = {
112
- type: 'custom',
113
- wasm: 'canister.wasm',
114
- candid: 'canister.did',
115
- };
116
- }
117
- return {
118
- version: 1,
119
- canisters,
120
- defaults: {
121
- build: {
122
- packtool: 'mops sources',
123
- },
124
- },
125
- networks: {
126
- local: {
127
- type: 'ephemeral',
128
- bind: '127.0.0.1:4944',
129
- },
130
- },
131
- };
132
- }
133
- function startDfx(verbose = false) {
134
- stopDfx(verbose);
135
- let dir = path.join(getRootDir(), '.mops/.bench');
136
- fs.writeFileSync(path.join(dir, 'dfx.json'), JSON.stringify(dfxJson(''), null, 2));
137
- execSync('dfx start --background --clean --artificial-delay 0' + (verbose ? '' : ' -qqqq'), { cwd: dir, stdio: ['inherit', verbose ? 'inherit' : 'ignore', 'inherit'] });
138
- }
139
- function stopDfx(verbose = false) {
140
- let dir = path.join(getRootDir(), '.mops/.bench');
141
- execSync('dfx stop' + (verbose ? '' : ' -qqqq'), { cwd: dir, stdio: ['pipe', verbose ? 'inherit' : 'ignore', 'pipe'] });
142
- }
143
- async function deployBenchFile(file, options = {}) {
109
+ async function deployBenchFile(file, options, replica) {
144
110
  let rootDir = getRootDir();
145
111
  let tempDir = path.join(rootDir, '.mops/.bench/', path.parse(file).name);
146
112
  let canisterName = path.parse(file).name;
147
113
  // prepare temp files
148
114
  fs.mkdirSync(tempDir, { recursive: true });
149
- fs.writeFileSync(path.join(tempDir, 'dfx.json'), JSON.stringify(dfxJson(canisterName, options), null, 2));
115
+ fs.writeFileSync(path.join(tempDir, 'dfx.json'), JSON.stringify(replica.dfxJson(canisterName), null, 2));
150
116
  let benchCanisterData = fs.readFileSync(new URL('./bench/bench-canister.mo', import.meta.url), 'utf8');
151
117
  benchCanisterData = benchCanisterData.replace('./user-bench', path.relative(tempDir, file).replace(/.mo$/g, ''));
152
118
  fs.writeFileSync(path.join(tempDir, 'canister.mo'), benchCanisterData);
@@ -157,30 +123,21 @@ async function deployBenchFile(file, options = {}) {
157
123
  await execaCommand(`${mocPath} -c --idl canister.mo ${mocArgs} ${(await sources({ cwd: tempDir })).join(' ')}`, { cwd: tempDir, stdio: options.verbose ? 'pipe' : ['pipe', 'ignore', 'pipe'] });
158
124
  options.verbose && console.timeEnd(`build ${canisterName}`);
159
125
  // deploy canister
126
+ let wasm = path.join(tempDir, 'canister.wasm');
160
127
  options.verbose && console.time(`deploy ${canisterName}`);
161
- await execaCommand(`dfx deploy ${canisterName} --mode reinstall --yes --identity anonymous`, { cwd: tempDir, stdio: options.verbose ? 'pipe' : ['pipe', 'ignore', 'pipe'] });
128
+ // await execaCommand(`dfx deploy ${canisterName} --mode reinstall --yes --identity anonymous`, {cwd: tempDir, stdio: options.verbose ? 'pipe' : ['pipe', 'ignore', 'pipe']});
129
+ await replica.deploy(canisterName, wasm, tempDir);
162
130
  options.verbose && console.timeEnd(`deploy ${canisterName}`);
163
131
  // init bench
164
132
  options.verbose && console.time(`init ${canisterName}`);
165
- let canisterId = execSync(`dfx canister id ${canisterName}`, { cwd: tempDir }).toString().trim();
166
- let actor = await createActor(canisterId, {
167
- agentOptions: {
168
- host: 'http://127.0.0.1:4944',
169
- },
170
- });
133
+ let actor = await replica.getActor(canisterName);
171
134
  await actor.init();
172
135
  options.verbose && console.timeEnd(`init ${canisterName}`);
173
136
  }
174
- async function runBenchFile(file, options = {}) {
137
+ async function runBenchFile(file, options, replica) {
175
138
  let rootDir = getRootDir();
176
- let tempDir = path.join(rootDir, '.mops/.bench/', path.parse(file).name);
177
139
  let canisterName = path.parse(file).name;
178
- let canisterId = execSync(`dfx canister id ${canisterName}`, { cwd: tempDir }).toString().trim();
179
- let actor = await createActor(canisterId, {
180
- agentOptions: {
181
- host: 'http://127.0.0.1:4944',
182
- },
183
- });
140
+ let actor = await replica.getActor(canisterName);
184
141
  let schema = await actor.getSchema();
185
142
  // load previous results
186
143
  let prevResults;
@@ -213,8 +170,8 @@ async function runBenchFile(file, options = {}) {
213
170
  let percent = (Number(res[prop]) - Number(prevRes[prop])) / Number(prevRes[prop]) * 100;
214
171
  let sign = percent > 0 ? '+' : '';
215
172
  let percentText = percent == 0 ? '0%' : sign + percent.toFixed(2) + '%';
216
- // diff = ' (' + (percent > 0 ? chalk.red(percentText) : chalk.green(percentText)) + ')'; // alignment is broken
217
- diff = ' (' + percentText + ')';
173
+ let color = percent == 0 ? 'gray' : (percent > 0 ? 'red' : 'green');
174
+ diff = ` (${chalk[color](percentText)})`;
218
175
  }
219
176
  else {
220
177
  diff = chalk.yellow(' (no previous results)');
@@ -229,7 +186,10 @@ async function runBenchFile(file, options = {}) {
229
186
  }
230
187
  resArr.push(curRow);
231
188
  }
232
- return markdownTable(resArr, { align: ['l', ...'r'.repeat(schema.cols.length)] });
189
+ return markdownTable(resArr, {
190
+ align: ['l', ...'r'.repeat(schema.cols.length)],
191
+ stringLength: stringWidth,
192
+ });
233
193
  };
234
194
  let printResults = () => {
235
195
  logUpdate(`
@@ -239,7 +199,9 @@ async function runBenchFile(file, options = {}) {
239
199
  \n\n${chalk.blue('Heap')}\n\n${getTable('rts_heap_size')}
240
200
  `);
241
201
  };
242
- printResults();
202
+ if (!process.env.CI) {
203
+ printResults();
204
+ }
243
205
  // run all cells
244
206
  for (let [rowIndex, row] of schema.rows.entries()) {
245
207
  for (let [colIndex, col] of schema.cols.entries()) {
@@ -247,9 +209,14 @@ async function runBenchFile(file, options = {}) {
247
209
  // let res = await actor.runCellUpdate(BigInt(rowIndex), BigInt(colIndex));
248
210
  let res = await actor.runCellUpdateAwait(BigInt(rowIndex), BigInt(colIndex));
249
211
  results.set(`${row}:${col}`, res);
250
- printResults();
212
+ if (!process.env.CI) {
213
+ printResults();
214
+ }
251
215
  }
252
216
  }
217
+ if (process.env.CI) {
218
+ printResults();
219
+ }
253
220
  logUpdate.done();
254
221
  // save results
255
222
  if (options.save) {
@@ -257,7 +224,8 @@ async function runBenchFile(file, options = {}) {
257
224
  let json = {
258
225
  version: 1,
259
226
  moc: options.moc,
260
- dfx: options.dfx,
227
+ replica: options.replica,
228
+ replicaVersion: options.replicaVersion,
261
229
  gc: options.gc,
262
230
  forceGc: options.forceGc,
263
231
  results: Array.from(results.entries()),
@@ -1,7 +1,7 @@
1
1
  type InstallAllOptions = {
2
2
  verbose?: boolean;
3
3
  silent?: boolean;
4
- lockfile?: 'save' | 'check' | 'ignore';
4
+ lock?: 'check' | 'update' | 'ignore';
5
5
  };
6
- export declare function installAll({ verbose, silent, lockfile }?: InstallAllOptions): Promise<void>;
6
+ export declare function installAll({ verbose, silent, lock }?: InstallAllOptions): Promise<void>;
7
7
  export {};
@@ -5,7 +5,7 @@ import { install } from './install.js';
5
5
  import { installFromGithub } from '../vessel.js';
6
6
  import { notifyInstalls } from '../notify-installs.js';
7
7
  import { checkIntegrity } from '../integrity.js';
8
- export async function installAll({ verbose = false, silent = false, lockfile } = {}) {
8
+ export async function installAll({ verbose = false, silent = false, lock } = {}) {
9
9
  if (!checkConfigFile()) {
10
10
  return;
11
11
  }
@@ -26,12 +26,12 @@ export async function installAll({ verbose = false, silent = false, lockfile } =
26
26
  installedPackages = { ...installedPackages, ...res };
27
27
  }
28
28
  }
29
- if (!silent && lockfile !== 'ignore') {
29
+ if (!silent && lock !== 'ignore') {
30
30
  logUpdate('Checking integrity...');
31
31
  }
32
32
  await Promise.all([
33
33
  notifyInstalls(Object.keys(installedPackages)),
34
- checkIntegrity(lockfile),
34
+ checkIntegrity(lock),
35
35
  ]);
36
36
  if (!silent) {
37
37
  logUpdate.clear();
@@ -2,7 +2,7 @@ type RemoveOptions = {
2
2
  verbose?: boolean;
3
3
  dev?: boolean;
4
4
  dryRun?: boolean;
5
- lockfile?: 'save' | 'ignore';
5
+ lock?: 'update' | 'ignore';
6
6
  };
7
- export declare function remove(name: string, { dev, verbose, dryRun, lockfile }?: RemoveOptions): Promise<void>;
7
+ export declare function remove(name: string, { dev, verbose, dryRun, lock }?: RemoveOptions): Promise<void>;
8
8
  export {};
@@ -2,8 +2,9 @@ import fs from 'node:fs';
2
2
  import { deleteSync } from 'del';
3
3
  import chalk from 'chalk';
4
4
  import { formatDir, formatGithubDir, checkConfigFile, readConfig, writeConfig } from '../mops.js';
5
+ import { checkIntegrity } from '../integrity.js';
5
6
  // eslint-disable-next-line @typescript-eslint/no-unused-vars
6
- export async function remove(name, { dev = false, verbose = false, dryRun = false, lockfile } = {}) {
7
+ export async function remove(name, { dev = false, verbose = false, dryRun = false, lock } = {}) {
7
8
  if (!checkConfigFile()) {
8
9
  return;
9
10
  }
@@ -80,6 +81,6 @@ export async function remove(name, { dev = false, verbose = false, dryRun = fals
80
81
  delete config['dev-dependencies'][name];
81
82
  }
82
83
  dryRun || writeConfig(config);
83
- // await checkIntegrity(lockfile);
84
+ await checkIntegrity(lock);
84
85
  console.log(chalk.green('Package removed ') + `${name} = "${version}"`);
85
86
  }
@@ -1,5 +1,5 @@
1
1
  type SyncOptions = {
2
- lockfile?: 'save' | 'ignore';
2
+ lock?: 'update' | 'ignore';
3
3
  };
4
- export declare function sync({ lockfile }?: SyncOptions): Promise<void>;
4
+ export declare function sync({ lock }?: SyncOptions): Promise<void>;
5
5
  export {};
@@ -6,7 +6,7 @@ import { checkConfigFile, getRootDir, readConfig } from '../mops.js';
6
6
  import { add } from './add.js';
7
7
  import { remove } from './remove.js';
8
8
  import { checkIntegrity } from '../integrity.js';
9
- export async function sync({ lockfile } = {}) {
9
+ export async function sync({ lock } = {}) {
10
10
  if (!checkConfigFile()) {
11
11
  return;
12
12
  }
@@ -19,14 +19,14 @@ export async function sync({ lockfile } = {}) {
19
19
  let devDeps = new Set(Object.keys(config['dev-dependencies'] || {}));
20
20
  // add missing packages
21
21
  for (let pkg of missing) {
22
- await add(pkg, { lockfile: 'ignore' });
22
+ await add(pkg, { lock: 'ignore' });
23
23
  }
24
24
  // remove unused packages
25
25
  for (let pkg of unused) {
26
26
  let dev = devDeps.has(pkg) && !deps.has(pkg);
27
- await remove(pkg, { dev, lockfile: 'ignore' });
27
+ await remove(pkg, { dev, lock: 'ignore' });
28
28
  }
29
- await checkIntegrity(lockfile);
29
+ await checkIntegrity(lock);
30
30
  }
31
31
  let ignore = [
32
32
  '**/node_modules/**',
@@ -0,0 +1,4 @@
1
+ export declare let isCached: (version: string) => boolean;
2
+ export declare let download: (version: string, { silent }?: {
3
+ silent?: boolean | undefined;
4
+ }) => Promise<void>;
@@ -0,0 +1,36 @@
1
+ import path from 'node:path';
2
+ import fs from 'fs-extra';
3
+ import { globalCacheDir } from '../../mops.js';
4
+ import { downloadGithubRelease } from './toolchain-utils.js';
5
+ let cacheDir = path.join(globalCacheDir, 'moc');
6
+ export let isCached = (version) => {
7
+ let dir = path.join(cacheDir, version);
8
+ return fs.existsSync(dir) && fs.existsSync(path.join(dir, 'moc'));
9
+ };
10
+ export let download = async (version, { silent = false } = {}) => {
11
+ if (process.platform == 'win32') {
12
+ console.log('Windows is not supported. Please use WSL');
13
+ process.exit(1);
14
+ }
15
+ if (!version) {
16
+ console.log('version is not defined');
17
+ process.exit(1);
18
+ }
19
+ if (isCached(version)) {
20
+ return;
21
+ }
22
+ let url;
23
+ if (parseInt(version.replaceAll('.', '')) >= parseInt('0.9.5'.replaceAll('.', ''))) {
24
+ let platfrom = process.platform == 'darwin' ? 'Darwin' : 'Linux';
25
+ let arch = process.arch.startsWith('arm') ? 'arm64' : 'x86_64';
26
+ // currently only x64 binaries are available
27
+ arch = 'x86_64';
28
+ url = `https://github.com/dfinity/motoko/releases/download/${version}/motoko-${platfrom}-${arch}-${version}.tar.gz`;
29
+ }
30
+ else {
31
+ let platfrom = process.platform == 'darwin' ? 'macos' : 'linux64';
32
+ url = `https://github.com/dfinity/motoko/releases/download/${version}/motoko-${platfrom}-${version}.tar.gz`;
33
+ }
34
+ silent || console.log(`Downloading ${url}`);
35
+ await downloadGithubRelease(url, path.join(cacheDir, version));
36
+ };
@@ -0,0 +1 @@
1
+ export {};