Skip to content
New issue

Have a question about this project? Sign up for a free GitHub account to open an issue and contact its maintainers and the community.

By clicking “Sign up for GitHub”, you agree to our terms of service and privacy statement. We’ll occasionally send you account related emails.

Already on GitHub? Sign in to your account

gulp treats flags after -- as task names #2383

Open
dawidgarus opened this issue Oct 1, 2019 · 13 comments
Open

gulp treats flags after -- as task names #2383

dawidgarus opened this issue Oct 1, 2019 · 13 comments

Comments

@dawidgarus
Copy link

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

@phated
Copy link
Member

phated commented Oct 1, 2019

(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.

@sttk
Copy link
Contributor

sttk commented Oct 2, 2019

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.

@dawidgarus
Copy link
Author

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.

@sttk
Copy link
Contributor

sttk commented Oct 4, 2019

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.

@phated
Copy link
Member

phated commented Oct 5, 2019

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!

@dawidgarus
Copy link
Author

@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
};

@phated
Copy link
Member

phated commented Oct 6, 2019

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.

@dawidgarus
Copy link
Author

dawidgarus commented Oct 6, 2019

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.

@sttk
Copy link
Contributor

sttk commented Oct 7, 2019

@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
Copy link
Contributor

sttk commented Oct 7, 2019

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

@dawidgarus
Copy link
Author

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.

@sttk
Copy link
Contributor

sttk commented Oct 12, 2019

@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 --.

@cs01
Copy link

cs01 commented Apr 20, 2020

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.

Sign up for free to join this conversation on GitHub. Already have an account? Sign in to comment
Projects
Status: No status
Development

No branches or pull requests

4 participants