nps icon indicating copy to clipboard operation
nps copied to clipboard

How can I pass arguments to an nps command?

Open dweber019 opened this issue 9 years ago • 29 comments

  • nps version: latest
  • node version: lastest
  • npm version: lastest

The command executed:

npm start -- --env.platform=mobile
nps serve --env.platform=mobile

The output:

You provided one or more invalid flags: env Did you forget to put your command in quotes?

Or it just runs without applying the argument.

Problem description:

How can I pass arguments to an nps command? Before I was using npm scripts and there I could pass arguments form the command line like https://docs.npmjs.com/cli/run-script.

This is not possible or at least not documented.

Use case:

I like to provide something dynamically to the command. E.g. the name of a configuration file. I don't like to configure for each dynamic option an nps command and in addition, to be user friendly, I would also have to configure all the npm scripts for each nps command.

Suggested solution:

Add the same option as npm-script does to support passing arguments from the command line.

dweber019 avatar Apr 15 '17 19:04 dweber019

Try:

nps "serve --env.platform=mobile"

kentcdodds avatar Apr 15 '17 19:04 kentcdodds

Nice I know now that I can do:

nps "serve --env.platform=mobile"

Putting the command in " solves the problem in nps

dweber019 avatar Apr 15 '17 19:04 dweber019

Thanks for using nps and filing an issue. If there's something that could be improved with the docs, please make a pull request: http://makeapullrequest.com

kentcdodds avatar Apr 15 '17 19:04 kentcdodds

@kentcdodds How can I do the same over npm e.g.:

npm start -- --env.platform=mobile

Or do I have to use strictly nps now?

Would be nice if the user could just rely on the defaulting behavior and just pass an argument at the very beginning.

dweber019 avatar Apr 15 '17 19:04 dweber019

Hmmm.... That's a use case I hadn't considered. Most of the time you just make it a script (for example, call it mobile) and run: npm start mobile

kentcdodds avatar Apr 15 '17 19:04 kentcdodds

Yes but if there is dynamic parameter, there is ability to pass without writing the full nps command path.

I would be nice if I could run:

npm start -- --env.platform=mobile
npm run build -- --env.platform=mobile

without knowing the whole nps logic/path. It would be nice for Developers which have nothing to do with the build/runtime process.

Totally get your npm start mobile suggestion but imagine I have two options --env.platform and --env.config which can be combined. I would end up with a lot of npm scripts without changing the base command in nps, just the arguments change.

dweber019 avatar Apr 15 '17 20:04 dweber019

Try: ./node_modules/.bin/nps "serve --env.platform=mobile" 👍

kentcdodds avatar Apr 15 '17 20:04 kentcdodds

Doesn't solve my issue of being dynamic from the command line but it definitely solves some issues in the nps configuration file.

dweber019 avatar Apr 16 '17 00:04 dweber019

Doesn't solve my issue of being dynamic from the command line

Could you explain what you mean?

kentcdodds avatar Apr 16 '17 00:04 kentcdodds

The comment from @gunnx in this issue #101 is what I mean (or at least it describes the npm-script argument issue). There is no possibility to pass any kind of custom argument to nps without using the full nps command path and using nps directly.

So I can't do this:

npm run <any-script> -- --myargument=example

Because the double quote won't work as the nps command is behind the npm-script.

And I can't do this:

nps "mobile.build --myargument=example"

When the targeted full command path is mobile.build.development. Even when the default behavior is setup to reach command mobile.build.development by just typing mobile.build.

Summary:

  1. No argument passing over npm-scripts at all
  2. No argument passing over nps default behavior. So as soon as there is an argument involved I can't leverage the default behavior system.
  3. Ending up in building a lot of commands/option entries because I have to cover all my possible argument combinations

But I think currently there isn't any solution for my problem. So it's more of a feature/enhancement to be considered in the future ;)

dweber019 avatar Apr 16 '17 01:04 dweber019

Ok, let's talk about how to solve this problem. What do you mean by:

And I can't do this:

nps "mobile.build --myargument=example"

kentcdodds avatar Apr 16 '17 01:04 kentcdodds

Let's do it ;)

Imagine this configuration:

module.exports = {
  scripts: {
    default: 'nps mobile',
    mobile: {
      default: 'nps mobile.build',
      build: {
        default: 'nps mobile.build.development',
        development: 'any command'
      }
    }
  }
}

In the end I like to call mobile.build.development any time.

I can do this currently by calling:

nps
nps mobile
nps mobile.build
nps mobile.build.development

Now I would like to pass a custom argument to the command behind mobile.build.development.

Suddenly, I can only do this by calling nps "mobile.build.development --argumentname=value" directly. So no defaulting anymore.

I can't do this because the behavior changed to:

nps --argumentname=value" // Not working anymore
nps "mobile --argumentname=value" // Not working anymore
nps "mobile.build --argumentname=value" // Not working anymore
nps "mobile.build.development --argumentname=value" // Still working

dweber019 avatar Apr 16 '17 08:04 dweber019

@dweber019 Yeah there's a few occasions where I really miss the option to do this, I've got around it for most things by creating specific package-scripts entries to cover the common flags. It's where you want to pass dynamic values that it falls down, for example in my BDD test framework I have the option to running certain tags by passing them as a value but there are lots of tags and you can pass multiple tags or conditional tags, something thats just not realistic to be done via package-scripts.

some examples:

npm start -- --tags 'not @skip'
npm start -- --tags '@smoke and not @skip'
npm start -- --tags '@CI and not @skip'
npm start -- --tags '(@smoke or @ui) and (not @slow)'

I understand the reason to remove this was the confusion about whether to pass or not, would it be possible to have a new flag for nps that then passes that down to the actual command.

gunnx avatar Apr 16 '17 10:04 gunnx

@gunnx your suggestion about a new flag would be awesome.

Btw. I could solve my npm run issue. If I have the following npm script:

"scripts": {
    "start": "nps"
}

I can pass arguments like npm start -- "mobile.build.development --argumentname=value".

So only the argument passing nps internally over defaulting behaviors is an issue.

dweber019 avatar Apr 16 '17 10:04 dweber019

I'm really sorry that I'm struggling to understand the issue. Could you explain what you meant by:

Would be nice if the user could just rely on the defaulting behavior and just pass an argument at the very beginning.

What if we exposed an additional binary (nps-raw?) that behaves similar to the old binary. The behavior would be that it doesn't accept any flags of its own and all flags are forwarded to the command:

nps-raw serve --foo=bar --baz --buzz=foobar

Would that solve the use-case?

kentcdodds avatar Apr 17 '17 15:04 kentcdodds

I don't think this will fix the defaulting issue.

The custom argument should be passed from default command to default command until the final command is reached.

dweber019 avatar Apr 18 '17 16:04 dweber019

I think that it would. If you used nps-raw exclusively even in your package-scripts.js file, then I believe that it would fix the issue.

Would you like to try it out and makeapullrequest.com? :)

kentcdodds avatar Apr 19 '17 05:04 kentcdodds

I am running into the same issue. I will try to explain it a little differently and hopefully provide a solution.

Script I am running npm start build -- --build {CI_BUILD_NUMBER}

Script processed as nps build "--" "--build" "{CI_BUILD_NUMBER}"

Ideally processed as nps "build --build {CI_BUILD_NUMBER}"

Although extracting nps-raw would work, the potential simpler solution (from the outside looking in) would be to treat anything after "--" as an option flag. This may be a breaking change, but I am not sure, since any point that "--" is found nps will throw the invalid flag(s) passed: error.

kwelch avatar May 16 '17 21:05 kwelch

Yeah, I think we'd be safe to call that a patch. If you'd like to implement that, I'd happily accept :+1:

kentcdodds avatar May 16 '17 21:05 kentcdodds

This should be closable. Only potential dependency would be documentation.

kwelch avatar May 17 '17 13:05 kwelch

Whoops, forgot to ask you to document that in your PR. Could you do that really quick? Then we can close this. Thanks @kwelch!

kentcdodds avatar May 17 '17 16:05 kentcdodds

So looking back at this to add docs, and the unit tests passes, but the functionality added in #138 does not work when called. I am starting to look into #139 instead.

kwelch avatar May 25 '17 03:05 kwelch

Good call :+1:

kentcdodds avatar May 25 '17 05:05 kentcdodds

I want this too, use case is local dev using npm start which runs via nps, a webpack-dev-server, would like to simply change the port, e.g. npm start --port 8000, although making a static for the port wouldn't be hard, it's really not efficient to make a different configuration every time a dev wants to change something like a port. could it be passed via an env var? sure, but this doesn't seem like the right design to me.

xenoterracide avatar Dec 27 '17 18:12 xenoterracide

This is exactly what I'm looking for. My primary use case is using it for isolating specific tests: npm test -- --watch --match='test name'

I see a solution was merged, but I'm looking for the documentation because I can't seem to get it to work the way I expect.

GarthDB avatar May 18 '18 21:05 GarthDB

@GarthDB Looks like it was merged but hasn't been published yet

dkent600 avatar Jun 06 '18 17:06 dkent600

All my packages are automatically published. If it hasn't been published then something went wrong with the build.

kentcdodds avatar Jun 06 '18 17:06 kentcdodds

Given the following config:

module.exports = {
  scripts: {
    test: {
      default: 'jest --config jest/config.js',
    },
  },
}

Got passing arguments to work like this yarn nps "test -u"

image

infctr avatar Dec 28 '18 14:12 infctr

To clarify on usage, here is an example package-scripts.js:

const scripts = {
	myScript: "echo Hi",
};
module.exports.scripts = scripts;

Example usage: (without "--")

(base) PS C:\Test> npm start "myScript myArg"   

> [email protected] start C:\Test
> nps "myScript myArg"

nps is executing `myScript` : echo Hi myArg
Hi myArg

Example usage: (with "--")


> [email protected] start C:\Test
> nps "myScript -- myArg"

nps is executing `myScript` : echo Hi -- myArg
Hi -- myArg

Venryx avatar Aug 17 '21 17:08 Venryx