-
-
Notifications
You must be signed in to change notification settings - Fork 9.6k
[WIP] [Console] Refactored console formatting #31131
New issue
Have a question about this project? Sign up for a free GitHub account to open an issue and contact its maintainers and the community.
By clicking “Sign up for GitHub”, you agree to our terms of service and privacy statement. We’ll occasionally send you account related emails.
Already on GitHub? Sign in to your account
Conversation
@ro0NL Hello again :) I'm waiting for your observations. Yes, it became huge. :-/ |
@@ -6,6 +6,13 @@ CHANGELOG | |||
|
|||
* added support for hyperlinks | |||
* added `ProgressBar::iterate()` method that simplify updating the progress bar when iterating | |||
* refactored console output formatter: add lexer and tokens. Important changes: | |||
* added `<wrap>` and `<nowrap>` formatter tags to console | |||
* [BC BREAK] earlier the unhandled/unknown tags will be shown, but now every tag will disappear after formatting. If you want to show a "tag", you have to escape it with `\` sign: `\<visibleTag>...\</visibleTag>`. You can use the `\Symfony\Component\Console\Formatter\OutputFormatter::escape()` function as well. |
There was a problem hiding this comment.
Choose a reason for hiding this comment
The reason will be displayed to describe this comment to others. Learn more.
BC breaks are a no-go in a minor version. This must trigger a deprecation instead to provide a migration path.
* refactored console output formatter: add lexer and tokens. Important changes: | ||
* added `<wrap>` and `<nowrap>` formatter tags to console | ||
* [BC BREAK] earlier the unhandled/unknown tags will be shown, but now every tag will disappear after formatting. If you want to show a "tag", you have to escape it with `\` sign: `\<visibleTag>...\</visibleTag>`. You can use the `\Symfony\Component\Console\Formatter\OutputFormatter::escape()` function as well. | ||
* [BC BREAK] `\Symfony\Component\Console\Formatter\OutputFormatterStyleInterface` was changed: `apply()` function was removed, and there were set 2 new methods: `start()`, `close()` |
There was a problem hiding this comment.
Choose a reason for hiding this comment
The reason will be displayed to describe this comment to others. Learn more.
no-go. This must use deprecations, and adding new methods in an interface is also a no-go (use a separate interface maybe ?)
* added `<wrap>` and `<nowrap>` formatter tags to console | ||
* [BC BREAK] earlier the unhandled/unknown tags will be shown, but now every tag will disappear after formatting. If you want to show a "tag", you have to escape it with `\` sign: `\<visibleTag>...\</visibleTag>`. You can use the `\Symfony\Component\Console\Formatter\OutputFormatter::escape()` function as well. | ||
* [BC BREAK] `\Symfony\Component\Console\Formatter\OutputFormatterStyleInterface` was changed: `apply()` function was removed, and there were set 2 new methods: `start()`, `close()` | ||
* [BC BREAK] `\Symfony\Component\Console\Formatter\OutputFormatter` is no longer instance of `WrappableOutputFormatterInterface` |
There was a problem hiding this comment.
Choose a reason for hiding this comment
The reason will be displayed to describe this comment to others. Learn more.
that BC break is also a no-go.
class Lexer implements LexerInterface | ||
{ | ||
/** @var FullTextToken */ | ||
protected $fullTextToken; |
There was a problem hiding this comment.
Choose a reason for hiding this comment
The reason will be displayed to describe this comment to others. Learn more.
everything must use private visibility, not protected one, unless we explicitly decide to make inheritance the supported extension point (hint: such decision is always the last choice).
* | ||
* @param string $text | ||
* | ||
* @return \IteratorAggregate |
There was a problem hiding this comment.
Choose a reason for hiding this comment
The reason will be displayed to describe this comment to others. Learn more.
should return \Traversable
or iterable
. There is no reason to enforce that \IteratorAggregate
is used to implementator the iterator.
{ | ||
$this->styles[] = $style; | ||
$this->styles[$depth] = $style; |
There was a problem hiding this comment.
Choose a reason for hiding this comment
The reason will be displayed to describe this comment to others. Learn more.
this is not pushing anything anymore. It replaces an element of the stack
* file that was distributed with this source code. | ||
*/ | ||
|
||
namespace Symfony\Component\Console\Formatter\Tokens; |
There was a problem hiding this comment.
Choose a reason for hiding this comment
The reason will be displayed to describe this comment to others. Learn more.
our namespaces are singular
@@ -15,6 +15,10 @@ | |||
use Symfony\Component\Console\Formatter\OutputFormatter; | |||
use Symfony\Component\Console\Formatter\OutputFormatterStyle; | |||
|
|||
/** | |||
* @author Fabien Potencier <fabien@symfony.com> | |||
* @author Krisztián Ferenczi <ferenczi.krisztian@gmail.com> |
There was a problem hiding this comment.
Choose a reason for hiding this comment
The reason will be displayed to describe this comment to others. Learn more.
We don't put @author
phpdoc on test files.
$style = new OutputFormatterStyle('blue', 'white'); | ||
$formatter->setStyle('test', $style); |
There was a problem hiding this comment.
Choose a reason for hiding this comment
The reason will be displayed to describe this comment to others. Learn more.
this test should be kept unchanged. If you cannot, it means there is a BC break. And that's not something we want
@@ -318,26 +323,13 @@ public function testContentWithLineBreaks() | |||
)); | |||
} | |||
|
|||
public function testFormatAndWrap() |
There was a problem hiding this comment.
Choose a reason for hiding this comment
The reason will be displayed to describe this comment to others. Learn more.
this test must be kept.
Can we also get a performance comparison of the old and new system ? |
I will make one. I think the new is worse, but I thought this is the console, we don't want to format large texts/outputs, and the time isn't so important on the console. I inserted a limitation here: https://github.com/symfony/symfony/pull/31131/files#diff-a42222f449d2d525a1100ed2b995e429R43 on the bases of this: http://piotrpasich.com/spl-iterators-against-the-performance/ (first comment: http://piotrpasich.com/spl-iterators-against-the-performance/#comment-1818526630 ) |
@stof I wrote a benchmark: https://gist.github.com/fchris82/e09e4d9723e4b0e73a768ab53860d321 and I ran it:
Yes, there are big differences. Maybe should I keep the original Formatter and create a new one for wrapping and other actions? |
@stof Hello, I made a twice faster solution with plain array token container: fchris82@d4fc1d2 $tokens = [
[Lexer::TYPE_WORD, 'Lorem'],
[Lexer::TYPE_SEPARATOR, ' '],
[Lexer::TYPE_WORD, 'ipsum'],
// ...
new FullTokenTag('<comment>'),
// ...
]; This solution is faster, but some things are lost in this case, eg: type hinting (there are strings and Token objects mixed in "one array") What do you prefer? My opinion: I kept the original |
why does your benchmark result have |
@stof You misunderstood my last comment. There are more problems with the word wrapping in SymfonyStyle now:
There are 3 different "solution" now:
Yes, this solution is much slower, but works, it wraps the text well, easy to extend, and my question is: does this speed matter on console? Is there any different than the full text is shown I would like to solve the problem, I don't insist on this version, only I think this is the "best" version, with an reasonable speed "problem". |
@stof Please give me a direction, what do you prefer:
|
Antecedent:
I made a full refactoring. The original output formatting isn't elegant and hard to extend. I made a lexer with tokens and visitors. This solution is based on Design Patterns: Elements of Reusable Object-Oriented Software book, from Erich Gamma, Richard Helm, Ralph Johnson, John M Vlissides (Chapter 2)
TODO: