1 |
|
2 |
|
3 | const path = require('path')
|
4 | const execa = require('execa')
|
5 | const merge = require('merge-options')
|
6 |
|
7 | /** @typedef { import("execa").Options} ExecaOptions */
|
8 | /** @typedef { import("execa").ExecaChildProcess} ExecaChildProcess */
|
9 |
|
10 | const defaultInput = [
|
11 | 'package.json',
|
12 | '.aegir.js*',
|
13 | './test/**/*.js',
|
14 | './src/**/*.js',
|
15 | '!./test/fixtures/**/*.js'
|
16 | ]
|
17 |
|
18 | const commandNames = ['dependency-check', 'dep-check', 'dep']
|
19 |
|
20 | /**
|
21 | * Returns true if the user invoked the command with non-flag or
|
22 | * optional args
|
23 | *
|
24 | * @param {Array} input - input files maybe passed by the user, maybe defaults
|
25 | * @param {Array} processArgs - process.argv or similar
|
26 | * @returns {boolean}
|
27 | */
|
28 | const hasPassedFileArgs = (input, processArgs) => {
|
29 | // if any of the passed paths are not in the process.argv used to invoke
|
30 | // this command, we have been passed defaults and not user input
|
31 | for (const path of input) {
|
32 | if (!processArgs.includes(path)) {
|
33 | return false
|
34 | }
|
35 | }
|
36 |
|
37 | return true
|
38 | }
|
39 |
|
40 | /**
|
41 | * Check dependencies
|
42 | *
|
43 | * @param {object} argv - Command line arguments passed to the process.
|
44 | * @param {Array} processArgs - Unparsed command line arguments used to start the process
|
45 | * @param {ExecaOptions} execaOptions - execa options.
|
46 | * @returns {ExecaChildProcess} - Child process that does dependency check.
|
47 | */
|
48 | const check = (argv = { _: [], input: [], ignore: [] }, processArgs = [], execaOptions) => {
|
49 | const forwardOptions = argv['--'] ? argv['--'] : []
|
50 | let input = argv.input
|
51 | const ignore = argv.ignore
|
52 |
|
53 | if (argv.productionOnly) {
|
54 | if (!hasPassedFileArgs(input, processArgs)) {
|
55 | input = [
|
56 | 'package.json',
|
57 | './src/**/*.js'
|
58 | ]
|
59 | }
|
60 |
|
61 | forwardOptions.push('--no-dev')
|
62 | }
|
63 |
|
64 | if (ignore.length) {
|
65 | // this allows us to specify ignores on a per-module basis while also orchestrating the command across multiple modules.
|
66 | //
|
67 | // e.g. npm script in package.json:
|
68 | // "dependency-check": "aegir dependency-check -i cross-env",
|
69 | //
|
70 | // .travis.yml:
|
71 | // lerna run dependency-check -- -p -- --unused
|
72 | //
|
73 | // results in the following being run in the package:
|
74 | // aegir dependency-check -i cross-env -p -- --unused
|
75 | ignore.forEach(i => {
|
76 | forwardOptions.push('-i', i)
|
77 | })
|
78 | }
|
79 |
|
80 | return execa('dependency-check',
|
81 | [
|
82 | ...input,
|
83 | '--missing',
|
84 | ...forwardOptions
|
85 | ],
|
86 | merge(
|
87 | {
|
88 | localDir: path.join(__dirname, '..'),
|
89 | preferLocal: true
|
90 | },
|
91 | execaOptions
|
92 | )
|
93 | )
|
94 | }
|
95 |
|
96 | module.exports = check
|
97 | module.exports.defaultInput = defaultInput
|
98 | module.exports.commandNames = commandNames
|