@juit/check-updates 2.0.6 → 3.0.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/check-updates.js DELETED
@@ -1,228 +0,0 @@
1
- #!/usr/bin/env node
2
-
3
- // dist/main.mjs
4
- import * as yargs from "yargs";
5
-
6
- // dist/updater.mjs
7
- import { readFile as readFile2, writeFile } from "node:fs/promises";
8
- import * as glob from "glob";
9
- import semver from "semver";
10
- import fetch from "npm-registry-fetch";
11
-
12
- // dist/npmrc.mjs
13
- import fs from "node:fs/promises";
14
- import path from "node:path";
15
- import { parse } from "ini";
16
- function replaceEnvironmentVariable(token) {
17
- return token.replace(/^\$\{?([^}]*)\}?$/, (_match, ...vars) => {
18
- return process.env[vars[0]] || "";
19
- });
20
- }
21
- async function readFile(filename) {
22
- try {
23
- const data = await fs.readFile(filename, "utf8");
24
- const npmrc = parse(data);
25
- for (const key in npmrc) {
26
- if (typeof npmrc[key] === "string") {
27
- npmrc[key] = replaceEnvironmentVariable(npmrc[key]);
28
- }
29
- }
30
- return npmrc;
31
- } catch (error) {
32
- if (error.code === "ENOENT")
33
- return {};
34
- throw error;
35
- }
36
- }
37
- async function readNpmRc(packageJsonFile) {
38
- const local = readFile(path.resolve(packageJsonFile, "..", ".npmrc"));
39
- const user = readFile(
40
- process.env.NPM_CONFIG_USERCONFIG ? process.env.NPM_CONFIG_USERCONFIG : process.env.HOME ? path.resolve(process.env.HOME, ".npmrc") : ""
41
- );
42
- const global = readFile(
43
- process.env.NPM_CONFIG_GLOBALCONFIG ? process.env.NPM_CONFIG_GLOBALCONFIG : "/etc/npmrc"
44
- );
45
- return Object.assign({}, ...await Promise.all([global, user, local]));
46
- }
47
-
48
- // dist/updater.mjs
49
- var cache = {};
50
- var [K, R, G, Y, B] = [0, 31, 32, 33, 34].map((x) => `\x1B[${x}m`);
51
- async function processPackages(patterns, options) {
52
- const { bump: bump2, quick: quick2, strict: strict2, debug: debug2, dryrun: dryrun2 } = options;
53
- function $debug(...args2) {
54
- if (debug2 && args2)
55
- console.log(`${R}[DEBUG]${K}`, ...args2);
56
- }
57
- function getVersions(name, npmrc) {
58
- if (name in cache) {
59
- $debug(`Returning cached versions for ${Y}${name}${K}`);
60
- return cache[name];
61
- }
62
- $debug(`Retrieving versions for package ${Y}${name}${K}`);
63
- const range = new semver.Range(">=0.0.0", { includePrerelease: false });
64
- return cache[name] = fetch.json(name, Object.assign({}, npmrc, { spec: name })).then((data) => {
65
- return Object.entries(data.versions).filter(([, info]) => !info.deprecated).map(([version]) => version).filter((version) => range.test(version)).sort(semver.rcompare);
66
- });
67
- }
68
- async function updateDependency(name, rangeString, npmrc) {
69
- const match = /^\s*([~^])\s*(\d+(\.\d+(\.\d+)?)?)\s*$/.exec(rangeString);
70
- if (!match) {
71
- $debug(`Not processing range ${G}${rangeString}${K} for ${Y}${name}${K}`);
72
- return rangeString;
73
- }
74
- const [, specifier = "", version = ""] = match;
75
- if (!strict2) {
76
- const r = rangeString;
77
- rangeString = `>=${version}`;
78
- if (specifier === "~")
79
- rangeString += ` <${semver.inc(version, "major")}`;
80
- $debug(`Extending version for ${Y}${name}${K} from ${G}${r}${K} to ${G}${rangeString}${K}`);
81
- }
82
- const range = new semver.Range(rangeString);
83
- const versions = await getVersions(name, npmrc);
84
- for (const v of versions) {
85
- if (range.test(v))
86
- return `${specifier}${v}`;
87
- }
88
- return `${specifier}${version}`;
89
- }
90
- async function processPackage(file) {
91
- process.stdout.write(`Processing ${G}${file}${K} `);
92
- const data = JSON.parse(await readFile2(file, "utf8"));
93
- if (data.name) {
94
- process.stdout.write(`[${Y}${data.name}`);
95
- if (data.version)
96
- process.stdout.write(` ${data.version}`);
97
- process.stdout.write(`${K}] `);
98
- }
99
- if (debug2)
100
- process.stdout.write("\n");
101
- const npmrc = await readNpmRc(file);
102
- const changes2 = [];
103
- let mainDependencyChanges = 0;
104
- for (const type in data) {
105
- if (!type.match(/[dD]ependencies$/))
106
- continue;
107
- if (type.match(/bundled?Dependencies/))
108
- continue;
109
- const kind = type.length > 12 ? ` [${type.slice(0, -12)}]` : "";
110
- const dependencies = {};
111
- const promises = Object.keys(data[type] || {}).sort().map(async (name) => {
112
- const from = data[type][name];
113
- const to = await updateDependency(name, from, npmrc);
114
- if (!debug2)
115
- process.stdout.write(".");
116
- if (from !== to) {
117
- changes2.push({ name, from, to, kind });
118
- if (type === "dependencies")
119
- mainDependencyChanges++;
120
- }
121
- dependencies[name] = to;
122
- });
123
- await Promise.all(promises);
124
- if (Object.keys(dependencies).length) {
125
- data[type] = Object.entries(dependencies).sort(([a], [b]) => a.localeCompare(b)).reduce((deps, [name, version]) => {
126
- deps[name] = version;
127
- return deps;
128
- }, {});
129
- } else {
130
- delete data[type];
131
- }
132
- }
133
- if (debug2)
134
- process.stdout.write("Updated with");
135
- if (!changes2.length) {
136
- console.log(` ${R}no changes${K}`);
137
- return 0;
138
- }
139
- changes2.sort(({ name: a }, { name: b }) => a < b ? -1 : a > b ? 1 : 0);
140
- console.log(` ${R}${changes2.length} changes${K}`);
141
- let lname = 0;
142
- let lfrom = 0;
143
- let lto = 0;
144
- for (const { name, from, to } of changes2) {
145
- lname = lname > name.length ? lname : name.length;
146
- lfrom = lfrom > from.length ? lfrom : from.length;
147
- lto = lto > to.length ? lto : to.length;
148
- }
149
- for (const { name, from, to, kind } of changes2) {
150
- console.log(` * ${Y}${name.padEnd(lname)}${K} : ${G}${from.padStart(lfrom)}${K} -> ${G}${to.padEnd(lto)} ${B}${kind}${K}`);
151
- }
152
- if (quick2 && mainDependencyChanges === 0) {
153
- console.log(`No changes to main dependencies, ${Y}ignoring ${changes2.length} other changes${K}`);
154
- return 0;
155
- }
156
- if (bump2) {
157
- const bumped = semver.inc(data.version, bump2);
158
- console.log(` - Bumping version ${Y}${data.version}${K} -> ${G}${bumped}${K}`);
159
- data.version = bumped;
160
- }
161
- if (dryrun2) {
162
- console.log(`Dry run, not writing ${G}${file}${K}`);
163
- return 0;
164
- } else {
165
- await writeFile(file, JSON.stringify(data, null, 2) + "\n");
166
- return changes2.length;
167
- }
168
- }
169
- const files2 = await glob.glob(patterns);
170
- let changes = 0;
171
- let newline = false;
172
- for (const file of files2) {
173
- if (newline)
174
- console.log();
175
- const packageChanges = await processPackage(file);
176
- newline = !!packageChanges;
177
- changes += packageChanges;
178
- }
179
- return changes;
180
- }
181
-
182
- // dist/main.mjs
183
- var parsed = await yargs.default(process.argv.slice(2)).usage("$0 [--options ...] [package.json ...]").help("h").alias("h", "help").alias("v", "version").option("s", {
184
- alias: "strict",
185
- type: "boolean",
186
- description: [
187
- "Strictly adhere to semver rules for tilde (~x.y.z)",
188
- "and caret (^x.y.z) dependency ranges"
189
- ].join("\n")
190
- }).option("q", {
191
- alias: "quick",
192
- type: "boolean",
193
- description: [
194
- "Consider dev/peer/optional dependency updates if and",
195
- "only if the main depenencies also had updates"
196
- ].join("\n")
197
- }).option("d", {
198
- alias: "debug",
199
- type: "boolean",
200
- description: "Output debugging informations"
201
- }).option("n", {
202
- alias: "no-errors",
203
- type: "boolean",
204
- description: "Exit with 0 (zero) in case of no updates"
205
- }).options("b", {
206
- alias: "bump",
207
- coerce: (bump2) => bump2 == true ? "patch" : bump2,
208
- choices: ["major", "minor", "patch"],
209
- description: "Bump the version of the package file on changes"
210
- }).options("x", {
211
- alias: "dry-run",
212
- type: "boolean",
213
- description: "Only process changes without writing to disk"
214
- }).epilogue([
215
- "Multiple files (or globs) can be specified on the command line.\n",
216
- 'When no files are specified, the default is to process the "package.json" file in the current directory'
217
- ].join("\n")).strictOptions().argv;
218
- var { b: bump, s: strict, q: quick, n: noerr, d: debug, x: dryrun, _: args = [] } = parsed;
219
- var files = args.map((arg) => arg.toString());
220
- if (!files.length)
221
- files.push("package.json");
222
- try {
223
- const changes = await processPackages(files, { strict, quick, debug, dryrun, bump });
224
- process.exit(changes ? 0 : noerr ? 0 : -1);
225
- } catch (error) {
226
- console.error(error);
227
- process.exit(1);
228
- }
package/src/main.ts DELETED
@@ -1,75 +0,0 @@
1
- #!/usr/bin/env node
2
-
3
- import * as yargs from 'yargs'
4
-
5
- import { processPackages } from './updater'
6
-
7
- type ReleaseType = 'major' | 'minor' | 'patch'
8
-
9
- /* ========================================================================== *
10
- * CALL UP MAIN() AND DEAL WITH THE ASYNC PROMISE IT RETURNS *
11
- * ========================================================================== */
12
-
13
- /* Parse command line arguments */
14
- const parsed = await yargs.default(process.argv.slice(2))
15
- .usage('$0 [--options ...] [package.json ...]')
16
- .help('h').alias('h', 'help').alias('v', 'version')
17
- .option('s', {
18
- alias: 'strict',
19
- type: 'boolean',
20
- description: [
21
- 'Strictly adhere to semver rules for tilde (~x.y.z)',
22
- 'and caret (^x.y.z) dependency ranges',
23
- ].join('\n'),
24
- })
25
- .option('q', {
26
- alias: 'quick',
27
- type: 'boolean',
28
- description: [
29
- 'Consider dev/peer/optional dependency updates if and',
30
- 'only if the main depenencies also had updates',
31
- ].join('\n'),
32
- })
33
- .option('d', {
34
- alias: 'debug',
35
- type: 'boolean',
36
- description: 'Output debugging informations',
37
- })
38
- .option('n', {
39
- alias: 'no-errors',
40
- type: 'boolean',
41
- description: 'Exit with 0 (zero) in case of no updates',
42
- })
43
- .options('b', {
44
- alias: 'bump',
45
- coerce: ((bump): ReleaseType => bump == true ? 'patch' : bump),
46
- choices: [ 'major', 'minor', 'patch' ] as ReleaseType[],
47
- description: 'Bump the version of the package file on changes',
48
- })
49
- .options('x', {
50
- alias: 'dry-run',
51
- type: 'boolean',
52
- description: 'Only process changes without writing to disk',
53
- })
54
- .epilogue([
55
- 'Multiple files (or globs) can be specified on the command line.\n',
56
- 'When no files are specified, the default is to process the "package.json" file in the current directory',
57
- ].join('\n'))
58
- .strictOptions()
59
- .argv
60
-
61
- /* Expand parsed arguments */
62
- const { b: bump, s: strict, q: quick, n: noerr, d: debug, x: dryrun, _: args = [] } = parsed
63
-
64
- /* Normalize arguments and default to package.json in the current directory */
65
- const files = args.map((arg) => arg.toString())
66
- if (! files.length) files.push('package.json')
67
-
68
- /* Process packages, one by one */
69
- try {
70
- const changes = await processPackages(files, { strict, quick, debug, dryrun, bump })
71
- process.exit(changes ? 0 : noerr ? 0 : -1)
72
- } catch (error) {
73
- console.error(error)
74
- process.exit(1)
75
- }