ic-mops 0.27.2 → 0.28.0-pre.1
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/commands/add.ts +8 -2
- package/commands/install-all.ts +7 -2
- package/commands/install.ts +16 -7
- package/commands/sources.ts +13 -112
- package/declarations/main/main.did +4 -0
- package/declarations/main/main.did.d.ts +4 -0
- package/declarations/main/main.did.js +5 -0
- package/dist/commands/add.js +6 -2
- package/dist/commands/install-all.js +6 -2
- package/dist/commands/install.d.ts +1 -1
- package/dist/commands/install.js +14 -5
- package/dist/commands/sources.js +12 -95
- package/dist/declarations/main/main.did +4 -0
- package/dist/declarations/main/main.did.d.ts +4 -0
- package/dist/declarations/main/main.did.js +5 -0
- package/dist/mops.d.ts +1 -0
- package/dist/mops.js +17 -2
- package/dist/notify-installs.d.ts +1 -0
- package/dist/notify-installs.js +8 -0
- package/dist/out/cli.d.ts +2 -0
- package/dist/out/cli.js +114581 -0
- package/dist/package.json +1 -1
- package/dist/resolve-packages.d.ts +3 -0
- package/dist/resolve-packages.js +108 -0
- package/mops.ts +18 -2
- package/notify-installs.ts +9 -0
- package/package.json +1 -1
- package/resolve-packages.ts +131 -0
package/commands/add.ts
CHANGED
|
@@ -4,6 +4,7 @@ import logUpdate from 'log-update';
|
|
|
4
4
|
import {checkConfigFile, getHighestVersion, parseGithubURL, readConfig, writeConfig} from '../mops.js';
|
|
5
5
|
import {installFromGithub} from '../vessel.js';
|
|
6
6
|
import {install} from './install.js';
|
|
7
|
+
import {notifyInstalls} from '../notify-installs.js';
|
|
7
8
|
|
|
8
9
|
export async function add(name: string, {verbose = false, dev = false} = {}) {
|
|
9
10
|
if (!checkConfigFile()) {
|
|
@@ -66,14 +67,17 @@ export async function add(name: string, {verbose = false, dev = false} = {}) {
|
|
|
66
67
|
};
|
|
67
68
|
}
|
|
68
69
|
|
|
70
|
+
let installedPackages = {};
|
|
71
|
+
|
|
69
72
|
if (pkgDetails.repo) {
|
|
70
73
|
await installFromGithub(pkgDetails.name, pkgDetails.repo, {verbose: verbose});
|
|
71
74
|
}
|
|
72
75
|
else if (!pkgDetails.path) {
|
|
73
|
-
let
|
|
74
|
-
if (
|
|
76
|
+
let res = await install(pkgDetails.name, pkgDetails.version, {verbose: verbose});
|
|
77
|
+
if (res === false) {
|
|
75
78
|
return;
|
|
76
79
|
}
|
|
80
|
+
installedPackages = {...installedPackages, ...res};
|
|
77
81
|
}
|
|
78
82
|
|
|
79
83
|
const depsProp = dev ? 'dev-dependencies' : 'dependencies';
|
|
@@ -84,7 +88,9 @@ export async function add(name: string, {verbose = false, dev = false} = {}) {
|
|
|
84
88
|
else {
|
|
85
89
|
throw Error(`Invalid config file: [${depsProp}] not found`);
|
|
86
90
|
}
|
|
91
|
+
|
|
87
92
|
writeConfig(config);
|
|
93
|
+
notifyInstalls(Object.keys(installedPackages));
|
|
88
94
|
|
|
89
95
|
logUpdate.clear();
|
|
90
96
|
console.log(chalk.green('Package installed ') + `${pkgDetails.name} = "${pkgDetails.repo || pkgDetails.path || pkgDetails.version}"`);
|
package/commands/install-all.ts
CHANGED
|
@@ -3,6 +3,7 @@ import logUpdate from 'log-update';
|
|
|
3
3
|
import {checkConfigFile, readConfig} from '../mops.js';
|
|
4
4
|
import {install} from './install.js';
|
|
5
5
|
import {installFromGithub} from '../vessel.js';
|
|
6
|
+
import {notifyInstalls} from '../notify-installs.js';
|
|
6
7
|
|
|
7
8
|
export async function installAll({verbose = false, silent = false} = {}) {
|
|
8
9
|
if (!checkConfigFile()) {
|
|
@@ -13,19 +14,23 @@ export async function installAll({verbose = false, silent = false} = {}) {
|
|
|
13
14
|
let deps = Object.values(config.dependencies || {});
|
|
14
15
|
let devDeps = Object.values(config['dev-dependencies'] || {});
|
|
15
16
|
let allDeps = [...deps, ...devDeps];
|
|
17
|
+
let installedPackages = {};
|
|
16
18
|
|
|
17
19
|
for (let {name, repo, path, version} of allDeps) {
|
|
18
20
|
if (repo) {
|
|
19
21
|
await installFromGithub(name, repo, {verbose, silent});
|
|
20
22
|
}
|
|
21
23
|
else if (!path) {
|
|
22
|
-
let
|
|
23
|
-
if (
|
|
24
|
+
let res = await install(name, version, {verbose, silent});
|
|
25
|
+
if (res === false) {
|
|
24
26
|
return;
|
|
25
27
|
}
|
|
28
|
+
installedPackages = {...installedPackages, ...res};
|
|
26
29
|
}
|
|
27
30
|
}
|
|
28
31
|
|
|
32
|
+
notifyInstalls(Object.keys(installedPackages));
|
|
33
|
+
|
|
29
34
|
if (!silent) {
|
|
30
35
|
logUpdate.clear();
|
|
31
36
|
console.log(chalk.green('All packages installed'));
|
package/commands/install.ts
CHANGED
|
@@ -7,7 +7,7 @@ import {parallel} from '../parallel.js';
|
|
|
7
7
|
import {installFromGithub} from '../vessel.js';
|
|
8
8
|
import {addCache, copyCache, isCached} from '../cache.js';
|
|
9
9
|
|
|
10
|
-
export async function install(pkg: string, version = '', {verbose = false, silent = false, dep = false} = {}) {
|
|
10
|
+
export async function install(pkg: string, version = '', {verbose = false, silent = false, dep = false} = {}): Promise<Record<string, string> | false> {
|
|
11
11
|
if (!checkConfigFile()) {
|
|
12
12
|
return false;
|
|
13
13
|
}
|
|
@@ -32,14 +32,15 @@ export async function install(pkg: string, version = '', {verbose = false, silen
|
|
|
32
32
|
|
|
33
33
|
let dir = formatDir(pkg, version);
|
|
34
34
|
let actor = await mainActor();
|
|
35
|
+
let alreadyInstalled = false;
|
|
35
36
|
|
|
36
37
|
// already installed
|
|
37
38
|
if (fs.existsSync(dir)) {
|
|
38
39
|
silent || logUpdate(`${dep ? 'Dependency' : 'Installing'} ${pkg}@${version} (already installed)`);
|
|
40
|
+
alreadyInstalled = true;
|
|
39
41
|
}
|
|
40
42
|
// copy from cache
|
|
41
43
|
else if (isCached(`${pkg}@${version}`)) {
|
|
42
|
-
actor.notifyInstall(pkg, version);
|
|
43
44
|
await copyCache(`${pkg}@${version}`, dir);
|
|
44
45
|
silent || logUpdate(`${dep ? 'Dependency' : 'Installing'} ${pkg}@${version} (cache)`);
|
|
45
46
|
}
|
|
@@ -65,15 +66,12 @@ export async function install(pkg: string, version = '', {verbose = false, silen
|
|
|
65
66
|
|
|
66
67
|
let storage = await storageActor(packageDetails.publication.storage);
|
|
67
68
|
|
|
68
|
-
actor.notifyInstall(pkg, version);
|
|
69
|
-
|
|
70
69
|
// download files
|
|
71
70
|
let filesData = new Map;
|
|
72
71
|
let threads = 16;
|
|
73
72
|
|
|
74
73
|
// GitHub Actions fails with "fetch failed" if there are multiple concurrent actions
|
|
75
74
|
if (process.env.GITHUB_ENV) {
|
|
76
|
-
console.log('Running in GitHub Actions, reducing threads to 4');
|
|
77
75
|
threads = 4;
|
|
78
76
|
}
|
|
79
77
|
|
|
@@ -119,17 +117,28 @@ export async function install(pkg: string, version = '', {verbose = false, silen
|
|
|
119
117
|
let ok = true;
|
|
120
118
|
let config = readConfig(path.join(dir, 'mops.toml'));
|
|
121
119
|
let deps = Object.values(config.dependencies || {});
|
|
120
|
+
let installedDeps = {};
|
|
122
121
|
for (const {name, repo, version} of deps) {
|
|
123
122
|
if (repo) {
|
|
124
123
|
await installFromGithub(name, repo, {silent, verbose});
|
|
125
124
|
}
|
|
126
125
|
else {
|
|
127
126
|
let res = await install(name, version, {silent, verbose});
|
|
128
|
-
if (
|
|
127
|
+
if (res) {
|
|
128
|
+
installedDeps = {...installedDeps, ...res};
|
|
129
|
+
}
|
|
130
|
+
else {
|
|
129
131
|
ok = false;
|
|
130
132
|
}
|
|
131
133
|
}
|
|
132
134
|
}
|
|
133
135
|
|
|
134
|
-
|
|
136
|
+
if (!alreadyInstalled) {
|
|
137
|
+
installedDeps = {...installedDeps, [pkg]: version};
|
|
138
|
+
}
|
|
139
|
+
|
|
140
|
+
if (ok) {
|
|
141
|
+
return installedDeps;
|
|
142
|
+
}
|
|
143
|
+
return false;
|
|
135
144
|
}
|
package/commands/sources.ts
CHANGED
|
@@ -1,9 +1,7 @@
|
|
|
1
1
|
import path from 'node:path';
|
|
2
2
|
import fs from 'node:fs';
|
|
3
|
-
import
|
|
4
|
-
import {
|
|
5
|
-
import {VesselConfig, readVesselConfig} from '../vessel.js';
|
|
6
|
-
import {Config, Dependency} from '../types.js';
|
|
3
|
+
import {checkConfigFile, formatDir, formatGithubDir, getDependencyType, readConfig} from '../mops.js';
|
|
4
|
+
import {resolvePackages} from '../resolve-packages.js';
|
|
7
5
|
|
|
8
6
|
// TODO: resolve conflicts
|
|
9
7
|
export async function sources({verbose = false} = {}) {
|
|
@@ -11,118 +9,21 @@ export async function sources({verbose = false} = {}) {
|
|
|
11
9
|
return [];
|
|
12
10
|
}
|
|
13
11
|
|
|
14
|
-
let
|
|
15
|
-
let versions: Record<string, string[]> = {};
|
|
16
|
-
|
|
17
|
-
let compareVersions = (a: string = '0.0.0', b: string = '0.0.0') => {
|
|
18
|
-
let ap = a.split('.').map((x: string) => parseInt(x)) as [number, number, number];
|
|
19
|
-
let bp = b.split('.').map((x: string) => parseInt(x)) as [number, number, number];
|
|
20
|
-
if (ap[0] - bp[0]) {
|
|
21
|
-
return Math.sign(ap[0] - bp[0]);
|
|
22
|
-
}
|
|
23
|
-
if (ap[0] === bp[0] && ap[1] - bp[1]) {
|
|
24
|
-
return Math.sign(ap[1] - bp[1]);
|
|
25
|
-
}
|
|
26
|
-
if (ap[0] === bp[0] && ap[1] === bp[1] && ap[2] - bp[2]) {
|
|
27
|
-
return Math.sign(ap[2] - bp[2]);
|
|
28
|
-
}
|
|
29
|
-
return 0;
|
|
30
|
-
};
|
|
31
|
-
|
|
32
|
-
const gitVerRegex = new RegExp(/v(\d{1,2}\.\d{1,2}\.\d{1,2})(-.*)?$/);
|
|
33
|
-
|
|
34
|
-
const compareGitVersions = (repoA: string, repoB: string) => {
|
|
35
|
-
const {branch: a} = parseGithubURL(repoA);
|
|
36
|
-
const {branch: b} = parseGithubURL(repoB);
|
|
37
|
-
|
|
38
|
-
if (gitVerRegex.test(a) && gitVerRegex.test(b)) {
|
|
39
|
-
return compareVersions(a.substring(1) , b.substring(1));
|
|
40
|
-
}
|
|
41
|
-
else if (!gitVerRegex.test(a)) {
|
|
42
|
-
return -1;
|
|
43
|
-
}
|
|
44
|
-
else {
|
|
45
|
-
return 1;
|
|
46
|
-
}
|
|
47
|
-
};
|
|
48
|
-
|
|
49
|
-
let collectDeps = async (config: Config | VesselConfig, isRoot = false) => {
|
|
50
|
-
let allDeps = [...Object.values(config.dependencies || {})];
|
|
51
|
-
if (isRoot) {
|
|
52
|
-
allDeps = [...allDeps, ...Object.values(config['dev-dependencies'] || {})];
|
|
53
|
-
}
|
|
54
|
-
for (const pkgDetails of allDeps) {
|
|
55
|
-
const {name, repo, version} = pkgDetails;
|
|
56
|
-
|
|
57
|
-
// take root dep version or bigger one
|
|
58
|
-
if (
|
|
59
|
-
isRoot
|
|
60
|
-
|| !packages[name]
|
|
61
|
-
|| !packages[name]?.isRoot
|
|
62
|
-
&& (
|
|
63
|
-
repo && packages[name]?.repo && compareGitVersions(packages[name]?.repo || '', repo) === -1
|
|
64
|
-
|| compareVersions(packages[name]?.version, version) === -1)
|
|
65
|
-
) {
|
|
66
|
-
packages[name] = {
|
|
67
|
-
...pkgDetails,
|
|
68
|
-
isRoot,
|
|
69
|
-
};
|
|
70
|
-
}
|
|
71
|
-
|
|
72
|
-
let nestedConfig;
|
|
73
|
-
|
|
74
|
-
if (repo) {
|
|
75
|
-
const dir = formatGithubDir(name, repo);
|
|
76
|
-
nestedConfig = await readVesselConfig(dir) || {};
|
|
77
|
-
}
|
|
78
|
-
else if (!pkgDetails.path && version) {
|
|
79
|
-
const file = formatDir(name, version) + '/mops.toml';
|
|
80
|
-
nestedConfig = readConfig(file);
|
|
81
|
-
}
|
|
82
|
-
|
|
83
|
-
if (nestedConfig && !pkgDetails.path) {
|
|
84
|
-
await collectDeps(nestedConfig);
|
|
85
|
-
}
|
|
86
|
-
|
|
87
|
-
if (!versions[name]) {
|
|
88
|
-
versions[name] = [];
|
|
89
|
-
}
|
|
90
|
-
|
|
91
|
-
if (repo) {
|
|
92
|
-
const {branch} = parseGithubURL(repo);
|
|
93
|
-
versions[name]?.push(branch);
|
|
94
|
-
}
|
|
95
|
-
else if (version) {
|
|
96
|
-
versions[name]?.push(version);
|
|
97
|
-
}
|
|
98
|
-
}
|
|
99
|
-
};
|
|
100
|
-
|
|
101
|
-
let config = readConfig();
|
|
102
|
-
await collectDeps(config, true);
|
|
103
|
-
|
|
104
|
-
// show conflicts
|
|
105
|
-
if (verbose) {
|
|
106
|
-
for (let [dep, vers] of Object.entries(versions)) {
|
|
107
|
-
if (vers.length > 1) {
|
|
108
|
-
console.log(chalk.yellow('WARN:'), `Conflicting package versions "${dep}" - ${vers.join(', ')}`);
|
|
109
|
-
}
|
|
110
|
-
}
|
|
111
|
-
}
|
|
12
|
+
let resolvedPackages = await resolvePackages({verbose});
|
|
112
13
|
|
|
113
14
|
// sources
|
|
114
|
-
|
|
115
|
-
|
|
15
|
+
return Object.entries(resolvedPackages).map(([name, version]) => {
|
|
16
|
+
let depType = getDependencyType(version);
|
|
17
|
+
|
|
116
18
|
let pkgDir;
|
|
117
|
-
if (
|
|
118
|
-
pkgDir = path.relative(process.cwd(),
|
|
119
|
-
pkgDir = pkgDir.replaceAll('{MOPS_ENV}', process.env.MOPS_ENV || 'local');
|
|
19
|
+
if (depType === 'local') {
|
|
20
|
+
pkgDir = path.relative(process.cwd(), version);
|
|
120
21
|
}
|
|
121
|
-
else if (
|
|
122
|
-
pkgDir = path.relative(process.cwd(), formatGithubDir(name,
|
|
22
|
+
else if (depType === 'github') {
|
|
23
|
+
pkgDir = path.relative(process.cwd(), formatGithubDir(name, version));
|
|
123
24
|
}
|
|
124
|
-
else if (
|
|
125
|
-
pkgDir = path.relative(process.cwd(), formatDir(name,
|
|
25
|
+
else if (depType === 'mops') {
|
|
26
|
+
pkgDir = path.relative(process.cwd(), formatDir(name, version));
|
|
126
27
|
}
|
|
127
28
|
else {
|
|
128
29
|
return;
|
|
@@ -139,7 +40,7 @@ export async function sources({verbose = false} = {}) {
|
|
|
139
40
|
}
|
|
140
41
|
|
|
141
42
|
// use pkgDir if baseDir doesn't exist for local packages
|
|
142
|
-
if (
|
|
43
|
+
if (depType === 'local' && !fs.existsSync(pkgBaseDir)) {
|
|
143
44
|
pkgBaseDir = pkgDir;
|
|
144
45
|
}
|
|
145
46
|
|
|
@@ -301,6 +301,10 @@ service : {
|
|
|
301
301
|
getTotalPackages: () -> (nat) query;
|
|
302
302
|
getUser: (principal) -> (opt User__1) query;
|
|
303
303
|
notifyInstall: (PackageName__1, PackageVersion) -> () oneway;
|
|
304
|
+
notifyInstalls: (vec record {
|
|
305
|
+
PackageName__1;
|
|
306
|
+
PackageVersion;
|
|
307
|
+
}) -> () oneway;
|
|
304
308
|
restore: (nat, nat) -> ();
|
|
305
309
|
search: (Text, opt nat, opt nat) -> (vec PackageSummary, PageCount) query;
|
|
306
310
|
setUserProp: (text, text) -> (Result_3);
|
|
@@ -247,6 +247,10 @@ export interface _SERVICE {
|
|
|
247
247
|
'getTotalPackages' : ActorMethod<[], bigint>,
|
|
248
248
|
'getUser' : ActorMethod<[Principal], [] | [User__1]>,
|
|
249
249
|
'notifyInstall' : ActorMethod<[PackageName__1, PackageVersion], undefined>,
|
|
250
|
+
'notifyInstalls' : ActorMethod<
|
|
251
|
+
[Array<[PackageName__1, PackageVersion]>],
|
|
252
|
+
undefined
|
|
253
|
+
>,
|
|
250
254
|
'restore' : ActorMethod<[bigint, bigint], undefined>,
|
|
251
255
|
'search' : ActorMethod<
|
|
252
256
|
[Text, [] | [bigint], [] | [bigint]],
|
|
@@ -275,6 +275,11 @@ export const idlFactory = ({ IDL }) => {
|
|
|
275
275
|
[],
|
|
276
276
|
['oneway'],
|
|
277
277
|
),
|
|
278
|
+
'notifyInstalls' : IDL.Func(
|
|
279
|
+
[IDL.Vec(IDL.Tuple(PackageName__1, PackageVersion))],
|
|
280
|
+
[],
|
|
281
|
+
['oneway'],
|
|
282
|
+
),
|
|
278
283
|
'restore' : IDL.Func([IDL.Nat, IDL.Nat], [], []),
|
|
279
284
|
'search' : IDL.Func(
|
|
280
285
|
[Text, IDL.Opt(IDL.Nat), IDL.Opt(IDL.Nat)],
|
package/dist/commands/add.js
CHANGED
|
@@ -4,6 +4,7 @@ import logUpdate from 'log-update';
|
|
|
4
4
|
import { checkConfigFile, getHighestVersion, parseGithubURL, readConfig, writeConfig } from '../mops.js';
|
|
5
5
|
import { installFromGithub } from '../vessel.js';
|
|
6
6
|
import { install } from './install.js';
|
|
7
|
+
import { notifyInstalls } from '../notify-installs.js';
|
|
7
8
|
export async function add(name, { verbose = false, dev = false } = {}) {
|
|
8
9
|
if (!checkConfigFile()) {
|
|
9
10
|
return;
|
|
@@ -59,14 +60,16 @@ export async function add(name, { verbose = false, dev = false } = {}) {
|
|
|
59
60
|
version: ver,
|
|
60
61
|
};
|
|
61
62
|
}
|
|
63
|
+
let installedPackages = {};
|
|
62
64
|
if (pkgDetails.repo) {
|
|
63
65
|
await installFromGithub(pkgDetails.name, pkgDetails.repo, { verbose: verbose });
|
|
64
66
|
}
|
|
65
67
|
else if (!pkgDetails.path) {
|
|
66
|
-
let
|
|
67
|
-
if (
|
|
68
|
+
let res = await install(pkgDetails.name, pkgDetails.version, { verbose: verbose });
|
|
69
|
+
if (res === false) {
|
|
68
70
|
return;
|
|
69
71
|
}
|
|
72
|
+
installedPackages = { ...installedPackages, ...res };
|
|
70
73
|
}
|
|
71
74
|
const depsProp = dev ? 'dev-dependencies' : 'dependencies';
|
|
72
75
|
let deps = config[depsProp];
|
|
@@ -77,6 +80,7 @@ export async function add(name, { verbose = false, dev = false } = {}) {
|
|
|
77
80
|
throw Error(`Invalid config file: [${depsProp}] not found`);
|
|
78
81
|
}
|
|
79
82
|
writeConfig(config);
|
|
83
|
+
notifyInstalls(Object.keys(installedPackages));
|
|
80
84
|
logUpdate.clear();
|
|
81
85
|
console.log(chalk.green('Package installed ') + `${pkgDetails.name} = "${pkgDetails.repo || pkgDetails.path || pkgDetails.version}"`);
|
|
82
86
|
}
|
|
@@ -3,6 +3,7 @@ import logUpdate from 'log-update';
|
|
|
3
3
|
import { checkConfigFile, readConfig } from '../mops.js';
|
|
4
4
|
import { install } from './install.js';
|
|
5
5
|
import { installFromGithub } from '../vessel.js';
|
|
6
|
+
import { notifyInstalls } from '../notify-installs.js';
|
|
6
7
|
export async function installAll({ verbose = false, silent = false } = {}) {
|
|
7
8
|
if (!checkConfigFile()) {
|
|
8
9
|
return;
|
|
@@ -11,17 +12,20 @@ export async function installAll({ verbose = false, silent = false } = {}) {
|
|
|
11
12
|
let deps = Object.values(config.dependencies || {});
|
|
12
13
|
let devDeps = Object.values(config['dev-dependencies'] || {});
|
|
13
14
|
let allDeps = [...deps, ...devDeps];
|
|
15
|
+
let installedPackages = {};
|
|
14
16
|
for (let { name, repo, path, version } of allDeps) {
|
|
15
17
|
if (repo) {
|
|
16
18
|
await installFromGithub(name, repo, { verbose, silent });
|
|
17
19
|
}
|
|
18
20
|
else if (!path) {
|
|
19
|
-
let
|
|
20
|
-
if (
|
|
21
|
+
let res = await install(name, version, { verbose, silent });
|
|
22
|
+
if (res === false) {
|
|
21
23
|
return;
|
|
22
24
|
}
|
|
25
|
+
installedPackages = { ...installedPackages, ...res };
|
|
23
26
|
}
|
|
24
27
|
}
|
|
28
|
+
notifyInstalls(Object.keys(installedPackages));
|
|
25
29
|
if (!silent) {
|
|
26
30
|
logUpdate.clear();
|
|
27
31
|
console.log(chalk.green('All packages installed'));
|
package/dist/commands/install.js
CHANGED
|
@@ -28,13 +28,14 @@ export async function install(pkg, version = '', { verbose = false, silent = fal
|
|
|
28
28
|
}
|
|
29
29
|
let dir = formatDir(pkg, version);
|
|
30
30
|
let actor = await mainActor();
|
|
31
|
+
let alreadyInstalled = false;
|
|
31
32
|
// already installed
|
|
32
33
|
if (fs.existsSync(dir)) {
|
|
33
34
|
silent || logUpdate(`${dep ? 'Dependency' : 'Installing'} ${pkg}@${version} (already installed)`);
|
|
35
|
+
alreadyInstalled = true;
|
|
34
36
|
}
|
|
35
37
|
// copy from cache
|
|
36
38
|
else if (isCached(`${pkg}@${version}`)) {
|
|
37
|
-
actor.notifyInstall(pkg, version);
|
|
38
39
|
await copyCache(`${pkg}@${version}`, dir);
|
|
39
40
|
silent || logUpdate(`${dep ? 'Dependency' : 'Installing'} ${pkg}@${version} (cache)`);
|
|
40
41
|
}
|
|
@@ -56,13 +57,11 @@ export async function install(pkg, version = '', { verbose = false, silent = fal
|
|
|
56
57
|
let filesIds = filesIdsRes.ok;
|
|
57
58
|
total = filesIds.length + 2;
|
|
58
59
|
let storage = await storageActor(packageDetails.publication.storage);
|
|
59
|
-
actor.notifyInstall(pkg, version);
|
|
60
60
|
// download files
|
|
61
61
|
let filesData = new Map;
|
|
62
62
|
let threads = 16;
|
|
63
63
|
// GitHub Actions fails with "fetch failed" if there are multiple concurrent actions
|
|
64
64
|
if (process.env.GITHUB_ENV) {
|
|
65
|
-
console.log('Running in GitHub Actions, reducing threads to 4');
|
|
66
65
|
threads = 4;
|
|
67
66
|
}
|
|
68
67
|
await parallel(threads, filesIds, async (fileId) => {
|
|
@@ -101,16 +100,26 @@ export async function install(pkg, version = '', { verbose = false, silent = fal
|
|
|
101
100
|
let ok = true;
|
|
102
101
|
let config = readConfig(path.join(dir, 'mops.toml'));
|
|
103
102
|
let deps = Object.values(config.dependencies || {});
|
|
103
|
+
let installedDeps = {};
|
|
104
104
|
for (const { name, repo, version } of deps) {
|
|
105
105
|
if (repo) {
|
|
106
106
|
await installFromGithub(name, repo, { silent, verbose });
|
|
107
107
|
}
|
|
108
108
|
else {
|
|
109
109
|
let res = await install(name, version, { silent, verbose });
|
|
110
|
-
if (
|
|
110
|
+
if (res) {
|
|
111
|
+
installedDeps = { ...installedDeps, ...res };
|
|
112
|
+
}
|
|
113
|
+
else {
|
|
111
114
|
ok = false;
|
|
112
115
|
}
|
|
113
116
|
}
|
|
114
117
|
}
|
|
115
|
-
|
|
118
|
+
if (!alreadyInstalled) {
|
|
119
|
+
installedDeps = { ...installedDeps, [pkg]: version };
|
|
120
|
+
}
|
|
121
|
+
if (ok) {
|
|
122
|
+
return installedDeps;
|
|
123
|
+
}
|
|
124
|
+
return false;
|
|
116
125
|
}
|
package/dist/commands/sources.js
CHANGED
|
@@ -1,108 +1,25 @@
|
|
|
1
1
|
import path from 'node:path';
|
|
2
2
|
import fs from 'node:fs';
|
|
3
|
-
import
|
|
4
|
-
import {
|
|
5
|
-
import { readVesselConfig } from '../vessel.js';
|
|
3
|
+
import { checkConfigFile, formatDir, formatGithubDir, getDependencyType, readConfig } from '../mops.js';
|
|
4
|
+
import { resolvePackages } from '../resolve-packages.js';
|
|
6
5
|
// TODO: resolve conflicts
|
|
7
6
|
export async function sources({ verbose = false } = {}) {
|
|
8
7
|
if (!checkConfigFile()) {
|
|
9
8
|
return [];
|
|
10
9
|
}
|
|
11
|
-
let
|
|
12
|
-
let versions = {};
|
|
13
|
-
let compareVersions = (a = '0.0.0', b = '0.0.0') => {
|
|
14
|
-
let ap = a.split('.').map((x) => parseInt(x));
|
|
15
|
-
let bp = b.split('.').map((x) => parseInt(x));
|
|
16
|
-
if (ap[0] - bp[0]) {
|
|
17
|
-
return Math.sign(ap[0] - bp[0]);
|
|
18
|
-
}
|
|
19
|
-
if (ap[0] === bp[0] && ap[1] - bp[1]) {
|
|
20
|
-
return Math.sign(ap[1] - bp[1]);
|
|
21
|
-
}
|
|
22
|
-
if (ap[0] === bp[0] && ap[1] === bp[1] && ap[2] - bp[2]) {
|
|
23
|
-
return Math.sign(ap[2] - bp[2]);
|
|
24
|
-
}
|
|
25
|
-
return 0;
|
|
26
|
-
};
|
|
27
|
-
const gitVerRegex = new RegExp(/v(\d{1,2}\.\d{1,2}\.\d{1,2})(-.*)?$/);
|
|
28
|
-
const compareGitVersions = (repoA, repoB) => {
|
|
29
|
-
const { branch: a } = parseGithubURL(repoA);
|
|
30
|
-
const { branch: b } = parseGithubURL(repoB);
|
|
31
|
-
if (gitVerRegex.test(a) && gitVerRegex.test(b)) {
|
|
32
|
-
return compareVersions(a.substring(1), b.substring(1));
|
|
33
|
-
}
|
|
34
|
-
else if (!gitVerRegex.test(a)) {
|
|
35
|
-
return -1;
|
|
36
|
-
}
|
|
37
|
-
else {
|
|
38
|
-
return 1;
|
|
39
|
-
}
|
|
40
|
-
};
|
|
41
|
-
let collectDeps = async (config, isRoot = false) => {
|
|
42
|
-
let allDeps = [...Object.values(config.dependencies || {})];
|
|
43
|
-
if (isRoot) {
|
|
44
|
-
allDeps = [...allDeps, ...Object.values(config['dev-dependencies'] || {})];
|
|
45
|
-
}
|
|
46
|
-
for (const pkgDetails of allDeps) {
|
|
47
|
-
const { name, repo, version } = pkgDetails;
|
|
48
|
-
// take root dep version or bigger one
|
|
49
|
-
if (isRoot
|
|
50
|
-
|| !packages[name]
|
|
51
|
-
|| !packages[name]?.isRoot
|
|
52
|
-
&& (repo && packages[name]?.repo && compareGitVersions(packages[name]?.repo || '', repo) === -1
|
|
53
|
-
|| compareVersions(packages[name]?.version, version) === -1)) {
|
|
54
|
-
packages[name] = {
|
|
55
|
-
...pkgDetails,
|
|
56
|
-
isRoot,
|
|
57
|
-
};
|
|
58
|
-
}
|
|
59
|
-
let nestedConfig;
|
|
60
|
-
if (repo) {
|
|
61
|
-
const dir = formatGithubDir(name, repo);
|
|
62
|
-
nestedConfig = await readVesselConfig(dir) || {};
|
|
63
|
-
}
|
|
64
|
-
else if (!pkgDetails.path && version) {
|
|
65
|
-
const file = formatDir(name, version) + '/mops.toml';
|
|
66
|
-
nestedConfig = readConfig(file);
|
|
67
|
-
}
|
|
68
|
-
if (nestedConfig && !pkgDetails.path) {
|
|
69
|
-
await collectDeps(nestedConfig);
|
|
70
|
-
}
|
|
71
|
-
if (!versions[name]) {
|
|
72
|
-
versions[name] = [];
|
|
73
|
-
}
|
|
74
|
-
if (repo) {
|
|
75
|
-
const { branch } = parseGithubURL(repo);
|
|
76
|
-
versions[name]?.push(branch);
|
|
77
|
-
}
|
|
78
|
-
else if (version) {
|
|
79
|
-
versions[name]?.push(version);
|
|
80
|
-
}
|
|
81
|
-
}
|
|
82
|
-
};
|
|
83
|
-
let config = readConfig();
|
|
84
|
-
await collectDeps(config, true);
|
|
85
|
-
// show conflicts
|
|
86
|
-
if (verbose) {
|
|
87
|
-
for (let [dep, vers] of Object.entries(versions)) {
|
|
88
|
-
if (vers.length > 1) {
|
|
89
|
-
console.log(chalk.yellow('WARN:'), `Conflicting package versions "${dep}" - ${vers.join(', ')}`);
|
|
90
|
-
}
|
|
91
|
-
}
|
|
92
|
-
}
|
|
10
|
+
let resolvedPackages = await resolvePackages({ verbose });
|
|
93
11
|
// sources
|
|
94
|
-
|
|
95
|
-
|
|
12
|
+
return Object.entries(resolvedPackages).map(([name, version]) => {
|
|
13
|
+
let depType = getDependencyType(version);
|
|
96
14
|
let pkgDir;
|
|
97
|
-
if (
|
|
98
|
-
pkgDir = path.relative(process.cwd(),
|
|
99
|
-
pkgDir = pkgDir.replaceAll('{MOPS_ENV}', process.env.MOPS_ENV || 'local');
|
|
15
|
+
if (depType === 'local') {
|
|
16
|
+
pkgDir = path.relative(process.cwd(), version);
|
|
100
17
|
}
|
|
101
|
-
else if (
|
|
102
|
-
pkgDir = path.relative(process.cwd(), formatGithubDir(name,
|
|
18
|
+
else if (depType === 'github') {
|
|
19
|
+
pkgDir = path.relative(process.cwd(), formatGithubDir(name, version));
|
|
103
20
|
}
|
|
104
|
-
else if (
|
|
105
|
-
pkgDir = path.relative(process.cwd(), formatDir(name,
|
|
21
|
+
else if (depType === 'mops') {
|
|
22
|
+
pkgDir = path.relative(process.cwd(), formatDir(name, version));
|
|
106
23
|
}
|
|
107
24
|
else {
|
|
108
25
|
return;
|
|
@@ -117,7 +34,7 @@ export async function sources({ verbose = false } = {}) {
|
|
|
117
34
|
pkgBaseDir = path.join(pkgDir, 'src');
|
|
118
35
|
}
|
|
119
36
|
// use pkgDir if baseDir doesn't exist for local packages
|
|
120
|
-
if (
|
|
37
|
+
if (depType === 'local' && !fs.existsSync(pkgBaseDir)) {
|
|
121
38
|
pkgBaseDir = pkgDir;
|
|
122
39
|
}
|
|
123
40
|
return `--package ${name} ${pkgBaseDir}`;
|
|
@@ -301,6 +301,10 @@ service : {
|
|
|
301
301
|
getTotalPackages: () -> (nat) query;
|
|
302
302
|
getUser: (principal) -> (opt User__1) query;
|
|
303
303
|
notifyInstall: (PackageName__1, PackageVersion) -> () oneway;
|
|
304
|
+
notifyInstalls: (vec record {
|
|
305
|
+
PackageName__1;
|
|
306
|
+
PackageVersion;
|
|
307
|
+
}) -> () oneway;
|
|
304
308
|
restore: (nat, nat) -> ();
|
|
305
309
|
search: (Text, opt nat, opt nat) -> (vec PackageSummary, PageCount) query;
|
|
306
310
|
setUserProp: (text, text) -> (Result_3);
|
|
@@ -247,6 +247,10 @@ export interface _SERVICE {
|
|
|
247
247
|
'getTotalPackages' : ActorMethod<[], bigint>,
|
|
248
248
|
'getUser' : ActorMethod<[Principal], [] | [User__1]>,
|
|
249
249
|
'notifyInstall' : ActorMethod<[PackageName__1, PackageVersion], undefined>,
|
|
250
|
+
'notifyInstalls' : ActorMethod<
|
|
251
|
+
[Array<[PackageName__1, PackageVersion]>],
|
|
252
|
+
undefined
|
|
253
|
+
>,
|
|
250
254
|
'restore' : ActorMethod<[bigint, bigint], undefined>,
|
|
251
255
|
'search' : ActorMethod<
|
|
252
256
|
[Text, [] | [bigint], [] | [bigint]],
|
|
@@ -275,6 +275,11 @@ export const idlFactory = ({ IDL }) => {
|
|
|
275
275
|
[],
|
|
276
276
|
['oneway'],
|
|
277
277
|
),
|
|
278
|
+
'notifyInstalls' : IDL.Func(
|
|
279
|
+
[IDL.Vec(IDL.Tuple(PackageName__1, PackageVersion))],
|
|
280
|
+
[],
|
|
281
|
+
['oneway'],
|
|
282
|
+
),
|
|
278
283
|
'restore' : IDL.Func([IDL.Nat, IDL.Nat], [], []),
|
|
279
284
|
'search' : IDL.Func(
|
|
280
285
|
[Text, IDL.Opt(IDL.Nat), IDL.Opt(IDL.Nat)],
|
package/dist/mops.d.ts
CHANGED
|
@@ -25,6 +25,7 @@ export declare function parseGithubURL(href: string): {
|
|
|
25
25
|
gitName: string | undefined;
|
|
26
26
|
branch: string;
|
|
27
27
|
};
|
|
28
|
+
export declare function getDependencyType(version: string): "mops" | "github" | "local";
|
|
28
29
|
export declare function readConfig(configFile?: string): Config;
|
|
29
30
|
export declare function writeConfig(config: Config, configFile?: string): void;
|
|
30
31
|
export declare function formatDir(name: string, version: string): string;
|
package/dist/mops.js
CHANGED
|
@@ -186,6 +186,20 @@ export function parseGithubURL(href) {
|
|
|
186
186
|
}
|
|
187
187
|
return { org, gitName, branch };
|
|
188
188
|
}
|
|
189
|
+
export function getDependencyType(version) {
|
|
190
|
+
if (!version || typeof version !== 'string') {
|
|
191
|
+
throw Error(`Invalid dependency value "${version}"`);
|
|
192
|
+
}
|
|
193
|
+
if (version.startsWith('https://github.com/')) {
|
|
194
|
+
return 'github';
|
|
195
|
+
}
|
|
196
|
+
else if (version.match(/^(\.?\.)?\//)) {
|
|
197
|
+
return 'local';
|
|
198
|
+
}
|
|
199
|
+
else {
|
|
200
|
+
return 'mops';
|
|
201
|
+
}
|
|
202
|
+
}
|
|
189
203
|
export function readConfig(configFile = getClosestConfigFile()) {
|
|
190
204
|
let text = fs.readFileSync(configFile).toString();
|
|
191
205
|
let toml = TOML.parse(text);
|
|
@@ -194,10 +208,11 @@ export function readConfig(configFile = getClosestConfigFile()) {
|
|
|
194
208
|
if (!data || typeof data !== 'string') {
|
|
195
209
|
throw Error(`Invalid dependency value ${name} = "${data}"`);
|
|
196
210
|
}
|
|
197
|
-
|
|
211
|
+
let depType = getDependencyType(data);
|
|
212
|
+
if (depType === 'github') {
|
|
198
213
|
deps[name] = { name, repo: data, version: '' };
|
|
199
214
|
}
|
|
200
|
-
else if (
|
|
215
|
+
else if (depType === 'local') {
|
|
201
216
|
deps[name] = { name, repo: '', path: data, version: '' };
|
|
202
217
|
}
|
|
203
218
|
else {
|