Reputation: 374
I have handy command for looking for TODO notes in my files. It works fine directly from the command line (ubuntu).
This is the plain CLI command:
grep -lir --color --exclude-dir={node_modules,libs} --exclude=package.json 'todo'
And this its occurrence in package.json
{
"private": true,
…
"scripts": {
"css:dev": "node tasks/postcss.js --mode development",
"css:build": "node tasks/postcss.js --mode production",
"js:dev": "webpack --mode development",
"js:build": "webpack --mode production",
"lint:css": "npx stylelint assets/css",
"lint:js": "npx eslint assets/js",
"images": "node tasks/images.js",
"sprite": "node tasks/svgsprite.js",
"todo": "grep -lir --color --exclude-dir={node_modules,libs} --exclude=package.json 'todo'"
}
}
When running with npm or yarn it ignores the exlude parameter and runs through the node_modules folder.
I have no idea how to fix it.
Upvotes: 3
Views: 2314
Reputation: 5808
The original command-line execution works because the bash
shell expands the expression --exclude-dir={node_modules,libs}
to --exclude-dir=node_modules --exclude-dir=libs
before invoking grep
. grep
is happy to take multiple --exclude-dir
arguments and it will exclude directories that match any of the specified names.
The problem with the command in package.json
arises because npm
does not use bash
to run the command. It uses plain old sh
to run the command.
On some systems sh
is just another name for bash
, and on those systems putting the original command in package.json
will work. Presumably Ahmed's system is one of those.
However, on other systems (notably Debian and its descendants) sh
is not the same as bash
. On these systems sh
is a much simpler shell, and it does not expand the --exclude-dir={node_modules,libs}
expression. So grep
sees the unexpanded argument and thinks it's being told to exclude a directory whose name is literally {node_modules,libs}
. Obviously that's not going to produce the result you want.
There are two obvious ways to fix this. One is to tell npm
to tell sh
to launch a bash
shell to execute the original command:
"todo": "bash -c \"grep -lir --color --exclude-dir={node_modules,libs} --exclude=package.json 'todo'\""
The other, which I prefer because it doesn't involve multiple levels of shell or nested/escaped quotes, is to explicitly specify both directory names in the command:
"todo": "grep -lir --color --exclude-dir=node_modules --exclude-dir=libs --exclude=package.json 'todo'"
Upvotes: 4