Skip to content

Commit 81afb35

Browse files
authored
npm run depalign -- --align packageName [--range=latest] (#2422)
* npm run depcheck --align packageName [--range=latest] * rather surgically update the package.json files. * no Object.assign()
1 parent 95906df commit 81afb35

File tree

1 file changed

+54
-0
lines changed

1 file changed

+54
-0
lines changed

scripts/depalign.js

Lines changed: 54 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -1,7 +1,9 @@
11
const path = require('path');
22
const { promises: fs } = require('fs');
33
const chalk = require('chalk');
4+
const pacote = require('pacote');
45
const { runInDir } = require('./run-in-dir');
6+
const { forEachPackage } = require('./monorepo/for-each-package');
57
const { updatePackageJson } = require('./monorepo/update-package-json');
68
const { withProgress } = require('./monorepo/with-progress');
79
const {
@@ -11,6 +13,8 @@ const {
1113
} = require('./workspace-dependencies');
1214
const { calculateReplacements, intersects } = require('./semver-helpers');
1315

16+
const DEPENDENCY_GROUPS = ['peerDependencies', 'dependencies', 'devDependencies'];
17+
1418
const USAGE = `Check for dependency alignment issues.
1519
1620
USAGE: depalign.js [--skip-deduped] [--json] [--autofix] [--type peer,optional]
@@ -23,6 +27,8 @@ Options:
2327
--types-only Will only include a dependency in the report if all packages have this dependency as one of the provided with --type argument.
2428
--autofix Output a list of replacements to normalize ranges and align everything to the highest possible range.
2529
--autofix-only Will only autofix dependencies provided with this option
30+
--align Update peerDepencencies, dependencies and devDependencies that specify the package
31+
--range The range to use when aligning (default latest)
2632
--dangerously-include-mismatched Include mismatched dependencies into autofix.
2733
--config Path to the config. Default is .depalignrc.json
2834
--validate-config Check that 'ignore' option in the config doesn't include extraneous dependencies and versions
@@ -67,13 +73,20 @@ async function main(args) {
6773

6874
const outputJson = args.json;
6975
const shouldApplyFixes = args.autofix;
76+
const alignPackage = args.align;
77+
const alignToRange = args.range || 'latest';
7078
const shouldCheckConfig = args['validate-config'];
7179
const fixOnly = new Set(args['autofix-only']);
7280
const includeTypes = args.type;
7381
const includeTypesOnly = args['types-only'];
7482
const includeDeduped = !args['skip-deduped'];
7583
const includeMismatched = args['dangerously-include-mismatched'];
7684

85+
if (alignPackage) {
86+
await alignPackageToRange(alignPackage, alignToRange);
87+
return;
88+
}
89+
7790
const workspaces = await collectWorkspacesMeta();
7891
const dependencies = collectWorkspacesDependencies(workspaces);
7992
const report = generateReport(dependencies, {
@@ -187,6 +200,47 @@ async function main(args) {
187200
process.exitCode = report.mismatched.size;
188201
}
189202

203+
async function alignPackageToRange(packageName, range) {
204+
range = range === 'latest'
205+
// resolve in registry so we don't update package.json to literally "latest"
206+
? `^${(await pacote.manifest(`${packageName}@${range}`)).version}`
207+
: range
208+
209+
await forEachPackage(async ({ location, packageJson }) => {
210+
if (!hasDep(packageJson, packageName)) {
211+
return;
212+
}
213+
214+
await updatePackageJson(location, (pkgJson) => {
215+
return updateDepToRange(pkgJson, packageName, range);
216+
});
217+
});
218+
219+
await runInDir('npm install');
220+
}
221+
222+
function hasDep(packageJson, packageName) {
223+
for (const group of DEPENDENCY_GROUPS) {
224+
if (packageJson[group] && packageJson[group][packageName]) {
225+
return true;
226+
}
227+
}
228+
229+
return false;
230+
}
231+
232+
function updateDepToRange(packageJson, packageName, range) {
233+
const updated = { ...packageJson };
234+
235+
for (const group of DEPENDENCY_GROUPS) {
236+
if (packageJson[group] && packageJson[group][packageName]) {
237+
updated[group] = { ...packageJson[group], [packageName]: range };
238+
}
239+
}
240+
241+
return updated;
242+
}
243+
190244
function generateReport(
191245
dependencies,
192246
{ includeTypes, includeTypesOnly, ignore = {} } = { ignore: {} }

0 commit comments

Comments
 (0)