Skip to content

Commit f6fdd6c

Browse files
committed
Remove discovery dependency, fixes #40, closes #54
POC how to not be dependent on discovery Fix unit tests Fix factory method Remove duplicated service Move discovery to compiler pass Applied fixes from StyleCI Fix puli executable Use class constant Fix puli command order Fix lowest dependency issue Fix HHVM tests Improve tests
1 parent 5eadbc6 commit f6fdd6c

File tree

11 files changed

+291
-48
lines changed

11 files changed

+291
-48
lines changed

.gitignore

Lines changed: 1 addition & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -5,3 +5,4 @@ composer.lock
55
phpspec.yml
66
phpunit.xml
77
puli.json
8+
puli.phar

.travis.yml

Lines changed: 1 addition & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -34,6 +34,7 @@ before_install:
3434
- travis_retry composer self-update
3535

3636
install:
37+
- wget https://github.com/puli/cli/releases/download/1.0.0-beta10/puli.phar && chmod +x puli.phar
3738
- composer require symfony/symfony:${SYMFONY_VERSION} --no-update
3839
- travis_retry composer update ${COMPOSER_FLAGS} --prefer-source --no-interaction
3940

Lines changed: 85 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -0,0 +1,85 @@
1+
<?php
2+
3+
namespace Http\HttplugBundle\DependencyInjection\Compiler;
4+
5+
use Http\Client\HttpClient;
6+
use Http\HttplugBundle\Util\HttplugFactory;
7+
use Http\Message\MessageFactory;
8+
use Http\Message\StreamFactory;
9+
use Http\Message\UriFactory;
10+
use Symfony\Component\DependencyInjection\Compiler\CompilerPassInterface;
11+
use Symfony\Component\DependencyInjection\ContainerBuilder;
12+
use Symfony\Component\DependencyInjection\Exception\RuntimeException;
13+
use Symfony\Component\DependencyInjection\Reference;
14+
15+
/**
16+
* Adds fallback and discovery services.
17+
*
18+
* @author Márk Sági-Kazár <[email protected]>
19+
*/
20+
final class DiscoveryPass implements CompilerPassInterface
21+
{
22+
/**
23+
* Fallback services and classes.
24+
*
25+
* @var array
26+
*/
27+
private $services = [
28+
'client' => HttpClient::class,
29+
'message_factory' => MessageFactory::class,
30+
'uri_factory' => UriFactory::class,
31+
'stream_factory' => StreamFactory::class,
32+
];
33+
34+
/**
35+
* {@inheritdoc}
36+
*/
37+
public function process(ContainerBuilder $container)
38+
{
39+
$useDiscovery = false;
40+
41+
foreach ($this->services as $service => $class) {
42+
$serviceId = sprintf('httplug.%s.default', $service);
43+
44+
if (false === $container->has($serviceId)) {
45+
// Register and create factory for the first time
46+
if (false === $useDiscovery) {
47+
$this->registerFactory($container);
48+
49+
$factory = [
50+
new Reference('httplug.factory'),
51+
'find',
52+
];
53+
54+
$useDiscovery = true;
55+
}
56+
57+
$definition = $container->register($serviceId, $class);
58+
59+
$definition->setFactory($factory);
60+
$definition->addArgument($class);
61+
}
62+
}
63+
}
64+
65+
/**
66+
* @param ContainerBuilder $container
67+
*
68+
* @throws RuntimeException
69+
*/
70+
private function registerFactory(ContainerBuilder $container)
71+
{
72+
if (false === $container->has('puli.discovery')) {
73+
throw new RuntimeException(
74+
'You need to install puli/symfony-bundle or add configuration at httplug.classes in order to use this bundle. Refer to http://docs.php-http/en/latest/integrations/index.html'
75+
);
76+
}
77+
78+
$definition = $container->register('httplug.factory', HttplugFactory::class);
79+
80+
$definition
81+
->addArgument(new Reference('puli.discovery'))
82+
->setPublic(false)
83+
;
84+
}
85+
}

DependencyInjection/HttplugExtension.php

Lines changed: 1 addition & 3 deletions
Original file line numberDiff line numberDiff line change
@@ -33,7 +33,6 @@ public function load(array $configs, ContainerBuilder $container)
3333

3434
$loader->load('services.xml');
3535
$loader->load('plugins.xml');
36-
$loader->load('discovery.xml');
3736

3837
$enabled = is_bool($config['toolbar']['enabled']) ? $config['toolbar']['enabled'] : $container->hasParameter('kernel.debug') && $container->getParameter('kernel.debug');
3938
if ($enabled) {
@@ -48,14 +47,14 @@ public function load(array $configs, ContainerBuilder $container)
4847

4948
foreach ($config['classes'] as $service => $class) {
5049
if (!empty($class)) {
51-
$container->removeDefinition(sprintf('httplug.%s.default', $service));
5250
$container->register(sprintf('httplug.%s.default', $service), $class);
5351
}
5452
}
5553

5654
foreach ($config['main_alias'] as $type => $id) {
5755
$container->setAlias(sprintf('httplug.%s', $type), $id);
5856
}
57+
5958
$this->configurePlugins($container, $config['plugins']);
6059
$this->configureClients($container, $config);
6160
}
@@ -174,7 +173,6 @@ private function configurePluginByName($name, Definition $definition, array $con
174173

175174
/**
176175
* @param ContainerBuilder $container
177-
* @param Definition $parent
178176
* @param array $config
179177
*/
180178
private function configureAuthentication(ContainerBuilder $container, array $config)

HttplugBundle.php

Lines changed: 8 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -2,6 +2,8 @@
22

33
namespace Http\HttplugBundle;
44

5+
use Http\HttplugBundle\DependencyInjection\Compiler\DiscoveryPass;
6+
use Symfony\Component\DependencyInjection\ContainerBuilder;
57
use Symfony\Component\HttpKernel\Bundle\Bundle;
68

79
/**
@@ -10,4 +12,10 @@
1012
*/
1113
class HttplugBundle extends Bundle
1214
{
15+
public function build(ContainerBuilder $container)
16+
{
17+
parent::build($container);
18+
19+
$container->addCompilerPass(new DiscoveryPass());
20+
}
1321
}

Resources/config/discovery.xml

Lines changed: 0 additions & 25 deletions
This file was deleted.

Tests/Resources/app/AppKernel.php

Lines changed: 7 additions & 1 deletion
Original file line numberDiff line numberDiff line change
@@ -10,10 +10,16 @@ class AppKernel extends Kernel
1010
*/
1111
public function registerBundles()
1212
{
13-
return [
13+
$bundles = [
1414
new \Symfony\Bundle\FrameworkBundle\FrameworkBundle(),
1515
new \Http\HttplugBundle\HttplugBundle(),
1616
];
17+
18+
if (false === defined('HHVM_VERSION')) {
19+
array_splice($bundles, 1, 0, [new \Puli\SymfonyBundle\PuliBundle()]);
20+
}
21+
22+
return $bundles;
1723
}
1824

1925
/**
Lines changed: 76 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -0,0 +1,76 @@
1+
<?php
2+
3+
namespace Http\HttplugBundle\Tests\Unit\DependencyInjection\Compiler;
4+
5+
use Http\Client\HttpClient;
6+
use Http\HttplugBundle\DependencyInjection\Compiler\DiscoveryPass;
7+
use Http\HttplugBundle\Util\HttplugFactory;
8+
use Http\Message\MessageFactory;
9+
use Http\Message\StreamFactory;
10+
use Http\Message\UriFactory;
11+
use Matthias\SymfonyDependencyInjectionTest\PhpUnit\AbstractCompilerPassTestCase;
12+
use Symfony\Component\DependencyInjection\ContainerBuilder;
13+
use Symfony\Component\DependencyInjection\Definition;
14+
15+
/**
16+
* @author Márk Sági-Kazár <[email protected]>
17+
*/
18+
final class DiscoveryPassTest extends AbstractCompilerPassTestCase
19+
{
20+
protected function registerCompilerPass(ContainerBuilder $container)
21+
{
22+
$container->addCompilerPass(new DiscoveryPass());
23+
}
24+
25+
public function testDiscoveryFallbacks()
26+
{
27+
$this->setDefinition('puli.discovery', new Definition('Puli\Discovery\Api\Discovery'));
28+
29+
$this->compile();
30+
31+
$this->assertContainerBuilderHasService('httplug.factory', HttplugFactory::class);
32+
33+
$this->assertContainerBuilderHasService('httplug.client.default', HttpClient::class);
34+
$this->assertContainerBuilderHasService('httplug.message_factory.default', MessageFactory::class);
35+
$this->assertContainerBuilderHasService('httplug.uri_factory.default', UriFactory::class);
36+
$this->assertContainerBuilderHasService('httplug.stream_factory.default', StreamFactory::class);
37+
}
38+
39+
public function testDiscoveryPartialFallbacks()
40+
{
41+
$this->setDefinition('puli.discovery', new Definition('Puli\Discovery\Api\Discovery'));
42+
$this->setDefinition('httplug.client.default', new Definition('Http\Adapter\Guzzle6\Client'));
43+
44+
$this->compile();
45+
46+
$this->assertContainerBuilderHasService('httplug.factory', HttplugFactory::class);
47+
48+
$this->assertContainerBuilderHasService('httplug.client.default', 'Http\Adapter\Guzzle6\Client');
49+
$this->assertContainerBuilderHasService('httplug.message_factory.default', MessageFactory::class);
50+
$this->assertContainerBuilderHasService('httplug.uri_factory.default', UriFactory::class);
51+
$this->assertContainerBuilderHasService('httplug.stream_factory.default', StreamFactory::class);
52+
}
53+
54+
public function testNoDiscoveryFallbacks()
55+
{
56+
$this->setDefinition('httplug.client.default', new Definition(HttpClient::class));
57+
$this->setDefinition('httplug.message_factory.default', new Definition(MessageFactory::class));
58+
$this->setDefinition('httplug.uri_factory.default', new Definition(UriFactory::class));
59+
$this->setDefinition('httplug.stream_factory.default', new Definition(StreamFactory::class));
60+
61+
$this->compile();
62+
63+
$this->assertContainerBuilderNotHasService('httplug.factory');
64+
}
65+
66+
/**
67+
* Overridden test as we have dependencies in this compiler pass.
68+
*
69+
* @test
70+
* @expectedException \RuntimeException
71+
*/
72+
public function compilation_should_not_fail_with_empty_container()
73+
{
74+
$this->compile();
75+
}
76+
}

Tests/Unit/DependencyInjection/HttplugExtensionTest.php

Lines changed: 0 additions & 17 deletions
Original file line numberDiff line numberDiff line change
@@ -24,11 +24,6 @@ public function testConfigLoadDefault()
2424
foreach (['client', 'message_factory', 'uri_factory', 'stream_factory'] as $type) {
2525
$this->assertContainerBuilderHasAlias("httplug.$type", "httplug.$type.default");
2626
}
27-
28-
$this->assertContainerBuilderHasService('httplug.client.default', 'Http\Client\HttpClient');
29-
$this->assertContainerBuilderHasService('httplug.message_factory.default', 'Http\Message\MessageFactory');
30-
$this->assertContainerBuilderHasService('httplug.uri_factory.default', 'Http\Message\UriFactory');
31-
$this->assertContainerBuilderHasService('httplug.stream_factory.default', 'Http\Message\StreamFactory');
3227
}
3328

3429
public function testConfigLoadClass()
@@ -39,14 +34,7 @@ public function testConfigLoadClass()
3934
],
4035
]);
4136

42-
foreach (['client', 'message_factory', 'uri_factory', 'stream_factory'] as $type) {
43-
$this->assertContainerBuilderHasAlias("httplug.$type", "httplug.$type.default");
44-
}
45-
4637
$this->assertContainerBuilderHasService('httplug.client.default', 'Http\Adapter\Guzzle6\Client');
47-
$this->assertContainerBuilderHasService('httplug.message_factory.default', 'Http\Message\MessageFactory');
48-
$this->assertContainerBuilderHasService('httplug.uri_factory.default', 'Http\Message\UriFactory');
49-
$this->assertContainerBuilderHasService('httplug.stream_factory.default', 'Http\Message\StreamFactory');
5038
}
5139

5240
public function testConfigLoadService()
@@ -63,10 +51,5 @@ public function testConfigLoadService()
6351
foreach (['client', 'message_factory', 'uri_factory', 'stream_factory'] as $type) {
6452
$this->assertContainerBuilderHasAlias("httplug.$type", "my_{$type}_service");
6553
}
66-
67-
$this->assertContainerBuilderHasService('httplug.client.default', 'Http\Client\HttpClient');
68-
$this->assertContainerBuilderHasService('httplug.message_factory.default', 'Http\Message\MessageFactory');
69-
$this->assertContainerBuilderHasService('httplug.uri_factory.default', 'Http\Message\UriFactory');
70-
$this->assertContainerBuilderHasService('httplug.stream_factory.default', 'Http\Message\StreamFactory');
7154
}
7255
}

0 commit comments

Comments
 (0)