diff options
author | polo <ordipolo@gmx.fr> | 2024-08-13 23:45:21 +0200 |
---|---|---|
committer | polo <ordipolo@gmx.fr> | 2024-08-13 23:45:21 +0200 |
commit | bf6655a534a6775d30cafa67bd801276bda1d98d (patch) | |
tree | c6381e3f6c81c33eab72508f410b165ba05f7e9c /vendor/symfony/console/Command/TraceableCommand.php | |
parent | 94d67a4b51f8e62e7d518cce26a526ae1ec48278 (diff) | |
download | AppliGestionPHP-bf6655a534a6775d30cafa67bd801276bda1d98d.zip |
VERSION 0.2 doctrine ORM et entités
Diffstat (limited to 'vendor/symfony/console/Command/TraceableCommand.php')
-rw-r--r-- | vendor/symfony/console/Command/TraceableCommand.php | 356 |
1 files changed, 356 insertions, 0 deletions
diff --git a/vendor/symfony/console/Command/TraceableCommand.php b/vendor/symfony/console/Command/TraceableCommand.php new file mode 100644 index 0000000..9ffb68d --- /dev/null +++ b/vendor/symfony/console/Command/TraceableCommand.php | |||
@@ -0,0 +1,356 @@ | |||
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 | namespace Symfony\Component\Console\Command; | ||
13 | |||
14 | use Symfony\Component\Console\Application; | ||
15 | use Symfony\Component\Console\Completion\CompletionInput; | ||
16 | use Symfony\Component\Console\Completion\CompletionSuggestions; | ||
17 | use Symfony\Component\Console\Helper\HelperInterface; | ||
18 | use Symfony\Component\Console\Helper\HelperSet; | ||
19 | use Symfony\Component\Console\Input\InputDefinition; | ||
20 | use Symfony\Component\Console\Input\InputInterface; | ||
21 | use Symfony\Component\Console\Output\ConsoleOutputInterface; | ||
22 | use Symfony\Component\Console\Output\OutputInterface; | ||
23 | use Symfony\Component\Stopwatch\Stopwatch; | ||
24 | |||
25 | /** | ||
26 | * @internal | ||
27 | * | ||
28 | * @author Jules Pietri <jules@heahprod.com> | ||
29 | */ | ||
30 | final class TraceableCommand extends Command implements SignalableCommandInterface | ||
31 | { | ||
32 | public readonly Command $command; | ||
33 | public int $exitCode; | ||
34 | public ?int $interruptedBySignal = null; | ||
35 | public bool $ignoreValidation; | ||
36 | public bool $isInteractive = false; | ||
37 | public string $duration = 'n/a'; | ||
38 | public string $maxMemoryUsage = 'n/a'; | ||
39 | public InputInterface $input; | ||
40 | public OutputInterface $output; | ||
41 | /** @var array<string, mixed> */ | ||
42 | public array $arguments; | ||
43 | /** @var array<string, mixed> */ | ||
44 | public array $options; | ||
45 | /** @var array<string, mixed> */ | ||
46 | public array $interactiveInputs = []; | ||
47 | public array $handledSignals = []; | ||
48 | |||
49 | public function __construct( | ||
50 | Command $command, | ||
51 | private readonly Stopwatch $stopwatch, | ||
52 | ) { | ||
53 | if ($command instanceof LazyCommand) { | ||
54 | $command = $command->getCommand(); | ||
55 | } | ||
56 | |||
57 | $this->command = $command; | ||
58 | |||
59 | // prevent call to self::getDefaultDescription() | ||
60 | $this->setDescription($command->getDescription()); | ||
61 | |||
62 | parent::__construct($command->getName()); | ||
63 | |||
64 | // init below enables calling {@see parent::run()} | ||
65 | [$code, $processTitle, $ignoreValidationErrors] = \Closure::bind(function () { | ||
66 | return [$this->code, $this->processTitle, $this->ignoreValidationErrors]; | ||
67 | }, $command, Command::class)(); | ||
68 | |||
69 | if (\is_callable($code)) { | ||
70 | $this->setCode($code); | ||
71 | } | ||
72 | |||
73 | if ($processTitle) { | ||
74 | parent::setProcessTitle($processTitle); | ||
75 | } | ||
76 | |||
77 | if ($ignoreValidationErrors) { | ||
78 | parent::ignoreValidationErrors(); | ||
79 | } | ||
80 | |||
81 | $this->ignoreValidation = $ignoreValidationErrors; | ||
82 | } | ||
83 | |||
84 | public function __call(string $name, array $arguments): mixed | ||
85 | { | ||
86 | return $this->command->{$name}(...$arguments); | ||
87 | } | ||
88 | |||
89 | public function getSubscribedSignals(): array | ||
90 | { | ||
91 | return $this->command instanceof SignalableCommandInterface ? $this->command->getSubscribedSignals() : []; | ||
92 | } | ||
93 | |||
94 | public function handleSignal(int $signal, int|false $previousExitCode = 0): int|false | ||
95 | { | ||
96 | if (!$this->command instanceof SignalableCommandInterface) { | ||
97 | return false; | ||
98 | } | ||
99 | |||
100 | $event = $this->stopwatch->start($this->getName().'.handle_signal'); | ||
101 | |||
102 | $exit = $this->command->handleSignal($signal, $previousExitCode); | ||
103 | |||
104 | $event->stop(); | ||
105 | |||
106 | if (!isset($this->handledSignals[$signal])) { | ||
107 | $this->handledSignals[$signal] = [ | ||
108 | 'handled' => 0, | ||
109 | 'duration' => 0, | ||
110 | 'memory' => 0, | ||
111 | ]; | ||
112 | } | ||
113 | |||
114 | ++$this->handledSignals[$signal]['handled']; | ||
115 | $this->handledSignals[$signal]['duration'] += $event->getDuration(); | ||
116 | $this->handledSignals[$signal]['memory'] = max( | ||
117 | $this->handledSignals[$signal]['memory'], | ||
118 | $event->getMemory() >> 20 | ||
119 | ); | ||
120 | |||
121 | return $exit; | ||
122 | } | ||
123 | |||
124 | /** | ||
125 | * {@inheritdoc} | ||
126 | * | ||
127 | * Calling parent method is required to be used in {@see parent::run()}. | ||
128 | */ | ||
129 | public function ignoreValidationErrors(): void | ||
130 | { | ||
131 | $this->ignoreValidation = true; | ||
132 | $this->command->ignoreValidationErrors(); | ||
133 | |||
134 | parent::ignoreValidationErrors(); | ||
135 | } | ||
136 | |||
137 | public function setApplication(?Application $application = null): void | ||
138 | { | ||
139 | $this->command->setApplication($application); | ||
140 | } | ||
141 | |||
142 | public function getApplication(): ?Application | ||
143 | { | ||
144 | return $this->command->getApplication(); | ||
145 | } | ||
146 | |||
147 | public function setHelperSet(HelperSet $helperSet): void | ||
148 | { | ||
149 | $this->command->setHelperSet($helperSet); | ||
150 | } | ||
151 | |||
152 | public function getHelperSet(): ?HelperSet | ||
153 | { | ||
154 | return $this->command->getHelperSet(); | ||
155 | } | ||
156 | |||
157 | public function isEnabled(): bool | ||
158 | { | ||
159 | return $this->command->isEnabled(); | ||
160 | } | ||
161 | |||
162 | public function complete(CompletionInput $input, CompletionSuggestions $suggestions): void | ||
163 | { | ||
164 | $this->command->complete($input, $suggestions); | ||
165 | } | ||
166 | |||
167 | /** | ||
168 | * {@inheritdoc} | ||
169 | * | ||
170 | * Calling parent method is required to be used in {@see parent::run()}. | ||
171 | */ | ||
172 | public function setCode(callable $code): static | ||
173 | { | ||
174 | $this->command->setCode($code); | ||
175 | |||
176 | return parent::setCode(function (InputInterface $input, OutputInterface $output) use ($code): int { | ||
177 | $event = $this->stopwatch->start($this->getName().'.code'); | ||
178 | |||
179 | $this->exitCode = $code($input, $output); | ||
180 | |||
181 | $event->stop(); | ||
182 | |||
183 | return $this->exitCode; | ||
184 | }); | ||
185 | } | ||
186 | |||
187 | /** | ||
188 | * @internal | ||
189 | */ | ||
190 | public function mergeApplicationDefinition(bool $mergeArgs = true): void | ||
191 | { | ||
192 | $this->command->mergeApplicationDefinition($mergeArgs); | ||
193 | } | ||
194 | |||
195 | public function setDefinition(array|InputDefinition $definition): static | ||
196 | { | ||
197 | $this->command->setDefinition($definition); | ||
198 | |||
199 | return $this; | ||
200 | } | ||
201 | |||
202 | public function getDefinition(): InputDefinition | ||
203 | { | ||
204 | return $this->command->getDefinition(); | ||
205 | } | ||
206 | |||
207 | public function getNativeDefinition(): InputDefinition | ||
208 | { | ||
209 | return $this->command->getNativeDefinition(); | ||
210 | } | ||
211 | |||
212 | public function addArgument(string $name, ?int $mode = null, string $description = '', mixed $default = null, array|\Closure $suggestedValues = []): static | ||
213 | { | ||
214 | $this->command->addArgument($name, $mode, $description, $default, $suggestedValues); | ||
215 | |||
216 | return $this; | ||
217 | } | ||
218 | |||
219 | public function addOption(string $name, string|array|null $shortcut = null, ?int $mode = null, string $description = '', mixed $default = null, array|\Closure $suggestedValues = []): static | ||
220 | { | ||
221 | $this->command->addOption($name, $shortcut, $mode, $description, $default, $suggestedValues); | ||
222 | |||
223 | return $this; | ||
224 | } | ||
225 | |||
226 | /** | ||
227 | * {@inheritdoc} | ||
228 | * | ||
229 | * Calling parent method is required to be used in {@see parent::run()}. | ||
230 | */ | ||
231 | public function setProcessTitle(string $title): static | ||
232 | { | ||
233 | $this->command->setProcessTitle($title); | ||
234 | |||
235 | return parent::setProcessTitle($title); | ||
236 | } | ||
237 | |||
238 | public function setHelp(string $help): static | ||
239 | { | ||
240 | $this->command->setHelp($help); | ||
241 | |||
242 | return $this; | ||
243 | } | ||
244 | |||
245 | public function getHelp(): string | ||
246 | { | ||
247 | return $this->command->getHelp(); | ||
248 | } | ||
249 | |||
250 | public function getProcessedHelp(): string | ||
251 | { | ||
252 | return $this->command->getProcessedHelp(); | ||
253 | } | ||
254 | |||
255 | public function getSynopsis(bool $short = false): string | ||
256 | { | ||
257 | return $this->command->getSynopsis($short); | ||
258 | } | ||
259 | |||
260 | public function addUsage(string $usage): static | ||
261 | { | ||
262 | $this->command->addUsage($usage); | ||
263 | |||
264 | return $this; | ||
265 | } | ||
266 | |||
267 | public function getUsages(): array | ||
268 | { | ||
269 | return $this->command->getUsages(); | ||
270 | } | ||
271 | |||
272 | public function getHelper(string $name): HelperInterface | ||
273 | { | ||
274 | return $this->command->getHelper($name); | ||
275 | } | ||
276 | |||
277 | public function run(InputInterface $input, OutputInterface $output): int | ||
278 | { | ||
279 | $this->input = $input; | ||
280 | $this->output = $output; | ||
281 | $this->arguments = $input->getArguments(); | ||
282 | $this->options = $input->getOptions(); | ||
283 | $event = $this->stopwatch->start($this->getName(), 'command'); | ||
284 | |||
285 | try { | ||
286 | $this->exitCode = parent::run($input, $output); | ||
287 | } finally { | ||
288 | $event->stop(); | ||
289 | |||
290 | if ($output instanceof ConsoleOutputInterface && $output->isDebug()) { | ||
291 | $output->getErrorOutput()->writeln((string) $event); | ||
292 | } | ||
293 | |||
294 | $this->duration = $event->getDuration().' ms'; | ||
295 | $this->maxMemoryUsage = ($event->getMemory() >> 20).' MiB'; | ||
296 | |||
297 | if ($this->isInteractive) { | ||
298 | $this->extractInteractiveInputs($input->getArguments(), $input->getOptions()); | ||
299 | } | ||
300 | } | ||
301 | |||
302 | return $this->exitCode; | ||
303 | } | ||
304 | |||
305 | protected function initialize(InputInterface $input, OutputInterface $output): void | ||
306 | { | ||
307 | $event = $this->stopwatch->start($this->getName().'.init', 'command'); | ||
308 | |||
309 | $this->command->initialize($input, $output); | ||
310 | |||
311 | $event->stop(); | ||
312 | } | ||
313 | |||
314 | protected function interact(InputInterface $input, OutputInterface $output): void | ||
315 | { | ||
316 | if (!$this->isInteractive = Command::class !== (new \ReflectionMethod($this->command, 'interact'))->getDeclaringClass()->getName()) { | ||
317 | return; | ||
318 | } | ||
319 | |||
320 | $event = $this->stopwatch->start($this->getName().'.interact', 'command'); | ||
321 | |||
322 | $this->command->interact($input, $output); | ||
323 | |||
324 | $event->stop(); | ||
325 | } | ||
326 | |||
327 | protected function execute(InputInterface $input, OutputInterface $output): int | ||
328 | { | ||
329 | $event = $this->stopwatch->start($this->getName().'.execute', 'command'); | ||
330 | |||
331 | $exitCode = $this->command->execute($input, $output); | ||
332 | |||
333 | $event->stop(); | ||
334 | |||
335 | return $exitCode; | ||
336 | } | ||
337 | |||
338 | private function extractInteractiveInputs(array $arguments, array $options): void | ||
339 | { | ||
340 | foreach ($arguments as $argName => $argValue) { | ||
341 | if (\array_key_exists($argName, $this->arguments) && $this->arguments[$argName] === $argValue) { | ||
342 | continue; | ||
343 | } | ||
344 | |||
345 | $this->interactiveInputs[$argName] = $argValue; | ||
346 | } | ||
347 | |||
348 | foreach ($options as $optName => $optValue) { | ||
349 | if (\array_key_exists($optName, $this->options) && $this->options[$optName] === $optValue) { | ||
350 | continue; | ||
351 | } | ||
352 | |||
353 | $this->interactiveInputs['--'.$optName] = $optValue; | ||
354 | } | ||
355 | } | ||
356 | } | ||