-
-
Notifications
You must be signed in to change notification settings - Fork 9.6k
[Console] Support binary / negatable options #26292
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
Conversation
….g. --foo and --no-foo.
I've looked at the implementation, it looks like this feature is handled in the "handling" side. It seems to me that this (nice feature) is richer way to define an option. In that trail of thought it would seem logical to move the implementation of this to the input side. A possible place for this would be the For the feature itself, I really like it. A definite DX improvement 👍 |
Registering two versions of an option is how Symfony handles To this end, having separate input definitions for the positive and negative values as we do today makes it more difficult to make this work. See #24314. |
@frankdejonge I thought of a way to implement your suggestion.
This means that you would still define just one InputOption, as you suggested. Perhaps this is what you intended all along, and I simply did not understand. I was thinking that having two InputOptions would get in the way of the configuration system; however, if the negated option was merely a reflection of the primary InputOption, then your configuration could define either I'll update the PR here to reflect this idea. |
…rrayInput classes to InputOption class. Make InputDefinition handle negative options by creating a NegatedInputOption.
@frankdejonge I pushed a new commit that reimplements this feature as selected above. One challenge with this approach is that originally, the input object did not ask the input definition to process the value in any way. Instead, the handling of each option was hardcoded in ArgvInput, with similar logic duplicated in ArrayInput. To get around this, I refactored the code somewhat so that both ArgvInput and ArrayInput pass their value through the InputOption. Doing this also provided the opportunity to reduce some duplicate code in these classes. The result does work just fine, and has some benefits, but I am ambivalent about which implementation is preferable. The new methods checkValue and effectiveName are perhaps not optimal. (Suggestions for better names for these methods gladly accepted.) In the end, it does not matter to me how this is implemented, as long as the final result works. If this version is not an improvement, we can try something else, or perhaps just revert to a8ad2be. |
Status: needs work |
I was holding off on fixing the tests and documentation pending feedback on the implementation approach. Since there has been no further feedback there, I'll move forward with the rest of the work. |
There was a problem hiding this comment.
Choose a reason for hiding this comment
The reason will be displayed to describe this comment to others. Learn more.
I've done a quick code review and made some minor comments along the way. This feature is really nice. Would love to have it in 4.4 :)
@@ -200,4 +194,20 @@ public function getStream() | ||
{ | ||
return $this->stream; | ||
} | ||
|
||
/** | ||
* Look up the option definition for the given option name. |
There was a problem hiding this comment.
Choose a reason for hiding this comment
The reason will be displayed to describe this comment to others. Learn more.
Looks
/** | ||
* Look up the option definition for the given option name. | ||
* | ||
* @param string $name |
There was a problem hiding this comment.
Choose a reason for hiding this comment
The reason will be displayed to describe this comment to others. Learn more.
As this would target 4.4, you can use type hints instead of phpdocs.
@@ -106,6 +110,11 @@ public function getName() | ||
return $this->name; | ||
} | ||
|
||
public function effectiveName() |
There was a problem hiding this comment.
Choose a reason for hiding this comment
The reason will be displayed to describe this comment to others. Learn more.
Should probably be getEffectiveName()
instead.
The wonder about the negatable option allowing I agree that we need better support for different console argument/option types.
|
I'm wondering the exact use case. Also, would it allow things like |
In Drush, it is possible to change the default value for any commandline option of any command by adding a configuration value to the drush.yml config file. This is supported by the package consolidation/config, which can be used with any Symfony Console program. (Note also that consolidation/config provides features orthoganal to symfony/config, and the two packages may be used together.) The current implementation works fine for everything except binary options. Binary options do not work, because The main requirement for this PR, then, is for
Generally speaking, binary commandline options do not take values, so |
Oh, and regarding the question of whether conflicting binary options such as Any behavior would be okay, though, as long as it is consistent and documented. |
Another use case for allowing both |
We've just moved away from |
…nderson, jderusse) This PR was merged into the 5.3-dev branch. Discussion ---------- [Console] Support binary / negatable options | Q | A | ------------- | --- | Branch? | 5.x | Bug fix? | no | New feature? | yes | Deprecations? | no | Tickets | Fix #24314 | License | MIT | Doc PR | TODO This PR take over #26292 to introduce a new option mode `NEGATABLE` that ease creation of option and their negation (ie. `--foo`, `--no-foo`) Negated options applies only to flag options (`VALUE_NONE`) ``` ./cli.php --foo var_dump(getOption('foo')); // true ./cli.php --no-foo var_dump(getOption('foo')); // false ``` Commits ------- 1a9a3c3 Implement negatable option 8d455db [WIP] Implements #24314: Support binary / negatable options, e.g. --foo and --no-foo.
e.g. --foo and --no-foo.
Work-in-progress.
Hoping for some feedback here before updating tests and docs, so that I do not need to do that twice.
The implementation here is slightly more capable than the description in the original issue (#24314). Two new InputOption constants are added:
This allows for flexible use of the negatable option.
true
,false
ornull
(the last differentiates between --foo, --no-foo, and no option specifice)--browser=firefox
or--no-browser
to clear, otherwise returns a default likechrome
--foo=bar
or--no-foo
are accepted, but--foo
throws an exceptionI can fine-tune this further if different behavior is desired.