UNPKG

1.58 kBJavaScriptView Raw
1'use strict'
2
3const parse = require('string-argv')
4const npmWhich = require('npm-which')(process.cwd())
5const checkPkgScripts = require('./checkPkgScripts')
6
7const debug = require('debug')('lint-staged:find-bin')
8
9// Find and load the package.json at the root of the project.
10let pkg
11try {
12 // eslint-disable-next-line import/no-dynamic-require, global-require
13 pkg = require(`${process.cwd()}/package.json`)
14 debug('Loaded package.json using `process.cwd()`')
15} catch (ignore) {
16 debug('Could not load package.json using `process.cwd()`')
17 pkg = {}
18}
19
20const cache = new Map()
21
22module.exports = function findBin(cmd) {
23 debug('Resolving binary for command `%s`', cmd)
24
25 /*
26 * Try to locate the binary in node_modules/.bin and if this fails, in
27 * $PATH.
28 *
29 * This allows to use linters installed for the project:
30 *
31 * "lint-staged": {
32 * "*.js": "eslint"
33 * }
34 */
35 const [binName, ...args] = parse(cmd)
36
37 if (cache.has(binName)) {
38 debug('Resolving binary for `%s` from cache', binName)
39 return { bin: cache.get(binName), args }
40 }
41
42 try {
43 /* npm-which tries to resolve the bin in local node_modules/.bin */
44 /* and if this fails it look in $PATH */
45 const bin = npmWhich.sync(binName)
46 debug('Binary for `%s` resolved to `%s`', cmd, bin)
47 cache.set(binName, bin)
48 return { bin, args }
49 } catch (err) {
50 // throw helpful error if matching script is present in package.json
51 checkPkgScripts(pkg, cmd, binName, args)
52 throw new Error(`${binName} could not be found. Try \`npm install ${binName}\`.`)
53 }
54}