0

This is a slightly different question than this thread.

I'm looking for the best way to pass command line arguments into my package.json file and npm scripts. I'm not interested in passing it, ultimately, into a script.

There are questions about how to do this but none specifically addressing the issues with trying to use a bash function in the package.json

My npm script is:

"Gocommit": "f() { cd dev; git add -A; git commit -m '$1'; git push;}; f"

I want to be able to write..

npm run Gocommit message

or

npm run Gocommit -- message

And have it use my flag or argument as the commit message.

But it just keeps using $1

Where did I go wrong?

Union find
  • 7,759
  • 13
  • 60
  • 111

1 Answers1

0

Two changes I made to fix.

  1. Move bash script to bash script

Npm script is now: sh script.sh

2) Don't need the function wrap in the .sh script or the quotes.

Final script is: cd dev; git add -A; git commit -m "$*"; git push;

Union find
  • 7,759
  • 13
  • 60
  • 111
  • `cd dev || return`. Otherwise, you can still run the `add` and `commit` even if the `cd` fails. – Charles Duffy Apr 13 '18 at 22:09
  • Also, `git commit -m $1` needs to be `git commit -m "$1"` or commit messages with whitespace (you put whitespace in your commit messages, right?) will break. – Charles Duffy Apr 13 '18 at 22:10
  • (When embedding code inside a JSON string, that means `\"$1\"`). – Charles Duffy Apr 13 '18 at 22:11
  • Thanks, yeah I am concerned this will just pass in one word commit messages. Let me try your suggestion – Union find Apr 13 '18 at 22:13
  • Yeah so `npm run Gocommit message test` becomes `sh script.sh "message" "test"` So I need a way of capturing all the arguments into one variable – Union find Apr 13 '18 at 22:14
  • Better practice would be usage like `npm run Gocommit "message test"`. Gives the user more control that way -- if you don't quote, there's a significant set of expansions you don't want and can't avoid. – Charles Duffy Apr 14 '18 at 01:34
  • 1
    ...for instance, consider if you ran `npm run Gocommit ignore files matching *.txt`. Without the quotes, the `*.txt` is replaced with a list of text files in the current directory before your function is called. If, instead, you made it `npm run Gocommit "ignore files matching *.txt"`, that's mooted. – Charles Duffy Apr 14 '18 at 01:34
  • 1
    ...also, using only `$1` for the message (and requiring the user to quote) means that `$2` and onward are available for future extension. – Charles Duffy Apr 14 '18 at 02:00
  • Amazing feedback @CharlesDuffy. Thanks. Is there anyway to detect if the user has left off quotes and ignore? – Union find Apr 14 '18 at 04:57
  • 1
    Whenever the OS starts a new program, the calling convention is `int main(int argc, char **argv)`, so before a shell can actually start an external program like `npm`, the original command line was already deconstructed into a list of separate C strings, expanded globs, etc. Quoting provides instruction *to the user's shell* as to how to do that conversion, but by the time `npm` is started, it's impossible to tell whether something was entered as `hello\ world`, `"hello world"`, `'hello world'`, `hello' 'world`, etc., because they all turn into the same array element. – Charles Duffy Apr 14 '18 at 14:52