-
Notifications
You must be signed in to change notification settings - Fork 11.3k
[9.x] Console: Alternative Attribute Syntax for Artisan Commands for better type support and more. #41131
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
Symfony already has an attribute for defining console commands -> symfony/symfony#40234 Can't we (re)use that? |
Definitely some good work on this but imho I believe the current mechanism to define the command signature is enough. This would add an awful lot for us to maintain. I'm personally also not a fan of attributes... |
@driesvints thank you for the feedback. Is this already a "no" for merging this? :) |
@thettler I don't merge PR's, Taylor does. Just adding my opinion. |
…es; Some Refactoring
@X-Coder264 Thanks for the Feedback. I didn't knew this Attribute already exist. I had a look but came to the conclusion that we can't simply reuse it. There are two reasons for that:
But i am open for a different opinion here. 😄 🔧 But i did changed some things:
|
Thanks for your pull request to Laravel! Unfortunately, I'm going to delay merging this code for now. To preserve our ability to adequately maintain the framework, we need to be very careful regarding the amount of code we include. If possible, please consider releasing your code as a package so that the community can still take advantage of your contributions! If you feel absolutely certain that this code corrects a bug in the framework, please "@" mention me in a follow-up comment with further explanation so that GitHub will send me a notification of your response. |
@thettler please make it a package! |
FWIW, Symfony 6.1 deprecates the |
For everybody who likes the idea i have created a Package with all of the Features i mentioned in the PR: Laravel Console ToolkitIt supports
Feel free to try it out and give me Feedback. |
🔨 What does this PR do?
This PR aims to add an alternative syntax to the artisan command signature by using attributes. It is fully backwards compatible and does not break the existing
$signature
syntax.👀 How does it look?
➕ What are the benefits?
$signature
because you get more help from the IDE and you don't need to remember the custom string syntax.➖ What are the drawbacks?
$signature
syntax especially for small commands, but of course you could still use the$signature
syntax for those commands and the attributes for more complex ones.🔮 What can be done in future?
In order to keep this PR as small as possible i only added the base functionality. But i already have a lot of ideas what can be done with this kind of syntax.
Casting
At the moment only Enum Types are casted by default. But it is easily possible to add a caster to an argument or option to directly cast a command input to an object, model ... or something else. This could look like this or it would check if the typed class implements the Castable interface.
Show
Validation
Also the Validator could be added like this:
Show
Auto Ask
It's a good practise to ask the user for a required argument if it was not provided instead of failing the command. This could be the default behaviour or can be turned on like this:
Show
🔬 How does it work?
Basically there are two differed types of attributes. The
ArtisanCommand
and theConsoleInput
.ArtisanCommand Attribute
This attribute is placed at the class level and defines the
name
,description
,help
, if the command is hidden and aliases for the command.Console Input
Console inputs are written als properties on the command class who get decorated with ether the
Argument
or theOption
attribute.Arguments
If there is a non-nullable type the argument will be required. If you want an optional argument or an argument with an default value you ether make the type nullable or add an initial value to the property
If you need an array argument simply typehint the property as array. If you want it to be optional or with a default value make it nullable or add a default.
Options
Options are pretty similar regarding the default and optional syntax. But with one catch. There are two different kinds of options, one without a value (simple boolean flags) and ones with values. The ones with Values are pretty much the same as the arguments. Nullable -> optional, With initial value -> default Value.
If you want a boolean flag option simply typehint
bool
and the value will be false if the option wasn't used and true if it was used:To use shortcuts on options you can simply specify the shortcut on the
Option
attributeIf you want to use a negatable options you can simply specify it on the
Option
attributeDescriptions
Arguments and options can have a description you can simply specify it on the attribute:
Alias
Arguments and options can be aliased to avoid conflicts with other parent properties or to make the api more readable for the user:
Enum support
Enums will be automatically be cast back and forth.
❤️ Thank you
Thank you very much for taking the time and reading this. This is my first PR to Laravel so
i am open for feedback and discussion about the syntax or implementation and happily change the PR accordingly.