/
cli.js
executable file
·117 lines (104 loc) · 3.74 KB
/
cli.js
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
import fs from 'fs';
import path from 'path';
import yargs from 'yargs';
import lodash from 'lodash';
import depcheck from './index';
import { version } from '../package.json';
function checkPathExist(dir, errorMessage) {
return new Promise((resolve, reject) =>
fs.exists(dir, (result) =>
(result ? resolve() : reject(errorMessage))));
}
function getParsers(parsers) {
return lodash.isUndefined(parsers)
? undefined
: lodash(parsers)
.split(',')
.map((keyValuePair) => keyValuePair.split(':'))
.fromPairs()
.mapValues((value) => value.split('&').map((name) => depcheck.parser[name]))
.value();
}
function getDetectors(detectors) {
return lodash.isUndefined(detectors)
? undefined
: detectors.split(',').map((name) => depcheck.detector[name]);
}
function getSpecials(specials) {
return lodash.isUndefined(specials)
? undefined
: specials.split(',').map((name) => depcheck.special[name]);
}
function noIssue(result) {
return lodash.isEmpty(result.dependencies)
&& lodash.isEmpty(result.devDependencies)
&& lodash.isEmpty(result.missing);
}
function prettify(caption, deps) {
const list = deps.map((dep) => `* ${dep}`);
return list.length ? [caption].concat(list) : [];
}
function mapMissing(missing, rootDir) {
return lodash.map(missing, (foundInFiles, key) =>
`${key}: ${lodash.replace(lodash.first(foundInFiles), rootDir, '.')}`);
}
function print(result, log, json, rootDir) {
if (json) {
log(JSON.stringify(result, (key, value) => (lodash.isError(value) ? value.stack : value)));
} else if (noIssue(result)) {
log('No depcheck issue');
} else {
const deps = prettify('Unused dependencies', result.dependencies);
const devDeps = prettify('Unused devDependencies', result.devDependencies);
const missing = prettify('Missing dependencies', mapMissing(result.missing, rootDir));
const content = deps.concat(devDeps, missing).join('\n');
log(content);
}
return result;
}
export default function cli(args, log, error, exit) {
const opt = yargs(args)
.usage('Usage: $0 [DIRECTORY]')
.boolean([
'dev',
'ignore-bin-package',
'skip-missing',
])
.default({
dev: true,
'ignore-bin-package': false,
'skip-missing': false,
})
.describe('ignore-bin-package', 'Ignore package with bin entry')
.describe('skip-missing', 'Skip calculation of missing dependencies')
.describe('json', 'Output results to JSON')
.describe('ignores', 'Comma separated package list to ignore')
.describe('ignore-dirs', 'Comma separated folder names to ignore')
.describe('parsers', 'Comma separated glob:parser pair list')
.describe('detectors', 'Comma separated detector list')
.describe('specials', 'Comma separated special parser list')
.version('version', 'Show version number', version)
.help('help', 'Show this help message');
const dir = opt.argv._[0] || '.';
const rootDir = path.resolve(dir);
checkPathExist(rootDir, `Path ${dir} does not exist`)
.then(() => checkPathExist(
path.resolve(rootDir, 'package.json'),
`Path ${dir} does not contain a package.json file`,
))
.then(() => depcheck(rootDir, {
ignoreBinPackage: opt.argv.ignoreBinPackage,
ignoreMatches: (opt.argv.ignores || '').split(','),
ignoreDirs: (opt.argv.ignoreDirs || '').split(','),
parsers: getParsers(opt.argv.parsers),
detectors: getDetectors(opt.argv.detectors),
specials: getSpecials(opt.argv.specials),
skipMissing: opt.argv.skipMissing,
}))
.then((result) => print(result, log, opt.argv.json, rootDir))
.then((result) => exit((opt.argv.json || noIssue(result)) ? 0 : -1))
.catch((errorMessage) => {
error(errorMessage);
exit(-1);
});
}