From db750ed8ae80de9417e7964c532ab4bc44b4f9d4 Mon Sep 17 00:00:00 2001 From: =?UTF-8?q?Gabriel=20Ostroluck=C3=BD?= Date: Sat, 10 Nov 2018 20:58:44 +0100 Subject: [PATCH] [Console] Add hyperlinks support --- src/Symfony/Component/Console/CHANGELOG.md | 5 ++ .../Console/Formatter/OutputFormatter.php | 4 +- .../Formatter/OutputFormatterStyle.php | 19 +++++-- .../Tests/Formatter/OutputFormatterTest.php | 51 +++++++------------ 4 files changed, 41 insertions(+), 38 deletions(-) diff --git a/src/Symfony/Component/Console/CHANGELOG.md b/src/Symfony/Component/Console/CHANGELOG.md index b9175109c4..017decf63b 100644 --- a/src/Symfony/Component/Console/CHANGELOG.md +++ b/src/Symfony/Component/Console/CHANGELOG.md @@ -1,6 +1,11 @@ CHANGELOG ========= +4.3.0 +----- + + * added support for hyperlinks + 4.2.0 ----- diff --git a/src/Symfony/Component/Console/Formatter/OutputFormatter.php b/src/Symfony/Component/Console/Formatter/OutputFormatter.php index fd3bbd12d3..600cf76f50 100644 --- a/src/Symfony/Component/Console/Formatter/OutputFormatter.php +++ b/src/Symfony/Component/Console/Formatter/OutputFormatter.php @@ -141,7 +141,7 @@ class OutputFormatter implements WrappableOutputFormatterInterface { $offset = 0; $output = ''; - $tagRegex = '[a-z][a-z0-9,_=;-]*+'; + $tagRegex = '[a-z][^<>]*+'; $currentLineLength = 0; preg_match_all("#<(($tagRegex) | /($tagRegex)?)>#ix", $message, $matches, PREG_OFFSET_CAPTURE); foreach ($matches[0] as $i => $match) { @@ -215,6 +215,8 @@ class OutputFormatter implements WrappableOutputFormatterInterface $style->setForeground($match[1]); } elseif ('bg' == $match[0]) { $style->setBackground($match[1]); + } elseif ('href' === $match[0]) { + $style->setHref($match[1]); } elseif ('options' === $match[0]) { preg_match_all('([^,;]+)', $match[1], $options); $options = array_shift($options); diff --git a/src/Symfony/Component/Console/Formatter/OutputFormatterStyle.php b/src/Symfony/Component/Console/Formatter/OutputFormatterStyle.php index 906021f6f9..445de6a200 100644 --- a/src/Symfony/Component/Console/Formatter/OutputFormatterStyle.php +++ b/src/Symfony/Component/Console/Formatter/OutputFormatterStyle.php @@ -52,6 +52,7 @@ class OutputFormatterStyle implements OutputFormatterStyleInterface private $foreground; private $background; + private $href; private $options = array(); /** @@ -118,6 +119,11 @@ class OutputFormatterStyle implements OutputFormatterStyleInterface $this->background = static::$availableBackgroundColors[$color]; } + public function setHref(string $url): void + { + $this->href = $url; + } + /** * Sets some specific style option. * @@ -187,11 +193,14 @@ class OutputFormatterStyle implements OutputFormatterStyleInterface $setCodes[] = $this->background['set']; $unsetCodes[] = $this->background['unset']; } - if (\count($this->options)) { - foreach ($this->options as $option) { - $setCodes[] = $option['set']; - $unsetCodes[] = $option['unset']; - } + + foreach ($this->options as $option) { + $setCodes[] = $option['set']; + $unsetCodes[] = $option['unset']; + } + + if (null !== $this->href) { + $text = "\033]8;;$this->href\033\\$text\033]8;;\033\\"; } if (0 === \count($setCodes)) { diff --git a/src/Symfony/Component/Console/Tests/Formatter/OutputFormatterTest.php b/src/Symfony/Component/Console/Tests/Formatter/OutputFormatterTest.php index b51668cfa7..2639b94043 100644 --- a/src/Symfony/Component/Console/Tests/Formatter/OutputFormatterTest.php +++ b/src/Symfony/Component/Console/Tests/Formatter/OutputFormatterTest.php @@ -228,7 +228,7 @@ class OutputFormatterTest extends TestCase ); } - public function testNotDecoratedFormatter() + public function testFormatterHasStyles() { $formatter = new OutputFormatter(false); @@ -236,39 +236,26 @@ class OutputFormatterTest extends TestCase $this->assertTrue($formatter->hasStyle('info')); $this->assertTrue($formatter->hasStyle('comment')); $this->assertTrue($formatter->hasStyle('question')); + } - $this->assertEquals( - 'some error', $formatter->format('some error') - ); - $this->assertEquals( - 'some info', $formatter->format('some info') - ); - $this->assertEquals( - 'some comment', $formatter->format('some comment') - ); - $this->assertEquals( - 'some question', $formatter->format('some question') - ); - $this->assertEquals( - 'some text with inline style', $formatter->format('some text with inline style') - ); + /** + * @dataProvider provideDecoratedAndNonDecoratedOutput + */ + public function testNotDecoratedFormatter(string $input, string $expectedNonDecoratedOutput, string $expectedDecoratedOutput) + { + $this->assertEquals($expectedDecoratedOutput, (new OutputFormatter(true))->format($input)); + $this->assertEquals($expectedNonDecoratedOutput, (new OutputFormatter(false))->format($input)); + } - $formatter->setDecorated(true); - - $this->assertEquals( - "\033[37;41msome error\033[39;49m", $formatter->format('some error') - ); - $this->assertEquals( - "\033[32msome info\033[39m", $formatter->format('some info') - ); - $this->assertEquals( - "\033[33msome comment\033[39m", $formatter->format('some comment') - ); - $this->assertEquals( - "\033[30;46msome question\033[39;49m", $formatter->format('some question') - ); - $this->assertEquals( - "\033[31msome text with inline style\033[39m", $formatter->format('some text with inline style') + public function provideDecoratedAndNonDecoratedOutput() + { + return array( + array('some error', 'some error', "\033[37;41msome error\033[39;49m"), + array('some info', 'some info', "\033[32msome info\033[39m"), + array('some comment', 'some comment', "\033[33msome comment\033[39m"), + array('some question', 'some question', "\033[30;46msome question\033[39;49m"), + array('some text with inline style', 'some text with inline style', "\033[31msome text with inline style\033[39m"), + array('some URL', 'some URL', "\033]8;;idea://open/?file=/path/somefile.php&line=12\033\\some URL\033]8;;\033\\"), ); }