Skip to content

Instantly share code, notes, and snippets.

@dhermes
Last active October 29, 2019 18:08
Show Gist options
  • Star 0 You must be signed in to star a gist
  • Fork 0 You must be signed in to fork a gist
  • Save dhermes/24fae07ef032fa09a58abb30fd912bbc to your computer and use it in GitHub Desktop.
Save dhermes/24fae07ef032fa09a58abb30fd912bbc to your computer and use it in GitHub Desktop.
Forwarding args with `npm`

Forwarding args with npm

No Flags Directly to npm run

$ npm run foo

> @ foo .../npm-script-flag-forwarding
> ./info.sh && npm run bar --custom1=cheese

npm_config_argv={"remain":[],"cooked":["run","foo"],"original":["run","foo"]}

> @ bar .../npm-script-flag-forwarding
> ./info.sh && npm run baz --custom2=burger

npm_config_argv={"remain":[],"cooked":["run","bar","--custom1","cheese"],"original":["run","bar","--custom1=cheese"]}
npm_config_custom1=cheese

> @ baz .../npm-script-flag-forwarding
> ./info.sh

npm_config_argv={"remain":[],"cooked":["run","baz","--custom2","burger"],"original":["run","baz","--custom2=burger"]}
npm_config_custom2=burger
npm_config_custom1=cheese

Flag Passed to 1st npm run Invocation

$ npm run foo --custom3=pickles

> @ foo .../npm-script-flag-forwarding
> ./info.sh && npm run bar --custom1=cheese

npm_config_argv={"remain":[],"cooked":["run","foo","--custom3","pickles"],"original":["run","foo","--custom3=pickles"]}
npm_config_custom3=pickles

> @ bar .../npm-script-flag-forwarding
> ./info.sh && npm run baz --custom2=burger

npm_config_argv={"remain":[],"cooked":["run","bar","--custom1","cheese"],"original":["run","bar","--custom1=cheese"]}
npm_config_custom3=pickles
npm_config_custom1=cheese

> @ baz .../npm-script-flag-forwarding
> ./info.sh

npm_config_argv={"remain":[],"cooked":["run","baz","--custom2","burger"],"original":["run","baz","--custom2=burger"]}
npm_config_custom2=burger
npm_config_custom3=pickles
npm_config_custom1=cheese

Flag Passed to 2nd npm run Invocation

$ npm run foo -- --custom3=pickles

> @ foo .../npm-script-flag-forwarding
> ./info.sh && npm run bar --custom1=cheese "--custom3=pickles"

npm_config_argv={"remain":["--custom3=pickles"],"cooked":["run","foo","--","--custom3=pickles"],"original":["run","foo","--","--custom3=pickles"]}

> @ bar .../npm-script-flag-forwarding
> ./info.sh && npm run baz --custom2=burger

npm_config_argv={"remain":[],"cooked":["run","bar","--custom1","cheese","--custom3","pickles"],"original":["run","bar","--custom1=cheese","--custom3=pickles"]}
npm_config_custom3=pickles
npm_config_custom1=cheese

> @ baz .../npm-script-flag-forwarding
> ./info.sh

npm_config_argv={"remain":[],"cooked":["run","baz","--custom2","burger"],"original":["run","baz","--custom2=burger"]}
npm_config_custom2=burger
npm_config_custom3=pickles
npm_config_custom1=cheese

Flag Passed to 3rd npm run Invocation

$ npm run foo -- -- --custom3=pickles

> @ foo .../npm-script-flag-forwarding
> ./info.sh && npm run bar --custom1=cheese "--" "--custom3=pickles"

npm_config_argv={"remain":["--","--custom3=pickles"],"cooked":["run","foo","--","--","--custom3=pickles"],"original":["run","foo","--","--","--custom3=pickles"]}

> @ bar .../npm-script-flag-forwarding
> ./info.sh && npm run baz --custom2=burger "--custom3=pickles"

npm_config_argv={"remain":["--custom3=pickles"],"cooked":["run","bar","--custom1","cheese","--","--custom3=pickles"],"original":["run","bar","--custom1=cheese","--","--custom3=pickles"]}
npm_config_custom1=cheese

> @ baz .../npm-script-flag-forwarding
> ./info.sh

npm_config_argv={"remain":[],"cooked":["run","baz","--custom2","burger","--custom3","pickles"],"original":["run","baz","--custom2=burger","--custom3=pickles"]}
npm_config_custom2=burger
npm_config_custom3=pickles
npm_config_custom1=cheese

Flag Passed to 4th (nonexistent) npm run Invocation

$ npm run foo -- -- -- --custom3=pickles

> @ foo .../npm-script-flag-forwarding
> ./info.sh && npm run bar --custom1=cheese "--" "--" "--custom3=pickles"

npm_config_argv={"remain":["--","--","--custom3=pickles"],"cooked":["run","foo","--","--","--","--custom3=pickles"],"original":["run","foo","--","--","--","--custom3=pickles"]}

> @ bar .../npm-script-flag-forwarding
> ./info.sh && npm run baz --custom2=burger "--" "--custom3=pickles"

npm_config_argv={"remain":["--","--custom3=pickles"],"cooked":["run","bar","--custom1","cheese","--","--","--custom3=pickles"],"original":["run","bar","--custom1=cheese","--","--","--custom3=pickles"]}
npm_config_custom1=cheese

> @ baz .../npm-script-flag-forwarding
> ./info.sh "--custom3=pickles"

npm_config_argv={"remain":["--custom3=pickles"],"cooked":["run","baz","--custom2","burger","--","--custom3=pickles"],"original":["run","baz","--custom2=burger","--","--custom3=pickles"]}
npm_config_custom2=burger
npm_config_custom1=cheese

Passing Multiple Flags

$ npm run foo -- -- --custom3=pickles --custom4=mustard

> @ foo .../npm-script-flag-forwarding
> ./info.sh && npm run bar --custom1=cheese "--" "--custom3=pickles" "--custom4=mustard"

npm_config_argv={"remain":["--","--custom3=pickles","--custom4=mustard"],"cooked":["run","foo","--","--","--custom3=pickles","--custom4=mustard"],"original":["run","foo","--","--","--custom3=pickles","--custom4=mustard"]}

> @ bar .../npm-script-flag-forwarding
> ./info.sh && npm run baz --custom2=burger "--custom3=pickles" "--custom4=mustard"

npm_config_argv={"remain":["--custom3=pickles","--custom4=mustard"],"cooked":["run","bar","--custom1","cheese","--","--custom3=pickles","--custom4=mustard"],"original":["run","bar","--custom1=cheese","--","--custom3=pickles","--custom4=mustard"]}
npm_config_custom1=cheese

> @ baz .../npm-script-flag-forwarding
> ./info.sh

npm_config_argv={"remain":[],"cooked":["run","baz","--custom2","burger","--custom3","pickles","--custom4","mustard"],"original":["run","baz","--custom2=burger","--custom3=pickles","--custom4=mustard"]}
npm_config_custom2=burger
npm_config_custom3=pickles
npm_config_custom1=cheese
npm_config_custom4=mustard

Flag Passed Without =

Unfortunately npm doesn't handle --custom3 pickles in the same way it handles --custom3=pickles

$ npm run foo --custom3 pickles

> @ foo .../npm-script-flag-forwarding
> ./info.sh && npm run bar --custom1=cheese "pickles"

npm_config_argv={"remain":["pickles"],"cooked":["run","foo","--custom3","pickles"],"original":["run","foo","--custom3","pickles"]}
npm_config_custom3=true

> @ bar .../npm-script-flag-forwarding
> ./info.sh && npm run baz --custom2=burger "pickles"

npm_config_argv={"remain":["pickles"],"cooked":["run","bar","--custom1","cheese","pickles"],"original":["run","bar","--custom1=cheese","pickles"]}
npm_config_custom3=true
npm_config_custom1=cheese

> @ baz .../npm-script-flag-forwarding
> ./info.sh "pickles"

npm_config_argv={"remain":["pickles"],"cooked":["run","baz","--custom2","burger","pickles"],"original":["run","baz","--custom2=burger","pickles"]}
npm_config_custom2=burger
npm_config_custom3=true
npm_config_custom1=cheese

Development

To populate this file run

python populate.py
# Forwarding args with `npm`
## No Flags Directly to `npm run`
```
$ npm run foo
{no_forward}
```
## Flag Passed to 1st `npm run` Invocation
```
$ npm run foo --custom3=pickles
{forward0}
```
## Flag Passed to 2nd `npm run` Invocation
```
$ npm run foo -- --custom3=pickles
{forward1}
```
## Flag Passed to 3rd `npm run` Invocation
```
$ npm run foo -- -- --custom3=pickles
{forward2}
```
## Flag Passed to 4th (nonexistent) `npm run` Invocation
```
$ npm run foo -- -- -- --custom3=pickles
{forward3}
```
## Passing Multiple Flags
```
$ npm run foo -- -- --custom3=pickles --custom4=mustard
{multiple_flags}
```
## Flag Passed Without `=`
Unfortunately `npm` doesn't handle `--custom3 pickles` in the same way
it handles `--custom3=pickles`
```
$ npm run foo --custom3 pickles
{no_equals}
```
## Development
To populate this file run
```
python populate.py
```
#!/bin/sh
if [[ -z "${npm_config_argv}" ]]; then
echo "npm_config_argv environment variable expected to be set by the caller."
exit 1
fi
echo "npm_config_argv=${npm_config_argv}"
env | grep -e '^npm_config_custom' || true
{
"scripts": {
"foo": "./info.sh && npm run bar --custom1=cheese",
"bar": "./info.sh && npm run baz --custom2=burger",
"baz": "./info.sh"
}
}
import os
import pathlib
import subprocess
COMMANDS = {
"no_forward": ("npm", "run", "foo"),
"forward0": ("npm", "run", "foo", "--custom3=pickles"),
"forward1": ("npm", "run", "foo", "--", "--custom3=pickles"),
"forward2": ("npm", "run", "foo", "--", "--", "--custom3=pickles"),
"forward3": ("npm", "run", "foo", "--", "--", "--", "--custom3=pickles"),
"no_equals": ("npm", "run", "foo", "--custom3", "pickles"),
"multiple_flags": (
"npm",
"run",
"foo",
"--",
"--",
"--custom3=pickles",
"--custom4=mustard",
),
}
CURR_DIR = pathlib.Path(__file__).resolve().parent
def main():
# Make sure we're running the same directory as `populate.py`
os.chdir(CURR_DIR)
with open("README.md.template", "r") as file_obj:
template = file_obj.read()
values = {}
for name, cmd in COMMANDS.items():
result = subprocess.check_output(cmd).decode("ascii")
values[name] = result.replace(str(CURR_DIR), f".../{CURR_DIR.name}")
readme = template.format(**values)
with open("README.md", "w") as file_obj:
file_obj.write(readme)
if __name__ == "__main__":
main()
Sign up for free to join this conversation on GitHub. Already have an account? Sign in to comment