From 138dad64405679bf53671a730eef77cf0cb51d69 Mon Sep 17 00:00:00 2001 From: Maxime Steinhausser Date: Thu, 22 Mar 2018 23:33:06 +0100 Subject: [PATCH] [VarDumper] Some tweaks after Nicolas' commit & ServerDumperPlaceholderCommand --- .../Command/ServerDumpPlaceholderCommand.php | 44 ++++++++++++++ .../DependencyInjection/Configuration.php | 2 +- .../DependencyInjection/DebugExtension.php | 20 ++++++- .../DebugBundle/Resources/config/services.xml | 15 +++-- .../DataCollector/DumpDataCollector.php | 2 +- .../DataCollector/DumpDataCollectorTest.php | 59 +------------------ src/Symfony/Component/VarDumper/CHANGELOG.md | 2 +- .../Command/Descriptor/CliDescriptor.php | 2 +- .../VarDumper/Command/ServerDumpCommand.php | 18 +++--- .../VarDumper/Dumper/ServerDumper.php | 3 +- .../Tests/Dumper/ServerDumperTest.php | 18 ++---- .../VarDumper/Tests/Fixtures/dump_server.php | 2 +- 12 files changed, 95 insertions(+), 92 deletions(-) create mode 100644 src/Symfony/Bundle/DebugBundle/Command/ServerDumpPlaceholderCommand.php diff --git a/src/Symfony/Bundle/DebugBundle/Command/ServerDumpPlaceholderCommand.php b/src/Symfony/Bundle/DebugBundle/Command/ServerDumpPlaceholderCommand.php new file mode 100644 index 0000000000..8b314a8c92 --- /dev/null +++ b/src/Symfony/Bundle/DebugBundle/Command/ServerDumpPlaceholderCommand.php @@ -0,0 +1,44 @@ + + * + * For the full copyright and license information, please view the LICENSE + * file that was distributed with this source code. + */ + +namespace Symfony\Bundle\DebugBundle\Command; + +use Symfony\Component\Console\Input\InputInterface; +use Symfony\Component\Console\Output\OutputInterface; +use Symfony\Component\Console\Style\SymfonyStyle; +use Symfony\Component\VarDumper\Command\ServerDumpCommand; +use Symfony\Component\VarDumper\Server\DumpServer; + +/** + * A placeholder command easing VarDumper server discovery. + * + * @author Maxime Steinhausser + * + * @internal + */ +class ServerDumpPlaceholderCommand extends ServerDumpCommand +{ + public function __construct(DumpServer $server = null, array $descriptors = array()) + { + parent::__construct(new class() extends DumpServer { + public function __construct() + { + } + }, $descriptors); + } + + protected function execute(InputInterface $input, OutputInterface $output) + { + (new SymfonyStyle($input, $output))->getErrorStyle()->warning('In order to use the VarDumper server, set the "debug.dump_destination" config option to "tcp://%env(VAR_DUMPER_SERVER)%"'); + + return 8; + } +} diff --git a/src/Symfony/Bundle/DebugBundle/DependencyInjection/Configuration.php b/src/Symfony/Bundle/DebugBundle/DependencyInjection/Configuration.php index 6f9f0b404d..cbb27c479f 100644 --- a/src/Symfony/Bundle/DebugBundle/DependencyInjection/Configuration.php +++ b/src/Symfony/Bundle/DebugBundle/DependencyInjection/Configuration.php @@ -48,7 +48,7 @@ class Configuration implements ConfigurationInterface ->end() ->scalarNode('dump_destination') ->info('A stream URL where dumps should be written to') - ->example('php://stderr, or tcp://%env(VAR_DUMPER_SERVER)% when using the `server:dump` command') + ->example('php://stderr, or tcp://%env(VAR_DUMPER_SERVER)% when using the "server:dump" command') ->defaultNull() ->end() ->end() diff --git a/src/Symfony/Bundle/DebugBundle/DependencyInjection/DebugExtension.php b/src/Symfony/Bundle/DebugBundle/DependencyInjection/DebugExtension.php index 99d3fdf926..a81c495970 100644 --- a/src/Symfony/Bundle/DebugBundle/DependencyInjection/DebugExtension.php +++ b/src/Symfony/Bundle/DebugBundle/DependencyInjection/DebugExtension.php @@ -11,11 +11,13 @@ namespace Symfony\Bundle\DebugBundle\DependencyInjection; +use Symfony\Bundle\DebugBundle\Command\ServerDumpPlaceholderCommand; use Symfony\Component\Config\FileLocator; use Symfony\Component\DependencyInjection\ContainerBuilder; use Symfony\Component\DependencyInjection\Extension\Extension; use Symfony\Component\DependencyInjection\Loader\XmlFileLoader; use Symfony\Component\DependencyInjection\Reference; +use Symfony\Component\VarDumper\Dumper\ServerDumper; /** * DebugExtension. @@ -43,11 +45,18 @@ class DebugExtension extends Extension if (null === $config['dump_destination']) { //no-op } elseif (0 === strpos($config['dump_destination'], 'tcp://')) { + $serverDumperHost = $config['dump_destination']; $container->getDefinition('debug.dump_listener') ->replaceArgument(1, new Reference('var_dumper.server_dumper')) ; - $container->getDefinition('var_dumper.command.server_dump') - ->replaceArgument(1, new Reference('var_dumper.server_dumper')) + $container->getDefinition('data_collector.dump') + ->replaceArgument(4, new Reference('var_dumper.server_dumper')) + ; + $container->getDefinition('var_dumper.dump_server') + ->replaceArgument(0, $serverDumperHost) + ; + $container->getDefinition('var_dumper.server_dumper') + ->replaceArgument(0, $serverDumperHost) ; } else { $container->getDefinition('var_dumper.cli_dumper') @@ -57,6 +66,13 @@ class DebugExtension extends Extension ->replaceArgument(4, new Reference('var_dumper.cli_dumper')) ; } + + if (!isset($serverDumperHost)) { + $container->getDefinition('var_dumper.command.server_dump')->setClass(ServerDumpPlaceholderCommand::class); + if (!class_exists(ServerDumper::class)) { + $container->removeDefinition('var_dumper.command.server_dump'); + } + } } /** diff --git a/src/Symfony/Bundle/DebugBundle/Resources/config/services.xml b/src/Symfony/Bundle/DebugBundle/Resources/config/services.xml index 97c3679039..a0bbde8d3d 100644 --- a/src/Symfony/Bundle/DebugBundle/Resources/config/services.xml +++ b/src/Symfony/Bundle/DebugBundle/Resources/config/services.xml @@ -4,11 +4,13 @@ xmlns:xsi="http://www.w3.org/2001/XMLSchema-instance" xsi:schemaLocation="http://symfony.com/schema/dic/services http://symfony.com/schema/dic/services/services-1.0.xsd"> + + 127.0.0.1:9912 + + - 127.0.0.1:9912 - @@ -70,7 +72,14 @@ + + + + + + + @@ -83,9 +92,7 @@ - - diff --git a/src/Symfony/Component/HttpKernel/DataCollector/DumpDataCollector.php b/src/Symfony/Component/HttpKernel/DataCollector/DumpDataCollector.php index d494a374b6..aca9e005fe 100644 --- a/src/Symfony/Component/HttpKernel/DataCollector/DumpDataCollector.php +++ b/src/Symfony/Component/HttpKernel/DataCollector/DumpDataCollector.php @@ -58,7 +58,7 @@ class DumpDataCollector extends DataCollector implements DataDumperInterface &$this->clonesCount, ); - $this->sourceContextProvider = $dumper instanceof ServerDumper ? $dumper->getContextProviders()['source'] : new SourceContextProvider($this->charset); + $this->sourceContextProvider = $dumper instanceof ServerDumper && isset($dumper->getContextProviders()['source']) ? $dumper->getContextProviders()['source'] : new SourceContextProvider($this->charset); } public function __clone() diff --git a/src/Symfony/Component/HttpKernel/Tests/DataCollector/DumpDataCollectorTest.php b/src/Symfony/Component/HttpKernel/Tests/DataCollector/DumpDataCollectorTest.php index d98fb57fe4..0c5fc6b6a1 100644 --- a/src/Symfony/Component/HttpKernel/Tests/DataCollector/DumpDataCollectorTest.php +++ b/src/Symfony/Component/HttpKernel/Tests/DataCollector/DumpDataCollectorTest.php @@ -12,11 +12,10 @@ namespace Symfony\Component\HttpKernel\Tests\DataCollector; use PHPUnit\Framework\TestCase; -use Symfony\Component\HttpKernel\DataCollector\DumpDataCollector; use Symfony\Component\HttpFoundation\Request; use Symfony\Component\HttpFoundation\Response; +use Symfony\Component\HttpKernel\DataCollector\DumpDataCollector; use Symfony\Component\VarDumper\Cloner\Data; -use Symfony\Component\VarDumper\Dumper\DataDumperInterface; use Symfony\Component\VarDumper\Dumper\ServerDumper; /** @@ -62,33 +61,11 @@ class DumpDataCollectorTest extends TestCase $data = new Data(array(array(123))); // Server is up, server dumper is used - $serverDumper = $this->getMockBuilder(ServerDumper::class)->getMock(); + $serverDumper = $this->getMockBuilder(ServerDumper::class)->disableOriginalConstructor()->getMock(); $serverDumper->expects($this->once())->method('dump'); $serverDumper->method('isServerListening')->willReturn(true); - // configured dumper is never used - $dumper = $this->getMockBuilder(DataDumperInterface::class)->getMock(); - $dumper->expects($this->never())->method('dump'); - - $collector = new DumpDataCollector(null, null, null, null, $dumper, $serverDumper); - $collector->dump($data); - - // Collect doesn't re-trigger dump - ob_start(); - $collector->collect(new Request(), new Response()); - $this->assertEmpty(ob_get_clean()); - $this->assertStringMatchesFormat('a:3:{i:0;a:5:{s:4:"data";%c:39:"Symfony\Component\VarDumper\Cloner\Data":%a', $collector->serialize()); - - // Server is down, server dumper is never used - $serverDumper = $this->getMockBuilder(ServerDumper::class)->getMock(); - $serverDumper->expects($this->never())->method('dump'); - $serverDumper->method('isServerListening')->willReturn(false); - - // configured dumper is used - $dumper = $this->getMockBuilder(DataDumperInterface::class)->getMock(); - $dumper->expects($this->exactly(2))->method('dump'); // called twice in doDump if not a CLiDumper instance - - $collector = new DumpDataCollector(null, null, null, null, $dumper, $serverDumper); + $collector = new DumpDataCollector(null, null, null, null, $serverDumper); $collector->dump($data); // Collect doesn't re-trigger dump @@ -155,34 +132,4 @@ EOTXT; $collector->__destruct(); $this->assertSame("DumpDataCollectorTest.php on line {$line}:\n456\n", ob_get_clean()); } - - public function testFlushWithServerDumper() - { - $data = new Data(array(array(456))); - - // Server is up, server dumper is used - $serverDumper = $this->getMockBuilder(ServerDumper::class)->getMock(); - $serverDumper->expects($this->once())->method('dump'); - $serverDumper->method('isServerListening')->willReturn(true); - - $collector = new DumpDataCollector(null, null, null, null, null, $serverDumper); - $collector->dump($data); - - ob_start(); - $collector->__destruct(); - $this->assertEmpty(ob_get_clean()); - - // Server is down, buffered dump is flushed on destruct - $serverDumper = $this->getMockBuilder(ServerDumper::class)->getMock(); - $serverDumper->expects($this->never())->method('dump'); - $serverDumper->method('isServerListening')->willReturn(false); - - $collector = new DumpDataCollector(null, null, null, null, null, $serverDumper); - $collector->dump($data); - $line = __LINE__ - 1; - - ob_start(); - $collector->__destruct(); - $this->assertSame("DumpDataCollectorTest.php on line {$line}:\n456\n", ob_get_clean()); - } } diff --git a/src/Symfony/Component/VarDumper/CHANGELOG.md b/src/Symfony/Component/VarDumper/CHANGELOG.md index c16986256f..34d9bbb0f5 100644 --- a/src/Symfony/Component/VarDumper/CHANGELOG.md +++ b/src/Symfony/Component/VarDumper/CHANGELOG.md @@ -7,7 +7,7 @@ CHANGELOG * added a `ServerDumper` to send serialized Data clones to a server * added a `ServerDumpCommand` and `DumpServer` to run a server collecting and displaying dumps on a single place with multiple formats support - * added `CliDescriptor` and `HtmlDescriptor` descriptors for `server:dump` cli and html formats support + * added `CliDescriptor` and `HtmlDescriptor` descriptors for `server:dump` CLI and HTML formats support 4.0.0 ----- diff --git a/src/Symfony/Component/VarDumper/Command/Descriptor/CliDescriptor.php b/src/Symfony/Component/VarDumper/Command/Descriptor/CliDescriptor.php index a4580824ff..562258fa36 100644 --- a/src/Symfony/Component/VarDumper/Command/Descriptor/CliDescriptor.php +++ b/src/Symfony/Component/VarDumper/Command/Descriptor/CliDescriptor.php @@ -36,7 +36,7 @@ class CliDescriptor implements DumpDescriptorInterface public function describe(OutputInterface $output, Data $data, array $context, int $clientId): void { - $io = new SymfonyStyle(new ArrayInput(array()), $output); + $io = $output instanceof SymfonyStyle ? $output : new SymfonyStyle(new ArrayInput(array()), $output); $rows = array(array('date', date('r', $context['timestamp']))); $lastIdentifier = $this->lastIdentifier; diff --git a/src/Symfony/Component/VarDumper/Command/ServerDumpCommand.php b/src/Symfony/Component/VarDumper/Command/ServerDumpCommand.php index cda24a06ce..1619450523 100644 --- a/src/Symfony/Component/VarDumper/Command/ServerDumpCommand.php +++ b/src/Symfony/Component/VarDumper/Command/ServerDumpCommand.php @@ -11,7 +11,6 @@ namespace Symfony\Component\VarDumper\Command; -use Psr\Log\LoggerInterface; use Symfony\Component\Console\Command\Command; use Symfony\Component\Console\Exception\InvalidArgumentException; use Symfony\Component\Console\Input\InputInterface; @@ -37,14 +36,14 @@ class ServerDumpCommand extends Command { protected static $defaultName = 'server:dump'; - private $logger; + private $server; /** @var DumpDescriptorInterface[] */ private $descriptors; - public function __construct(array $descriptors = array(), LoggerInterface $logger = null) + public function __construct(DumpServer $server, array $descriptors = array()) { - $this->logger = $logger; + $this->server = $server; $this->descriptors = $descriptors + array( 'cli' => new CliDescriptor(new CliDumper()), 'html' => new HtmlDescriptor(new HtmlDumper()), @@ -58,7 +57,7 @@ class ServerDumpCommand extends Command $availableFormats = implode(', ', array_keys($this->descriptors)); $this - ->addOption('format', null, InputOption::VALUE_REQUIRED, "The output format ($availableFormats)", 'cli') + ->addOption('format', null, InputOption::VALUE_REQUIRED, sprintf('The output format (%s)', $availableFormats), 'cli') ->setDescription('Starts a dump server that collects and displays dumps in a single place') ->setHelp(<<<'EOF' %command.name% starts a dump server that collects and displays @@ -88,14 +87,13 @@ EOF $errorIo = $io->getErrorStyle(); $errorIo->title('Symfony Var Dumper Server'); - $server = new DumpServer(null, $this->logger); - $server->start(); + $this->server->start(); - $errorIo->success(sprintf('Server listening on %s', $server->getHost())); + $errorIo->success(sprintf('Server listening on %s', $this->server->getHost())); $errorIo->comment('Quit the server with CONTROL-C.'); - $server->listen(function (Data $data, array $context, int $clientId) use ($descriptor, $output) { - $descriptor->describe($output, $data, $context, $clientId); + $this->server->listen(function (Data $data, array $context, int $clientId) use ($descriptor, $io) { + $descriptor->describe($io, $data, $context, $clientId); }); } } diff --git a/src/Symfony/Component/VarDumper/Dumper/ServerDumper.php b/src/Symfony/Component/VarDumper/Dumper/ServerDumper.php index 3ae5beee3e..106ae89aed 100644 --- a/src/Symfony/Component/VarDumper/Dumper/ServerDumper.php +++ b/src/Symfony/Component/VarDumper/Dumper/ServerDumper.php @@ -13,7 +13,6 @@ namespace Symfony\Component\VarDumper\Dumper; use Symfony\Component\VarDumper\Cloner\Data; use Symfony\Component\VarDumper\Dumper\ContextProvider\ContextProviderInterface; -use Symfony\Component\VarDumper\Server\DumpServer; /** * ServerDumper forwards serialized Data clones to a server. @@ -43,7 +42,7 @@ class ServerDumper implements DataDumperInterface $this->contextProviders = $contextProviders; } - public function getContextProviders(): ?array + public function getContextProviders(): array { return $this->contextProviders; } diff --git a/src/Symfony/Component/VarDumper/Tests/Dumper/ServerDumperTest.php b/src/Symfony/Component/VarDumper/Tests/Dumper/ServerDumperTest.php index d9c70fb10d..0ac5cad845 100644 --- a/src/Symfony/Component/VarDumper/Tests/Dumper/ServerDumperTest.php +++ b/src/Symfony/Component/VarDumper/Tests/Dumper/ServerDumperTest.php @@ -21,21 +21,13 @@ use Symfony\Component\VarDumper\Dumper\ServerDumper; class ServerDumperTest extends TestCase { - public static function setUpBeforeClass() - { - putenv('VAR_DUMPER_SERVER=tcp://127.0.0.1:9913'); - } - - public static function tearDownAfterClass() - { - putenv('VAR_DUMPER_SERVER'); - } + private const VAR_DUMPER_SERVER = 'tcp://127.0.0.1:9913'; public function testDumpForwardsToWrappedDumperWhenServerIsUnavailable() { $wrappedDumper = $this->getMockBuilder(DataDumperInterface::class)->getMock(); - $dumper = new ServerDumper(null, $wrappedDumper); + $dumper = new ServerDumper(self::VAR_DUMPER_SERVER, $wrappedDumper); $cloner = new VarCloner(); $data = $cloner->cloneVar('foo'); @@ -47,7 +39,7 @@ class ServerDumperTest extends TestCase public function testIsServerListening() { - $dumper = new ServerDumper(); + $dumper = new ServerDumper(self::VAR_DUMPER_SERVER); $this->assertFalse($dumper->isServerListening()); @@ -73,7 +65,7 @@ class ServerDumperTest extends TestCase $cloner = new VarCloner(); $data = $cloner->cloneVar('foo'); - $dumper = new ServerDumper(null, $wrappedDumper, array( + $dumper = new ServerDumper(self::VAR_DUMPER_SERVER, $wrappedDumper, array( 'foo_provider' => new class() implements ContextProviderInterface { public function getContext(): ?array { @@ -117,7 +109,7 @@ DUMP { $process = new PhpProcess(file_get_contents(__DIR__.'/../Fixtures/dump_server.php'), null, array( 'COMPONENT_ROOT' => __DIR__.'/../../', - 'VAR_DUMPER_SERVER' => 'tcp://127.0.0.1:9913', + 'VAR_DUMPER_SERVER' => self::VAR_DUMPER_SERVER, )); $process->inheritEnvironmentVariables(true); diff --git a/src/Symfony/Component/VarDumper/Tests/Fixtures/dump_server.php b/src/Symfony/Component/VarDumper/Tests/Fixtures/dump_server.php index 195009bd8a..5c79ea5151 100644 --- a/src/Symfony/Component/VarDumper/Tests/Fixtures/dump_server.php +++ b/src/Symfony/Component/VarDumper/Tests/Fixtures/dump_server.php @@ -25,7 +25,7 @@ VarDumper::setHandler(function ($var) use ($cloner, $dumper) { $dumper->dump($data); }); -$server = new DumpServer(); +$server = new DumpServer(getenv('VAR_DUMPER_SERVER')); $server->start();