Skip to content

Commit 95b616d

Browse files
authored
Merge pull request #3 from hkdobrev/find-binary
Find binaries with npm-which and execute with execa
2 parents 3d42857 + 4fec6c1 commit 95b616d

File tree

5 files changed

+55
-18
lines changed

5 files changed

+55
-18
lines changed

README.md

Lines changed: 11 additions & 1 deletion
Original file line numberDiff line numberDiff line change
@@ -70,7 +70,17 @@ Configuration should be an object where each key is a file or directory mathed b
7070

7171
## What commands are supported?
7272

73-
For now, only globally available commands are allowed. PRs welcome so local scripts are used first.
73+
Supported are any executables installed locally or globally via `npm` or Yarn as well as any executable from your `$PATH`.
74+
75+
> Using globally installed scripts is discouraged, since run-if-changed may not work for someone who doesn't have it installed.
76+
77+
`run-if-changed` is using [npm-which](https://github.com/timoxley/npm-which) to locate locally installed scripts. So in your `.run-if-changedrc` you can write:
78+
79+
```json
80+
{
81+
"src": "webpack"
82+
}
83+
```
7484

7585
Sequences of commands are supported. Pass an array of commands instead of a single one and they will run sequentially.
7686

find-binary.js

Lines changed: 25 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -0,0 +1,25 @@
1+
const parseStringArgv = require('string-argv');
2+
const which = require('npm-which')(process.cwd());
3+
4+
/*
5+
* Try to locate the binary in node_modules/.bin and if this fails, in $PATH.
6+
*
7+
* This allows to use commands installed for the project:
8+
*
9+
* "run-if-checked": {
10+
* "src": "webpack"
11+
* }
12+
*/
13+
module.exports = function findBinary(commandString) {
14+
const [binaryName, ...args] = parseStringArgv(commandString);
15+
16+
/* npm-which tries to resolve the bin in local node_modules/.bin */
17+
/* and if this fails it look in $PATH */
18+
try {
19+
const binaryPath = which.sync(binaryName);
20+
21+
return { binaryPath, args };
22+
} catch (err) {
23+
throw new Error(`${binaryName} binary not found! Probably try \`yarn install ${binaryName}\`.`);
24+
}
25+
};

index.js

Lines changed: 10 additions & 16 deletions
Original file line numberDiff line numberDiff line change
@@ -1,10 +1,10 @@
11
#!/usr/bin/env node
22

33
const cli = require('commander');
4-
const util = require('util');
54
const process = require('process');
65
const cosmiconfig = require('cosmiconfig');
7-
const exec = util.promisify(require('child_process').exec);
6+
const execa = require('execa');
7+
const findBinary = require('./find-binary');
88
const pkg = require('./package.json');
99

1010
cli
@@ -13,21 +13,15 @@ cli
1313

1414
const binary = `${__dirname}/bin/git-run-if-changed.sh`;
1515

16-
async function runCommandsIfFileChanged(fileToCheck, commands) {
16+
function runCommandsIfFileChanged(fileToCheck, commands) {
1717
const commandsList = Array.isArray(commands) ? commands : [commands];
18-
const commandsString = commandsList.map(x => `"${x}"`).join(' ');
19-
const command = `${binary} "${fileToCheck}" ${commandsString}`;
20-
const response = await exec(command);
21-
const { stdout, stderr } = response;
22-
if (stdout) {
23-
console.log(stdout);
24-
}
25-
if (response instanceof Error) {
26-
console.error('There was an error executing script:');
27-
}
28-
if (stderr) {
29-
console.error(stderr);
30-
}
18+
const commandsListResolved = commandsList.map((cmd) => {
19+
const { binaryPath, args: binaryArgs } = findBinary(cmd);
20+
21+
return [binaryPath].concat(binaryArgs).join(' ');
22+
});
23+
const args = [fileToCheck].concat(commandsListResolved);
24+
execa(binary, args).stdout.pipe(process.stdout);
3125
}
3226

3327
const configResult = cosmiconfig('run-if-changed').searchSync();

package.json

Lines changed: 4 additions & 1 deletion
Original file line numberDiff line numberDiff line change
@@ -10,7 +10,10 @@
1010
"private": false,
1111
"dependencies": {
1212
"commander": "^2.19.0",
13-
"cosmiconfig": "^5.0.7"
13+
"cosmiconfig": "^5.0.7",
14+
"execa": "^1.0.0",
15+
"npm-which": "^3.0.1",
16+
"string-argv": "^0.1.1"
1417
},
1518
"devDependencies": {
1619
"eslint": "^5.11.1",

yarn.lock

Lines changed: 5 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -2229,6 +2229,11 @@ string-argv@^0.0.2:
22292229
resolved "https://registry.yarnpkg.com/string-argv/-/string-argv-0.0.2.tgz#dac30408690c21f3c3630a3ff3a05877bdcbd736"
22302230
integrity sha1-2sMECGkMIfPDYwo/86BYd73L1zY=
22312231

2232+
string-argv@^0.1.1:
2233+
version "0.1.1"
2234+
resolved "https://registry.yarnpkg.com/string-argv/-/string-argv-0.1.1.tgz#66bd5ae3823708eaa1916fa5412703150d4ddfaf"
2235+
integrity sha512-El1Va5ehZ0XTj3Ekw4WFidXvTmt9SrC0+eigdojgtJMVtPkF0qbBe9fyNSl9eQf+kUHnTSQxdQYzuHfZy8V+DQ==
2236+
22322237
string-width@^1.0.1:
22332238
version "1.0.2"
22342239
resolved "https://registry.yarnpkg.com/string-width/-/string-width-1.0.2.tgz#118bdf5b8cdc51a2a7e70d211e07e2b0b9b107d3"

0 commit comments

Comments
 (0)