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

Add explicit support for #[Command], #[Hook], and more PHP8 Attributes #223

Merged
merged 39 commits into from
Sep 10, 2021

Conversation

weitzman
Copy link
Member

@weitzman weitzman commented Jul 26, 2021

Also adds php8 constructor properties to help IDE complete attribute names.

Needed for drush-ops/drush#4798

Disposition

This pull request:

  • Fixes a bug
  • Adds a feature
  • Breaks backwards compatibility
  • Has tests that cover changes

@codecov
Copy link

codecov bot commented Jul 26, 2021

Codecov Report

Merging #223 (792caa7) into main (6c15959) will increase coverage by 0.02%.
The diff coverage is 100.00%.

Impacted file tree graph

@@             Coverage Diff              @@
##               main     #223      +/-   ##
============================================
+ Coverage     89.74%   89.76%   +0.02%     
+ Complexity      741      731      -10     
============================================
  Files            45       45              
  Lines          1921     1896      -25     
============================================
- Hits           1724     1702      -22     
+ Misses          197      194       -3     
Impacted Files Coverage Δ
src/Parser/CommandInfo.php 98.46% <100.00%> (+1.20%) ⬆️
src/Parser/Internal/AttributesDocBlockParser.php 100.00% <100.00%> (ø)

Continue to review full report at Codecov.

Legend - Click here to learn more
Δ = absolute <relative> (impact), ø = not affected, ? = missing data
Powered by Codecov. Last update 6c15959...792caa7. Read the comment docs.

@weitzman weitzman changed the title Add support for command and hook as attributes Add expicit support for command, hook and lots more attributes Jul 27, 2021
@weitzman weitzman changed the title Add expicit support for command, hook and lots more attributes Add explicit support for command, hook and lots more attributes Jul 28, 2021
Copy link

@beejeebus beejeebus left a comment

Choose a reason for hiding this comment

The reason will be displayed to describe this comment to others. Learn more.

:shipit:

@weitzman
Copy link
Member Author

weitzman commented Jul 30, 2021

I'm happy to proceed with this PR, but I have a feeling we will want to end up with multiple annotations on a method, not a single CommandLineAttributes with many properties. For example, see Doctrine.

@beejeebus
Copy link

ah, interesting.

@greg-1-anderson
Copy link
Member

greg-1-anderson commented Aug 27, 2021

At first I thought that having a lot of distinct attributes wouldn't be good, but after looking at the Doctrine example, maybe it's better that way. It has the added advantage of not requiring the use of multi-line attributes, although in truth I don't think we'd ever want to encourage people to write commands that used BOTH docblocks AND attributes at the same time, so that's maybe not a huge factor.

Maybe something like this:

    #[CLI\Command(name: 'my:echo', aliases: ['c', 'd'])]
    #[CLI\Description(text: "This is the my:echo command")]
    #[CLI\Options(list: ['flip', 'encrypt')]
    public function myEcho($one, $two = '', $flip = false, $encrypt = false) {
        ....    
    }

Or, equivalently:

    #[CLI\Command(name: 'my:echo', aliases: ['c', 'd'])]
    #[CLI\Description(text: "This is the my:echo command")]
    #[CLI\Options(list: ['flip' => false, 'encrypt' => false)]
    public function myEcho(InputInterface $input, $one, $two) {
        $flip = $input->getOption('flip');
        $encrypt = $input->getOption('encrypt');
    }

Can we have multiple instances of the same attribute, e.g. if we wanted multiple CLI\Option()] attributes instead of one CLI\Options()] attribute? I am not at all sold on what the specific required attribute or structures thereof should be, but I think that for the most part, if we start splitting things apart, we'd usually want one attribute for one type of datum. There can be some exceptions, for example, like putting both the name and the aliases in the CLI\Command attribute, since these are both related to "what you call it".

@greg-1-anderson
Copy link
Member

Oh, and getting rid of the $options array (optionally, for BC) is something I've wanted to do for a long time, but that can be a separate effort from this PR. The second form, with InputInterface, should already work.

@greg-1-anderson
Copy link
Member

I fixed up the handling of options in the attribute parser, so that they may now be passed as ordinary method parameters. See #230

@greg-1-anderson
Copy link
Member

I realize that my CLI\Options example isn't good, as the option attributes should name the option and provide its description, not its default value.

@greg-1-anderson
Copy link
Member

I did a non-definitive test. I think that the example below would probably work:

    #[CLI\Command(name: 'my:echo', aliases: ['c', 'd'])]
    #[CLI\Description(text: "This is the my:echo command")]
    #[CLI\Option(name: 'flip', description: 'Reverse the order of the output')]
    #[CLI\Option(name: 'encrypt', description: 'Encrypt the output with a key no one knows')]
    public function myEcho($one, $two = '', $flip = false, $encrypt = false) {
        ....    
    }

@weitzman
Copy link
Member Author

weitzman commented Sep 5, 2021

AnnotatedCommandFactoryTest is more thorough than AttributesCommandFactoryTest. I think a followup could refactor so we get same assertions in each.

@weitzman
Copy link
Member Author

weitzman commented Sep 5, 2021

With this latest push, Attribute classes have a handle method which alters CommandInfo as needed. This is nice and clean IMO. The AttributeParser hardly does anything at all.

@weitzman weitzman changed the title Add explicit support for command, hook and lots more attributes Add explicit support for #]Command], #[Hook], and more PHP8 Attributes Sep 6, 2021
@weitzman weitzman changed the title Add explicit support for #]Command], #[Hook], and more PHP8 Attributes Add explicit support for #[Command], #[Hook], and more PHP8 Attributes Sep 6, 2021

public static function handle(\ReflectionAttribute $attribute, CommandInfo $commandInfo)
{
$commandInfo->addAnnotation(static::NAME, null);
Copy link
Member

Choose a reason for hiding this comment

The reason will be displayed to describe this comment to others. Learn more.

This is an example attribute, not a general-purpose attribute, I suppose?

Copy link
Member Author

Choose a reason for hiding this comment

The reason will be displayed to describe this comment to others. Learn more.

Its a base class. Its used by https://github.com/drush-ops/drush/pull/4821/files#diff-2a2e5ff65cd12399a0f627fc3881b2445974d8e0717fcb4f0c894c09fe4681de, for example. I renamed to NoArgumentsBase and made it abstract. This class is not used by AC so it could easily move to Drush if preferred.

Copy link
Member

@greg-1-anderson greg-1-anderson left a comment

Choose a reason for hiding this comment

The reason will be displayed to describe this comment to others. Learn more.

Looks pretty neat, just a couple style comments.

Copy link
Member

@greg-1-anderson greg-1-anderson left a comment

Choose a reason for hiding this comment

The reason will be displayed to describe this comment to others. Learn more.

OK to merge after removing or explaining NoArgumentsBase

@weitzman weitzman merged commit e99c65c into main Sep 10, 2021
@weitzman weitzman deleted the attributes-command-hook branch September 10, 2021 04:32
@weitzman weitzman mentioned this pull request Apr 2, 2024
Sign up for free to join this conversation on GitHub. Already have an account? Sign in to comment
Labels
None yet
Projects
None yet
Development

Successfully merging this pull request may close these issues.

3 participants