From 8767a701f52495175d77f9683fc543fa34441124 Mon Sep 17 00:00:00 2001 From: Nicolas Grekas Date: Wed, 30 Jun 2021 15:15:49 +0200 Subject: [PATCH 01/24] CS fix --- Style/StyleInterface.php | 2 +- Style/SymfonyStyle.php | 4 ++-- 2 files changed, 3 insertions(+), 3 deletions(-) diff --git a/Style/StyleInterface.php b/Style/StyleInterface.php index afb841c0d..38d23b77e 100644 --- a/Style/StyleInterface.php +++ b/Style/StyleInterface.php @@ -85,7 +85,7 @@ public function table(array $headers, array $rows); * * @return mixed */ - public function ask(string $question, ?string $default = null, callable $validator = null); + public function ask(string $question, string $default = null, callable $validator = null); /** * Asks a question with the user input hidden. diff --git a/Style/SymfonyStyle.php b/Style/SymfonyStyle.php index 075fe6621..4fa665075 100644 --- a/Style/SymfonyStyle.php +++ b/Style/SymfonyStyle.php @@ -59,7 +59,7 @@ public function __construct(InputInterface $input, OutputInterface $output) * * @param string|array $messages The message to write in the block */ - public function block($messages, ?string $type = null, ?string $style = null, string $prefix = ' ', bool $padding = false, bool $escape = true) + public function block($messages, string $type = null, string $style = null, string $prefix = ' ', bool $padding = false, bool $escape = true) { $messages = \is_array($messages) ? array_values($messages) : [$messages]; @@ -264,7 +264,7 @@ public function definitionList(...$list) /** * {@inheritdoc} */ - public function ask(string $question, ?string $default = null, $validator = null) + public function ask(string $question, string $default = null, $validator = null) { $question = new Question($question, $default); $question->setValidator($validator); From 7f373a0cbe57069e57f726705c02db51c355552c Mon Sep 17 00:00:00 2001 From: Nicolas Grekas Date: Wed, 30 Jun 2021 17:48:15 +0200 Subject: [PATCH 02/24] Add some missing types --- Descriptor/DescriptorInterface.php | 7 +------ 1 file changed, 1 insertion(+), 6 deletions(-) diff --git a/Descriptor/DescriptorInterface.php b/Descriptor/DescriptorInterface.php index e3184a6a5..ebea30367 100644 --- a/Descriptor/DescriptorInterface.php +++ b/Descriptor/DescriptorInterface.php @@ -20,10 +20,5 @@ */ interface DescriptorInterface { - /** - * Describes an object if supported. - * - * @param object $object - */ - public function describe(OutputInterface $output, $object, array $options = []); + public function describe(OutputInterface $output, object $object, array $options = []); } From efa8ce36a5b967869473b20d7cb6eadea66447d6 Mon Sep 17 00:00:00 2001 From: Nicolas Grekas Date: Fri, 2 Jul 2021 16:28:33 +0200 Subject: [PATCH 03/24] Backport type fixes --- Command/Command.php | 18 +++++++++--------- Helper/Table.php | 8 ++++---- Input/InputArgument.php | 12 ++++++------ Input/InputInterface.php | 12 ++++++------ Input/InputOption.php | 14 +++++++------- Output/Output.php | 2 +- 6 files changed, 33 insertions(+), 33 deletions(-) diff --git a/Command/Command.php b/Command/Command.php index d4ab2eb8d..722e9428d 100644 --- a/Command/Command.php +++ b/Command/Command.php @@ -375,10 +375,10 @@ public function getNativeDefinition() /** * Adds an argument. * - * @param string $name The argument name - * @param int|null $mode The argument mode: InputArgument::REQUIRED or InputArgument::OPTIONAL - * @param string $description A description text - * @param string|string[]|null $default The default value (for InputArgument::OPTIONAL mode only) + * @param string $name The argument name + * @param int|null $mode The argument mode: InputArgument::REQUIRED or InputArgument::OPTIONAL + * @param string $description A description text + * @param mixed $default The default value (for InputArgument::OPTIONAL mode only) * * @throws InvalidArgumentException When argument mode is not valid * @@ -394,11 +394,11 @@ public function addArgument($name, $mode = null, $description = '', $default = n /** * Adds an option. * - * @param string $name The option name - * @param string|array|null $shortcut The shortcuts, can be null, a string of shortcuts delimited by | or an array of shortcuts - * @param int|null $mode The option mode: One of the InputOption::VALUE_* constants - * @param string $description A description text - * @param string|string[]|bool|null $default The default value (must be null for InputOption::VALUE_NONE) + * @param string $name The option name + * @param string|array|null $shortcut The shortcuts, can be null, a string of shortcuts delimited by | or an array of shortcuts + * @param int|null $mode The option mode: One of the InputOption::VALUE_* constants + * @param string $description A description text + * @param mixed $default The default value (must be null for InputOption::VALUE_NONE) * * @throws InvalidArgumentException If option mode is invalid or incompatible * diff --git a/Helper/Table.php b/Helper/Table.php index d51aee989..8f9e97240 100644 --- a/Helper/Table.php +++ b/Helper/Table.php @@ -585,11 +585,11 @@ private function buildTableRows(array $rows): TableRows return new TableRows(function () use ($rows, $unmergedRows): \Traversable { foreach ($rows as $rowKey => $row) { - yield $this->fillCells($row); + yield $row instanceof TableSeparator ? $row : $this->fillCells($row); if (isset($unmergedRows[$rowKey])) { - foreach ($unmergedRows[$rowKey] as $unmergedRow) { - yield $this->fillCells($unmergedRow); + foreach ($unmergedRows[$rowKey] as $row) { + yield $row instanceof TableSeparator ? $row : $this->fillCells($row); } } } @@ -670,7 +670,7 @@ private function fillNextRows(array $rows, int $line): array /** * fill cells for a row that contains colspan > 1. */ - private function fillCells($row) + private function fillCells(iterable $row) { $newRow = []; diff --git a/Input/InputArgument.php b/Input/InputArgument.php index 140c86d0e..11de14fe6 100644 --- a/Input/InputArgument.php +++ b/Input/InputArgument.php @@ -31,10 +31,10 @@ class InputArgument private $description; /** - * @param string $name The argument name - * @param int|null $mode The argument mode: self::REQUIRED or self::OPTIONAL - * @param string $description A description text - * @param string|string[]|null $default The default value (for self::OPTIONAL mode only) + * @param string $name The argument name + * @param int|null $mode The argument mode: self::REQUIRED or self::OPTIONAL + * @param string $description A description text + * @param mixed $default The default value (for self::OPTIONAL mode only) * * @throws InvalidArgumentException When argument mode is not valid */ @@ -86,7 +86,7 @@ public function isArray() /** * Sets the default value. * - * @param string|string[]|null $default The default value + * @param mixed $default The default value * * @throws LogicException When incorrect default value is given */ @@ -110,7 +110,7 @@ public function setDefault($default = null) /** * Returns the default value. * - * @return string|string[]|null The default value + * @return mixed */ public function getDefault() { diff --git a/Input/InputInterface.php b/Input/InputInterface.php index b9bcf3bbc..4ecab0f4f 100644 --- a/Input/InputInterface.php +++ b/Input/InputInterface.php @@ -85,7 +85,7 @@ public function getArguments(); * * @param string $name The argument name * - * @return string|string[]|null The argument value + * @return mixed * * @throws InvalidArgumentException When argument given doesn't exist */ @@ -94,8 +94,8 @@ public function getArgument($name); /** * Sets an argument value by name. * - * @param string $name The argument name - * @param string|string[]|null $value The argument value + * @param string $name The argument name + * @param mixed $value The argument value * * @throws InvalidArgumentException When argument given doesn't exist */ @@ -122,7 +122,7 @@ public function getOptions(); * * @param string $name The option name * - * @return string|string[]|bool|null The option value + * @return mixed * * @throws InvalidArgumentException When option given doesn't exist */ @@ -131,8 +131,8 @@ public function getOption($name); /** * Sets an option value by name. * - * @param string $name The option name - * @param string|string[]|bool|null $value The option value + * @param string $name The option name + * @param mixed $value The option value * * @throws InvalidArgumentException When option given doesn't exist */ diff --git a/Input/InputOption.php b/Input/InputOption.php index 5e48f88b8..2bb86cd2b 100644 --- a/Input/InputOption.php +++ b/Input/InputOption.php @@ -48,11 +48,11 @@ class InputOption private $description; /** - * @param string $name The option name - * @param string|array|null $shortcut The shortcuts, can be null, a string of shortcuts delimited by | or an array of shortcuts - * @param int|null $mode The option mode: One of the VALUE_* constants - * @param string $description A description text - * @param string|string[]|bool|null $default The default value (must be null for self::VALUE_NONE) + * @param string $name The option name + * @param string|array|null $shortcut The shortcuts, can be null, a string of shortcuts delimited by | or an array of shortcuts + * @param int|null $mode The option mode: One of the VALUE_* constants + * @param string $description A description text + * @param mixed $default The default value (must be null for self::VALUE_NONE) * * @throws InvalidArgumentException If option mode is invalid or incompatible */ @@ -164,7 +164,7 @@ public function isArray() /** * Sets the default value. * - * @param string|string[]|bool|null $default The default value + * @param mixed $default The default value * * @throws LogicException When incorrect default value is given */ @@ -188,7 +188,7 @@ public function setDefault($default = null) /** * Returns the default value. * - * @return string|string[]|bool|null The default value + * @return mixed */ public function getDefault() { diff --git a/Output/Output.php b/Output/Output.php index 857248133..fb838f053 100644 --- a/Output/Output.php +++ b/Output/Output.php @@ -163,7 +163,7 @@ public function write($messages, $newline = false, $options = self::OUTPUT_NORMA break; } - $this->doWrite($message, $newline); + $this->doWrite($message ?? '', $newline); } } From 5eb3ff23689a75e82bec4d3c5519eb3b520e6fca Mon Sep 17 00:00:00 2001 From: Nicolas Grekas Date: Fri, 2 Jul 2021 18:25:02 +0200 Subject: [PATCH 04/24] [Console] fix type annotations on InputInterface --- Input/InputInterface.php | 6 +++--- 1 file changed, 3 insertions(+), 3 deletions(-) diff --git a/Input/InputInterface.php b/Input/InputInterface.php index 4ecab0f4f..b96a0c627 100644 --- a/Input/InputInterface.php +++ b/Input/InputInterface.php @@ -83,7 +83,7 @@ public function getArguments(); /** * Returns the argument value for a given argument name. * - * @param string $name The argument name + * @param string|int $name The InputArgument name or position * * @return mixed * @@ -94,8 +94,8 @@ public function getArgument($name); /** * Sets an argument value by name. * - * @param string $name The argument name - * @param mixed $value The argument value + * @param string|int $name The InputArgument name or position + * @param mixed $value The argument value * * @throws InvalidArgumentException When argument given doesn't exist */ From d4c4ac30d2dc666fc72fc3c57fdc9df113e6b184 Mon Sep 17 00:00:00 2001 From: Nicolas Grekas Date: Fri, 2 Jul 2021 15:24:31 +0200 Subject: [PATCH 05/24] Backport type fixes --- Command/Command.php | 2 +- Descriptor/Descriptor.php | 2 +- Descriptor/MarkdownDescriptor.php | 2 +- Input/InputOption.php | 8 +++----- Output/ConsoleSectionOutput.php | 2 +- Output/TrimmedBufferOutput.php | 2 +- Question/Question.php | 8 ++------ Style/SymfonyStyle.php | 4 ++-- 8 files changed, 12 insertions(+), 18 deletions(-) diff --git a/Command/Command.php b/Command/Command.php index 5eb8bf10f..eeeea038a 100644 --- a/Command/Command.php +++ b/Command/Command.php @@ -376,7 +376,7 @@ public function getNativeDefinition() * Adds an argument. * * @param int|null $mode The argument mode: InputArgument::REQUIRED or InputArgument::OPTIONAL - * @param mixed $default The default value (for InputArgument::OPTIONAL mode only) + * @param mixed $default The default value (for InputArgument::OPTIONAL mode only) * * @throws InvalidArgumentException When argument mode is not valid * diff --git a/Descriptor/Descriptor.php b/Descriptor/Descriptor.php index 2ecc59e4e..a3648301f 100644 --- a/Descriptor/Descriptor.php +++ b/Descriptor/Descriptor.php @@ -34,7 +34,7 @@ abstract class Descriptor implements DescriptorInterface /** * {@inheritdoc} */ - public function describe(OutputInterface $output, $object, array $options = []) + public function describe(OutputInterface $output, object $object, array $options = []) { $this->output = $output; diff --git a/Descriptor/MarkdownDescriptor.php b/Descriptor/MarkdownDescriptor.php index 3748335ea..4f0df6519 100644 --- a/Descriptor/MarkdownDescriptor.php +++ b/Descriptor/MarkdownDescriptor.php @@ -31,7 +31,7 @@ class MarkdownDescriptor extends Descriptor /** * {@inheritdoc} */ - public function describe(OutputInterface $output, $object, array $options = []) + public function describe(OutputInterface $output, object $object, array $options = []) { $decorated = $output->isDecorated(); $output->setDecorated(false); diff --git a/Input/InputOption.php b/Input/InputOption.php index 2bb86cd2b..1bba552e3 100644 --- a/Input/InputOption.php +++ b/Input/InputOption.php @@ -48,11 +48,9 @@ class InputOption private $description; /** - * @param string $name The option name - * @param string|array|null $shortcut The shortcuts, can be null, a string of shortcuts delimited by | or an array of shortcuts - * @param int|null $mode The option mode: One of the VALUE_* constants - * @param string $description A description text - * @param mixed $default The default value (must be null for self::VALUE_NONE) + * @param string|array|null $shortcut The shortcuts, can be null, a string of shortcuts delimited by | or an array of shortcuts + * @param int|null $mode The option mode: One of the VALUE_* constants + * @param mixed $default The default value (must be null for self::VALUE_NONE) * * @throws InvalidArgumentException If option mode is invalid or incompatible */ diff --git a/Output/ConsoleSectionOutput.php b/Output/ConsoleSectionOutput.php index c19edbf95..ec9fece86 100644 --- a/Output/ConsoleSectionOutput.php +++ b/Output/ConsoleSectionOutput.php @@ -92,7 +92,7 @@ public function addContent(string $input) /** * {@inheritdoc} */ - protected function doWrite($message, $newline) + protected function doWrite(string $message, bool $newline) { if (!$this->isDecorated()) { parent::doWrite($message, $newline); diff --git a/Output/TrimmedBufferOutput.php b/Output/TrimmedBufferOutput.php index a03aa835f..370f9888d 100644 --- a/Output/TrimmedBufferOutput.php +++ b/Output/TrimmedBufferOutput.php @@ -54,7 +54,7 @@ public function fetch() /** * {@inheritdoc} */ - protected function doWrite($message, $newline) + protected function doWrite(string $message, bool $newline) { $this->buffer .= $message; diff --git a/Question/Question.php b/Question/Question.php index 0b5eefd54..85613fc6e 100644 --- a/Question/Question.php +++ b/Question/Question.php @@ -95,13 +95,11 @@ public function isHidden() /** * Sets whether the user response must be hidden or not. * - * @param bool $hidden - * * @return $this * * @throws LogicException In case the autocompleter is also used */ - public function setHidden($hidden) + public function setHidden(bool $hidden) { if ($this->autocompleterCallback) { throw new LogicException('A hidden question cannot use the autocompleter.'); @@ -125,11 +123,9 @@ public function isHiddenFallback() /** * Sets whether to fallback on non-hidden question if the response can not be hidden. * - * @param bool $fallback - * * @return $this */ - public function setHiddenFallback($fallback) + public function setHiddenFallback(bool $fallback) { $this->hiddenFallback = (bool) $fallback; diff --git a/Style/SymfonyStyle.php b/Style/SymfonyStyle.php index 4fa665075..668288f5c 100644 --- a/Style/SymfonyStyle.php +++ b/Style/SymfonyStyle.php @@ -264,7 +264,7 @@ public function definitionList(...$list) /** * {@inheritdoc} */ - public function ask(string $question, string $default = null, $validator = null) + public function ask(string $question, string $default = null, callable $validator = null) { $question = new Question($question, $default); $question->setValidator($validator); @@ -275,7 +275,7 @@ public function ask(string $question, string $default = null, $validator = null) /** * {@inheritdoc} */ - public function askHidden(string $question, $validator = null) + public function askHidden(string $question, callable $validator = null) { $question = new Question($question); From b8bcd5b5396f606227288d1a7ab470486e178822 Mon Sep 17 00:00:00 2001 From: Nicolas Grekas Date: Fri, 2 Jul 2021 19:03:33 +0200 Subject: [PATCH 06/24] [Console] fix handling positional arguments --- Input/Input.php | 4 ++++ Tests/Input/InputTest.php | 5 +++++ 2 files changed, 9 insertions(+) diff --git a/Input/Input.php b/Input/Input.php index 6e4c01e95..6b093e750 100644 --- a/Input/Input.php +++ b/Input/Input.php @@ -110,6 +110,8 @@ public function getArgument($name) throw new InvalidArgumentException(sprintf('The "%s" argument does not exist.', $name)); } + $name = \is_int($name) ? key(\array_slice($this->definition->getArguments(), $name, 1, true)) : $name; + return $this->arguments[$name] ?? $this->definition->getArgument($name)->getDefault(); } @@ -122,6 +124,8 @@ public function setArgument($name, $value) throw new InvalidArgumentException(sprintf('The "%s" argument does not exist.', $name)); } + $name = \is_int($name) ? key(\array_slice($this->definition->getArguments(), $name, 1, true)) : $name; + $this->arguments[$name] = $value; } diff --git a/Tests/Input/InputTest.php b/Tests/Input/InputTest.php index 48c287cd9..3441351b4 100644 --- a/Tests/Input/InputTest.php +++ b/Tests/Input/InputTest.php @@ -75,6 +75,11 @@ public function testArguments() $input = new ArrayInput(['name' => 'foo'], new InputDefinition([new InputArgument('name'), new InputArgument('bar', InputArgument::OPTIONAL, '', 'default')])); $this->assertEquals('default', $input->getArgument('bar'), '->getArgument() returns the default value for optional arguments'); $this->assertEquals(['name' => 'foo', 'bar' => 'default'], $input->getArguments(), '->getArguments() returns all argument values, even optional ones'); + + $input = new ArrayInput(['arg1' => 'foo'], new InputDefinition([new InputArgument('arg1'), new InputArgument('arg2')])); + $input->setArgument(1, 'bar'); + $this->assertEquals('bar', $input->getArgument(1)); + $this->assertEquals(['arg1' => 'foo', 'arg2' => 'bar'], $input->getArguments()); } public function testSetInvalidArgument() From 7de02eb53af445cc82fac4e86d6ed8e0dfceabff Mon Sep 17 00:00:00 2001 From: Robin Chalas Date: Sun, 4 Jul 2021 00:48:29 +0200 Subject: [PATCH 07/24] Revert "bug #41952 [Console] fix handling positional arguments (nicolas-grekas)" This reverts commit e93f8c0ad37dbd6d14a3dbc615b2a198f6354006, reversing changes made to eb83be474cd54115f0cb7ad72d60fe06e4ee36de. --- Input/Input.php | 4 ---- Tests/Input/InputTest.php | 5 ----- 2 files changed, 9 deletions(-) diff --git a/Input/Input.php b/Input/Input.php index 6b093e750..6e4c01e95 100644 --- a/Input/Input.php +++ b/Input/Input.php @@ -110,8 +110,6 @@ public function getArgument($name) throw new InvalidArgumentException(sprintf('The "%s" argument does not exist.', $name)); } - $name = \is_int($name) ? key(\array_slice($this->definition->getArguments(), $name, 1, true)) : $name; - return $this->arguments[$name] ?? $this->definition->getArgument($name)->getDefault(); } @@ -124,8 +122,6 @@ public function setArgument($name, $value) throw new InvalidArgumentException(sprintf('The "%s" argument does not exist.', $name)); } - $name = \is_int($name) ? key(\array_slice($this->definition->getArguments(), $name, 1, true)) : $name; - $this->arguments[$name] = $value; } diff --git a/Tests/Input/InputTest.php b/Tests/Input/InputTest.php index 3441351b4..48c287cd9 100644 --- a/Tests/Input/InputTest.php +++ b/Tests/Input/InputTest.php @@ -75,11 +75,6 @@ public function testArguments() $input = new ArrayInput(['name' => 'foo'], new InputDefinition([new InputArgument('name'), new InputArgument('bar', InputArgument::OPTIONAL, '', 'default')])); $this->assertEquals('default', $input->getArgument('bar'), '->getArgument() returns the default value for optional arguments'); $this->assertEquals(['name' => 'foo', 'bar' => 'default'], $input->getArguments(), '->getArguments() returns all argument values, even optional ones'); - - $input = new ArrayInput(['arg1' => 'foo'], new InputDefinition([new InputArgument('arg1'), new InputArgument('arg2')])); - $input->setArgument(1, 'bar'); - $this->assertEquals('bar', $input->getArgument(1)); - $this->assertEquals(['arg1' => 'foo', 'arg2' => 'bar'], $input->getArguments()); } public function testSetInvalidArgument() From 71910832828cf4b26efcda8ff58e9e7fc455f307 Mon Sep 17 00:00:00 2001 From: Nicolas Grekas Date: Sun, 4 Jul 2021 11:02:18 +0200 Subject: [PATCH 08/24] Revert "minor #41949 [Console] fix type annotations on InputInterface (nicolas-grekas)" This reverts commit ed09dc138e2be63303eaf6ddacabdb1ad6e2965e, reversing changes made to 7e78fb1197dfc6626ff2a1490fa2865fba4ee313. --- Input/InputInterface.php | 6 +++--- 1 file changed, 3 insertions(+), 3 deletions(-) diff --git a/Input/InputInterface.php b/Input/InputInterface.php index b96a0c627..4ecab0f4f 100644 --- a/Input/InputInterface.php +++ b/Input/InputInterface.php @@ -83,7 +83,7 @@ public function getArguments(); /** * Returns the argument value for a given argument name. * - * @param string|int $name The InputArgument name or position + * @param string $name The argument name * * @return mixed * @@ -94,8 +94,8 @@ public function getArgument($name); /** * Sets an argument value by name. * - * @param string|int $name The InputArgument name or position - * @param mixed $value The argument value + * @param string $name The argument name + * @param mixed $value The argument value * * @throws InvalidArgumentException When argument given doesn't exist */ From c17de77ffa90c9b4b98e7b5887489302e74e0b18 Mon Sep 17 00:00:00 2001 From: Nicolas Grekas Date: Sun, 4 Jul 2021 11:08:18 +0200 Subject: [PATCH 09/24] [Console] Fix type annotation on InputInterface::hasArgument() --- Input/Input.php | 6 +++--- Input/InputInterface.php | 2 +- 2 files changed, 4 insertions(+), 4 deletions(-) diff --git a/Input/Input.php b/Input/Input.php index 6e4c01e95..d7f29073e 100644 --- a/Input/Input.php +++ b/Input/Input.php @@ -106,7 +106,7 @@ public function getArguments() */ public function getArgument($name) { - if (!$this->definition->hasArgument($name)) { + if (!$this->definition->hasArgument((string) $name)) { throw new InvalidArgumentException(sprintf('The "%s" argument does not exist.', $name)); } @@ -118,7 +118,7 @@ public function getArgument($name) */ public function setArgument($name, $value) { - if (!$this->definition->hasArgument($name)) { + if (!$this->definition->hasArgument((string) $name)) { throw new InvalidArgumentException(sprintf('The "%s" argument does not exist.', $name)); } @@ -130,7 +130,7 @@ public function setArgument($name, $value) */ public function hasArgument($name) { - return $this->definition->hasArgument($name); + return $this->definition->hasArgument((string) $name); } /** diff --git a/Input/InputInterface.php b/Input/InputInterface.php index 4ecab0f4f..5d0db5c18 100644 --- a/Input/InputInterface.php +++ b/Input/InputInterface.php @@ -104,7 +104,7 @@ public function setArgument($name, $value); /** * Returns true if an InputArgument object exists by name or position. * - * @param string|int $name The InputArgument name or position + * @param string $name The InputArgument name or position * * @return bool true if the InputArgument object exists, false otherwise */ From 703c75045988860229b6b6ed1a30398b1cfaa6f5 Mon Sep 17 00:00:00 2001 From: Nicolas Grekas Date: Sun, 4 Jul 2021 11:31:36 +0200 Subject: [PATCH 10/24] CS fix --- Input/InputInterface.php | 2 +- 1 file changed, 1 insertion(+), 1 deletion(-) diff --git a/Input/InputInterface.php b/Input/InputInterface.php index 5d0db5c18..86353ab60 100644 --- a/Input/InputInterface.php +++ b/Input/InputInterface.php @@ -104,7 +104,7 @@ public function setArgument($name, $value); /** * Returns true if an InputArgument object exists by name or position. * - * @param string $name The InputArgument name or position + * @param string $name The argument name * * @return bool true if the InputArgument object exists, false otherwise */ From ee9270a35d7c93164e3e8b5a321ff8f6e72f364d Mon Sep 17 00:00:00 2001 From: Tomas Votruba Date: Mon, 5 Jul 2021 10:48:31 +0200 Subject: [PATCH 11/24] [Console] SymfonyStyle - add string type to confirm() $question by contract --- Style/SymfonyStyle.php | 2 +- 1 file changed, 1 insertion(+), 1 deletion(-) diff --git a/Style/SymfonyStyle.php b/Style/SymfonyStyle.php index 668288f5c..7fd74aa67 100644 --- a/Style/SymfonyStyle.php +++ b/Style/SymfonyStyle.php @@ -288,7 +288,7 @@ public function askHidden(string $question, callable $validator = null) /** * {@inheritdoc} */ - public function confirm($question, $default = true) + public function confirm(string $question, bool $default = true) { return $this->askQuestion(new ConfirmationQuestion($question, $default)); } From b426956a6b2e4f4e0f2cecbde50996721f06804c Mon Sep 17 00:00:00 2001 From: Nicolas Grekas Date: Mon, 5 Jul 2021 08:27:11 +0200 Subject: [PATCH 12/24] [DependencyInjection][Console] tighten types --- Input/InputArgument.php | 12 ++++++------ Input/InputDefinition.php | 8 ++------ Input/InputInterface.php | 10 +++++----- Input/InputOption.php | 16 +++++----------- Question/Question.php | 6 +++--- 5 files changed, 21 insertions(+), 31 deletions(-) diff --git a/Input/InputArgument.php b/Input/InputArgument.php index 11de14fe6..085aca5a7 100644 --- a/Input/InputArgument.php +++ b/Input/InputArgument.php @@ -31,10 +31,10 @@ class InputArgument private $description; /** - * @param string $name The argument name - * @param int|null $mode The argument mode: self::REQUIRED or self::OPTIONAL - * @param string $description A description text - * @param mixed $default The default value (for self::OPTIONAL mode only) + * @param string $name The argument name + * @param int|null $mode The argument mode: self::REQUIRED or self::OPTIONAL + * @param string $description A description text + * @param string|bool|int|float|array|null $default The default value (for self::OPTIONAL mode only) * * @throws InvalidArgumentException When argument mode is not valid */ @@ -86,7 +86,7 @@ public function isArray() /** * Sets the default value. * - * @param mixed $default The default value + * @param string|bool|int|float|array|null $default * * @throws LogicException When incorrect default value is given */ @@ -110,7 +110,7 @@ public function setDefault($default = null) /** * Returns the default value. * - * @return mixed + * @return string|bool|int|float|array|null */ public function getDefault() { diff --git a/Input/InputDefinition.php b/Input/InputDefinition.php index db55315a8..e2cd6d714 100644 --- a/Input/InputDefinition.php +++ b/Input/InputDefinition.php @@ -185,9 +185,7 @@ public function getArgumentRequiredCount() } /** - * Gets the default values. - * - * @return array An array of default values + * @return array */ public function getArgumentDefaults() { @@ -316,9 +314,7 @@ public function getOptionForShortcut($shortcut) } /** - * Gets an array of default values. - * - * @return array An array of all default values + * @return array */ public function getOptionDefaults() { diff --git a/Input/InputInterface.php b/Input/InputInterface.php index 86353ab60..8efc62326 100644 --- a/Input/InputInterface.php +++ b/Input/InputInterface.php @@ -51,9 +51,9 @@ public function hasParameterOption($values, $onlyParams = false); * Does not necessarily return the correct result for short options * when multiple flags are combined in the same option. * - * @param string|array $values The value(s) to look for in the raw parameters (can be an array) - * @param mixed $default The default value to return if no result is found - * @param bool $onlyParams Only check real parameters, skip those following an end of options (--) signal + * @param string|array $values The value(s) to look for in the raw parameters (can be an array) + * @param string|bool|int|float|array|null $default The default value to return if no result is found + * @param bool $onlyParams Only check real parameters, skip those following an end of options (--) signal * * @return mixed The option value */ @@ -76,7 +76,7 @@ public function validate(); /** * Returns all the given arguments merged with the default values. * - * @return array + * @return array */ public function getArguments(); @@ -113,7 +113,7 @@ public function hasArgument($name); /** * Returns all the given options merged with the default values. * - * @return array + * @return array */ public function getOptions(); diff --git a/Input/InputOption.php b/Input/InputOption.php index 2bb86cd2b..710e9a809 100644 --- a/Input/InputOption.php +++ b/Input/InputOption.php @@ -48,11 +48,9 @@ class InputOption private $description; /** - * @param string $name The option name - * @param string|array|null $shortcut The shortcuts, can be null, a string of shortcuts delimited by | or an array of shortcuts - * @param int|null $mode The option mode: One of the VALUE_* constants - * @param string $description A description text - * @param mixed $default The default value (must be null for self::VALUE_NONE) + * @param string|array|null $shortcut The shortcuts, can be null, a string of shortcuts delimited by | or an array of shortcuts + * @param int|null $mode The option mode: One of the VALUE_* constants + * @param string|bool|int|float|array|null $default The default value (must be null for self::VALUE_NONE) * * @throws InvalidArgumentException If option mode is invalid or incompatible */ @@ -162,11 +160,7 @@ public function isArray() } /** - * Sets the default value. - * - * @param mixed $default The default value - * - * @throws LogicException When incorrect default value is given + * @param string|bool|int|float|array|null $default */ public function setDefault($default = null) { @@ -188,7 +182,7 @@ public function setDefault($default = null) /** * Returns the default value. * - * @return mixed + * @return string|bool|int|float|array|null */ public function getDefault() { diff --git a/Question/Question.php b/Question/Question.php index 2d46d1a98..cc108018f 100644 --- a/Question/Question.php +++ b/Question/Question.php @@ -32,8 +32,8 @@ class Question private $trimmable = true; /** - * @param string $question The question to ask to the user - * @param mixed $default The default answer to return if the user enters nothing + * @param string $question The question to ask to the user + * @param string|bool|int|float|null $default The default answer to return if the user enters nothing */ public function __construct(string $question, $default = null) { @@ -54,7 +54,7 @@ public function getQuestion() /** * Returns the default answer. * - * @return mixed + * @return string|bool|int|float|null */ public function getDefault() { From ca3dbfbcbe5f0a8bc1fd915584cb2b2388add0bd Mon Sep 17 00:00:00 2001 From: Nicolas Grekas Date: Mon, 5 Jul 2021 08:31:06 +0200 Subject: [PATCH 13/24] cs fix --- Output/TrimmedBufferOutput.php | 7 +------ 1 file changed, 1 insertion(+), 6 deletions(-) diff --git a/Output/TrimmedBufferOutput.php b/Output/TrimmedBufferOutput.php index a03aa835f..4ca63c49b 100644 --- a/Output/TrimmedBufferOutput.php +++ b/Output/TrimmedBufferOutput.php @@ -24,12 +24,7 @@ class TrimmedBufferOutput extends Output private $maxLength; private $buffer = ''; - public function __construct( - int $maxLength, - ?int $verbosity = self::VERBOSITY_NORMAL, - bool $decorated = false, - OutputFormatterInterface $formatter = null - ) { + public function __construct(int $maxLength, ?int $verbosity = self::VERBOSITY_NORMAL, bool $decorated = false, OutputFormatterInterface $formatter = null) { if ($maxLength <= 0) { throw new InvalidArgumentException(sprintf('"%s()" expects a strictly positive maxLength. Got %d.', __METHOD__, $maxLength)); } From 8d5b01e1b0f9eadfedb0d3e3acb3aec7fe61f230 Mon Sep 17 00:00:00 2001 From: Javier Eguiluz Date: Tue, 13 Jul 2021 11:47:43 +0200 Subject: [PATCH 14/24] Fix minor typos --- Tests/Helper/ProgressBarTest.php | 6 +++--- 1 file changed, 3 insertions(+), 3 deletions(-) diff --git a/Tests/Helper/ProgressBarTest.php b/Tests/Helper/ProgressBarTest.php index 9fdaa570d..0cf06353d 100644 --- a/Tests/Helper/ProgressBarTest.php +++ b/Tests/Helper/ProgressBarTest.php @@ -1018,14 +1018,14 @@ public function testMaxSecondsBetweenRedraws() $bar->setRedrawFrequency(4); // disable step based redraws $bar->start(); - $bar->setProgress(1); // No treshold hit, no redraw + $bar->setProgress(1); // No threshold hit, no redraw $bar->maxSecondsBetweenRedraws(2); sleep(1); $bar->setProgress(2); // Still no redraw because it takes 2 seconds for a redraw sleep(1); $bar->setProgress(3); // 1+1 = 2 -> redraw finally $bar->setProgress(4); // step based redraw freq hit, redraw even without sleep - $bar->setProgress(5); // No treshold hit, no redraw + $bar->setProgress(5); // No threshold hit, no redraw $bar->maxSecondsBetweenRedraws(3); sleep(2); $bar->setProgress(6); // No redraw even though 2 seconds passed. Throttling has priority @@ -1056,7 +1056,7 @@ public function testMinSecondsBetweenRedraws() $bar->setProgress(3); // 1 second passed but we changed threshold, should not draw sleep(1); $bar->setProgress(4); // 1+1 seconds = 2 seconds passed which conforms threshold, draw - $bar->setProgress(5); // No treshold hit, no redraw + $bar->setProgress(5); // No threshold hit, no redraw rewind($output->getStream()); $this->assertEquals( From 8b5132c1a24bb6add638e7202e1546c666c2e627 Mon Sep 17 00:00:00 2001 From: Javier Eguiluz Date: Tue, 13 Jul 2021 11:11:08 +0200 Subject: [PATCH 15/24] Use PHP_OS_FAMILY if possible --- Helper/SymfonyQuestionHelper.php | 2 +- Tests/Helper/SymfonyQuestionHelperTest.php | 2 +- 2 files changed, 2 insertions(+), 2 deletions(-) diff --git a/Helper/SymfonyQuestionHelper.php b/Helper/SymfonyQuestionHelper.php index fd9b703fc..01f94aba4 100644 --- a/Helper/SymfonyQuestionHelper.php +++ b/Helper/SymfonyQuestionHelper.php @@ -100,7 +100,7 @@ protected function writeError(OutputInterface $output, \Exception $error) private function getEofShortcut(): string { - if (false !== strpos(\PHP_OS, 'WIN')) { + if ('Windows' === \PHP_OS_FAMILY) { return 'Ctrl+Z then Enter'; } diff --git a/Tests/Helper/SymfonyQuestionHelperTest.php b/Tests/Helper/SymfonyQuestionHelperTest.php index b57ac1d60..ed0800852 100644 --- a/Tests/Helper/SymfonyQuestionHelperTest.php +++ b/Tests/Helper/SymfonyQuestionHelperTest.php @@ -218,7 +218,7 @@ public function testAskMultilineQuestionIncludesHelpText() { $expected = 'Write an essay (press Ctrl+D to continue)'; - if (false !== strpos(\PHP_OS, 'WIN')) { + if ('Windows' === \PHP_OS_FAMILY) { $expected = 'Write an essay (press Ctrl+Z then Enter to continue)'; } From bec5954c73c4ee57f79349173a299afbf94ab9df Mon Sep 17 00:00:00 2001 From: Javier Eguiluz Date: Fri, 16 Jul 2021 15:30:15 +0200 Subject: [PATCH 16/24] Optimized some strlen() calls when possible --- Helper/QuestionHelper.php | 2 +- Input/StringInput.php | 4 ++-- 2 files changed, 3 insertions(+), 3 deletions(-) diff --git a/Helper/QuestionHelper.php b/Helper/QuestionHelper.php index 2f582d458..5c3ecc4e5 100644 --- a/Helper/QuestionHelper.php +++ b/Helper/QuestionHelper.php @@ -382,7 +382,7 @@ private function mostRecentlyEnteredValue(string $entered): string } $choices = explode(',', $entered); - if (\strlen($lastChoice = trim($choices[\count($choices) - 1])) > 0) { + if ('' !== $lastChoice = trim($choices[\count($choices) - 1])) { return $lastChoice; } diff --git a/Input/StringInput.php b/Input/StringInput.php index 2625514ef..eb5c07fdd 100644 --- a/Input/StringInput.php +++ b/Input/StringInput.php @@ -50,9 +50,9 @@ private function tokenize(string $input): array while ($cursor < $length) { if (preg_match('/\s+/A', $input, $match, 0, $cursor)) { } elseif (preg_match('/([^="\'\s]+?)(=?)('.self::REGEX_QUOTED_STRING.'+)/A', $input, $match, 0, $cursor)) { - $tokens[] = $match[1].$match[2].stripcslashes(str_replace(['"\'', '\'"', '\'\'', '""'], '', substr($match[3], 1, \strlen($match[3]) - 2))); + $tokens[] = $match[1].$match[2].stripcslashes(str_replace(['"\'', '\'"', '\'\'', '""'], '', substr($match[3], 1, -1))); } elseif (preg_match('/'.self::REGEX_QUOTED_STRING.'/A', $input, $match, 0, $cursor)) { - $tokens[] = stripcslashes(substr($match[0], 1, \strlen($match[0]) - 2)); + $tokens[] = stripcslashes(substr($match[0], 1, -1)); } elseif (preg_match('/'.self::REGEX_STRING.'/A', $input, $match, 0, $cursor)) { $tokens[] = stripcslashes($match[1]); } else { From a96e44ed3144d6c68757f8a392c92f7056d46df9 Mon Sep 17 00:00:00 2001 From: "Alexander M. Turek" Date: Sun, 18 Jul 2021 16:04:40 +0200 Subject: [PATCH 17/24] Indicate compatibility with psr/log 2 and 3 Signed-off-by: Alexander M. Turek --- composer.json | 5 +++-- 1 file changed, 3 insertions(+), 2 deletions(-) diff --git a/composer.json b/composer.json index 5c573df2b..0955ba578 100644 --- a/composer.json +++ b/composer.json @@ -29,10 +29,10 @@ "symfony/lock": "^4.4|^5.0", "symfony/process": "^3.4|^4.0|^5.0", "symfony/var-dumper": "^4.3|^5.0", - "psr/log": "~1.0" + "psr/log": "^1|^2" }, "provide": { - "psr/log-implementation": "1.0" + "psr/log-implementation": "1.0|2.0" }, "suggest": { "symfony/event-dispatcher": "", @@ -41,6 +41,7 @@ "psr/log": "For using the console logger" }, "conflict": { + "psr/log": ">=3", "symfony/dependency-injection": "<3.4", "symfony/event-dispatcher": "<4.3|>=5", "symfony/lock": "<4.4", From 991fcb37d391c93cf7b69bbbccd09fd2583504ec Mon Sep 17 00:00:00 2001 From: Javier Eguiluz Date: Sat, 17 Jul 2021 20:11:21 +0200 Subject: [PATCH 18/24] Simplify some code with null coalesce operator --- Event/ConsoleErrorEvent.php | 2 +- 1 file changed, 1 insertion(+), 1 deletion(-) diff --git a/Event/ConsoleErrorEvent.php b/Event/ConsoleErrorEvent.php index 25d9b8812..57d9b38ba 100644 --- a/Event/ConsoleErrorEvent.php +++ b/Event/ConsoleErrorEvent.php @@ -53,6 +53,6 @@ public function setExitCode(int $exitCode): void public function getExitCode(): int { - return null !== $this->exitCode ? $this->exitCode : (\is_int($this->error->getCode()) && 0 !== $this->error->getCode() ? $this->error->getCode() : 1); + return $this->exitCode ?? (\is_int($this->error->getCode()) && 0 !== $this->error->getCode() ? $this->error->getCode() : 1); } } From 681a074054bc6fc00dfeb5f862f266847d9a8465 Mon Sep 17 00:00:00 2001 From: PaoRuby Date: Tue, 13 Jul 2021 10:09:00 -0500 Subject: [PATCH 19/24] [Console] Run commands when implements SignalableCommandInterface without pcntl and they have'nt signals --- Application.php | 2 +- Tests/ApplicationTest.php | 15 ++++++++++++++- 2 files changed, 15 insertions(+), 2 deletions(-) diff --git a/Application.php b/Application.php index 2cf824474..2a4966b46 100644 --- a/Application.php +++ b/Application.php @@ -940,7 +940,7 @@ protected function doRunCommand(Command $command, InputInterface $input, OutputI } } - if ($command instanceof SignalableCommandInterface) { + if ($command instanceof SignalableCommandInterface && ($this->signalsToDispatchEvent || $command->getSubscribedSignals())) { if (!$this->signalRegistry) { throw new RuntimeException('Unable to subscribe to signal events. Make sure that the `pcntl` extension is installed and that "pcntl_*" functions are not disabled by your php.ini\'s "disable_functions" directive.'); } diff --git a/Tests/ApplicationTest.php b/Tests/ApplicationTest.php index da9b3cadf..0c7445d6a 100644 --- a/Tests/ApplicationTest.php +++ b/Tests/ApplicationTest.php @@ -36,6 +36,7 @@ use Symfony\Component\Console\Output\Output; use Symfony\Component\Console\Output\OutputInterface; use Symfony\Component\Console\Output\StreamOutput; +use Symfony\Component\Console\SignalRegistry\SignalRegistry; use Symfony\Component\Console\Tester\ApplicationTester; use Symfony\Component\DependencyInjection\ContainerBuilder; use Symfony\Component\EventDispatcher\EventDispatcher; @@ -1861,6 +1862,18 @@ public function testSignal() $this->assertTrue($command->signaled); $this->assertTrue($dispatcherCalled); } + + public function testSignalableCommandInterfaceWithoutSignals() + { + $command = new SignableCommand(); + + $dispatcher = new EventDispatcher(); + $application = new Application(); + $application->setAutoExit(false); + $application->setDispatcher($dispatcher); + $application->add($command); + $this->assertSame(0, $application->run(new ArrayInput(['signal']))); + } } class CustomApplication extends Application @@ -1928,7 +1941,7 @@ class SignableCommand extends Command implements SignalableCommandInterface public function getSubscribedSignals(): array { - return [\SIGALRM]; + return SignalRegistry::isSupported() ? [\SIGALRM] : []; } public function handleSignal(int $signal): void From 2c469857cd969d26fd817fb799ce1f64ef73be1b Mon Sep 17 00:00:00 2001 From: Nicolas Grekas Date: Wed, 21 Jul 2021 10:27:50 +0200 Subject: [PATCH 20/24] phpdoc fixes --- Command/Command.php | 2 +- 1 file changed, 1 insertion(+), 1 deletion(-) diff --git a/Command/Command.php b/Command/Command.php index 722e9428d..1e109b194 100644 --- a/Command/Command.php +++ b/Command/Command.php @@ -464,7 +464,7 @@ public function getName() /** * @param bool $hidden Whether or not the command should be hidden from the list of commands * - * @return Command The current instance + * @return $this */ public function setHidden($hidden) { From 2afbda9a2cd3e4164c7b7c912332460db5a59ef5 Mon Sep 17 00:00:00 2001 From: Roman Martinuk Date: Tue, 20 Jul 2021 19:36:01 +0300 Subject: [PATCH 21/24] [Console] fix table setHeaderTitle without headers --- Helper/Table.php | 14 ++++++++------ Tests/Helper/TableTest.php | 21 +++++++++++++++++++++ 2 files changed, 29 insertions(+), 6 deletions(-) diff --git a/Helper/Table.php b/Helper/Table.php index 8f9e97240..1d0a22baa 100644 --- a/Helper/Table.php +++ b/Helper/Table.php @@ -374,6 +374,7 @@ public function render() $isHeader = !$this->horizontal; $isFirstRow = $this->horizontal; + $hasTitle = (bool) $this->headerTitle; foreach ($rows as $row) { if ($divider === $row) { $isHeader = false; @@ -391,12 +392,13 @@ public function render() } if ($isHeader || $isFirstRow) { - if ($isFirstRow) { - $this->renderRowSeparator(self::SEPARATOR_TOP_BOTTOM); - $isFirstRow = false; - } else { - $this->renderRowSeparator(self::SEPARATOR_TOP, $this->headerTitle, $this->style->getHeaderTitleFormat()); - } + $this->renderRowSeparator( + $isHeader ? self::SEPARATOR_TOP : self::SEPARATOR_TOP_BOTTOM, + $hasTitle ? $this->headerTitle : null, + $hasTitle ? $this->style->getHeaderTitleFormat() : null + ); + $isFirstRow = false; + $hasTitle = false; } if ($this->horizontal) { $this->renderRow($row, $this->style->getCellRowFormat(), $this->style->getCellHeaderFormat()); diff --git a/Tests/Helper/TableTest.php b/Tests/Helper/TableTest.php index d02d6ea42..eed0b1662 100644 --- a/Tests/Helper/TableTest.php +++ b/Tests/Helper/TableTest.php @@ -1115,6 +1115,27 @@ public function renderSetTitle() ]; } + public function testSetTitleWithoutHeaders() + { + (new Table($output = $this->getOutputStream())) + ->setHeaderTitle('Reproducer') + ->setRows([ + ['Value', '123-456'], + ['Some other value', '789-0'], + ]) + ->render(); + + $expected = <<<'TABLE' ++-------- Reproducer --------+ +| Value | 123-456 | +| Some other value | 789-0 | ++------------------+---------+ + +TABLE; + + $this->assertSame($expected, $this->getOutputContent($output)); + } + public function testColumnMaxWidths() { $table = new Table($output = $this->getOutputStream()); From e72a90094116babaad683f02f36dbefc8d9e8c08 Mon Sep 17 00:00:00 2001 From: Tobias Schultze Date: Sun, 4 Jul 2021 19:20:55 +0200 Subject: [PATCH 22/24] Leverage str_ends_with added the php80 polyfill to requirements when necessary --- Formatter/OutputFormatter.php | 2 +- Style/SymfonyStyle.php | 2 +- composer.json | 2 +- 3 files changed, 3 insertions(+), 3 deletions(-) diff --git a/Formatter/OutputFormatter.php b/Formatter/OutputFormatter.php index fa4189d04..b0355d811 100644 --- a/Formatter/OutputFormatter.php +++ b/Formatter/OutputFormatter.php @@ -54,7 +54,7 @@ public static function escape($text) */ public static function escapeTrailingBackslash(string $text): string { - if ('\\' === substr($text, -1)) { + if (str_ends_with($text, '\\')) { $len = \strlen($text); $text = rtrim($text, '\\'); $text = str_replace("\0", '', $text); diff --git a/Style/SymfonyStyle.php b/Style/SymfonyStyle.php index ecdf9b1a3..66db3ad5a 100644 --- a/Style/SymfonyStyle.php +++ b/Style/SymfonyStyle.php @@ -442,7 +442,7 @@ private function autoPrependText(): void { $fetched = $this->bufferedOutput->fetch(); //Prepend new line if last char isn't EOL: - if ("\n" !== substr($fetched, -1)) { + if (!str_ends_with($fetched, "\n")) { $this->newLine(); } } diff --git a/composer.json b/composer.json index 0955ba578..90cbd24f5 100644 --- a/composer.json +++ b/composer.json @@ -19,7 +19,7 @@ "php": ">=7.1.3", "symfony/polyfill-mbstring": "~1.0", "symfony/polyfill-php73": "^1.8", - "symfony/polyfill-php80": "^1.15", + "symfony/polyfill-php80": "^1.16", "symfony/service-contracts": "^1.1|^2" }, "require-dev": { From 9979144038a91c3a998192997529233f803e783f Mon Sep 17 00:00:00 2001 From: "Alexander M. Turek" Date: Mon, 7 Jun 2021 01:15:42 +0200 Subject: [PATCH 23/24] Leverage str_contains/str_starts_with Signed-off-by: Alexander M. Turek --- Application.php | 6 +++--- Command/Command.php | 2 +- Formatter/OutputFormatter.php | 2 +- Helper/QuestionHelper.php | 6 +++--- Input/ArgvInput.php | 12 ++++++------ Input/ArrayInput.php | 4 ++-- Input/InputOption.php | 2 +- Logger/ConsoleLogger.php | 2 +- 8 files changed, 18 insertions(+), 18 deletions(-) diff --git a/Application.php b/Application.php index ed6d00190..15d537dac 100644 --- a/Application.php +++ b/Application.php @@ -877,7 +877,7 @@ private function doActuallyRenderThrowable(\Throwable $e, OutputInterface $outpu $len = 0; } - if (false !== strpos($message, "@anonymous\0")) { + if (str_contains($message, "@anonymous\0")) { $message = preg_replace_callback('/[a-zA-Z_\x7f-\xff][\\\\a-zA-Z0-9_\x7f-\xff]*+@anonymous\x00.*?\.php(?:0x?|:[0-9]++\$)[0-9a-fA-F]++/', function ($m) { return class_exists($m[0], false) ? (get_parent_class($m[0]) ?: key(class_implements($m[0])) ?: 'class').'@anonymous' : $m[0]; }, $message); @@ -1155,7 +1155,7 @@ private function findAlternatives(string $name, iterable $collection): array } $lev = levenshtein($subname, $parts[$i]); - if ($lev <= \strlen($subname) / 3 || '' !== $subname && false !== strpos($parts[$i], $subname)) { + if ($lev <= \strlen($subname) / 3 || '' !== $subname && str_contains($parts[$i], $subname)) { $alternatives[$collectionName] = $exists ? $alternatives[$collectionName] + $lev : $lev; } elseif ($exists) { $alternatives[$collectionName] += $threshold; @@ -1165,7 +1165,7 @@ private function findAlternatives(string $name, iterable $collection): array foreach ($collection as $item) { $lev = levenshtein($name, $item); - if ($lev <= \strlen($name) / 3 || false !== strpos($item, $name)) { + if ($lev <= \strlen($name) / 3 || str_contains($item, $name)) { $alternatives[$item] = isset($alternatives[$item]) ? $alternatives[$item] - $lev : $lev; } } diff --git a/Command/Command.php b/Command/Command.php index 1e109b194..da9b9f6af 100644 --- a/Command/Command.php +++ b/Command/Command.php @@ -613,7 +613,7 @@ public function getSynopsis($short = false) */ public function addUsage($usage) { - if (0 !== strpos($usage, $this->name)) { + if (!str_starts_with($usage, $this->name)) { $usage = sprintf('%s %s', $this->name, $usage); } diff --git a/Formatter/OutputFormatter.php b/Formatter/OutputFormatter.php index b0355d811..0f969c7ad 100644 --- a/Formatter/OutputFormatter.php +++ b/Formatter/OutputFormatter.php @@ -180,7 +180,7 @@ public function formatAndWrap(string $message, int $width) $output .= $this->applyCurrentStyle(substr($message, $offset), $output, $width, $currentLineLength); - if (false !== strpos($output, "\0")) { + if (str_contains($output, "\0")) { return strtr($output, ["\0" => '\\', '\\<' => '<']); } diff --git a/Helper/QuestionHelper.php b/Helper/QuestionHelper.php index 5c3ecc4e5..089de76bd 100644 --- a/Helper/QuestionHelper.php +++ b/Helper/QuestionHelper.php @@ -311,7 +311,7 @@ private function autocomplete(OutputInterface $output, Question $question, $inpu $matches = array_filter( $autocomplete($ret), function ($match) use ($ret) { - return '' === $ret || 0 === strpos($match, $ret); + return '' === $ret || str_starts_with($match, $ret); } ); $numMatches = \count($matches); @@ -348,7 +348,7 @@ function ($match) use ($ret) { foreach ($autocomplete($ret) as $value) { // If typed characters match the beginning chunk of value (e.g. [AcmeDe]moBundle) - if (0 === strpos($value, $tempRet)) { + if (str_starts_with($value, $tempRet)) { $matches[$numMatches++] = $value; } } @@ -377,7 +377,7 @@ function ($match) use ($ret) { private function mostRecentlyEnteredValue(string $entered): string { // Determine the most recent value that the user entered - if (false === strpos($entered, ',')) { + if (!str_contains($entered, ',')) { return $entered; } diff --git a/Input/ArgvInput.php b/Input/ArgvInput.php index 6d2946926..b63529509 100644 --- a/Input/ArgvInput.php +++ b/Input/ArgvInput.php @@ -75,7 +75,7 @@ protected function parse() $this->parseArgument($token); } elseif ($parseOptions && '--' == $token) { $parseOptions = false; - } elseif ($parseOptions && 0 === strpos($token, '--')) { + } elseif ($parseOptions && str_starts_with($token, '--')) { $this->parseLongOption($token); } elseif ($parseOptions && '-' === $token[0] && '-' !== $token) { $this->parseShortOption($token); @@ -243,7 +243,7 @@ public function getFirstArgument() $isOption = false; foreach ($this->tokens as $i => $token) { if ($token && '-' === $token[0]) { - if (false !== strpos($token, '=') || !isset($this->tokens[$i + 1])) { + if (str_contains($token, '=') || !isset($this->tokens[$i + 1])) { continue; } @@ -285,8 +285,8 @@ public function hasParameterOption($values, $onlyParams = false) // Options with values: // For long options, test for '--option=' at beginning // For short options, test for '-o' at beginning - $leading = 0 === strpos($value, '--') ? $value.'=' : $value; - if ($token === $value || '' !== $leading && 0 === strpos($token, $leading)) { + $leading = str_starts_with($value, '--') ? $value.'=' : $value; + if ($token === $value || '' !== $leading && str_starts_with($token, $leading)) { return true; } } @@ -316,8 +316,8 @@ public function getParameterOption($values, $default = false, $onlyParams = fals // Options with values: // For long options, test for '--option=' at beginning // For short options, test for '-o' at beginning - $leading = 0 === strpos($value, '--') ? $value.'=' : $value; - if ('' !== $leading && 0 === strpos($token, $leading)) { + $leading = str_starts_with($value, '--') ? $value.'=' : $value; + if ('' !== $leading && str_starts_with($token, $leading)) { return substr($token, \strlen($leading)); } } diff --git a/Input/ArrayInput.php b/Input/ArrayInput.php index bf9a8a455..30bd2054a 100644 --- a/Input/ArrayInput.php +++ b/Input/ArrayInput.php @@ -133,9 +133,9 @@ protected function parse() if ('--' === $key) { return; } - if (0 === strpos($key, '--')) { + if (str_starts_with($key, '--')) { $this->addLongOption(substr($key, 2), $value); - } elseif (0 === strpos($key, '-')) { + } elseif (str_starts_with($key, '-')) { $this->addShortOption(substr($key, 1), $value); } else { $this->addArgument($key, $value); diff --git a/Input/InputOption.php b/Input/InputOption.php index 710e9a809..c40e0da34 100644 --- a/Input/InputOption.php +++ b/Input/InputOption.php @@ -56,7 +56,7 @@ class InputOption */ public function __construct(string $name, $shortcut = null, int $mode = null, string $description = '', $default = null) { - if (0 === strpos($name, '--')) { + if (str_starts_with($name, '--')) { $name = substr($name, 2); } diff --git a/Logger/ConsoleLogger.php b/Logger/ConsoleLogger.php index 4a0315656..c9ee03561 100644 --- a/Logger/ConsoleLogger.php +++ b/Logger/ConsoleLogger.php @@ -104,7 +104,7 @@ public function hasErrored() */ private function interpolate(string $message, array $context): string { - if (false === strpos($message, '{')) { + if (!str_contains($message, '{')) { return $message; } From e523c86d2c727b128ce339a72733c9688e002ed3 Mon Sep 17 00:00:00 2001 From: Roman Martinuk Date: Wed, 21 Jul 2021 21:24:53 +0300 Subject: [PATCH 24/24] skip test --- Tests/Helper/QuestionHelperTest.php | 4 ++++ 1 file changed, 4 insertions(+) diff --git a/Tests/Helper/QuestionHelperTest.php b/Tests/Helper/QuestionHelperTest.php index bba71cc59..9088d917c 100644 --- a/Tests/Helper/QuestionHelperTest.php +++ b/Tests/Helper/QuestionHelperTest.php @@ -835,6 +835,10 @@ public function testDisableStty() public function testTraversableMultiselectAutocomplete() { + if (!Terminal::hasSttyAvailable()) { + $this->markTestSkipped('`stty` is required to test autocomplete functionality'); + } + // // F // A<3x UP ARROW>,F