UNPKG

7.63 kBJavaScriptView Raw
1import { promisify } from 'util';
2import semver from 'semver';
3const { valid, coerce, compare } = semver;
4import { map, flatten } from '@ctx-core/array';
5import { _h__param } from '@ctx-core/cli-args';
6import { _queue } from '@ctx-core/queue';
7import fs from 'fs';
8import detect_indent from 'detect-indent';
9import child_process from 'child_process';
10const exec = promisify(child_process.exec);
11import globby from 'globby';
12const readFile = promisify(fs.readFile);
13const writeFile = promisify(fs.writeFile);
14export async function _workspaces() {
15 const txt__workspaces = (await exec('yarn workspaces info')).stdout;
16 const a1__txt__workspaces = txt__workspaces.split('\n');
17 const line__start__json__workspaces = a1__txt__workspaces.indexOf('{');
18 const line__end__json__workspaces = a1__txt__workspaces.indexOf('}');
19 const json__workspaces = a1__txt__workspaces.slice(line__start__json__workspaces, line__end__json__workspaces + 1).join('\n');
20 return JSON.parse(json__workspaces);
21}
22export async function each__package__json(txt__glob, fn) {
23 const a1__package__json = await globby(txt__glob);
24 const a1__promise = map(a1__package__json, fn);
25 await Promise.all(a1__promise);
26}
27export async function cli__npm_check_updates__monorepo() {
28 const h__param = _h__param(process.argv.slice(2), {
29 threads: '-t, --threads',
30 workspace_name: '-w, --workspace-name'
31 }, {
32 threads: 20,
33 });
34 const h1__name__workspace__h0__stdout = await npm_check_updates__monorepo(h__param);
35 for (let name__workspace in h1__name__workspace__h0__stdout) {
36 console.info(name__workspace);
37 console.info(h1__name__workspace__h0__stdout[name__workspace]);
38 }
39}
40export async function npm_check_updates__monorepo(opts = {}) {
41 const package_name__x__latest_version = {};
42 const package_name__x__already_warned = {};
43 const queue = _queue(opts.threads || 20);
44 const workspaces = await _workspaces();
45 const a1__workspace_name = opts.workspace_name
46 ? flatten([opts.workspace_name])
47 : Object.keys(workspaces);
48 const a1__promise = _a1__promise(a1__workspace_name, _promise__workspace);
49 if (!opts.workspace_name) {
50 a1__workspace_name.push('.');
51 a1__promise.push(_promise('.'));
52 }
53 const a1__stdout = await Promise.all(a1__promise);
54 return _h1__stdout__h0__name__workspace(a1__workspace_name, a1__stdout);
55 async function _promise(location = '.') {
56 const path__package__json = `${location}/package.json`;
57 const pkg_json = (await readFile(path__package__json)).toString();
58 const pkg = JSON.parse(pkg_json);
59 const { dependencies, peerDependencies, devDependencies, noUpdate } = pkg;
60 const update_a2 = [];
61 update_a2.push(await update__dependencies(dependencies, noUpdate));
62 update_a2.push(await update__dependencies(devDependencies, noUpdate));
63 update_a2.push(await update__dependencies(peerDependencies, noUpdate));
64 const update_a1 = flatten(update_a2);
65 if (update_a1.length) {
66 const indent = detect_indent(pkg_json).indent || '\t';
67 await writeFile(path__package__json, JSON.stringify(pkg, null, indent));
68 }
69 return update_a1.join('\n');
70 }
71 async function _promise__workspace(name__workspace) {
72 const workspace = workspaces[name__workspace];
73 const { location } = workspace;
74 return _promise(location);
75 }
76 async function update__dependencies(dependencies, noUpdate = []) {
77 var _a;
78 noUpdate = noUpdate || [];
79 const update_a1 = [];
80 for (let package_name in dependencies) {
81 if (~noUpdate.indexOf(package_name))
82 continue;
83 const dependency_workspace = workspaces[package_name];
84 const version = dependencies[package_name];
85 const has_carrot = version.slice(0, 1) === '^';
86 if (dependency_workspace) {
87 const { location } = dependency_workspace;
88 const pkg = JSON.parse((await readFile(`${location}/package.json`)).toString());
89 const latest_version = `${version.slice(0, 1) === '^' ? '^' : ''}${pkg.version}`;
90 package_name__x__latest_version[package_name] = pkg.version;
91 if (compare(coerce(latest_version), coerce(version)) > 0) {
92 push__update_a1(update_a1, package_name, version, latest_version);
93 dependencies[package_name] = latest_version;
94 }
95 }
96 else {
97 if (!valid(coerce(dependencies[package_name])))
98 continue;
99 if (package_name__x__latest_version[package_name] == null) {
100 const promise = queue.add(async () => (await exec(`npm show ${package_name}@latest | grep latest | grep \\: | cut -f2 -d: | xargs echo`)).stdout.trim());
101 package_name__x__latest_version[package_name] = promise;
102 }
103 if ((_a = package_name__x__latest_version[package_name]) === null || _a === void 0 ? void 0 : _a.then) {
104 package_name__x__latest_version[package_name] =
105 (await package_name__x__latest_version[package_name])
106 || '';
107 }
108 const latest_stripped_version = package_name__x__latest_version[package_name];
109 if (!latest_stripped_version && !package_name__x__already_warned[package_name]) {
110 package_name__x__already_warned[package_name] = true;
111 console.warn(`WARN: Unable to parse ${package_name} from npm registry`);
112 }
113 if (latest_stripped_version
114 && compare(coerce(latest_stripped_version), coerce(version)) > 0) {
115 const latest_version = `${has_carrot ? '^' : ''}${latest_stripped_version}`;
116 push__update_a1(update_a1, package_name, version, latest_version);
117 dependencies[package_name] = latest_version;
118 }
119 }
120 }
121 return update_a1;
122 }
123 function push__update_a1(update_a1, package_name, version, latest_version) {
124 update_a1.push(`${package_name}: ${version} -> ${latest_version}`);
125 }
126}
127export async function run_parallel__workspaces(cmd_a1, opts = {}) {
128 const queue = _queue(opts.threads || 20);
129 const workspaces = await _workspaces();
130 const cmd = cmd_a1.join(' ');
131 const name_a1__workspace = Object.keys(workspaces);
132 const promise_a1 = _a1__promise(name_a1__workspace, _promise);
133 const stdout_a1 = await Promise.all(promise_a1);
134 return _h1__stdout__h0__name__workspace(name_a1__workspace, stdout_a1);
135 async function _promise(name__workspace) {
136 const workspace = workspaces[name__workspace];
137 const { location } = workspace;
138 return (queue.add(async () => (await exec(`cd ${location}; ${cmd}`)).stdout.trim()));
139 }
140}
141function _a1__promise(a1__workspace, _promise) {
142 const a1__promise = [];
143 for (let i = 0; i < a1__workspace.length; i++) {
144 const name__workspace = a1__workspace[i];
145 a1__promise.push(_promise(name__workspace));
146 }
147 return a1__promise;
148}
149function _h1__stdout__h0__name__workspace(a1__name__workspace, stdout_a1) {
150 const stdout__name__workspace = {};
151 for (let i = 0; i < a1__name__workspace.length; i++) {
152 const name__workspace = a1__name__workspace[i];
153 stdout__name__workspace[name__workspace] = stdout_a1[i];
154 }
155 return stdout__name__workspace;
156}