-
-
Notifications
You must be signed in to change notification settings - Fork 9.4k
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
[Console][Feature Request] Required options #14716
Comments
@zerkms could you think of any existing command or application that requires you to provide options? |
@jakzal symfony requires PS: I know it can take it from environment variables as well, but still |
@zerkms it's not an example of a required option. You only need to add it if you want to run a command in mode different than the default one (for example prod). It's still optional. I was asking for an example of any command that forces you to provide an option all the time. It doesn't have to be Symfony nor php. Any command. I can't think of one, therefore I ask. |
The default one is not prod. At least in the default symfony distribution. So if in production you want to run a command you MUST specify I will think of it, but still - how lack of other commands prevents symfony from having such a feature? The other commands that require more or less sophisticated configuration use config files, while I prefer to have everything in a command line, since it's more portable and much easier to manage. |
I meant: if you want to run it in prod.
I'd prefer to be consistent with globally accepted standards. |
If you want to run it in prod you MUST ALWAYS specify
What are they? Any reference that is accepted and explicitly/implicitly followed? Again, having this feature does not mean that any of built-in commands will use it, but that developers will have more freedom |
The key here is IF ;) |
@zerkms If you are forced to specify an option all the time (hint: this is not the case for |
Most of them comes from GNU and Unix standards. Some examples:
"Option" by definition is optional, that's what distinguishes it from an argument. That's the meaning of this word, and you probably won't find it explicitly written anywhere but dictionary. |
If only you can express it as an argument (which you cannot if you need to pass 2 sets as in my original example) So guys, what stops Symfony as a general purpose framework have that and let developers to do what they want? It's an artificial limitation that does not make symfony better in any way.
If it was a standard it would be there. Now we have a set of ancient historical conventions. |
@jakzal The example of required options:
|
I can see some limited use-cases where it would make life easier if Symfony offered an option to support required options. Though I an not convinced that we should support it out if the box as it means more code that must not break while providing little value |
"Option" is OPTIONAL by default |
@salemgolemugoo it depends on how you name it. I prefer the term "parameter" The name "option" was taken from the assumption that something will stay "optional" forever, and that assumption was based on ... On what actually? It's the logic rules - the name must express the aims, not the opposite. |
@zerkms I know you suggestion makes sense in logical point of view. It's just that standard way is sometimes the best way to go to prevent many WTF issues by not following it. It's drawback per benefits. Many apps depends on standard, and we don't know how they use it. So if there is an easy manual way to do so, it's better to go with it. I've seen and made many great packages with really cool and use api methods. But they were absolutely non-standard with wast majority of others. So now they're useless and removed. They work and follow the logic still. Solution for your use case In ApiGen I made use required parameters like this. apigen generate -s ./src -d ./docs In command, delegate to options resolver. |
@TomasVotruba what "standard" you're referring to? As far as I know - there is no one. Symfony just follows a convention that someone 30 years ago decided will be a good thing. |
@zerkms By "standard" I mean "people are used to use it like this for a long time". I use sidewalks not because it's somewhere written, but because I've seen other people does it. Not because it's written somewhere. |
@TomasVotruba and my point was to implement something that is convenient, not something that is artificially limited by a 30+ years old irrational decision. We all like when our tools evolve: languages change with time - you do like php 5.6 and further php 7 don't you? And I'm sure if you were asked to use php 4.3.10 instead you wouldn't be that happy. So what is the point to keep the heritage of this? |
@zerkms You can easily implement it by yourself. |
@TomasVotruba I can do and I do myself a lot of things. This issue is a proposal to move further for the tool/community. |
I'd say that we should close this issue as "won't fix". @zerkms I agree with lots of the things you said ... but the proposed feature looks too narrow in its target. Besides, you can solve this problem by validating the options passed to the command and their values. |
@javiereguiluz I agree with you 👍 |
That's sad that the suggestion that will not break anything but will make symfony more flexible for an arbitrary use is discarded. But okay, let be it. |
If you reopen this request sometimes in the future, count me as a +1 vote. I'd like to use what is now called "options" as required named arguments in order for a command to be understandable at first sight. I have made the |
fyi you can add helper method to do this yourself, as we do in @Piwik protected function checkAllRequiredOptionsAreNotEmpty(InputInterface $input)
{
$options = $this->getDefinition()->getOptions();
foreach ($options as $option) {
$name = $option->getName();
$value = $input->getOption($name);
if ($option->isValueRequired() && empty($value)) {
throw new \InvalidArgumentException(sprintf('The required option %s is not set', $name));
}
}
} |
@mattab a minor issue in your code: the |
Good spotting @zerkms - pull request welcome :-) |
I also need required options. Fair enough not to have them by default and require a little custom code. I took the above and came up with: protected function checkAllRequiredOptionsAreNotEmpty(InputInterface $input)
{
$errors = [];
$options = $this->getDefinition()->getOptions();
foreach ($options as $option) {
$name = $option->getName();
$value = $input->getOption($name);
if ($option->isValueRequired() && ($value === null || $value === '')) {
$errors[] = sprintf('The required option --%s is not set or is empty', $name);
}
}
if (count($errors)) {
throw new \InvalidArgumentException(implode("\n\n", $errors));
}
} |
Options is NOT alway OPTIONAL, When option have value they are choices we need to select one. |
@edmondscommerce It should be like this: private function checkAllRequiredOptionsAreNotEmpty(InputInterface $input)
{
$errors = [];
$option1 = $this->getDefinition()->getOption('option1');
/** @var InputOption $option */
foreach ([$option1] as $option) {
$name = $option->getName();
$value = $input->getOption($name);
if ($value === null || $value === '' || ($option->isArray() && empty($value))) {
$errors[] = sprintf('The required option --%s is not set or is empty', $name);
}
}
if (count($errors)) {
throw new \InvalidArgumentException(implode("\n\n", $errors));
}
} |
Lack of required named parameters makes OOP in commands more clunky for no good reason... Since I disagree with your "low usage" reasoning, this simpliest example can be fairly common in well-written applications:
Using arguments for both is logically impossible, unless you call the parent after the definition, which may make the command look messy/inconsistent with other commands (e.g. Z that defines 2 required parameters) and still doesn't work with 2 required array parameters. Using option for any requires additional checks mentioned above. I hope you will reconsider this. @xabbuh @javiereguiluz |
One word comes to mind. Lazy |
One phrase comes to mind: Rename "Options" to "Named Arguments"or something like that without the |
The fact that arguments can be optional makes it hard to believe the reasoning that "options" are for optional values and arguments are better for required values. "Named arguments" is a better term, like @lenar and others suggest, and it would be nice to have this built-in. |
doesn't make it the most sense to introduce a |
I also need this. Because without that the order is relevant which can lead to manual errors. In the meantime I went with the solution provided by Piwik. |
Disclaimer: yes, I've seen #3524 and I cannot agree with it.
The problem with current implementation is that you cannot have the required options. Even though we do have required arguments it does not save us too much, since not all possible semantics can be covered with what we currently have.
Example: we need to accept a list of files and a list of processors to run against them.
We cannot use required array arguments for both since you cannot distinguish between a file name and a processor name in a reliable way.
We cannot use required array arguments and optional array options, since the options are, well, optional in this case.
So what we do is we follow either and put constraint checks manually.
So, what prevents Symfony from having required option parameters? Are there any technical reasons against that?
The text was updated successfully, but these errors were encountered: