ic-mops 1.0.0 → 1.1.0-pre.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,8 @@
1
1
  # Mops CLI Changelog
2
2
 
3
+ ## 1.0.1
4
+ - Fixed `mops user *` commands
5
+
3
6
  ## 1.0.0
4
7
  - `mops cache clean` now cleans local cache too (`.mops` folder)
5
8
  - Conflicting dependencies are now reported on `mops add/install/sources`
package/bundle/cli.tgz CHANGED
Binary file
package/cli.ts CHANGED
@@ -25,7 +25,6 @@ import {toolchain} from './commands/toolchain/index.js';
25
25
  import {Tool} from './types.js';
26
26
  import * as self from './commands/self.js';
27
27
  import {resolvePackages} from './resolve-packages.js';
28
- // import {docs} from './commands/docs.js';
29
28
 
30
29
  declare global {
31
30
  // eslint-disable-next-line no-var
@@ -90,6 +89,7 @@ program
90
89
  .command('install')
91
90
  .alias('i')
92
91
  .description('Install all dependencies specified in mops.toml')
92
+ .option('--no-toolchain', 'Do not install toolchain')
93
93
  .option('--verbose')
94
94
  .addOption(new Option('--lock <action>', 'Lockfile action').choices(['check', 'update', 'ignore']))
95
95
  .action(async (options) => {
@@ -102,10 +102,15 @@ program
102
102
  return;
103
103
  }
104
104
 
105
- await toolchain.ensureToolchainInited({strict: false});
105
+ if (options.toolchain) {
106
+ await toolchain.ensureToolchainInited({strict: false});
107
+ }
106
108
 
107
109
  let ok = await installAll(options);
108
- await toolchain.installAll(options);
110
+
111
+ if (options.toolchain) {
112
+ await toolchain.installAll(options);
113
+ }
109
114
 
110
115
  // check conflicts
111
116
  await resolvePackages({conflicts: 'warning'});
@@ -152,16 +157,6 @@ program
152
157
  console.log(getNetwork());
153
158
  });
154
159
 
155
- // user import
156
- program
157
- .command('mops user import <data>')
158
- .description('Import .pem file data to use as identity')
159
- .addOption(new Option('--no-encrypt', 'Do not ask for a password to encrypt identity'))
160
- .action(async (data, options) => {
161
- await importPem(data, options);
162
- await getPrincipal();
163
- });
164
-
165
160
  // sources
166
161
  program
167
162
  .command('sources')
@@ -173,21 +168,13 @@ program
173
168
  process.exit(1);
174
169
  }
175
170
  if (options.install) {
176
- await installAll({silent: true, lock: 'ignore', threads: 6});
171
+ await installAll({silent: true, lock: 'ignore', threads: 6, installFromLockFile: true});
177
172
  }
178
173
  await toolchain.ensureToolchainInited({strict: false});
179
174
  let sourcesArr = await sources(options);
180
175
  console.log(sourcesArr.join('\n'));
181
176
  });
182
177
 
183
- // get-principal
184
- program
185
- .command('get-principal')
186
- .description('Print your principal')
187
- .action(async () => {
188
- await getPrincipal();
189
- });
190
-
191
178
  // search
192
179
  program
193
180
  .command('search <text>')
@@ -225,7 +212,7 @@ program
225
212
  .option('-w, --watch', 'Enable watch mode')
226
213
  .action(async (filter, options) => {
227
214
  checkConfigFile(true);
228
- await installAll({silent: true, lock: 'ignore'});
215
+ await installAll({silent: true, lock: 'ignore', installFromLockFile: true});
229
216
  await test(filter, options);
230
217
  });
231
218
 
@@ -241,7 +228,7 @@ program
241
228
  .addOption(new Option('--verbose', 'Show more information'))
242
229
  .action(async (filter, options) => {
243
230
  checkConfigFile(true);
244
- await installAll({silent: true, lock: 'ignore'});
231
+ await installAll({silent: true, lock: 'ignore', installFromLockFile: true});
245
232
  await bench(filter, options);
246
233
  });
247
234
 
@@ -256,37 +243,48 @@ program
256
243
  await template();
257
244
  });
258
245
 
259
- // docs
260
- // program
261
- // .command('docs')
262
- // .description('Generate documentation (experimental)')
263
- // .action(async () => {
264
- // if (!checkConfigFile()) {
265
- // process.exit(1);
266
- // }
267
- // await docs();
268
- // });
269
-
270
- // user
271
- program
272
- .command('user')
273
- .addArgument(new Argument('<sub>').choices(['set', 'get']))
246
+ // mops user *
247
+ const userCommand = new Command('user').description('User management');
248
+
249
+ // user get-principal
250
+ userCommand
251
+ .command('get-principal')
252
+ .description('Print your principal')
253
+ .action(async () => {
254
+ await getPrincipal();
255
+ });
256
+
257
+ // user import
258
+ userCommand
259
+ .command('import <data>')
260
+ .description('Import .pem file data to use as identity')
261
+ .addOption(new Option('--no-encrypt', 'Do not ask for a password to encrypt identity'))
262
+ .action(async (data, options) => {
263
+ await importPem(data, options);
264
+ await getPrincipal();
265
+ });
266
+
267
+ // user set <prop> <value>
268
+ userCommand
269
+ .command('set')
274
270
  .addArgument(new Argument('<prop>').choices(['name', 'site', 'email', 'github', 'twitter']))
275
- .addArgument(new Argument('[value]'))
276
- .description('User settings')
277
- .action(async (sub, prop, value) => {
278
- if (sub == 'get') {
279
- await getUserProp(prop);
280
- }
281
- else if (sub == 'set') {
282
- if (!value) {
283
- console.log('error: missing required argument "value"');
284
- return;
285
- }
286
- await setUserProp(prop, value);
287
- }
271
+ .addArgument(new Argument('<value>'))
272
+ .description('Set user property')
273
+ .action(async (prop, value) => {
274
+ await setUserProp(prop, value);
288
275
  });
289
276
 
277
+ // user get <prop>
278
+ userCommand
279
+ .command('get')
280
+ .addArgument(new Argument('<prop>').choices(['name', 'site', 'email', 'github', 'twitter']))
281
+ .description('Get user property')
282
+ .action(async (prop) => {
283
+ await getUserProp(prop);
284
+ });
285
+
286
+ program.addCommand(userCommand);
287
+
290
288
  // bump
291
289
  program
292
290
  .command('bump [major|minor|patch]')
@@ -1,8 +1,8 @@
1
1
  import process from 'node:process';
2
2
  import chalk from 'chalk';
3
3
  import {createLogUpdate} from 'log-update';
4
- import {checkConfigFile, readConfig} from '../../mops.js';
5
- import {checkIntegrity} from '../../integrity.js';
4
+ import {checkConfigFile, parseDepValue, readConfig} from '../../mops.js';
5
+ import {checkIntegrity, checkLockFileLight, readLockFile} from '../../integrity.js';
6
6
  import {installDeps} from './install-deps.js';
7
7
  import {checkRequirements} from '../../check-requirements.js';
8
8
  import {syncLocalCache} from './sync-local-cache.js';
@@ -13,9 +13,10 @@ type InstallAllOptions = {
13
13
  silent ?: boolean;
14
14
  lock ?: 'check' | 'update' | 'ignore';
15
15
  threads ?: number;
16
+ installFromLockFile ?: boolean;
16
17
  }
17
18
 
18
- export async function installAll({verbose = false, silent = false, threads, lock} : InstallAllOptions = {}) : Promise<boolean> {
19
+ export async function installAll({verbose = false, silent = false, threads, lock, installFromLockFile} : InstallAllOptions = {}) : Promise<boolean> {
19
20
  if (!checkConfigFile()) {
20
21
  return false;
21
22
  }
@@ -24,12 +25,33 @@ export async function installAll({verbose = false, silent = false, threads, lock
24
25
  let deps = Object.values(config.dependencies || {});
25
26
  let devDeps = Object.values(config['dev-dependencies'] || {});
26
27
  let allDeps = [...deps, ...devDeps];
28
+ let installedFromLockFile = false;
27
29
 
28
- let ok = await installDeps(allDeps, {silent, verbose, threads});
29
- if (!ok) {
30
- return false;
30
+ // install from lock file to avoid installing intermediate dependencies
31
+ if ((lock !== 'ignore' || installFromLockFile) && checkLockFileLight()) {
32
+ let lockFileJson = readLockFile();
33
+
34
+ if (lockFileJson && lockFileJson.version === 3) {
35
+ verbose && console.log('Installing from lock file...');
36
+ installedFromLockFile = true;
37
+ let deps = Object.entries(lockFileJson.deps).map(([name, version]) => {
38
+ return parseDepValue(name, version);
39
+ });
40
+ let ok = await installDeps(deps, {silent, verbose, threads, ignoreTransitive: true});
41
+ if (!ok) {
42
+ return false;
43
+ }
44
+ }
31
45
  }
32
46
 
47
+ if (!installedFromLockFile) {
48
+ let ok = await installDeps(allDeps, {silent, verbose, threads});
49
+ if (!ok) {
50
+ return false;
51
+ }
52
+ }
53
+
54
+
33
55
  let logUpdate = createLogUpdate(process.stdout, {showCursor: true});
34
56
 
35
57
  if (!silent && lock !== 'ignore') {
@@ -9,13 +9,14 @@ type InstallDepOptions = {
9
9
  verbose ?: boolean;
10
10
  silent ?: boolean;
11
11
  threads ?: number;
12
+ ignoreTransitive ?: boolean;
12
13
  };
13
14
 
14
15
  // install dependency
15
16
  // returns false if failed
16
- export async function installDep(dep : Dependency, {verbose, silent, threads} : InstallDepOptions = {}, parentPkgPath ?: string) : Promise<boolean> {
17
+ export async function installDep(dep : Dependency, {verbose, silent, threads, ignoreTransitive} : InstallDepOptions = {}, parentPkgPath ?: string) : Promise<boolean> {
17
18
  if (dep.repo) {
18
- await installFromGithub(dep.name, dep.repo, {silent, verbose});
19
+ await installFromGithub(dep.name, dep.repo, {silent, verbose, ignoreTransitive});
19
20
  return true;
20
21
  }
21
22
  else if (dep.path) {
@@ -24,10 +25,10 @@ export async function installDep(dep : Dependency, {verbose, silent, threads} :
24
25
  if (parentPkgPath) {
25
26
  depPath = path.resolve(parentPkgPath, dep.path);
26
27
  }
27
- return installLocalDep(dep.name, depPath, {silent, verbose});
28
+ return installLocalDep(dep.name, depPath, {silent, verbose, ignoreTransitive});
28
29
  }
29
30
  else if (dep.version) {
30
- return installMopsDep(dep.name, dep.version, {silent, verbose, threads});
31
+ return installMopsDep(dep.name, dep.version, {silent, verbose, threads, ignoreTransitive});
31
32
  }
32
33
 
33
34
  return true;
@@ -5,16 +5,17 @@ type InstallDepsOptions = {
5
5
  verbose ?: boolean;
6
6
  silent ?: boolean;
7
7
  threads ?: number;
8
+ ignoreTransitive ?: boolean;
8
9
  };
9
10
 
10
11
  // install all dependencies
11
12
  // returns actual installed dependencies
12
13
  // returns false if failed
13
- export async function installDeps(deps : Dependency[], {verbose, silent, threads} : InstallDepsOptions = {}, parentPkgPath ?: string) : Promise<boolean> {
14
+ export async function installDeps(deps : Dependency[], {verbose, silent, threads, ignoreTransitive} : InstallDepsOptions = {}, parentPkgPath ?: string) : Promise<boolean> {
14
15
  let ok = true;
15
16
 
16
17
  for (const dep of deps) {
17
- let res = await installDep(dep, {verbose, silent, threads}, parentPkgPath);
18
+ let res = await installDep(dep, {verbose, silent, threads, ignoreTransitive}, parentPkgPath);
18
19
  if (!res) {
19
20
  ok = false;
20
21
  }
@@ -7,11 +7,12 @@ import {installDeps} from './install-deps.js';
7
7
  type InstallLocalDepOptions = {
8
8
  verbose ?: boolean;
9
9
  silent ?: boolean;
10
+ ignoreTransitive ?: boolean;
10
11
  };
11
12
 
12
13
  // skip install and just find non-local dependencies to install
13
14
  // pkgPath should be relative to the current root dir or absolute
14
- export async function installLocalDep(pkg : string, pkgPath = '', {verbose, silent} : InstallLocalDepOptions = {}) : Promise<boolean> {
15
+ export async function installLocalDep(pkg : string, pkgPath = '', {verbose, silent, ignoreTransitive} : InstallLocalDepOptions = {}) : Promise<boolean> {
15
16
  if (!silent) {
16
17
  let logUpdate = createLogUpdate(process.stdout, {showCursor: true});
17
18
  logUpdate(`Local dependency ${pkg} = "${pkgPath}"`);
@@ -25,7 +26,12 @@ export async function installLocalDep(pkg : string, pkgPath = '', {verbose, sile
25
26
  }
26
27
 
27
28
  // install dependencies
28
- let dir = path.resolve(getRootDir(), pkgPath);
29
- let config = readConfig(path.join(dir, 'mops.toml'));
30
- return installDeps(Object.values(config.dependencies || {}), {silent, verbose}, pkgPath);
31
- }
29
+ if (!ignoreTransitive) {
30
+ let dir = path.resolve(getRootDir(), pkgPath);
31
+ let config = readConfig(path.join(dir, 'mops.toml'));
32
+ return installDeps(Object.values(config.dependencies || {}), {silent, verbose}, pkgPath);
33
+ }
34
+ else {
35
+ return true;
36
+ }
37
+ }
@@ -19,9 +19,10 @@ type InstallMopsDepOptions = {
19
19
  silent ?: boolean;
20
20
  dep ?: boolean;
21
21
  threads ?: number;
22
+ ignoreTransitive ?: boolean;
22
23
  };
23
24
 
24
- export async function installMopsDep(pkg : string, version = '', {verbose, silent, dep, threads} : InstallMopsDepOptions = {}) : Promise<boolean> {
25
+ export async function installMopsDep(pkg : string, version = '', {verbose, silent, dep, threads, ignoreTransitive} : InstallMopsDepOptions = {}) : Promise<boolean> {
25
26
  threads = threads || 12;
26
27
  let depName = getDepName(pkg);
27
28
 
@@ -113,11 +114,13 @@ export async function installMopsDep(pkg : string, version = '', {verbose, silen
113
114
  }
114
115
 
115
116
  // install dependencies
116
- let config = readConfig(path.join(cacheDir, 'mops.toml'));
117
- let res = await installDeps(Object.values(config.dependencies || {}), {silent, verbose});
117
+ if (!ignoreTransitive) {
118
+ let config = readConfig(path.join(cacheDir, 'mops.toml'));
119
+ let res = await installDeps(Object.values(config.dependencies || {}), {silent, verbose});
118
120
 
119
- if (!res) {
120
- return false;
121
+ if (!res) {
122
+ return false;
123
+ }
121
124
  }
122
125
 
123
126
  return true;
package/dist/cli.js CHANGED
@@ -72,6 +72,7 @@ program
72
72
  .command('install')
73
73
  .alias('i')
74
74
  .description('Install all dependencies specified in mops.toml')
75
+ .option('--no-toolchain', 'Do not install toolchain')
75
76
  .option('--verbose')
76
77
  .addOption(new Option('--lock <action>', 'Lockfile action').choices(['check', 'update', 'ignore']))
77
78
  .action(async (options) => {
@@ -82,9 +83,13 @@ program
82
83
  if (!compatible) {
83
84
  return;
84
85
  }
85
- await toolchain.ensureToolchainInited({ strict: false });
86
+ if (options.toolchain) {
87
+ await toolchain.ensureToolchainInited({ strict: false });
88
+ }
86
89
  let ok = await installAll(options);
87
- await toolchain.installAll(options);
90
+ if (options.toolchain) {
91
+ await toolchain.installAll(options);
92
+ }
88
93
  // check conflicts
89
94
  await resolvePackages({ conflicts: 'warning' });
90
95
  if (!ok) {
@@ -125,15 +130,6 @@ program
125
130
  .action(async () => {
126
131
  console.log(getNetwork());
127
132
  });
128
- // user import
129
- program
130
- .command('mops user import <data>')
131
- .description('Import .pem file data to use as identity')
132
- .addOption(new Option('--no-encrypt', 'Do not ask for a password to encrypt identity'))
133
- .action(async (data, options) => {
134
- await importPem(data, options);
135
- await getPrincipal();
136
- });
137
133
  // sources
138
134
  program
139
135
  .command('sources')
@@ -145,19 +141,12 @@ program
145
141
  process.exit(1);
146
142
  }
147
143
  if (options.install) {
148
- await installAll({ silent: true, lock: 'ignore', threads: 6 });
144
+ await installAll({ silent: true, lock: 'ignore', threads: 6, installFromLockFile: true });
149
145
  }
150
146
  await toolchain.ensureToolchainInited({ strict: false });
151
147
  let sourcesArr = await sources(options);
152
148
  console.log(sourcesArr.join('\n'));
153
149
  });
154
- // get-principal
155
- program
156
- .command('get-principal')
157
- .description('Print your principal')
158
- .action(async () => {
159
- await getPrincipal();
160
- });
161
150
  // search
162
151
  program
163
152
  .command('search <text>')
@@ -193,7 +182,7 @@ program
193
182
  .option('-w, --watch', 'Enable watch mode')
194
183
  .action(async (filter, options) => {
195
184
  checkConfigFile(true);
196
- await installAll({ silent: true, lock: 'ignore' });
185
+ await installAll({ silent: true, lock: 'ignore', installFromLockFile: true });
197
186
  await test(filter, options);
198
187
  });
199
188
  // bench
@@ -208,7 +197,7 @@ program
208
197
  .addOption(new Option('--verbose', 'Show more information'))
209
198
  .action(async (filter, options) => {
210
199
  checkConfigFile(true);
211
- await installAll({ silent: true, lock: 'ignore' });
200
+ await installAll({ silent: true, lock: 'ignore', installFromLockFile: true });
212
201
  await bench(filter, options);
213
202
  });
214
203
  // template
@@ -221,35 +210,42 @@ program
221
210
  }
222
211
  await template();
223
212
  });
224
- // docs
225
- // program
226
- // .command('docs')
227
- // .description('Generate documentation (experimental)')
228
- // .action(async () => {
229
- // if (!checkConfigFile()) {
230
- // process.exit(1);
231
- // }
232
- // await docs();
233
- // });
234
- // user
235
- program
236
- .command('user')
237
- .addArgument(new Argument('<sub>').choices(['set', 'get']))
213
+ // mops user *
214
+ const userCommand = new Command('user').description('User management');
215
+ // user get-principal
216
+ userCommand
217
+ .command('get-principal')
218
+ .description('Print your principal')
219
+ .action(async () => {
220
+ await getPrincipal();
221
+ });
222
+ // user import
223
+ userCommand
224
+ .command('import <data>')
225
+ .description('Import .pem file data to use as identity')
226
+ .addOption(new Option('--no-encrypt', 'Do not ask for a password to encrypt identity'))
227
+ .action(async (data, options) => {
228
+ await importPem(data, options);
229
+ await getPrincipal();
230
+ });
231
+ // user set <prop> <value>
232
+ userCommand
233
+ .command('set')
238
234
  .addArgument(new Argument('<prop>').choices(['name', 'site', 'email', 'github', 'twitter']))
239
- .addArgument(new Argument('[value]'))
240
- .description('User settings')
241
- .action(async (sub, prop, value) => {
242
- if (sub == 'get') {
243
- await getUserProp(prop);
244
- }
245
- else if (sub == 'set') {
246
- if (!value) {
247
- console.log('error: missing required argument "value"');
248
- return;
249
- }
250
- await setUserProp(prop, value);
251
- }
235
+ .addArgument(new Argument('<value>'))
236
+ .description('Set user property')
237
+ .action(async (prop, value) => {
238
+ await setUserProp(prop, value);
239
+ });
240
+ // user get <prop>
241
+ userCommand
242
+ .command('get')
243
+ .addArgument(new Argument('<prop>').choices(['name', 'site', 'email', 'github', 'twitter']))
244
+ .description('Get user property')
245
+ .action(async (prop) => {
246
+ await getUserProp(prop);
252
247
  });
248
+ program.addCommand(userCommand);
253
249
  // bump
254
250
  program
255
251
  .command('bump [major|minor|patch]')
@@ -3,6 +3,7 @@ type InstallAllOptions = {
3
3
  silent?: boolean;
4
4
  lock?: 'check' | 'update' | 'ignore';
5
5
  threads?: number;
6
+ installFromLockFile?: boolean;
6
7
  };
7
- export declare function installAll({ verbose, silent, threads, lock }?: InstallAllOptions): Promise<boolean>;
8
+ export declare function installAll({ verbose, silent, threads, lock, installFromLockFile }?: InstallAllOptions): Promise<boolean>;
8
9
  export {};
@@ -1,13 +1,13 @@
1
1
  import process from 'node:process';
2
2
  import chalk from 'chalk';
3
3
  import { createLogUpdate } from 'log-update';
4
- import { checkConfigFile, readConfig } from '../../mops.js';
5
- import { checkIntegrity } from '../../integrity.js';
4
+ import { checkConfigFile, parseDepValue, readConfig } from '../../mops.js';
5
+ import { checkIntegrity, checkLockFileLight, readLockFile } from '../../integrity.js';
6
6
  import { installDeps } from './install-deps.js';
7
7
  import { checkRequirements } from '../../check-requirements.js';
8
8
  import { syncLocalCache } from './sync-local-cache.js';
9
9
  import { notifyInstalls } from '../../notify-installs.js';
10
- export async function installAll({ verbose = false, silent = false, threads, lock } = {}) {
10
+ export async function installAll({ verbose = false, silent = false, threads, lock, installFromLockFile } = {}) {
11
11
  if (!checkConfigFile()) {
12
12
  return false;
13
13
  }
@@ -15,9 +15,27 @@ export async function installAll({ verbose = false, silent = false, threads, loc
15
15
  let deps = Object.values(config.dependencies || {});
16
16
  let devDeps = Object.values(config['dev-dependencies'] || {});
17
17
  let allDeps = [...deps, ...devDeps];
18
- let ok = await installDeps(allDeps, { silent, verbose, threads });
19
- if (!ok) {
20
- return false;
18
+ let installedFromLockFile = false;
19
+ // install from lock file to avoid installing intermediate dependencies
20
+ if ((lock !== 'ignore' || installFromLockFile) && checkLockFileLight()) {
21
+ let lockFileJson = readLockFile();
22
+ if (lockFileJson && lockFileJson.version === 3) {
23
+ verbose && console.log('Installing from lock file...');
24
+ installedFromLockFile = true;
25
+ let deps = Object.entries(lockFileJson.deps).map(([name, version]) => {
26
+ return parseDepValue(name, version);
27
+ });
28
+ let ok = await installDeps(deps, { silent, verbose, threads, ignoreTransitive: true });
29
+ if (!ok) {
30
+ return false;
31
+ }
32
+ }
33
+ }
34
+ if (!installedFromLockFile) {
35
+ let ok = await installDeps(allDeps, { silent, verbose, threads });
36
+ if (!ok) {
37
+ return false;
38
+ }
21
39
  }
22
40
  let logUpdate = createLogUpdate(process.stdout, { showCursor: true });
23
41
  if (!silent && lock !== 'ignore') {
@@ -3,6 +3,7 @@ type InstallDepOptions = {
3
3
  verbose?: boolean;
4
4
  silent?: boolean;
5
5
  threads?: number;
6
+ ignoreTransitive?: boolean;
6
7
  };
7
- export declare function installDep(dep: Dependency, { verbose, silent, threads }?: InstallDepOptions, parentPkgPath?: string): Promise<boolean>;
8
+ export declare function installDep(dep: Dependency, { verbose, silent, threads, ignoreTransitive }?: InstallDepOptions, parentPkgPath?: string): Promise<boolean>;
8
9
  export {};
@@ -5,9 +5,9 @@ import { installLocalDep } from './install-local-dep.js';
5
5
  import { getRootDir } from '../../mops.js';
6
6
  // install dependency
7
7
  // returns false if failed
8
- export async function installDep(dep, { verbose, silent, threads } = {}, parentPkgPath) {
8
+ export async function installDep(dep, { verbose, silent, threads, ignoreTransitive } = {}, parentPkgPath) {
9
9
  if (dep.repo) {
10
- await installFromGithub(dep.name, dep.repo, { silent, verbose });
10
+ await installFromGithub(dep.name, dep.repo, { silent, verbose, ignoreTransitive });
11
11
  return true;
12
12
  }
13
13
  else if (dep.path) {
@@ -16,10 +16,10 @@ export async function installDep(dep, { verbose, silent, threads } = {}, parentP
16
16
  if (parentPkgPath) {
17
17
  depPath = path.resolve(parentPkgPath, dep.path);
18
18
  }
19
- return installLocalDep(dep.name, depPath, { silent, verbose });
19
+ return installLocalDep(dep.name, depPath, { silent, verbose, ignoreTransitive });
20
20
  }
21
21
  else if (dep.version) {
22
- return installMopsDep(dep.name, dep.version, { silent, verbose, threads });
22
+ return installMopsDep(dep.name, dep.version, { silent, verbose, threads, ignoreTransitive });
23
23
  }
24
24
  return true;
25
25
  }
@@ -3,6 +3,7 @@ type InstallDepsOptions = {
3
3
  verbose?: boolean;
4
4
  silent?: boolean;
5
5
  threads?: number;
6
+ ignoreTransitive?: boolean;
6
7
  };
7
- export declare function installDeps(deps: Dependency[], { verbose, silent, threads }?: InstallDepsOptions, parentPkgPath?: string): Promise<boolean>;
8
+ export declare function installDeps(deps: Dependency[], { verbose, silent, threads, ignoreTransitive }?: InstallDepsOptions, parentPkgPath?: string): Promise<boolean>;
8
9
  export {};
@@ -2,10 +2,10 @@ import { installDep } from './install-dep.js';
2
2
  // install all dependencies
3
3
  // returns actual installed dependencies
4
4
  // returns false if failed
5
- export async function installDeps(deps, { verbose, silent, threads } = {}, parentPkgPath) {
5
+ export async function installDeps(deps, { verbose, silent, threads, ignoreTransitive } = {}, parentPkgPath) {
6
6
  let ok = true;
7
7
  for (const dep of deps) {
8
- let res = await installDep(dep, { verbose, silent, threads }, parentPkgPath);
8
+ let res = await installDep(dep, { verbose, silent, threads, ignoreTransitive }, parentPkgPath);
9
9
  if (!res) {
10
10
  ok = false;
11
11
  }
@@ -1,6 +1,7 @@
1
1
  type InstallLocalDepOptions = {
2
2
  verbose?: boolean;
3
3
  silent?: boolean;
4
+ ignoreTransitive?: boolean;
4
5
  };
5
- export declare function installLocalDep(pkg: string, pkgPath?: string, { verbose, silent }?: InstallLocalDepOptions): Promise<boolean>;
6
+ export declare function installLocalDep(pkg: string, pkgPath?: string, { verbose, silent, ignoreTransitive }?: InstallLocalDepOptions): Promise<boolean>;
6
7
  export {};
@@ -5,7 +5,7 @@ import { getRootDir, readConfig } from '../../mops.js';
5
5
  import { installDeps } from './install-deps.js';
6
6
  // skip install and just find non-local dependencies to install
7
7
  // pkgPath should be relative to the current root dir or absolute
8
- export async function installLocalDep(pkg, pkgPath = '', { verbose, silent } = {}) {
8
+ export async function installLocalDep(pkg, pkgPath = '', { verbose, silent, ignoreTransitive } = {}) {
9
9
  if (!silent) {
10
10
  let logUpdate = createLogUpdate(process.stdout, { showCursor: true });
11
11
  logUpdate(`Local dependency ${pkg} = "${pkgPath}"`);
@@ -17,7 +17,12 @@ export async function installLocalDep(pkg, pkgPath = '', { verbose, silent } = {
17
17
  }
18
18
  }
19
19
  // install dependencies
20
- let dir = path.resolve(getRootDir(), pkgPath);
21
- let config = readConfig(path.join(dir, 'mops.toml'));
22
- return installDeps(Object.values(config.dependencies || {}), { silent, verbose }, pkgPath);
20
+ if (!ignoreTransitive) {
21
+ let dir = path.resolve(getRootDir(), pkgPath);
22
+ let config = readConfig(path.join(dir, 'mops.toml'));
23
+ return installDeps(Object.values(config.dependencies || {}), { silent, verbose }, pkgPath);
24
+ }
25
+ else {
26
+ return true;
27
+ }
23
28
  }
@@ -3,6 +3,7 @@ type InstallMopsDepOptions = {
3
3
  silent?: boolean;
4
4
  dep?: boolean;
5
5
  threads?: number;
6
+ ignoreTransitive?: boolean;
6
7
  };
7
- export declare function installMopsDep(pkg: string, version?: string, { verbose, silent, dep, threads }?: InstallMopsDepOptions): Promise<boolean>;
8
+ export declare function installMopsDep(pkg: string, version?: string, { verbose, silent, dep, threads, ignoreTransitive }?: InstallMopsDepOptions): Promise<boolean>;
8
9
  export {};
@@ -13,7 +13,7 @@ import { getDepCacheDir, getMopsDepCacheName, isDepCached } from '../../cache.js
13
13
  import { downloadFile, getPackageFilesInfo } from '../../api/downloadPackageFiles.js';
14
14
  import { installDeps } from './install-deps.js';
15
15
  import { getDepName } from '../../helpers/get-dep-name.js';
16
- export async function installMopsDep(pkg, version = '', { verbose, silent, dep, threads } = {}) {
16
+ export async function installMopsDep(pkg, version = '', { verbose, silent, dep, threads, ignoreTransitive } = {}) {
17
17
  threads = threads || 12;
18
18
  let depName = getDepName(pkg);
19
19
  if (!checkConfigFile()) {
@@ -90,10 +90,12 @@ export async function installMopsDep(pkg, version = '', { verbose, silent, dep,
90
90
  logUpdate.clear();
91
91
  }
92
92
  // install dependencies
93
- let config = readConfig(path.join(cacheDir, 'mops.toml'));
94
- let res = await installDeps(Object.values(config.dependencies || {}), { silent, verbose });
95
- if (!res) {
96
- return false;
93
+ if (!ignoreTransitive) {
94
+ let config = readConfig(path.join(cacheDir, 'mops.toml'));
95
+ let res = await installDeps(Object.values(config.dependencies || {}), { silent, verbose });
96
+ if (!res) {
97
+ return false;
98
+ }
97
99
  }
98
100
  return true;
99
101
  }
@@ -1,5 +1,25 @@
1
+ type LockFileV1 = {
2
+ version: 1;
3
+ mopsTomlHash: string;
4
+ hashes: Record<string, Record<string, string>>;
5
+ };
6
+ type LockFileV2 = {
7
+ version: 2;
8
+ mopsTomlDepsHash: string;
9
+ hashes: Record<string, Record<string, string>>;
10
+ };
11
+ type LockFileV3 = {
12
+ version: 3;
13
+ mopsTomlDepsHash: string;
14
+ hashes: Record<string, Record<string, string>>;
15
+ deps: Record<string, string>;
16
+ };
17
+ type LockFile = LockFileV1 | LockFileV2 | LockFileV3;
1
18
  export declare function checkIntegrity(lock?: 'check' | 'update' | 'ignore'): Promise<void>;
2
19
  export declare function getLocalFileHash(fileId: string): string;
3
20
  export declare function checkRemote(): Promise<void>;
21
+ export declare function readLockFile(): LockFile | null;
22
+ export declare function checkLockFileLight(): boolean;
4
23
  export declare function updateLockFile(): Promise<void>;
5
24
  export declare function checkLockFile(force?: boolean): Promise<void>;
25
+ export {};
package/dist/integrity.js CHANGED
@@ -78,21 +78,36 @@ export async function checkRemote() {
78
78
  }
79
79
  }
80
80
  }
81
- export async function updateLockFile() {
81
+ export function readLockFile() {
82
82
  let rootDir = getRootDir();
83
83
  let lockFile = path.join(rootDir, 'mops.lock');
84
- // if lock file exists and mops.toml hasn't changed, don't update it
85
84
  if (fs.existsSync(lockFile)) {
86
- let lockFileJson = JSON.parse(fs.readFileSync(lockFile).toString());
85
+ return JSON.parse(fs.readFileSync(lockFile).toString());
86
+ }
87
+ return null;
88
+ }
89
+ // check if lock file exists and integrity of mopsTomlDepsHash
90
+ export function checkLockFileLight() {
91
+ let existingLockFileJson = readLockFile();
92
+ if (existingLockFileJson) {
87
93
  let mopsTomlDepsHash = getMopsTomlDepsHash();
88
- if (mopsTomlDepsHash === lockFileJson.mopsTomlDepsHash) {
89
- return;
94
+ if (existingLockFileJson.version === 3 && mopsTomlDepsHash === existingLockFileJson.mopsTomlDepsHash) {
95
+ return true;
90
96
  }
91
97
  }
98
+ return false;
99
+ }
100
+ export async function updateLockFile() {
101
+ // if lock file exists and mops.toml hasn't changed, don't update it
102
+ if (checkLockFileLight()) {
103
+ return;
104
+ }
105
+ let resolvedDeps = await resolvePackages();
92
106
  let fileHashes = await getFileHashesFromRegistry();
93
107
  let lockFileJson = {
94
- version: 2,
108
+ version: 3,
95
109
  mopsTomlDepsHash: getMopsTomlDepsHash(),
110
+ deps: resolvedDeps,
96
111
  hashes: fileHashes.reduce((acc, [packageId, fileHashes]) => {
97
112
  acc[packageId] = fileHashes.reduce((acc, [fileId, hash]) => {
98
113
  acc[fileId] = bytesToHex(new Uint8Array(hash));
@@ -101,6 +116,8 @@ export async function updateLockFile() {
101
116
  return acc;
102
117
  }, {}),
103
118
  };
119
+ let rootDir = getRootDir();
120
+ let lockFile = path.join(rootDir, 'mops.lock');
104
121
  fs.writeFileSync(lockFile, JSON.stringify(lockFileJson, null, 2));
105
122
  }
106
123
  // compare hashes of local files with hashes from the lock file
@@ -118,9 +135,9 @@ export async function checkLockFile(force = false) {
118
135
  let lockFileJsonGeneric = JSON.parse(fs.readFileSync(lockFile).toString());
119
136
  let packageIds = await getResolvedMopsPackageIds();
120
137
  // check lock file version
121
- if (lockFileJsonGeneric.version !== 1 && lockFileJsonGeneric.version !== 2) {
138
+ if (lockFileJsonGeneric.version !== 1 && lockFileJsonGeneric.version !== 2 && lockFileJsonGeneric.version !== 3) {
122
139
  console.error('Integrity check failed');
123
- console.error(`Invalid lock file version: ${lockFileJsonGeneric.version}. Supported versions: 1`);
140
+ console.error(`Invalid lock file version: ${lockFileJsonGeneric.version}. Supported versions: 1, 2, 3`);
124
141
  process.exit(1);
125
142
  }
126
143
  let lockFileJson = lockFileJsonGeneric;
@@ -134,8 +151,8 @@ export async function checkLockFile(force = false) {
134
151
  process.exit(1);
135
152
  }
136
153
  }
137
- // V2: check mops.toml deps hash
138
- if (lockFileJson.version === 2) {
154
+ // V2, V3: check mops.toml deps hash
155
+ if (lockFileJson.version === 2 || lockFileJson.version === 3) {
139
156
  if (lockFileJson.mopsTomlDepsHash !== getMopsTomlDepsHash()) {
140
157
  console.error('Integrity check failed');
141
158
  console.error('Mismatched mops.toml dependencies hash');
@@ -144,6 +161,20 @@ export async function checkLockFile(force = false) {
144
161
  process.exit(1);
145
162
  }
146
163
  }
164
+ // V3: check locked deps (including GitHub and local packages)
165
+ if (lockFileJson.version === 3) {
166
+ let lockedDeps = { ...lockFileJson.deps };
167
+ let resolvedDeps = await resolvePackages();
168
+ for (let name of Object.keys(resolvedDeps)) {
169
+ if (lockedDeps[name] !== resolvedDeps[name]) {
170
+ console.error('Integrity check failed');
171
+ console.error(`Mismatched package ${name}`);
172
+ console.error(`Locked: ${lockedDeps[name]}`);
173
+ console.error(`Actual: ${resolvedDeps[name]}`);
174
+ process.exit(1);
175
+ }
176
+ }
177
+ }
147
178
  // check number of packages
148
179
  if (Object.keys(lockFileJson.hashes).length !== packageIds.length) {
149
180
  console.error('Integrity check failed');
package/dist/mops.d.ts CHANGED
@@ -1,5 +1,5 @@
1
1
  import { Identity } from '@dfinity/agent';
2
- import { Config } from './types.js';
2
+ import { Config, Dependency } from './types.js';
3
3
  import { mainActor, storageActor } from './api/actors.js';
4
4
  import { getNetwork } from './api/network.js';
5
5
  import { getHighestVersion } from './api/getHighestVersion.js';
@@ -21,6 +21,7 @@ export declare function parseGithubURL(href: string): {
21
21
  };
22
22
  export declare function getGithubCommit(repo: string, ref: string): Promise<any>;
23
23
  export declare function getDependencyType(version: string): "local" | "mops" | "github";
24
+ export declare function parseDepValue(name: string, value: string): Dependency;
24
25
  export declare function readConfig(configFile?: string): Config;
25
26
  export declare function writeConfig(config: Config, configFile?: string): void;
26
27
  export declare function formatDir(name: string, version: string): string;
package/dist/mops.js CHANGED
@@ -135,6 +135,18 @@ export function getDependencyType(version) {
135
135
  return 'mops';
136
136
  }
137
137
  }
138
+ export function parseDepValue(name, value) {
139
+ let depType = getDependencyType(value);
140
+ if (depType === 'github') {
141
+ return { name, repo: value, version: '' };
142
+ }
143
+ else if (depType === 'local') {
144
+ return { name, repo: '', path: value, version: '' };
145
+ }
146
+ else {
147
+ return { name, repo: '', version: value };
148
+ }
149
+ }
138
150
  export function readConfig(configFile = getClosestConfigFile()) {
139
151
  let text = fs.readFileSync(configFile).toString();
140
152
  let toml = TOML.parse(text);
@@ -143,16 +155,7 @@ export function readConfig(configFile = getClosestConfigFile()) {
143
155
  if (!data || typeof data !== 'string') {
144
156
  throw Error(`Invalid dependency value ${name} = "${data}"`);
145
157
  }
146
- let depType = getDependencyType(data);
147
- if (depType === 'github') {
148
- deps[name] = { name, repo: data, version: '' };
149
- }
150
- else if (depType === 'local') {
151
- deps[name] = { name, repo: '', path: data, version: '' };
152
- }
153
- else {
154
- deps[name] = { name, repo: '', version: data };
155
- }
158
+ deps[name] = parseDepValue(name, data);
156
159
  });
157
160
  };
158
161
  processDeps(toml.dependencies || {});
package/dist/package.json CHANGED
@@ -1,6 +1,6 @@
1
1
  {
2
2
  "name": "ic-mops",
3
- "version": "1.0.0",
3
+ "version": "1.1.0-pre.0",
4
4
  "type": "module",
5
5
  "bin": {
6
6
  "mops": "bin/mops.js",
@@ -5,10 +5,17 @@ import { checkConfigFile, getRootDir, parseGithubURL, readConfig } from './mops.
5
5
  import { readVesselConfig } from './vessel.js';
6
6
  import { getDepCacheDir, getDepCacheName } from './cache.js';
7
7
  import { getPackageId } from './helpers/get-package-id.js';
8
+ import { checkLockFileLight, readLockFile } from './integrity.js';
8
9
  export async function resolvePackages({ conflicts = 'ignore' } = {}) {
9
10
  if (!checkConfigFile()) {
10
11
  return {};
11
12
  }
13
+ if (checkLockFileLight()) {
14
+ let lockFileJson = readLockFile();
15
+ if (lockFileJson && lockFileJson.version === 3) {
16
+ return lockFileJson.deps;
17
+ }
18
+ }
12
19
  let rootDir = getRootDir();
13
20
  let packages = {};
14
21
  let versions = {};
package/dist/vessel.d.ts CHANGED
@@ -13,8 +13,9 @@ export declare const readVesselConfig: (dir: string, { cache, silent }?: {
13
13
  silent?: boolean | undefined;
14
14
  }) => Promise<VesselConfig | null>;
15
15
  export declare const downloadFromGithub: (repo: string, dest: string, onProgress: any) => Promise<unknown>;
16
- export declare const installFromGithub: (name: string, repo: string, { verbose, dep, silent }?: {
16
+ export declare const installFromGithub: (name: string, repo: string, { verbose, dep, silent, ignoreTransitive }?: {
17
17
  verbose?: boolean | undefined;
18
18
  dep?: boolean | undefined;
19
19
  silent?: boolean | undefined;
20
+ ignoreTransitive?: boolean | undefined;
20
21
  }) => Promise<void>;
package/dist/vessel.js CHANGED
@@ -116,7 +116,7 @@ export const downloadFromGithub = async (repo, dest, onProgress) => {
116
116
  });
117
117
  return promise;
118
118
  };
119
- export const installFromGithub = async (name, repo, { verbose = false, dep = false, silent = false } = {}) => {
119
+ export const installFromGithub = async (name, repo, { verbose = false, dep = false, silent = false, ignoreTransitive = false } = {}) => {
120
120
  let cacheName = getGithubDepCacheName(name, repo);
121
121
  let cacheDir = getDepCacheDir(cacheName);
122
122
  let logUpdate = createLogUpdate(process.stdout, { showCursor: true });
@@ -143,6 +143,9 @@ export const installFromGithub = async (name, repo, { verbose = false, dep = fal
143
143
  else {
144
144
  logUpdate.clear();
145
145
  }
146
+ if (ignoreTransitive) {
147
+ return;
148
+ }
146
149
  const config = await readVesselConfig(cacheDir, { silent });
147
150
  if (config) {
148
151
  for (const { name, repo } of config.dependencies) {
package/integrity.ts CHANGED
@@ -24,7 +24,14 @@ type LockFileV2 = {
24
24
  hashes : Record<string, Record<string, string>>;
25
25
  };
26
26
 
27
- type LockFile = LockFileV1 | LockFileV2;
27
+ type LockFileV3 = {
28
+ version : 3;
29
+ mopsTomlDepsHash : string;
30
+ hashes : Record<string, Record<string, string>>;
31
+ deps : Record<string, string>;
32
+ };
33
+
34
+ type LockFile = LockFileV1 | LockFileV2 | LockFileV3;
28
35
 
29
36
  export async function checkIntegrity(lock ?: 'check' | 'update' | 'ignore') {
30
37
  let force = !!lock;
@@ -109,24 +116,41 @@ export async function checkRemote() {
109
116
  }
110
117
  }
111
118
 
112
- export async function updateLockFile() {
119
+ export function readLockFile() : LockFile | null {
113
120
  let rootDir = getRootDir();
114
121
  let lockFile = path.join(rootDir, 'mops.lock');
115
-
116
- // if lock file exists and mops.toml hasn't changed, don't update it
117
122
  if (fs.existsSync(lockFile)) {
118
- let lockFileJson : LockFileV2 = JSON.parse(fs.readFileSync(lockFile).toString());
123
+ return JSON.parse(fs.readFileSync(lockFile).toString()) as LockFile;
124
+ }
125
+ return null;
126
+ }
127
+
128
+ // check if lock file exists and integrity of mopsTomlDepsHash
129
+ export function checkLockFileLight() : boolean {
130
+ let existingLockFileJson = readLockFile();
131
+ if (existingLockFileJson) {
119
132
  let mopsTomlDepsHash = getMopsTomlDepsHash();
120
- if (mopsTomlDepsHash === lockFileJson.mopsTomlDepsHash) {
121
- return;
133
+ if (existingLockFileJson.version === 3 && mopsTomlDepsHash === existingLockFileJson.mopsTomlDepsHash) {
134
+ return true;
122
135
  }
123
136
  }
137
+ return false;
138
+ }
139
+
140
+ export async function updateLockFile() {
141
+ // if lock file exists and mops.toml hasn't changed, don't update it
142
+ if (checkLockFileLight()) {
143
+ return;
144
+ }
145
+
146
+ let resolvedDeps = await resolvePackages();
124
147
 
125
148
  let fileHashes = await getFileHashesFromRegistry();
126
149
 
127
- let lockFileJson : LockFileV2 = {
128
- version: 2,
150
+ let lockFileJson : LockFileV3 = {
151
+ version: 3,
129
152
  mopsTomlDepsHash: getMopsTomlDepsHash(),
153
+ deps: resolvedDeps,
130
154
  hashes: fileHashes.reduce((acc, [packageId, fileHashes]) => {
131
155
  acc[packageId] = fileHashes.reduce((acc, [fileId, hash]) => {
132
156
  acc[fileId] = bytesToHex(new Uint8Array(hash));
@@ -136,6 +160,8 @@ export async function updateLockFile() {
136
160
  }, {} as Record<string, Record<string, string>>),
137
161
  };
138
162
 
163
+ let rootDir = getRootDir();
164
+ let lockFile = path.join(rootDir, 'mops.lock');
139
165
  fs.writeFileSync(lockFile, JSON.stringify(lockFileJson, null, 2));
140
166
  }
141
167
 
@@ -157,9 +183,9 @@ export async function checkLockFile(force = false) {
157
183
  let packageIds = await getResolvedMopsPackageIds();
158
184
 
159
185
  // check lock file version
160
- if (lockFileJsonGeneric.version !== 1 && lockFileJsonGeneric.version !== 2) {
186
+ if (lockFileJsonGeneric.version !== 1 && lockFileJsonGeneric.version !== 2 && lockFileJsonGeneric.version !== 3) {
161
187
  console.error('Integrity check failed');
162
- console.error(`Invalid lock file version: ${lockFileJsonGeneric.version}. Supported versions: 1`);
188
+ console.error(`Invalid lock file version: ${lockFileJsonGeneric.version}. Supported versions: 1, 2, 3`);
163
189
  process.exit(1);
164
190
  }
165
191
 
@@ -176,8 +202,8 @@ export async function checkLockFile(force = false) {
176
202
  }
177
203
  }
178
204
 
179
- // V2: check mops.toml deps hash
180
- if (lockFileJson.version === 2) {
205
+ // V2, V3: check mops.toml deps hash
206
+ if (lockFileJson.version === 2 || lockFileJson.version === 3) {
181
207
  if (lockFileJson.mopsTomlDepsHash !== getMopsTomlDepsHash()) {
182
208
  console.error('Integrity check failed');
183
209
  console.error('Mismatched mops.toml dependencies hash');
@@ -187,6 +213,22 @@ export async function checkLockFile(force = false) {
187
213
  }
188
214
  }
189
215
 
216
+ // V3: check locked deps (including GitHub and local packages)
217
+ if (lockFileJson.version === 3) {
218
+ let lockedDeps = {...lockFileJson.deps};
219
+ let resolvedDeps = await resolvePackages();
220
+
221
+ for (let name of Object.keys(resolvedDeps)) {
222
+ if (lockedDeps[name] !== resolvedDeps[name]) {
223
+ console.error('Integrity check failed');
224
+ console.error(`Mismatched package ${name}`);
225
+ console.error(`Locked: ${lockedDeps[name]}`);
226
+ console.error(`Actual: ${resolvedDeps[name]}`);
227
+ process.exit(1);
228
+ }
229
+ }
230
+ }
231
+
190
232
  // check number of packages
191
233
  if (Object.keys(lockFileJson.hashes).length !== packageIds.length) {
192
234
  console.error('Integrity check failed');
package/mops.ts CHANGED
@@ -8,7 +8,7 @@ import prompts from 'prompts';
8
8
  import fetch from 'node-fetch';
9
9
 
10
10
  import {decodeFile} from './pem.js';
11
- import {Config} from './types.js';
11
+ import {Config, Dependency} from './types.js';
12
12
  import {mainActor, storageActor} from './api/actors.js';
13
13
  import {getNetwork} from './api/network.js';
14
14
  import {getHighestVersion} from './api/getHighestVersion.js';
@@ -156,6 +156,19 @@ export function getDependencyType(version : string) {
156
156
  }
157
157
  }
158
158
 
159
+ export function parseDepValue(name : string, value : string) : Dependency {
160
+ let depType = getDependencyType(value);
161
+ if (depType === 'github') {
162
+ return {name, repo: value, version: ''};
163
+ }
164
+ else if (depType === 'local') {
165
+ return {name, repo: '', path: value, version: ''};
166
+ }
167
+ else {
168
+ return {name, repo: '', version: value};
169
+ }
170
+ }
171
+
159
172
  export function readConfig(configFile = getClosestConfigFile()) : Config {
160
173
  let text = fs.readFileSync(configFile).toString();
161
174
  let toml = TOML.parse(text);
@@ -165,16 +178,7 @@ export function readConfig(configFile = getClosestConfigFile()) : Config {
165
178
  if (!data || typeof data !== 'string') {
166
179
  throw Error(`Invalid dependency value ${name} = "${data}"`);
167
180
  }
168
- let depType = getDependencyType(data);
169
- if (depType === 'github') {
170
- deps[name] = {name, repo: data, version: ''};
171
- }
172
- else if (depType === 'local') {
173
- deps[name] = {name, repo: '', path: data, version: ''};
174
- }
175
- else {
176
- deps[name] = {name, repo: '', version: data};
177
- }
181
+ deps[name] = parseDepValue(name, data);
178
182
  });
179
183
  };
180
184
 
package/package.json CHANGED
@@ -1,6 +1,6 @@
1
1
  {
2
2
  "name": "ic-mops",
3
- "version": "1.0.0",
3
+ "version": "1.1.0-pre.0",
4
4
  "type": "module",
5
5
  "bin": {
6
6
  "mops": "dist/bin/mops.js",
@@ -6,12 +6,21 @@ import {VesselConfig, readVesselConfig} from './vessel.js';
6
6
  import {Config, Dependency} from './types.js';
7
7
  import {getDepCacheDir, getDepCacheName} from './cache.js';
8
8
  import {getPackageId} from './helpers/get-package-id.js';
9
+ import {checkLockFileLight, readLockFile} from './integrity.js';
9
10
 
10
11
  export async function resolvePackages({conflicts = 'ignore' as 'warning' | 'error' | 'ignore'} = {}) : Promise<Record<string, string>> {
11
12
  if (!checkConfigFile()) {
12
13
  return {};
13
14
  }
14
15
 
16
+ if (checkLockFileLight()) {
17
+ let lockFileJson = readLockFile();
18
+
19
+ if (lockFileJson && lockFileJson.version === 3) {
20
+ return lockFileJson.deps;
21
+ }
22
+ }
23
+
15
24
  let rootDir = getRootDir();
16
25
  let packages : Record<string, Dependency & {isRoot : boolean;}> = {};
17
26
  let versions : Record<string, Array<{
package/test ADDED
@@ -0,0 +1,4 @@
1
+ dev, toolchain 89s
2
+ no dev, no toolchain 68s
3
+ lockfile, toolchain 60s
4
+ lockfile, no toolchain 49s
package/vessel.ts CHANGED
@@ -149,7 +149,7 @@ export const downloadFromGithub = async (repo : string, dest : string, onProgres
149
149
  return promise;
150
150
  };
151
151
 
152
- export const installFromGithub = async (name : string, repo : string, {verbose = false, dep = false, silent = false} = {}) => {
152
+ export const installFromGithub = async (name : string, repo : string, {verbose = false, dep = false, silent = false, ignoreTransitive = false} = {}) => {
153
153
  let cacheName = getGithubDepCacheName(name, repo);
154
154
  let cacheDir = getDepCacheDir(cacheName);
155
155
 
@@ -183,6 +183,10 @@ export const installFromGithub = async (name : string, repo : string, {verbose =
183
183
  logUpdate.clear();
184
184
  }
185
185
 
186
+ if (ignoreTransitive) {
187
+ return;
188
+ }
189
+
186
190
  const config = await readVesselConfig(cacheDir, {silent});
187
191
 
188
192
  if (config) {