Skip to content
Merged
Show file tree
Hide file tree
Changes from all commits
Commits
File filter

Filter by extension

Filter by extension


Conversations
Failed to load comments.
Loading
Jump to
Jump to file
Failed to load files.
Loading
Diff view
Diff view
8 changes: 7 additions & 1 deletion Justfile
Original file line number Diff line number Diff line change
Expand Up @@ -4,7 +4,7 @@ _default:
just --list --unsorted

# Install all dependencies necesesary to run Annotated Container tools
install: _install_labrador_cs _install_phpunit _install_psalm _install_ac
install: _install_labrador_cs _install_phpunit _install_psalm _install_phploc _install_ac

_install_ac:
composer install
Expand All @@ -18,6 +18,9 @@ _install_phpunit:
_install_psalm:
cd tools/psalm && composer install

_install_phploc:
cd tools/phploc && composer install

# Run unit tests
test *FLAGS:
@XDEBUG_MODE=coverage ./tools/phpunit/vendor/bin/phpunit {{FLAGS}}
Expand Down Expand Up @@ -47,6 +50,9 @@ code-lint:
code-lint-fix:
@./tools/labrador-cs/vendor/bin/phpcbf -p --standard=./tools/labrador-cs/vendor/cspray/labrador-coding-standard/ruleset.xml --exclude=Generic.Files.LineLength src test

loc:
@./tools/phploc/vendor/bin/phploc src

# Run all CI checks. ALL checks will run, regardless of failures
ci-check:
-@just test
Expand Down
6 changes: 6 additions & 0 deletions annotated-container.xsd
Original file line number Diff line number Diff line change
Expand Up @@ -32,6 +32,7 @@

<xs:element name="definitionProviders" type="definitionProvidersType" minOccurs="0" maxOccurs="1" />
<xs:element name="parameterStores" type="parameterStoresType" minOccurs="0" maxOccurs="1" />
<xs:element name="listeners" type="listenersType" minOccurs="0" maxOccurs="1" />
</xs:all>
<xs:attribute name="version" type="xs:string" use="required" />
</xs:complexType>
Expand Down Expand Up @@ -86,5 +87,10 @@
</xs:sequence>
</xs:complexType>

<xs:complexType name="listenersType">
<xs:sequence minOccurs="0" maxOccurs="unbounded">
<xs:element name="listener" type="xs:token" />
</xs:sequence>
</xs:complexType>

</xs:schema>
9 changes: 2 additions & 7 deletions docs/how-to/02-bootstrap-your-container.md
Original file line number Diff line number Diff line change
Expand Up @@ -224,7 +224,7 @@ By default, boostrapping expects all the path fragments in your configuration to

namespace Acme\Demo;

use Cspray\AnnotatedContainer\Bootstrap\Bootstrap;use Cspray\AnnotatedContainer\Bootstrap\DefaultDefinitionProviderFactory;use Cspray\AnnotatedContainer\Bootstrap\DefaultParameterStoreFactory;use Cspray\AnnotatedContainer\ContainerFactory\PhpDiContainerFactory;use Cspray\AnnotatedContainer\Event\Emitter;
use Cspray\AnnotatedContainer\Bootstrap\Bootstrap;use Cspray\AnnotatedContainer\Bootstrap\Configuration\DefaultDefinitionProviderFactory;use Cspray\AnnotatedContainer\Bootstrap\Configuration\DefaultParameterStoreFactory;use Cspray\AnnotatedContainer\ContainerFactory\PhpDiContainerFactory;use Cspray\AnnotatedContainer\Event\Emitter;

// This method is an implementation provided by the reader
$directoryResolver = MyDirectoryResolver::create();
Expand Down Expand Up @@ -252,12 +252,7 @@ Setting up caching is something that you must explicitly opt into during your bo

namespace Acme\Demo;

use Cspray\AnnotatedContainer\Bootstrap\Bootstrap;
use Cspray\AnnotatedContainer\Bootstrap\CacheAwareBootstrappingConfigurationProvider;
use Cspray\AnnotatedContainer\Bootstrap\DefaultDefinitionProviderFactory;
use Cspray\AnnotatedContainer\Bootstrap\DefaultParameterStoreFactory;
use Cspray\AnnotatedContainer\Bootstrap\XmlBootstrappingConfigurationProvider;use Cspray\AnnotatedContainer\ContainerFactory\PhpDiContainerFactory;
use Cspray\AnnotatedContainer\Definition\Cache\FileBackedContainerDefinitionCache;use Cspray\AnnotatedContainer\Definition\Serializer\XmlContainerDefinitionSerializer;use Cspray\AnnotatedContainer\Event\Emitter;
use Cspray\AnnotatedContainer\Bootstrap\Bootstrap;use Cspray\AnnotatedContainer\Bootstrap\CacheAwareBootstrappingConfigurationProvider;use Cspray\AnnotatedContainer\Bootstrap\XmlBootstrappingConfigurationProvider;use Cspray\AnnotatedContainer\Definition\Cache\FileBackedContainerDefinitionCache;use Cspray\AnnotatedContainer\Definition\Serializer\XmlContainerDefinitionSerializer;use Cspray\AnnotatedContainer\Event\Emitter;

$container = Bootstrap::from(new Emitter())
->bootstrapContainer(
Expand Down
16 changes: 9 additions & 7 deletions known-issues.xml
Original file line number Diff line number Diff line change
@@ -1,6 +1,11 @@
<?xml version="1.0" encoding="UTF-8"?>
<files psalm-version="5.24.0@462c80e31c34e58cc4f750c656be3927e80e550e">
<file src="src/Bootstrap/ServiceWiringListener.php">
<file src="src/Bootstrap/Configuration/ContainerDefinitionAnalysisOptionsFromBootstrappingConfiguration.php">
<ArgumentTypeCoercion>
<code><![CDATA[$scanPaths]]></code>
</ArgumentTypeCoercion>
</file>
<file src="src/Bootstrap/Listener/ServiceWiringListener.php">
<MixedArgument>
<code><![CDATA[$service]]></code>
</MixedArgument>
Expand Down Expand Up @@ -66,7 +71,7 @@
[$serviceDelegateDefinition->classMethod()->class()->name(), $serviceDelegateDefinition->classMethod()->methodName()],
$this->parametersForServiceDelegateToArray($injector, $state, $serviceDelegateDefinition),
)]]></code>
<code><![CDATA[$value]]></code>
<code><![CDATA[$this->injector->make($id)]]></code>
</MixedReturnStatement>
</file>
<file src="src/ContainerFactory/ContainerFactoryOptionsBuilder.php">
Expand Down Expand Up @@ -234,11 +239,8 @@
</InvalidArgument>
</file>
<file src="src/StaticAnalysis/ContainerDefinitionAnalysisOptionsBuilder.php">
<LessSpecificReturnStatement>
<InvalidArgument>
<code><![CDATA[$this->directories]]></code>
</LessSpecificReturnStatement>
<MoreSpecificReturnType>
<code><![CDATA[array]]></code>
</MoreSpecificReturnType>
</InvalidArgument>
</file>
</files>
2 changes: 1 addition & 1 deletion psalm.xml
Original file line number Diff line number Diff line change
Expand Up @@ -36,7 +36,7 @@
<MissingTemplateParam>
<errorLevel type="suppress">
<!-- This anonymous class is 100% documented with the appropriate template param but it is not getting picked up properly -->
<file name="src/Bootstrap/ServiceWiringListener.php" />
<file name="src/Bootstrap/Listener/ServiceWiringListener.php" />
</errorLevel>
</MissingTemplateParam>
</issueHandlers>
Expand Down
19 changes: 18 additions & 1 deletion src/Bootstrap/Bootstrap.php
Original file line number Diff line number Diff line change
Expand Up @@ -3,6 +3,17 @@
namespace Cspray\AnnotatedContainer\Bootstrap;

use Cspray\AnnotatedContainer\AnnotatedContainer;
use Cspray\AnnotatedContainer\Bootstrap\Configuration\BootstrappingConfiguration;
use Cspray\AnnotatedContainer\Bootstrap\Configuration\ContainerDefinitionAnalysisOptionsFromBootstrappingConfiguration;
use Cspray\AnnotatedContainer\Bootstrap\Configuration\DefaultDefinitionProviderFactory;
use Cspray\AnnotatedContainer\Bootstrap\Configuration\DefaultListenerFactory;
use Cspray\AnnotatedContainer\Bootstrap\Configuration\DefaultParameterStoreFactory;
use Cspray\AnnotatedContainer\Bootstrap\Configuration\DefinitionProviderFactory;
use Cspray\AnnotatedContainer\Bootstrap\Configuration\ListenerFactory;
use Cspray\AnnotatedContainer\Bootstrap\Configuration\ParameterStoreFactory;
use Cspray\AnnotatedContainer\Bootstrap\Configuration\XmlBootstrappingConfiguration;
use Cspray\AnnotatedContainer\Bootstrap\DirectoryResolver\BootstrappingDirectoryResolver;
use Cspray\AnnotatedContainer\Bootstrap\DirectoryResolver\VendorPresenceBasedBootstrappingDirectoryResolver;
use Cspray\AnnotatedContainer\ContainerFactory\ContainerFactory;
use Cspray\AnnotatedContainer\ContainerFactory\ContainerFactoryOptionsBuilder;
use Cspray\AnnotatedContainer\Definition\ContainerDefinition;
Expand Down Expand Up @@ -33,6 +44,7 @@ public static function fromAnnotatedContainerConventions(
ContainerFactory $containerFactory,
Emitter $emitter,
ParameterStoreFactory $parameterStoreFactory = new DefaultParameterStoreFactory(),
ListenerFactory $listenerFactory = new DefaultListenerFactory(),
DefinitionProviderFactory $definitionProviderFactory = new DefaultDefinitionProviderFactory(),
BootstrappingDirectoryResolver $directoryResolver = new VendorPresenceBasedBootstrappingDirectoryResolver(),
Filesystem $filesystem = new PhpFunctionsFilesystem()
Expand All @@ -41,7 +53,8 @@ public static function fromAnnotatedContainerConventions(
$filesystem,
$directoryResolver->configurationPath('annotated-container.xml'),
$parameterStoreFactory,
$definitionProviderFactory
$definitionProviderFactory,
$listenerFactory
);

return self::fromCompleteSetup(
Expand Down Expand Up @@ -75,6 +88,10 @@ public function bootstrapContainer(

$this->stopwatch->start();

foreach ($this->bootstrappingConfiguration->listeners() as $listener) {
$this->emitter->addListener($listener);
}

$analysisOptions = $this->analysisOptions($this->bootstrappingConfiguration);

$this->emitter->emitBeforeBootstrap($this->bootstrappingConfiguration);
Expand Down
Original file line number Diff line number Diff line change
@@ -1,11 +1,12 @@
<?php declare(strict_types=1);

namespace Cspray\AnnotatedContainer\Bootstrap;
namespace Cspray\AnnotatedContainer\Bootstrap\Configuration;

use Cspray\AnnotatedContainer\ArchitecturalDecisionRecords\SingleEntrypointDefinitionProvider;
use Cspray\AnnotatedContainer\ContainerFactory\ParameterStore;
use Cspray\AnnotatedContainer\Definition\Cache\ContainerDefinitionCache;
use Cspray\AnnotatedContainer\Event\Listener;
use Cspray\AnnotatedContainer\StaticAnalysis\DefinitionProvider;
use Cspray\AnnotatedContainer\ContainerFactory\ParameterStore;

interface BootstrappingConfiguration {

Expand All @@ -23,4 +24,9 @@ public function containerDefinitionProvider() : ?DefinitionProvider;
* @return list<ParameterStore>
*/
public function parameterStores() : array;

/**
* @return list<Listener>
*/
public function listeners() : array;
}
Original file line number Diff line number Diff line change
@@ -1,6 +1,6 @@
<?php declare(strict_types=1);

namespace Cspray\AnnotatedContainer\Bootstrap;
namespace Cspray\AnnotatedContainer\Bootstrap\Configuration;

use Cspray\AnnotatedContainer\ArchitecturalDecisionRecords\SingleEntrypointDefinitionProvider;
use Cspray\AnnotatedContainer\Definition\Cache\ContainerDefinitionCache;
Expand Down Expand Up @@ -30,4 +30,8 @@ public function containerDefinitionProvider() : ?DefinitionProvider {
public function parameterStores() : array {
return $this->configuration->parameterStores();
}

public function listeners() : array {
return $this->configuration->listeners();
}
}
Original file line number Diff line number Diff line change
@@ -1,7 +1,8 @@
<?php declare(strict_types=1);

namespace Cspray\AnnotatedContainer\Bootstrap;
namespace Cspray\AnnotatedContainer\Bootstrap\Configuration;

use Cspray\AnnotatedContainer\Bootstrap\DirectoryResolver\BootstrappingDirectoryResolver;
use Cspray\AnnotatedContainer\StaticAnalysis\ContainerDefinitionAnalysisOptions;
use Cspray\AnnotatedContainer\StaticAnalysis\ContainerDefinitionAnalysisOptionsBuilder;

Expand Down
Original file line number Diff line number Diff line change
@@ -1,6 +1,6 @@
<?php declare(strict_types=1);

namespace Cspray\AnnotatedContainer\Bootstrap;
namespace Cspray\AnnotatedContainer\Bootstrap\Configuration;

use Cspray\AnnotatedContainer\Exception\InvalidDefinitionProvider;
use Cspray\AnnotatedContainer\StaticAnalysis\DefinitionProvider;
Expand Down
17 changes: 17 additions & 0 deletions src/Bootstrap/Configuration/DefaultListenerFactory.php
Original file line number Diff line number Diff line change
@@ -0,0 +1,17 @@
<?php declare(strict_types=1);

namespace Cspray\AnnotatedContainer\Bootstrap\Configuration;

use Cspray\AnnotatedContainer\Event\Listener;

final class DefaultListenerFactory implements ListenerFactory {

/**
* @param string|class-string<Listener> $identifier
* @return Listener
*/
public function createListener(string $identifier) : Listener {
assert(is_a($identifier, Listener::class, true));
return new $identifier();
}
}
Original file line number Diff line number Diff line change
@@ -1,6 +1,6 @@
<?php declare(strict_types=1);

namespace Cspray\AnnotatedContainer\Bootstrap;
namespace Cspray\AnnotatedContainer\Bootstrap\Configuration;

use Cspray\AnnotatedContainer\ContainerFactory\ParameterStore;
use Cspray\AnnotatedContainer\Exception\InvalidParameterStore;
Expand Down
Original file line number Diff line number Diff line change
@@ -1,6 +1,6 @@
<?php declare(strict_types=1);

namespace Cspray\AnnotatedContainer\Bootstrap;
namespace Cspray\AnnotatedContainer\Bootstrap\Configuration;

use Cspray\AnnotatedContainer\StaticAnalysis\DefinitionProvider;

Expand Down
Original file line number Diff line number Diff line change
@@ -1,6 +1,6 @@
<?php declare(strict_types=1);

namespace Cspray\AnnotatedContainer\Bootstrap;
namespace Cspray\AnnotatedContainer\Bootstrap\Configuration;

use Cspray\AnnotatedContainer\ContainerFactory\ParameterStore;

Expand Down
14 changes: 14 additions & 0 deletions src/Bootstrap/Configuration/ListenerFactory.php
Original file line number Diff line number Diff line change
@@ -0,0 +1,14 @@
<?php declare(strict_types=1);

namespace Cspray\AnnotatedContainer\Bootstrap\Configuration;

use Cspray\AnnotatedContainer\Event\Listener;

interface ListenerFactory {

/**
* @param string|class-string<Listener> $identifier
* @return Listener
*/
public function createListener(string $identifier) : Listener;
}
Original file line number Diff line number Diff line change
@@ -1,6 +1,6 @@
<?php declare(strict_types=1);

namespace Cspray\AnnotatedContainer\Bootstrap;
namespace Cspray\AnnotatedContainer\Bootstrap\Configuration;

use Cspray\AnnotatedContainer\ContainerFactory\ParameterStore;

Expand Down
Original file line number Diff line number Diff line change
@@ -1,19 +1,19 @@
<?php declare(strict_types=1);

namespace Cspray\AnnotatedContainer\Bootstrap;
namespace Cspray\AnnotatedContainer\Bootstrap\Configuration;

use Cspray\AnnotatedContainer\ArchitecturalDecisionRecords\SingleEntrypointDefinitionProvider;
use Cspray\AnnotatedContainer\ContainerFactory\ParameterStore;
use Cspray\AnnotatedContainer\Definition\Cache\ContainerDefinitionCache;
use Cspray\AnnotatedContainer\Event\Listener;
use Cspray\AnnotatedContainer\Exception\InvalidBootstrapConfiguration;
use Cspray\AnnotatedContainer\Filesystem\Filesystem;
use Cspray\AnnotatedContainer\StaticAnalysis\CompositeDefinitionProvider;
use Cspray\AnnotatedContainer\StaticAnalysis\DefinitionProvider;
use Cspray\AnnotatedContainer\ContainerFactory\ParameterStore;
use Cspray\AnnotatedContainer\Exception\InvalidBootstrapConfiguration;
use Cspray\AnnotatedContainer\ArchitecturalDecisionRecords\SingleEntrypointDefinitionProvider;
use DOMDocument;
use DOMElement;
use DOMNodeList;
use DOMXPath;

use function libxml_use_internal_errors;

final class XmlBootstrappingConfiguration implements BootstrappingConfiguration {
Expand All @@ -29,18 +29,24 @@ final class XmlBootstrappingConfiguration implements BootstrappingConfiguration
*/
private readonly array $parameterStores;

/**
* @var list<Listener>
*/
private readonly array $listeners;

public function __construct(
private readonly Filesystem $filesystem,
private readonly string $xmlFile,
private readonly ParameterStoreFactory $parameterStoreFactory,
private readonly DefinitionProviderFactory $definitionProviderFactory
private readonly DefinitionProviderFactory $definitionProviderFactory,
private readonly ListenerFactory $listenerFactory,
) {
if (!$this->filesystem->isFile($this->xmlFile)) {
throw InvalidBootstrapConfiguration::fromFileMissing($this->xmlFile);
}

try {
$schemaFile = dirname(__DIR__, 2) . '/annotated-container.xsd';
$schemaFile = dirname(__DIR__, 3) . '/annotated-container.xsd';
$dom = new DOMDocument();
$dom->loadXML($this->filesystem->read($this->xmlFile));
libxml_use_internal_errors(true);
Expand Down Expand Up @@ -117,9 +123,21 @@ public function __construct(
}
}

$listeners = [];
$listenerNodes = $xpath->query('/ac:annotatedContainer/ac:listeners/ac:listener/text()');
if ($listenerNodes instanceof DOMNodeList) {
foreach ($listenerNodes as $listenerNode) {
assert(isset($listenerNode->nodeValue));
$listenerType = trim($listenerNode->nodeValue);
$listener = $this->listenerFactory->createListener($listenerType);
$listeners[] = $listener;
}
}

$this->directories = $scanDirectories;
$this->definitionProvider = $definitionProvider;
$this->parameterStores = $parameterStores;
$this->listeners = $listeners;
} finally {
libxml_clear_errors();
libxml_use_internal_errors(false);
Expand All @@ -142,6 +160,13 @@ public function parameterStores() : array {
return $this->parameterStores;
}

/**
* @return list<Listener>
*/
public function listeners() : array {
return $this->listeners;
}

public function cache() : ?ContainerDefinitionCache {
return null;
}
Expand Down
Original file line number Diff line number Diff line change
@@ -1,6 +1,6 @@
<?php declare(strict_types=1);

namespace Cspray\AnnotatedContainer\Bootstrap;
namespace Cspray\AnnotatedContainer\Bootstrap\DirectoryResolver;

interface BootstrappingDirectoryResolver {

Expand Down
Original file line number Diff line number Diff line change
@@ -1,6 +1,6 @@
<?php declare(strict_types=1);

namespace Cspray\AnnotatedContainer\Bootstrap;
namespace Cspray\AnnotatedContainer\Bootstrap\DirectoryResolver;

final class RootDirectoryBootstrappingDirectoryResolver implements BootstrappingDirectoryResolver {

Expand Down
Loading