Skip to content

[Console] Allow commands to provide a default name for compile time registration #23887

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

Merged
merged 2 commits into from
Aug 24, 2017

Conversation

chalasr
Copy link
Member

@chalasr chalasr commented Aug 14, 2017

Q A
Branch? 3.4
Bug fix? no
New feature? yes
BC breaks? no
Deprecations? no
Tests pass? yes
Fixed tickets #23796
License MIT
Doc PR symfony/symfony-docs#8147

Copy link
Member

@nicolas-grekas nicolas-grekas left a comment

Choose a reason for hiding this comment

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

Would it make sense to use psr4+this to register existing commands?

$commandName = $tags[0]['command'];
if (!isset($tags[0]['command'])) {
$defaultNameProvider = array($class, 'getDefaultName');
$commandName = $defaultNameProvider();
Copy link
Member

Choose a reason for hiding this comment

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

$class::getDefaultName()

Copy link
Member Author

Choose a reason for hiding this comment

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

Fixed

@chalasr chalasr force-pushed the console-default-name branch from c7f9137 to ba4be99 Compare August 14, 2017 17:22
@chalasr
Copy link
Member Author

chalasr commented Aug 14, 2017

@nicolas-grekas That would require to make them autowired, right?

@nicolas-grekas
Copy link
Member

Correct, bad idea :)

@chalasr chalasr force-pushed the console-default-name branch 2 times, most recently from 2658662 to bd71187 Compare August 16, 2017 08:01
@@ -55,7 +56,7 @@ public function process(ContainerBuilder $container)

$commandId = 'console.command.'.strtolower(str_replace('\\', '_', $class));

if (!isset($tags[0]['command'])) {
if (!isset($tags[0]['command']) && !$r->implementsInterface(DefaultNameProviderInterface::class)) {
Copy link
Contributor

Choose a reason for hiding this comment

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

Should we deprecate this behavior?

Copy link
Member Author

Choose a reason for hiding this comment

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

That would mean deprecating non-lazy command services, deserves a dedicated discussion I think

Copy link
Contributor

@ro0NL ro0NL Aug 16, 2017

Choose a reason for hiding this comment

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

Hm right. Could application as a service be a next step? So we can simply wire via add method call.

Copy link
Member

@nicolas-grekas nicolas-grekas Aug 16, 2017

Choose a reason for hiding this comment

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

We should stop here IMHO. We don't do changes for the sake of it, so that if we force people to move on, the benefit must be clear.

Copy link
Contributor

Choose a reason for hiding this comment

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

Sure. Just saying we can then cleanly wire commands, the command loader etc. The benefit would be its more flexible and allows injecting the application elsewhere... that may be useful.

interface DefaultNameProviderInterface
{
/**
* @return string The name to which register the implementing Command
Copy link
Member

Choose a reason for hiding this comment

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

The name to use by default for calling the Command

Copy link
Member Author

Choose a reason for hiding this comment

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

Thanks

@chalasr chalasr force-pushed the console-default-name branch from bd71187 to 5d9ae6b Compare August 16, 2017 19:45
@nicolas-grekas
Copy link
Member

nicolas-grekas commented Aug 21, 2017

What about making it easier to define the default name of a command, by asking people to just fill in a
protected static $defaultName?

Here is a commit doing this to see what it could look like: 05c922a

Note that this also "fixes" an issue with inheritance, where the return value of getDefaultName() can be provided by the parent class, which usually is not desired. This also means we could just remove the interface btw.

@ogizanagi
Copy link
Contributor

Note that this also "fixes" an issue with inheritance, where the return value of getDefaultName() can be provided by the parent class, which usually is not desired. This also means we could just remove the interface btw.

This is enough to convince me 👍

@chalasr chalasr force-pushed the console-default-name branch from 106f353 to 7784b1b Compare August 21, 2017 11:22
@@ -29,6 +29,8 @@
*/
class Command
{
protected static $defaultName;
Copy link
Member

Choose a reason for hiding this comment

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

a docblock here to help people discover how this can be leveraged, and all good on my side

@@ -55,7 +55,7 @@ public function process(ContainerBuilder $container)

$commandId = 'console.command.'.strtolower(str_replace('\\', '_', $class));

if (!isset($tags[0]['command'])) {
if (!isset($tags[0]['command']) && !$commandName = $class::getDefaultName()) {
Copy link
Contributor

Choose a reason for hiding this comment

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

&& null === $commandName = ... ?

Copy link
Member

Choose a reason for hiding this comment

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

so, what should happen when $commandName === '' ? Registering the empty string is a no-go to me. As is LGTM.

Copy link
Contributor

Choose a reason for hiding this comment

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

an empty string would give the expected unexpected result :) "0" could be a valid name. Anyway... this is nitpicking; fine asis for me 👍

Copy link
Member

Choose a reason for hiding this comment

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

Supporting the 0 command name will be asked by @Tobion anyway 😂, so let's support it now.

@@ -46,6 +48,17 @@ class Command
private $helperSet;

/**
* @return string|null The name to use by default for calling the Command or null when no default name is set
*/
public static function getDefaultName()
Copy link
Contributor

Choose a reason for hiding this comment

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

final?

@chalasr chalasr force-pushed the console-default-name branch 6 times, most recently from e431d33 to 96411e8 Compare August 22, 2017 11:34
@chalasr
Copy link
Member Author

chalasr commented Aug 22, 2017

@nicolas-grekas applied

@chalasr chalasr force-pushed the console-default-name branch from 3a54ff8 to eda7d42 Compare August 24, 2017 14:44
@fabpot
Copy link
Member

fabpot commented Aug 24, 2017

Thank you @chalasr.

@fabpot fabpot merged commit eda7d42 into symfony:3.4 Aug 24, 2017
fabpot added a commit that referenced this pull request Aug 24, 2017
… compile time registration (chalasr, nicolas-grekas)

This PR was merged into the 3.4 branch.

Discussion
----------

[Console] Allow commands to provide a default name for compile time registration

| Q             | A
| ------------- | ---
| Branch?       | 3.4
| Bug fix?      | no
| New feature?  | yes
| BC breaks?    | no
| Deprecations? | no
| Tests pass?   | yes
| Fixed tickets | #23796
| License       | MIT
| Doc PR        | symfony/symfony-docs#8147

Commits
-------

eda7d42 [Console] Add protected static $defaultName to set the default name of a Command
5d9ae6b [Console] Allow commands to provide a default name for compile time registration
@chalasr chalasr deleted the console-default-name branch August 24, 2017 21:11
@mvrhov
Copy link

mvrhov commented Sep 30, 2017

Just in case I'm missing something.
Defining the name in the variable and having command registered as service shouldn't create command even in 3.4?
I'm asking this because if I put die in a constructor of a command registered as a service then everything dies and this means that the command is not lazily loaded.

@chalasr
Copy link
Member Author

chalasr commented Oct 6, 2017

@mvrhov Just tried and no issue on my side. Defining this property and registering the command as a console.command tagged service (nothing to configure with the new default config) is enough to make it loaded lazily, meaning that you can execute any other command without loading this one, except for list (or just bin/console) because it requires to load all commands.
Please open an issue with reproducer if you think there is a bug.

@mvrhov
Copy link

mvrhov commented Oct 6, 2017

Oh, I understood that it doesn't need to load them anymore no matter what. I've run the app/console directly when I tried that.

@stof
Copy link
Member

stof commented Oct 17, 2017

running just app/console actually runs the list command

@mvrhov
Copy link

mvrhov commented Oct 17, 2017

@stof: Yeah I know. Sorry for not being clear enough.
So I'm going to be now. Then this works. :)

This was referenced Oct 18, 2017
mbrodala added a commit to mbrodala/typo3-ext-migrations that referenced this pull request Mar 23, 2020
Due to some logic in Symfony "Command" the default name of extended
commands is not used in the extending command. So we need to copy all of
them.

See doctrine/migrations#839
And symfony/symfony#23887
lchrusciel added a commit to Sylius/Sylius that referenced this pull request Jul 17, 2020
This PR was merged into the 1.8-dev branch.

Discussion
----------

| Q               | A
| --------------- | -----
| Branch?         | master
| Bug fix?        | no
| New feature?    | no
| BC breaks?      | no
| Deprecations?   | no
| Related tickets | 
| License         | MIT

This commit is about of a little optimisation to avoid initialisation of all command services on each executing `bin/console` command.
Since Symfony 3.4 console commands can be lazy thanks to [a static name property](symfony/symfony#23887).
This change does not break BC because the BC layer is already [in the base command's constructor](https://github.com/symfony/symfony/pull/23887/files#diff-8e80595663798837db1b033187835535R75).

Commits
-------

91c9918 Make console commands lazy
o5 added a commit to slimapi/slimapi that referenced this pull request Feb 12, 2021
Sign up for free to join this conversation on GitHub. Already have an account? Sign in to comment
Projects
None yet
Development

Successfully merging this pull request may close these issues.

9 participants