Movatterモバイル変換


[0]ホーム

URL:


Skip to content

Navigation Menu

Sign in
Appearance settings

Search code, repositories, users, issues, pull requests...

Provide feedback

We read every piece of feedback, and take your input very seriously.

Saved searches

Use saved searches to filter your results more quickly

Sign up
Appearance settings

Commit39fab1f

Browse files
[Console] enable describing commands in ways that makes thelist command lazy
1 parent28533aa commit39fab1f

File tree

5 files changed

+320
-6
lines changed

5 files changed

+320
-6
lines changed

‎src/Symfony/Component/Console/CHANGELOG.md‎

Lines changed: 4 additions & 2 deletions
Original file line numberDiff line numberDiff line change
@@ -4,8 +4,10 @@ CHANGELOG
44
5.3
55
---
66

7-
* Added`GithubActionReporter` to render annotations in a Github Action
8-
* Added`InputOption::VALUE_NEGATABLE` flag to handle`--foo`/`--no-foo` options.
7+
* Add`GithubActionReporter` to render annotations in a Github Action
8+
* Add`InputOption::VALUE_NEGATABLE` flag to handle`--foo`/`--no-foo` options
9+
* Add the`Command::$defaultDescription` static property and the`description` attribute
10+
on the`console.command` tag to allow the`list` command to instantiate commands lazily
911

1012
5.2.0
1113
-----

‎src/Symfony/Component/Console/Command/Command.php‎

Lines changed: 22 additions & 1 deletion
Original file line numberDiff line numberDiff line change
@@ -39,6 +39,11 @@ class Command
3939
*/
4040
protectedstatic$defaultName;
4141

42+
/**
43+
* @var string|null The default command description
44+
*/
45+
protectedstatic$defaultDescription;
46+
4247
private$application;
4348
private$name;
4449
private$processTitle;
@@ -65,6 +70,17 @@ public static function getDefaultName()
6570
return$class ===$r->class ?static::$defaultName :null;
6671
}
6772

73+
/**
74+
* @return string|null The default command description or null when no default description is set
75+
*/
76+
publicstaticfunctiongetDefaultDescription(): ?string
77+
{
78+
$class =static::class;
79+
$r =new \ReflectionProperty($class,'defaultDescription');
80+
81+
return$class ===$r->class ?static::$defaultDescription :null;
82+
}
83+
6884
/**
6985
* @param string|null $name The name of the command; passing null means it must be set in configure()
7086
*
@@ -298,6 +314,8 @@ public function setCode(callable $code)
298314
* This method is not part of public API and should not be used directly.
299315
*
300316
* @param bool $mergeArgs Whether to merge or not the Application definition arguments to Command definition arguments
317+
*
318+
* @internal
301319
*/
302320
publicfunctionmergeApplicationDefinition(bool$mergeArgs =true)
303321
{
@@ -554,11 +572,14 @@ public function getProcessedHelp()
554572
*/
555573
publicfunctionsetAliases(iterable$aliases)
556574
{
575+
$list = [];
576+
557577
foreach ($aliasesas$alias) {
558578
$this->validateName($alias);
579+
$list[] =$alias;
559580
}
560581

561-
$this->aliases =$aliases;
582+
$this->aliases =\is_array($aliases) ?$aliases :$list;
562583

563584
return$this;
564585
}
Lines changed: 207 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -0,0 +1,207 @@
1+
<?php
2+
3+
/*
4+
* This file is part of the Symfony package.
5+
*
6+
* (c) Fabien Potencier <fabien@symfony.com>
7+
*
8+
* For the full copyright and license information, please view the LICENSE
9+
* file that was distributed with this source code.
10+
*/
11+
12+
namespaceSymfony\Component\Console\Command;
13+
14+
useSymfony\Component\Console\Application;
15+
useSymfony\Component\Console\Helper\HelperSet;
16+
useSymfony\Component\Console\Input\InputDefinition;
17+
useSymfony\Component\Console\Input\InputInterface;
18+
useSymfony\Component\Console\Output\OutputInterface;
19+
20+
/**
21+
* @author Nicolas Grekas <p@tchwork.com>
22+
*/
23+
finalclass LazyCommandextends Command
24+
{
25+
private$command;
26+
private$isEnabled;
27+
28+
publicfunction__construct(string$name,array$aliases,string$description,bool$isHidden,\Closure$commandFactory, ?bool$isEnabled =true)
29+
{
30+
$this->setName($name);
31+
$this->setAliases($aliases);
32+
$this->setHidden($isHidden);
33+
$this->setDescription($description);
34+
$this->command =$commandFactory;
35+
$this->isEnabled =$isEnabled;
36+
}
37+
38+
publicfunctionignoreValidationErrors():void
39+
{
40+
$this->getCommand()->ignoreValidationErrors();
41+
}
42+
43+
publicfunctionsetApplication(Application$application =null):void
44+
{
45+
if ($this->commandinstanceof parent) {
46+
$this->command->setApplication($application);
47+
}
48+
49+
parent::setApplication($application);
50+
}
51+
52+
publicfunctionsetHelperSet(HelperSet$helperSet):void
53+
{
54+
if ($this->commandinstanceof parent) {
55+
$this->command->setHelperSet($helperSet);
56+
}
57+
58+
parent::setHelperSet($helperSet);
59+
}
60+
61+
publicfunctionisEnabled():bool
62+
{
63+
return$this->isEnabled ??$this->getCommand()->isEnabled();
64+
}
65+
66+
publicfunctionrun(InputInterface$input,OutputInterface$output):int
67+
{
68+
return$this->getCommand()->run($input,$output);
69+
}
70+
71+
/**
72+
* @return $this
73+
*/
74+
publicfunctionsetCode(callable$code):self
75+
{
76+
$this->getCommand()->setCode($code);
77+
78+
return$this;
79+
}
80+
81+
/**
82+
* @internal
83+
*/
84+
publicfunctionmergeApplicationDefinition(bool$mergeArgs =true):void
85+
{
86+
$this->getCommand()->mergeApplicationDefinition($mergeArgs);
87+
}
88+
89+
/**
90+
* @return $this
91+
*/
92+
publicfunctionsetDefinition($definition):self
93+
{
94+
$this->getCommand()->setDefinition($definition);
95+
96+
return$this;
97+
}
98+
99+
publicfunctiongetDefinition():InputDefinition
100+
{
101+
return$this->getCommand()->getDefinition();
102+
}
103+
104+
publicfunctiongetNativeDefinition():InputDefinition
105+
{
106+
return$this->getCommand()->getNativeDefinition();
107+
}
108+
109+
/**
110+
* @return $this
111+
*/
112+
publicfunctionaddArgument(string$name,int$mode =null,string$description ='',$default =null):self
113+
{
114+
$this->getCommand()->addArgument($name,$mode,$description,$default);
115+
116+
return$this;
117+
}
118+
119+
/**
120+
* @return $this
121+
*/
122+
publicfunctionaddOption(string$name,$shortcut =null,int$mode =null,string$description ='',$default =null):self
123+
{
124+
$this->getCommand()->addOption($name,$shortcut,$mode,$description,$default);
125+
126+
return$this;
127+
}
128+
129+
/**
130+
* @return $this
131+
*/
132+
publicfunctionsetProcessTitle(string$title):self
133+
{
134+
$this->getCommand()->setProcessTitle($title);
135+
136+
return$this;
137+
}
138+
139+
/**
140+
* @return $this
141+
*/
142+
publicfunctionsetHelp(string$help):self
143+
{
144+
$this->getCommand()->setHelp($help);
145+
146+
return$this;
147+
}
148+
149+
publicfunctiongetHelp():string
150+
{
151+
return$this->getCommand()->getHelp();
152+
}
153+
154+
publicfunctiongetProcessedHelp():string
155+
{
156+
return$this->getCommand()->getProcessedHelp();
157+
}
158+
159+
publicfunctiongetSynopsis(bool$short =false):string
160+
{
161+
return$this->getCommand()->getSynopsis($short);
162+
}
163+
164+
/**
165+
* @return $this
166+
*/
167+
publicfunctionaddUsage(string$usage):self
168+
{
169+
$this->getCommand()->addUsage($usage);
170+
171+
return$this;
172+
}
173+
174+
publicfunctiongetUsages():array
175+
{
176+
return$this->getCommand()->getUsages();
177+
}
178+
179+
/**
180+
* @return mixed
181+
*/
182+
publicfunctiongetHelper(string$name)
183+
{
184+
return$this->getCommand()->getHelper($name);
185+
}
186+
187+
publicfunctiongetCommand():parent
188+
{
189+
if (!$this->commandinstanceof \Closure) {
190+
return$this->command;
191+
}
192+
193+
$command =$this->command = ($this->command)();
194+
$command->setApplication($this->getApplication());
195+
196+
if (null !==$this->getHelperSet()) {
197+
$command->setHelperSet($this->getHelperSet());
198+
}
199+
200+
$command->setName($this->getName());
201+
$command->setAliases($this->getAliases());
202+
$command->setHidden($this->isHidden());
203+
$command->setDescription($this->getDescription());
204+
205+
return$command;
206+
}
207+
}

‎src/Symfony/Component/Console/DependencyInjection/AddConsoleCommandPass.php‎

Lines changed: 39 additions & 3 deletions
Original file line numberDiff line numberDiff line change
@@ -12,11 +12,14 @@
1212
namespaceSymfony\Component\Console\DependencyInjection;
1313

1414
useSymfony\Component\Console\Command\Command;
15+
useSymfony\Component\Console\Command\LazyCommand;
1516
useSymfony\Component\Console\CommandLoader\ContainerCommandLoader;
17+
useSymfony\Component\DependencyInjection\Argument\ServiceClosureArgument;
1618
useSymfony\Component\DependencyInjection\Compiler\CompilerPassInterface;
1719
useSymfony\Component\DependencyInjection\Compiler\ServiceLocatorTagPass;
1820
useSymfony\Component\DependencyInjection\ContainerBuilder;
1921
useSymfony\Component\DependencyInjection\Exception\InvalidArgumentException;
22+
useSymfony\Component\DependencyInjection\Reference;
2023
useSymfony\Component\DependencyInjection\TypedReference;
2124

2225
/**
@@ -52,15 +55,22 @@ public function process(ContainerBuilder $container)
5255
$class =$container->getParameterBag()->resolveValue($definition->getClass());
5356

5457
if (isset($tags[0]['command'])) {
55-
$commandName =$tags[0]['command'];
58+
$aliases =$tags[0]['command'];
5659
}else {
5760
if (!$r =$container->getReflectionClass($class)) {
5861
thrownewInvalidArgumentException(sprintf('Class "%s" used for service "%s" cannot be found.',$class,$id));
5962
}
6063
if (!$r->isSubclassOf(Command::class)) {
6164
thrownewInvalidArgumentException(sprintf('The service "%s" tagged "%s" must be a subclass of "%s".',$id,$this->commandTag, Command::class));
6265
}
63-
$commandName =$class::getDefaultName();
66+
$aliases =$class::getDefaultName();
67+
}
68+
69+
$aliases =explode('|',$aliases);
70+
$commandName =array_shift($aliases);
71+
72+
if ($isHidden ='' ===$commandName) {
73+
$commandName =array_shift($aliases);
6474
}
6575

6676
if (null ===$commandName) {
@@ -74,23 +84,49 @@ public function process(ContainerBuilder $container)
7484
continue;
7585
}
7686

87+
$description =$tags[0]['description'] ??null;
88+
7789
unset($tags[0]);
7890
$lazyCommandMap[$commandName] =$id;
7991
$lazyCommandRefs[$id] =newTypedReference($id,$class);
80-
$aliases = [];
8192

8293
foreach ($tagsas$tag) {
8394
if (isset($tag['command'])) {
8495
$aliases[] =$tag['command'];
8596
$lazyCommandMap[$tag['command']] =$id;
8697
}
98+
99+
$description =$description ??$tag['description'] ??null;
87100
}
88101

89102
$definition->addMethodCall('setName', [$commandName]);
90103

91104
if ($aliases) {
92105
$definition->addMethodCall('setAliases', [$aliases]);
93106
}
107+
108+
if ($isHidden) {
109+
$definition->addMethodCall('setHidden', [true]);
110+
}
111+
112+
if (!$description) {
113+
if (!$r =$container->getReflectionClass($class)) {
114+
thrownewInvalidArgumentException(sprintf('Class "%s" used for service "%s" cannot be found.',$class,$id));
115+
}
116+
if (!$r->isSubclassOf(Command::class)) {
117+
thrownewInvalidArgumentException(sprintf('The service "%s" tagged "%s" must be a subclass of "%s".',$id,$this->commandTag, Command::class));
118+
}
119+
$description =$class::getDefaultDescription();
120+
}
121+
122+
if ($description) {
123+
$definition->addMethodCall('setDescription', [$description]);
124+
125+
$container->register('.'.$id.'.lazy', LazyCommand::class)
126+
->setArguments([$commandName,$aliases,$description,$isHidden,newServiceClosureArgument($lazyCommandRefs[$id])]);
127+
128+
$lazyCommandRefs[$id] =newReference('.'.$id.'.lazy');
129+
}
94130
}
95131

96132
$container

0 commit comments

Comments
 (0)

[8]ページ先頭

©2009-2025 Movatter.jp