summaryrefslogtreecommitdiff
path: root/vendor/symfony/console/Command/TraceableCommand.php
diff options
context:
space:
mode:
authorpolo <ordipolo@gmx.fr>2024-08-13 23:45:21 +0200
committerpolo <ordipolo@gmx.fr>2024-08-13 23:45:21 +0200
commitbf6655a534a6775d30cafa67bd801276bda1d98d (patch)
treec6381e3f6c81c33eab72508f410b165ba05f7e9c /vendor/symfony/console/Command/TraceableCommand.php
parent94d67a4b51f8e62e7d518cce26a526ae1ec48278 (diff)
downloadAppliGestionPHP-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.php356
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
12namespace Symfony\Component\Console\Command;
13
14use Symfony\Component\Console\Application;
15use Symfony\Component\Console\Completion\CompletionInput;
16use Symfony\Component\Console\Completion\CompletionSuggestions;
17use Symfony\Component\Console\Helper\HelperInterface;
18use Symfony\Component\Console\Helper\HelperSet;
19use Symfony\Component\Console\Input\InputDefinition;
20use Symfony\Component\Console\Input\InputInterface;
21use Symfony\Component\Console\Output\ConsoleOutputInterface;
22use Symfony\Component\Console\Output\OutputInterface;
23use Symfony\Component\Stopwatch\Stopwatch;
24
25/**
26 * @internal
27 *
28 * @author Jules Pietri <jules@heahprod.com>
29 */
30final 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}