ic-mops 0.22.0 → 0.23.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/cli.ts CHANGED
@@ -1,7 +1,7 @@
1
1
  #!/usr/bin/env node
2
2
 
3
3
  import fs from 'node:fs';
4
- import {program} from 'commander';
4
+ import {program, Argument} from 'commander';
5
5
  import chalk from 'chalk';
6
6
  import {Principal} from '@dfinity/principal';
7
7
 
@@ -21,6 +21,7 @@ import {selfUpdate} from './commands/self-update.js';
21
21
  import {remove} from './commands/remove.js';
22
22
  import {getUserProp, setUserProp} from './commands/user.js';
23
23
  import {bump} from './commands/bump.js';
24
+ import {sync} from './commands/sync.js';
24
25
  // import {docs} from './commands/docs.js';
25
26
 
26
27
  program.name('mops');
@@ -166,8 +167,9 @@ program
166
167
 
167
168
  // cache
168
169
  program
169
- .command('cache [sub-command]')
170
+ .command('cache')
170
171
  .description('Manage cache')
172
+ .addArgument(new Argument('<sub>').choices(['size', 'clean']))
171
173
  .action(async (sub) => {
172
174
  if (sub == 'clean') {
173
175
  await cleanCache();
@@ -177,9 +179,6 @@ program
177
179
  let size = await cacheSize();
178
180
  console.log('Cache size is ' + size);
179
181
  }
180
- else {
181
- console.log('Unknown sub command. Available sub commands: clean, size');
182
- }
183
182
  });
184
183
 
185
184
  // test
@@ -236,7 +235,10 @@ program
236
235
 
237
236
  // user
238
237
  program
239
- .command('user set|get <prop> [value]')
238
+ .command('user')
239
+ .addArgument(new Argument('<sub>').choices(['set', 'get']))
240
+ .addArgument(new Argument('<prop>').choices(['name', 'site', 'email', 'github', 'twitter']))
241
+ .addArgument(new Argument('[value]'))
240
242
  .description('User settings')
241
243
  .action(async (sub, prop, value) => {
242
244
  if (sub == 'get') {
@@ -249,9 +251,6 @@ program
249
251
  }
250
252
  await setUserProp(prop, value);
251
253
  }
252
- else {
253
- console.log('Unknown sub command. Available sub commands: set, get');
254
- }
255
254
  });
256
255
 
257
256
  // airdrop
@@ -294,4 +293,12 @@ program
294
293
  bump(part);
295
294
  });
296
295
 
296
+ // sync
297
+ program
298
+ .command('sync')
299
+ .description('Add missing packages and remove unused packages')
300
+ .action(async () => {
301
+ await sync();
302
+ });
303
+
297
304
  program.parse();
@@ -77,7 +77,7 @@ export async function remove(name: string, {dev = false, verbose = false, dryRun
77
77
  pkgDir = formatDir(dep.name, dep.version);
78
78
  }
79
79
  if (pkgDir && fs.existsSync(pkgDir)) {
80
- dryRun || deleteSync([`${pkgDir}`]);
80
+ dryRun || deleteSync([`${pkgDir}`], {force: true});
81
81
  verbose && console.log(`Removed local cache ${pkgDir}`);
82
82
  }
83
83
  }
@@ -0,0 +1,98 @@
1
+ import path from 'node:path';
2
+ import {execSync} from 'node:child_process';
3
+ import {globSync} from 'glob';
4
+ import chalk from 'chalk';
5
+ import {checkConfigFile, getRootDir, readConfig} from '../mops.js';
6
+ import {add} from './add.js';
7
+ import {remove} from './remove.js';
8
+
9
+ let ignore = [
10
+ '**/node_modules/**',
11
+ '**/.vessel/**',
12
+ '**/.git/**',
13
+ '**/.mops/**',
14
+ '**/test/**',
15
+ '**/*.test.mo',
16
+ ];
17
+
18
+ let mocPath = '';
19
+ function getMocPath(): string {
20
+ if (!mocPath) {
21
+ mocPath = process.env.DFX_MOC_PATH || '';
22
+ }
23
+ if (!mocPath) {
24
+ try {
25
+ mocPath = execSync('dfx cache show').toString().trim() + '/moc';
26
+ }
27
+ catch {}
28
+ }
29
+ if (!mocPath) {
30
+ mocPath = 'moc';
31
+ }
32
+ return mocPath;
33
+ }
34
+
35
+ async function getUsedPackages(): Promise<string[]> {
36
+ let rootDir = getRootDir();
37
+ let files = globSync('**/*.mo', {
38
+ cwd: rootDir,
39
+ nocase: true,
40
+ ignore: ignore,
41
+ });
42
+
43
+ let packages: Set<string> = new Set;
44
+
45
+ for (let file of files) {
46
+ let deps: string[] = execSync(`${getMocPath()} --print-deps ${path.join(rootDir, file)}`).toString().trim().split('\n');
47
+
48
+ for (let dep of deps) {
49
+ if (dep.startsWith('mo:') && !dep.startsWith('mo:prim') && !dep.startsWith('mo:⛔')) {
50
+ packages.add(dep.replace(/^mo:([^/]+).*$/, '$1'));
51
+ }
52
+ }
53
+ }
54
+
55
+ return [...packages];
56
+ }
57
+
58
+ async function getMissingPackages(): Promise<string[]> {
59
+ let config = readConfig();
60
+ let allDeps = [...Object.keys(config.dependencies || {}), ...Object.keys(config['dev-dependencies'] || {})];
61
+ let missing = new Set(await getUsedPackages());
62
+ for (let pkg of allDeps) {
63
+ missing.delete(pkg);
64
+ }
65
+ return [...missing];
66
+ }
67
+
68
+ async function getUnusedPackages(): Promise<string[]> {
69
+ let config = readConfig();
70
+ let allDeps = new Set([...Object.keys(config.dependencies || {})]);
71
+ let used = await getUsedPackages();
72
+ for (let pkg of used) {
73
+ allDeps.delete(pkg);
74
+ }
75
+ return [...allDeps];
76
+ }
77
+
78
+ export async function sync() {
79
+ if (!checkConfigFile()) {
80
+ return;
81
+ }
82
+
83
+ let missing = await getMissingPackages();
84
+ let unused = await getUnusedPackages();
85
+
86
+ missing.length && console.log(`${chalk.yellow('Missing packages:')} ${missing.join(', ')}`);
87
+ unused.length && console.log(`${chalk.yellow('Unused packages:')} ${unused.join(', ')}`);
88
+
89
+ // add missing packages
90
+ for (let pkg of missing) {
91
+ await add(pkg);
92
+ }
93
+
94
+ // remove unused packages
95
+ for (let pkg of unused) {
96
+ await remove(pkg);
97
+ }
98
+ }
package/dist/cli.js CHANGED
@@ -1,6 +1,6 @@
1
1
  #!/usr/bin/env node
2
2
  import fs from 'node:fs';
3
- import { program } from 'commander';
3
+ import { program, Argument } from 'commander';
4
4
  import chalk from 'chalk';
5
5
  import { Principal } from '@dfinity/principal';
6
6
  import { init } from './commands/init.js';
@@ -19,6 +19,7 @@ import { selfUpdate } from './commands/self-update.js';
19
19
  import { remove } from './commands/remove.js';
20
20
  import { getUserProp, setUserProp } from './commands/user.js';
21
21
  import { bump } from './commands/bump.js';
22
+ import { sync } from './commands/sync.js';
22
23
  // import {docs} from './commands/docs.js';
23
24
  program.name('mops');
24
25
  // --version
@@ -148,8 +149,9 @@ program
148
149
  });
149
150
  // cache
150
151
  program
151
- .command('cache [sub-command]')
152
+ .command('cache')
152
153
  .description('Manage cache')
154
+ .addArgument(new Argument('<sub>').choices(['size', 'clean']))
153
155
  .action(async (sub) => {
154
156
  if (sub == 'clean') {
155
157
  await cleanCache();
@@ -159,9 +161,6 @@ program
159
161
  let size = await cacheSize();
160
162
  console.log('Cache size is ' + size);
161
163
  }
162
- else {
163
- console.log('Unknown sub command. Available sub commands: clean, size');
164
- }
165
164
  });
166
165
  // test
167
166
  program
@@ -213,7 +212,10 @@ program
213
212
  });
214
213
  // user
215
214
  program
216
- .command('user set|get <prop> [value]')
215
+ .command('user')
216
+ .addArgument(new Argument('<sub>').choices(['set', 'get']))
217
+ .addArgument(new Argument('<prop>').choices(['name', 'site', 'email', 'github', 'twitter']))
218
+ .addArgument(new Argument('[value]'))
217
219
  .description('User settings')
218
220
  .action(async (sub, prop, value) => {
219
221
  if (sub == 'get') {
@@ -226,9 +228,6 @@ program
226
228
  }
227
229
  await setUserProp(prop, value);
228
230
  }
229
- else {
230
- console.log('Unknown sub command. Available sub commands: set, get');
231
- }
232
231
  });
233
232
  // airdrop
234
233
  program
@@ -268,4 +267,11 @@ program
268
267
  .action(async (part) => {
269
268
  bump(part);
270
269
  });
270
+ // sync
271
+ program
272
+ .command('sync')
273
+ .description('Add missing packages and remove unused packages')
274
+ .action(async () => {
275
+ await sync();
276
+ });
271
277
  program.parse();
@@ -67,7 +67,7 @@ export async function remove(name, { dev = false, verbose = false, dryRun = fals
67
67
  pkgDir = formatDir(dep.name, dep.version);
68
68
  }
69
69
  if (pkgDir && fs.existsSync(pkgDir)) {
70
- dryRun || deleteSync([`${pkgDir}`]);
70
+ dryRun || deleteSync([`${pkgDir}`], { force: true });
71
71
  verbose && console.log(`Removed local cache ${pkgDir}`);
72
72
  }
73
73
  }
@@ -0,0 +1 @@
1
+ export declare function sync(): Promise<void>;
@@ -0,0 +1,84 @@
1
+ import path from 'node:path';
2
+ import { execSync } from 'node:child_process';
3
+ import { globSync } from 'glob';
4
+ import chalk from 'chalk';
5
+ import { checkConfigFile, getRootDir, readConfig } from '../mops.js';
6
+ import { add } from './add.js';
7
+ import { remove } from './remove.js';
8
+ let ignore = [
9
+ '**/node_modules/**',
10
+ '**/.vessel/**',
11
+ '**/.git/**',
12
+ '**/.mops/**',
13
+ '**/test/**',
14
+ '**/*.test.mo',
15
+ ];
16
+ let mocPath = '';
17
+ function getMocPath() {
18
+ if (!mocPath) {
19
+ mocPath = process.env.DFX_MOC_PATH || '';
20
+ }
21
+ if (!mocPath) {
22
+ try {
23
+ mocPath = execSync('dfx cache show').toString().trim() + '/moc';
24
+ }
25
+ catch { }
26
+ }
27
+ if (!mocPath) {
28
+ mocPath = 'moc';
29
+ }
30
+ return mocPath;
31
+ }
32
+ async function getUsedPackages() {
33
+ let rootDir = getRootDir();
34
+ let files = globSync('**/*.mo', {
35
+ cwd: rootDir,
36
+ nocase: true,
37
+ ignore: ignore,
38
+ });
39
+ let packages = new Set;
40
+ for (let file of files) {
41
+ let deps = execSync(`${getMocPath()} --print-deps ${path.join(rootDir, file)}`).toString().trim().split('\n');
42
+ for (let dep of deps) {
43
+ if (dep.startsWith('mo:') && !dep.startsWith('mo:prim') && !dep.startsWith('mo:⛔')) {
44
+ packages.add(dep.replace(/^mo:([^/]+).*$/, '$1'));
45
+ }
46
+ }
47
+ }
48
+ return [...packages];
49
+ }
50
+ async function getMissingPackages() {
51
+ let config = readConfig();
52
+ let allDeps = [...Object.keys(config.dependencies || {}), ...Object.keys(config['dev-dependencies'] || {})];
53
+ let missing = new Set(await getUsedPackages());
54
+ for (let pkg of allDeps) {
55
+ missing.delete(pkg);
56
+ }
57
+ return [...missing];
58
+ }
59
+ async function getUnusedPackages() {
60
+ let config = readConfig();
61
+ let allDeps = new Set([...Object.keys(config.dependencies || {})]);
62
+ let used = await getUsedPackages();
63
+ for (let pkg of used) {
64
+ allDeps.delete(pkg);
65
+ }
66
+ return [...allDeps];
67
+ }
68
+ export async function sync() {
69
+ if (!checkConfigFile()) {
70
+ return;
71
+ }
72
+ let missing = await getMissingPackages();
73
+ let unused = await getUnusedPackages();
74
+ missing.length && console.log(`${chalk.yellow('Missing packages:')} ${missing.join(', ')}`);
75
+ unused.length && console.log(`${chalk.yellow('Unused packages:')} ${unused.join(', ')}`);
76
+ // add missing packages
77
+ for (let pkg of missing) {
78
+ await add(pkg);
79
+ }
80
+ // remove unused packages
81
+ for (let pkg of unused) {
82
+ await remove(pkg);
83
+ }
84
+ }
package/dist/package.json CHANGED
@@ -1,6 +1,6 @@
1
1
  {
2
2
  "name": "ic-mops",
3
- "version": "0.22.0",
3
+ "version": "0.23.0",
4
4
  "type": "module",
5
5
  "bin": {
6
6
  "mops": "dist/cli.js"
package/package.json CHANGED
@@ -1,6 +1,6 @@
1
1
  {
2
2
  "name": "ic-mops",
3
- "version": "0.22.0",
3
+ "version": "0.23.0",
4
4
  "type": "module",
5
5
  "bin": {
6
6
  "mops": "dist/cli.js"