gulp icon indicating copy to clipboard operation
gulp copied to clipboard

gulp treats flags after -- as task names

Open dawidgarus opened this issue 4 years ago • 13 comments

What actually happened?

>gulp default -- --version
[10:20:19] Using gulpfile [...]\gulpfile.js
[10:20:19] Task never defined: --version
[10:20:19] To list available tasks, try running: gulp --tasks

What were you expecting to happen? Gulp should ignore all cli arguments after --

Please post a sample of your gulpfile (preferably reduced to just the bit that's not working) N/A

What version of gulp are you using?

CLI version: 2.2.0 Local version: 4.0.2

What versions of npm and node are you using? npm 6.2.0 node 10.9.0

dawidgarus avatar Oct 01 '19 08:10 dawidgarus

(copied from the other issue)

I'm not sure which behavior I prefer because I've seen people that might want to prefix their tasks with a symbol (like a -).

If we change this, it would be a breaking change in the CLI.

This is going to take some more thinking through and probably end-user feedback.

phated avatar Oct 01 '19 21:10 phated

I think it's correct to regard all arguments after -- as non-options. -- is a special argument marking the end of options. This behavior is due to yargs and follows unix getopts.

sttk avatar Oct 02 '19 11:10 sttk

So there is no safe way to pass arbitrary arguments to gulp task? You can pass just a value, because it will be treated as task name. And if you use named flag, like --debug you are risking that in future version gulp will add it's own --debug which will result in conflict.

dawidgarus avatar Oct 04 '19 13:10 dawidgarus

I have considered before about task's flags to make naming spec., for example:

$ gulp task1 --task1:flag1 value1 --task1:flag2=value2 --task1:flag3,flag4=value4
---
(gulpfile.js)
gulp.task('task1',  (cb, {flag1, flag2, flag3, flag4}) => {
  ...
  cb();
});

If there are any ways to distinguish flags for tasks from normal flags (for gulp), this could be solved with no risk and avoiding breaking changes.

sttk avatar Oct 04 '19 15:10 sttk

In the future, maybe we can add configuration in the .gulp.js file to have gulp ignore flags. Here's a very rough idea:

module.exports = {
  ignoreFlags: ['--version']
};

And then if you ran gulp --version task1, it would print a warning "Ignoring --version flag due to local configuration" and then run task1

In the meantime, @sttk's suggestion is a great way to do things. You can even document those flags with the tasks using task metadata!

phated avatar Oct 05 '19 21:10 phated

@sttk @phated Yeah, imagine writing commands like gulp update-version --update-version:version=0.0.0 --update-version:from=0.0.0. In my opinion it's ridiculous. And what about subtasks which share argument - should I repeat it? I like the idea of declaring ignored flags, but why not use actually use task metadata instead of property in .gulp.js? This way we could do something like gulp task1 --help, where --help will be declared as flag for the task1 and the task and the task will be responsible for displaying help message for itself. And gulp --help would work as usual. But honestly, the simplest and the cleanest (although potentially breaking) solution would be to ignore flags after the task name, say: gulp --series task1 task2 --custom-flag --other-flag. How elegant is that? And the user is free to implement more fancy logic by himself, ex.: gulp task1 --args-for-task1 task2 --args-for-task2. To avoid breaking existing scripts (gulp task1 task2 --series) it could be enabled in .gulp.js:

module.exports = {
  ignoreFlagsAfterTask: true
};

dawidgarus avatar Oct 06 '19 19:10 dawidgarus

I'm not enjoying this pushy tone. We've given some solutions and possible future enhancements. I'm sorry if that is not sufficient.

As for any questions about why arguments are parsed in a specific manner, please go ask yargs. We use them for all argument parsing and I'm sure they have a reason for it.

phated avatar Oct 06 '19 19:10 phated

I'm sorry if my opinion came up as pushy. I've presented constructive criticism of proposed solutions, which highlighted flaws (some of which are majorly inconvenient) in those solutions, how to improve upon then and a viable alternative. Just because certain parser works in specific manner it doesn't mean it cannot be changed. It should be possible to make it work yargs: require('yargs')(preprocessArgs(process.args)).argv

EDIT: it's worth to mention that this is similar how node command works: node [options] script [arguments]. node --help script.js is different than node script.js --help, so it wouldn't odd behavior. On the contrary - quite familiar and natural for node users.

dawidgarus avatar Oct 06 '19 20:10 dawidgarus

@dawidgarus I'm sorry about my bad idea. Your point is just the reason I hadn't presented in the past.

BTW, I have a question about your idea. Gulp can combine multiple tasks with series or parallel. Moreover, default task can be called without task name. In these case, how will arguments be passed to the specific child tasks?

sttk avatar Oct 07 '19 13:10 sttk

In addition, if we support arguments for tasks, we might need to consider about passing them to tasks via .gulp.js, too.

sttk avatar Oct 07 '19 13:10 sttk

Personally, I would leave it up to the users. They still have access full list of arguments via process.args and they could parse it however they want.

dawidgarus avatar Oct 07 '19 15:10 dawidgarus

@dawidgarus I've understood. To place a flag after a task name does not mean that the task just before uses the flag but that Gulp just ignores the flag. I'm sorry that my understanding is late.

Since I sometimes add a flag after task names, I want a flag in .gulp.js to switch supporting this feature or not. However, unfortunately, it's difficult because Gulp parses CLI arguments before loading .gulp.js.

Based on that, now I think @phated's idea, Gulp ignores flags after --, is better. This is possible to change by using your preprocessArgs. Or it's also better to add another special flag if we should not change the meaning of --.

sttk avatar Oct 12 '19 03:10 sttk

Based on that, now I think @phated's idea, Gulp ignores flags after --, is better. This is possible to change by using your preprocessArgs. Or it's also better to add another special flag if we should not change the meaning of --.

Agreed. -- is a widely adopted convention, including in unix shells, Python's standard library, and npm.

>> npm run-script --help
npm run-script <command> [-- <args>...]

Personally, I would leave it up to the users. They still have access full list of arguments via process.args and they could parse it however they want.

I agree, but there are situations where this cannot be done given gulp's current parsing scheme (If there is, please let me know 😄 ). For example a gulp task cannot print its own help text because gulp will intercept, print gulp's help text, then and exit before invoking the task.

If gulp were to recognize -- as a delimiter between options and arguments, it could ignore everything after --. The task could still process the full process.argv, with the -- and everything.

cs01 avatar Apr 20 '20 17:04 cs01