From 25f231cd80ff1525b950b28c3e9e63ac9033d480 Mon Sep 17 00:00:00 2001 From: Daniel Bannert Date: Sat, 29 Sep 2018 11:15:27 +0200 Subject: [PATCH] added reset call if configurator was called in onPostAutoloadDump (#85) | Q | A | --------------- | --- | Bug fix? | yes | New feature? | no | BC breaks? | no | Deprecations? | no | Related tickets | - | License | MIT | Doc PR | - --- src/Automatic/Automatic.php | 30 ++++-- src/Automatic/Container.php | 30 +++--- .../Contract/PackageConfigurator.php | 11 ++ src/Automatic/Operation/AbstractOperation.php | 42 ++++---- src/Automatic/PackageConfigurator.php | 8 +- src/Automatic/ScriptExecutor.php | 2 +- tests/Automatic/AutomaticTest.php | 101 +++++++++++++++++- tests/Automatic/ContainerTest.php | 6 +- .../prisis/install/Configurator.php | 3 +- tests/Automatic/Operation/InstallTest.php | 6 +- tests/Automatic/Operation/UninstallTest.php | 6 +- tests/Automatic/ScriptExecutorTest.php | 14 +-- 12 files changed, 194 insertions(+), 65 deletions(-) create mode 100644 src/Automatic/Contract/PackageConfigurator.php diff --git a/src/Automatic/Automatic.php b/src/Automatic/Automatic.php index c61374a5..3b7cf324 100644 --- a/src/Automatic/Automatic.php +++ b/src/Automatic/Automatic.php @@ -37,6 +37,7 @@ use Narrowspark\Automatic\Common\Traits\ExpandTargetDirTrait; use Narrowspark\Automatic\Common\Traits\GetGenericPropertyReaderTrait; use Narrowspark\Automatic\Common\Util; +use Narrowspark\Automatic\Contract\Configurator as ConfiguratorContract; use Narrowspark\Automatic\Contract\Container as ContainerContract; use Narrowspark\Automatic\Installer\ConfiguratorInstaller; use Narrowspark\Automatic\Installer\InstallationManager; @@ -96,6 +97,13 @@ class Automatic implements PluginInterface, EventSubscriberInterface */ private static $activated = true; + /** + * Check if the Configurators a loaded. + * + * @var bool + */ + private static $configuratorsLoaded = false; + /** * Check if composer.lock should be updated. * @@ -470,16 +478,24 @@ public function onPostUninstall(PackageEvent $event): void * * Load configurators from "automatic-configurator". * + * @param \Composer\Script\Event $event + * * @throws \ReflectionException * * @return void */ - public function onPostAutoloadDump(): void + public function onPostAutoloadDump(Event $event): void { - $lock = $this->container->get(Lock::class); - $vendorDir = $this->container->get('vendor-dir'); - $configurator = $this->container->get(Configurator::class); - $classMap = (array) $lock->get(self::LOCK_CLASSMAP); + /** @var \Narrowspark\Automatic\Configurator $configurator */ + $configurator = $this->container->get(ConfiguratorContract::class); + + if (self::$configuratorsLoaded === true) { + $configurator->reset(); + } + + $lock = $this->container->get(Lock::class); + $vendorDir = $this->container->get('vendor-dir'); + $classMap = (array) $lock->get(self::LOCK_CLASSMAP); foreach ((array) $lock->get(ConfiguratorInstaller::LOCK_KEY) as $packageName => $classList) { foreach ($classMap[$packageName] as $class => $path) { @@ -497,6 +513,8 @@ public function onPostAutoloadDump(): void } } } + + self::$configuratorsLoaded = true; } /** @@ -658,7 +676,7 @@ public function executeAutoScripts(Event $event): void $reflectionClass = new ReflectionClass($class); if ($reflectionClass->isInstantiable() && $reflectionClass->hasMethod('getType')) { - $scriptExecutor->addExtender($class::getType(), $class); + $scriptExecutor->add($class::getType(), $class); } } } diff --git a/src/Automatic/Container.php b/src/Automatic/Container.php index d278faf2..8360a18c 100644 --- a/src/Automatic/Container.php +++ b/src/Automatic/Container.php @@ -11,8 +11,10 @@ use Narrowspark\Automatic\Common\ClassFinder; use Narrowspark\Automatic\Common\ScriptExtender\PhpScriptExtender; use Narrowspark\Automatic\Common\Traits\GetGenericPropertyReaderTrait; +use Narrowspark\Automatic\Contract\Configurator as ConfiguratorContract; use Narrowspark\Automatic\Contract\Container as ContainerContract; use Narrowspark\Automatic\Contract\Exception\InvalidArgumentException; +use Narrowspark\Automatic\Contract\PackageConfigurator as PackageConfiguratorContract; use Narrowspark\Automatic\Installer\ConfiguratorInstaller; use Narrowspark\Automatic\Installer\SkeletonInstaller; use Narrowspark\Automatic\Operation\Install; @@ -102,20 +104,27 @@ public function __construct(Composer $composer, IOInterface $io) $container->get(ClassFinder::class) ); }, - Configurator::class => static function (ContainerContract $container) { + ConfiguratorContract::class => static function (ContainerContract $container) { return new Configurator( $container->get(Composer::class), $container->get(IOInterface::class), $container->get('composer-extra') ); }, + PackageConfiguratorContract::class => static function (ContainerContract $container) { + return new PackageConfigurator( + $container->get(Composer::class), + $container->get(IOInterface::class), + $container->get('composer-extra') + ); + }, Install::class => static function (ContainerContract $container) { return new Install( $container->get('vendor-dir'), $container->get(Lock::class), $container->get(IOInterface::class), - $container->get(Configurator::class), - $container->get(PackageConfigurator::class), + $container->get(ConfiguratorContract::class), + $container->get(PackageConfiguratorContract::class), $container->get(ClassFinder::class) ); }, @@ -124,8 +133,8 @@ public function __construct(Composer $composer, IOInterface $io) $container->get('vendor-dir'), $container->get(Lock::class), $container->get(IOInterface::class), - $container->get(Configurator::class), - $container->get(PackageConfigurator::class), + $container->get(ConfiguratorContract::class), + $container->get(PackageConfiguratorContract::class), $container->get(ClassFinder::class) ); }, @@ -161,18 +170,11 @@ public function __construct(Composer $composer, IOInterface $io) $container->get('composer-extra') ); - $scriptExecutor->addExtender(ScriptExtender::getType(), ScriptExtender::class); - $scriptExecutor->addExtender(PhpScriptExtender::getType(), PhpScriptExtender::class); + $scriptExecutor->add(ScriptExtender::getType(), ScriptExtender::class); + $scriptExecutor->add(PhpScriptExtender::getType(), PhpScriptExtender::class); return $scriptExecutor; }, - PackageConfigurator::class => static function (ContainerContract $container) { - return new PackageConfigurator( - $container->get(Composer::class), - $container->get(IOInterface::class), - $container->get('composer-extra') - ); - }, LegacyTagsManager::class => static function (ContainerContract $container) { return new LegacyTagsManager($container->get(IOInterface::class)); }, diff --git a/src/Automatic/Contract/PackageConfigurator.php b/src/Automatic/Contract/PackageConfigurator.php new file mode 100644 index 00000000..e2f391ca --- /dev/null +++ b/src/Automatic/Contract/PackageConfigurator.php @@ -0,0 +1,11 @@ +vendorDir = $vendorDir; @@ -84,18 +84,18 @@ public function __construct( /** * Show a waring if remaining configurators are found in package config. * - * @param \Narrowspark\Automatic\Common\Contract\Package $package - * @param \Narrowspark\Automatic\PackageConfigurator $packageConfigurator - * @param \Narrowspark\Automatic\Configurator $configurator + * @param \Narrowspark\Automatic\Common\Contract\Package $package + * @param \Narrowspark\Automatic\Contract\PackageConfigurator $packageConfigurator + * @param \Narrowspark\Automatic\Contract\Configurator $configurator * * @return void */ protected function showWarningOnRemainingConfigurators( PackageContract $package, - PackageConfigurator $packageConfigurator, - Configurator $configurator + PackageConfiguratorContract $packageConfigurator, + ConfiguratorContract $configurator ): void { - $packageConfigurators = \array_keys((array) $package->getConfig(ConfiguratorContract::TYPE)); + $packageConfigurators = \array_keys((array) $package->getConfig(CommonConfiguratorContract::TYPE)); foreach (\array_keys($configurator->getConfigurators()) as $key => $value) { if (isset($packageConfigurators[$key])) { @@ -129,9 +129,9 @@ protected function showWarningOnRemainingConfigurators( */ protected function addPackageConfigurators(PackageContract $package): void { - if ($package->hasConfig(PackageConfigurator::TYPE)) { + if ($package->hasConfig(PackageConfiguratorContract::TYPE)) { /** @var \Narrowspark\Automatic\Common\Configurator\AbstractConfigurator $class */ - foreach ((array) $package->getConfig(PackageConfigurator::TYPE) as $name => $class) { + foreach ((array) $package->getConfig(PackageConfiguratorContract::TYPE) as $class) { $reflectionClass = new \ReflectionClass($class); if ($reflectionClass->isInstantiable() && $reflectionClass->hasMethod('getName')) { diff --git a/src/Automatic/PackageConfigurator.php b/src/Automatic/PackageConfigurator.php index be4d7e41..be80d9d4 100644 --- a/src/Automatic/PackageConfigurator.php +++ b/src/Automatic/PackageConfigurator.php @@ -3,14 +3,10 @@ namespace Narrowspark\Automatic; use Narrowspark\Automatic\Common\Contract\Configurator as ConfiguratorContract; +use Narrowspark\Automatic\Contract\PackageConfigurator as PackageConfiguratorContract; -final class PackageConfigurator extends AbstractConfigurator +final class PackageConfigurator extends AbstractConfigurator implements PackageConfiguratorContract { - /** - * @var string - */ - public const TYPE = 'custom-configurators'; - /** * Get a package configurator. * diff --git a/src/Automatic/ScriptExecutor.php b/src/Automatic/ScriptExecutor.php index 53f7c208..c2a11255 100644 --- a/src/Automatic/ScriptExecutor.php +++ b/src/Automatic/ScriptExecutor.php @@ -80,7 +80,7 @@ public function __construct(Composer $composer, IOInterface $io, ProcessExecutor * * @return void */ - public function addExtender(string $name, string $extender): void + public function add(string $name, string $extender): void { if (isset($this->extenders[$name])) { throw new InvalidArgumentException(\sprintf('Script executor with the name [%s] already exists.', $name)); diff --git a/tests/Automatic/AutomaticTest.php b/tests/Automatic/AutomaticTest.php index f675eff3..53553b35 100644 --- a/tests/Automatic/AutomaticTest.php +++ b/tests/Automatic/AutomaticTest.php @@ -24,8 +24,10 @@ use Composer\Util\ProcessExecutor; use Composer\Util\RemoteFilesystem; use Narrowspark\Automatic\Automatic; +use Narrowspark\Automatic\Contract\Configurator as ConfiguratorContract; use Narrowspark\Automatic\Contract\Container as ContainerContract; use Narrowspark\Automatic\Installer\ConfiguratorInstaller; +use Narrowspark\Automatic\Installer\InstallationManager as NarrowsparkInstallationManager; use Narrowspark\Automatic\Installer\SkeletonInstaller; use Narrowspark\Automatic\Lock; use Narrowspark\Automatic\Prefetcher\ParallelDownloader; @@ -167,7 +169,10 @@ public function testActivate(): void $this->automatic->getContainer()->get(Lock::class)->get('@readme') ); - static::assertInstanceOf(\Narrowspark\Automatic\Installer\InstallationManager::class, $this->automatic->getContainer()->get(\Narrowspark\Automatic\Installer\InstallationManager::class)); + static::assertInstanceOf( + NarrowsparkInstallationManager::class, + $this->automatic->getContainer()->get(NarrowsparkInstallationManager::class) + ); } public function testActivateWithNoInteractive(): void @@ -733,6 +738,100 @@ public function testRunSkeletonGeneratorWithoutInstaller(): void $this->automatic->runSkeletonGenerator($this->mock(Event::class)); } + public function testOnPostAutoloadDump(): void + { + $containerMock = $this->mock(ContainerContract::class); + $configuratorMock = $this->mock(ConfiguratorContract::class); + $configuratorMock->shouldReceive('reset') + ->never(); + $configuratorMock->shouldReceive('add') + ->once() + ->with('test', 'Test\Configurator'); + + $containerMock->shouldReceive('get') + ->once() + ->with(ConfiguratorContract::class) + ->andReturn($configuratorMock); + + $this->lockMock->shouldReceive('get') + ->once() + ->with(Automatic::LOCK_CLASSMAP) + ->andReturn([ + 'prisis/install' => [ + '\Test\Configurator' => '%vendor_path%/prisis/install/Configurator.php', + ], + ]); + $this->lockMock->shouldReceive('get') + ->with(ConfiguratorInstaller::LOCK_KEY) + ->andReturn([ + 'prisis/install' => [ + '\Test\Configurator', + ], + ]); + + $containerMock->shouldReceive('get') + ->once() + ->with(Lock::class) + ->andReturn($this->lockMock); + $containerMock->shouldReceive('get') + ->once() + ->with('vendor-dir') + ->andReturn(__DIR__ . \DIRECTORY_SEPARATOR . 'Fixture' . \DIRECTORY_SEPARATOR . 'Configurator'); + + $this->automatic->setContainer($containerMock); + $this->automatic->onPostAutoloadDump($this->mock(Event::class)); + + NSA::setProperty($this->automatic, 'configuratorsLoaded', false); + } + + public function testOnPostAutoloadDumpWithReset(): void + { + $containerMock = $this->mock(ContainerContract::class); + $configuratorMock = $this->mock(ConfiguratorContract::class); + $configuratorMock->shouldReceive('reset') + ->once(); + $configuratorMock->shouldReceive('add') + ->twice() + ->with('test', 'Test\Configurator'); + + $containerMock->shouldReceive('get') + ->twice() + ->with(ConfiguratorContract::class) + ->andReturn($configuratorMock); + + $this->lockMock->shouldReceive('get') + ->twice() + ->with(Automatic::LOCK_CLASSMAP) + ->andReturn([ + 'prisis/install' => [ + '\Test\Configurator' => '%vendor_path%/prisis/install/Configurator.php', + ], + ]); + $this->lockMock->shouldReceive('get') + ->twice() + ->with(ConfiguratorInstaller::LOCK_KEY) + ->andReturn([ + 'prisis/install' => [ + '\Test\Configurator', + ], + ]); + + $containerMock->shouldReceive('get') + ->twice() + ->with(Lock::class) + ->andReturn($this->lockMock); + $containerMock->shouldReceive('get') + ->twice() + ->with('vendor-dir') + ->andReturn(__DIR__ . \DIRECTORY_SEPARATOR . 'Fixture' . \DIRECTORY_SEPARATOR . 'Configurator'); + + $event = $this->mock(Event::class); + + $this->automatic->setContainer($containerMock); + $this->automatic->onPostAutoloadDump($event); + $this->automatic->onPostAutoloadDump($event); + } + /** * {@inheritdoc} */ diff --git a/tests/Automatic/ContainerTest.php b/tests/Automatic/ContainerTest.php index 9188c71a..178e5d99 100644 --- a/tests/Automatic/ContainerTest.php +++ b/tests/Automatic/ContainerTest.php @@ -13,7 +13,9 @@ use Narrowspark\Automatic\Common\ClassFinder; use Narrowspark\Automatic\Configurator; use Narrowspark\Automatic\Container; +use Narrowspark\Automatic\Contract\Configurator as ConfiguratorContract; use Narrowspark\Automatic\Contract\Exception\InvalidArgumentException; +use Narrowspark\Automatic\Contract\PackageConfigurator as PackageConfiguratorContract; use Narrowspark\Automatic\Installer\ConfiguratorInstaller; use Narrowspark\Automatic\Installer\SkeletonInstaller; use Narrowspark\Automatic\LegacyTagsManager; @@ -122,14 +124,14 @@ public function instancesProvider(): array [ClassFinder::class, ClassFinder::class], [ConfiguratorInstaller::class, ConfiguratorInstaller::class], [SkeletonInstaller::class, SkeletonInstaller::class], - [Configurator::class, Configurator::class], + [ConfiguratorContract::class, Configurator::class], [Install::class, Install::class], [Uninstall::class, Uninstall::class], [RemoteFilesystem::class, RemoteFilesystem::class], [ParallelDownloader::class, ParallelDownloader::class], [Prefetcher::class, Prefetcher::class], [ScriptExecutor::class, ScriptExecutor::class], - [PackageConfigurator::class, PackageConfigurator::class], + [PackageConfiguratorContract::class, PackageConfigurator::class], [LegacyTagsManager::class, LegacyTagsManager::class], ]; } diff --git a/tests/Automatic/Fixture/Configurator/prisis/install/Configurator.php b/tests/Automatic/Fixture/Configurator/prisis/install/Configurator.php index 51483213..490168d6 100644 --- a/tests/Automatic/Fixture/Configurator/prisis/install/Configurator.php +++ b/tests/Automatic/Fixture/Configurator/prisis/install/Configurator.php @@ -1,5 +1,6 @@ andReturn(false); $package->shouldReceive('hasConfig') ->once() - ->with(PackageConfigurator::TYPE) + ->with(PackageConfiguratorContract::TYPE) ->andReturn(true); $package->shouldReceive('getConfig') ->once() - ->with(PackageConfigurator::TYPE) + ->with(PackageConfiguratorContract::TYPE) ->andReturn([Configurator\EnvConfigurator::class]); $package->shouldReceive('getConfig') ->once() diff --git a/tests/Automatic/Operation/UninstallTest.php b/tests/Automatic/Operation/UninstallTest.php index 003279b1..a963710b 100644 --- a/tests/Automatic/Operation/UninstallTest.php +++ b/tests/Automatic/Operation/UninstallTest.php @@ -8,8 +8,8 @@ use Narrowspark\Automatic\Common\Contract\Configurator as ConfiguratorContract; use Narrowspark\Automatic\Common\Contract\Package as PackageContract; use Narrowspark\Automatic\Configurator; +use Narrowspark\Automatic\Contract\PackageConfigurator as PackageConfiguratorContract; use Narrowspark\Automatic\Operation\Uninstall; -use Narrowspark\Automatic\PackageConfigurator; use Narrowspark\Automatic\ScriptExecutor; use Narrowspark\Automatic\Test\Operation\Traits\ArrangeOperationsClasses; use Narrowspark\TestingHelper\Phpunit\MockeryTestCase; @@ -172,11 +172,11 @@ public function testTransform(): void ->andReturn(false); $package->shouldReceive('hasConfig') ->once() - ->with(PackageConfigurator::TYPE) + ->with(PackageConfiguratorContract::TYPE) ->andReturn(true); $package->shouldReceive('getConfig') ->once() - ->with(PackageConfigurator::TYPE) + ->with(PackageConfiguratorContract::TYPE) ->andReturn(['test' => Configurator\EnvConfigurator::class]); $package->shouldReceive('getConfig') ->once() diff --git a/tests/Automatic/ScriptExecutorTest.php b/tests/Automatic/ScriptExecutorTest.php index 5db1e119..f60091a8 100644 --- a/tests/Automatic/ScriptExecutorTest.php +++ b/tests/Automatic/ScriptExecutorTest.php @@ -55,7 +55,7 @@ public function testAddedExtenderThrowException(): void $this->expectException(InvalidArgumentException::class); $this->expectExceptionMessage('The class [stdClass] must implement the interface [Narrowspark\Automatic\Common\Contract\ScriptExtender].'); - $this->scriptExecutor->addExtender(ScriptExtender::getType(), \stdClass::class); + $this->scriptExecutor->add(ScriptExtender::getType(), \stdClass::class); } public function testAddedExtenderThrowExceptionOnExistendExtender(): void @@ -63,13 +63,13 @@ public function testAddedExtenderThrowExceptionOnExistendExtender(): void $this->expectException(InvalidArgumentException::class); $this->expectExceptionMessage('Script executor with the name [script] already exists.'); - $this->scriptExecutor->addExtender(ScriptExtender::getType(), ScriptExtender::class); - $this->scriptExecutor->addExtender(ScriptExtender::getType(), ScriptExtender::class); + $this->scriptExecutor->add(ScriptExtender::getType(), ScriptExtender::class); + $this->scriptExecutor->add(ScriptExtender::getType(), ScriptExtender::class); } public function testExecute(): void { - $this->scriptExecutor->addExtender(ScriptExtender::getType(), ScriptExtender::class); + $this->scriptExecutor->add(ScriptExtender::getType(), ScriptExtender::class); $this->ioMock->shouldReceive('isDecorated') ->once() @@ -96,7 +96,7 @@ public function testExecuteWithCmdError(): void { $this->expectException(ScriptExecutionException::class); - $this->scriptExecutor->addExtender(ScriptExtender::getType(), ScriptExtender::class); + $this->scriptExecutor->add(ScriptExtender::getType(), ScriptExtender::class); $this->ioMock->shouldReceive('isDecorated') ->once() @@ -127,7 +127,7 @@ public function testExecuteWithCmdError(): void public function testExecuteWithoutVerbose(): void { - $this->scriptExecutor->addExtender(ScriptExtender::getType(), ScriptExtender::class); + $this->scriptExecutor->add(ScriptExtender::getType(), ScriptExtender::class); $this->ioMock->shouldReceive('isDecorated') ->once() @@ -155,7 +155,7 @@ public function testExecuteWithoutVerboseAndCmdError(): void { $this->expectException(ScriptExecutionException::class); - $this->scriptExecutor->addExtender(ScriptExtender::getType(), ScriptExtender::class); + $this->scriptExecutor->add(ScriptExtender::getType(), ScriptExtender::class); $this->ioMock->shouldReceive('isDecorated') ->once()