-
Notifications
You must be signed in to change notification settings - Fork 6
/
cli.ts
128 lines (119 loc) · 3.69 KB
/
cli.ts
1
2
3
4
5
6
7
8
9
10
11
12
13
14
15
16
17
18
19
20
21
22
23
24
25
26
27
28
29
30
31
32
33
34
35
36
37
38
39
40
41
42
43
44
45
46
47
48
49
50
51
52
53
54
55
56
57
58
59
60
61
62
63
64
65
66
67
68
69
70
71
72
73
74
75
76
77
78
79
80
81
82
83
84
85
86
87
88
89
90
91
92
93
94
95
96
97
98
99
100
101
102
103
104
105
106
107
108
109
110
111
112
113
114
115
116
117
118
119
120
121
122
123
124
125
126
127
128
import { Command, Argument } from 'commander';
import { readFileSync } from 'node:fs';
import { join, dirname } from 'node:path';
import type { PackageJson } from 'type-fest';
import { fileURLToPath } from 'node:url';
import { CDVC } from './cdvc.js';
import { DEPENDENCY_TYPE, Options } from './types.js';
import { DEFAULT_DEP_TYPES } from './defaults.js';
const __dirname = dirname(fileURLToPath(import.meta.url));
function getCurrentPackageVersion(): string {
const packageJson = JSON.parse(
readFileSync(join(__dirname, '..', '..', 'package.json'), 'utf8'), // Relative to compiled version of this file in the dist folder.
) as PackageJson;
if (!packageJson.version) {
throw new Error('Could not find package.json `version`');
}
return packageJson.version;
}
/**
* Used for collecting repeated CLI options into an array.
* Example: --foo bar --foo baz => ['bar', 'baz']
*/
function collect(
value: string,
previous: readonly string[],
): readonly string[] {
return [...previous, value];
}
/**
* Used for collecting both repeated and CSV CLI options into an array.
* Example: --foo bar,baz,buz --foo biz => ['bar', 'baz', 'buz', 'biz']
* */
function collectCSV(
value: string,
previous: readonly string[],
): readonly string[] {
return [...previous, ...value.split(',')];
}
// Setup CLI.
export function run() {
const program = new Command();
program
.description(
'CLI tool which checks that dependencies are on consistent versions across a monorepo / npm/pnpm/Yarn workspace.',
)
.version(getCurrentPackageVersion())
.addArgument(new Argument('[path]', 'path to workspace root').default('.'))
.option(
'--dep-type <dependency-type>',
`Type of dependency to check (choices: ${Object.keys(
DEPENDENCY_TYPE,
).join(', ')}) (default: ${DEFAULT_DEP_TYPES.join(
', ',
)}) (option can be repeated)`,
collectCSV,
[],
)
.option(
'--fix',
'Whether to autofix inconsistencies (using highest version present)',
false,
)
.option(
'--ignore-dep <dependency-name>',
'Dependency to ignore (option can be repeated)',
collect,
[],
)
.option(
'--ignore-dep-pattern <dependency-name-pattern>',
'RegExp of dependency names to ignore (option can be repeated)',
collect,
[],
)
.option(
'--ignore-package <package-name>',
'Workspace package to ignore (option can be repeated)',
collect,
[],
)
.option(
'--ignore-package-pattern <package-name-pattern>',
'RegExp of package names to ignore (option can be repeated)',
collect,
[],
)
.option(
'--ignore-path <path>',
'Workspace-relative path of packages to ignore (option can be repeated)',
collect,
[],
)
.option(
'--ignore-path-pattern <path-pattern>',
'RegExp of workspace-relative path of packages to ignore (option can be repeated)',
collect,
[],
)
.action((path: string, options: Options) => {
const cdvc = new CDVC(path, options);
if (options.fix) {
// Show output for dependencies we fixed.
if (cdvc.hasMismatchingDependenciesFixable) {
console.log(cdvc.toFixedSummary());
}
// Show output for dependencies that still have mismatches.
if (cdvc.hasMismatchingDependenciesNotFixable) {
console.log(cdvc.toMismatchSummary());
process.exitCode = 1;
}
} else if (cdvc.hasMismatchingDependencies) {
// Show output for dependencies that have mismatches.
console.log(cdvc.toMismatchSummary());
process.exitCode = 1;
}
})
.parse(process.argv);
return program;
}