diff --git a/.travis.yml b/.travis.yml
index 4377483..429cdca 100644
--- a/.travis.yml
+++ b/.travis.yml
@@ -8,6 +8,7 @@ env:
global:
- COMPOSER_ARGS="--no-interaction"
- COVERAGE_DEPS="php-coveralls/php-coveralls"
+ - COMPOSER_VERSION=1
matrix:
fast_finish: true
@@ -38,6 +39,14 @@ matrix:
- php: 7.4
env:
- DEPS=latest
+ - php: 7.4
+ env:
+ - DEPS=lowest
+ - COMPOSER_VERSION=2
+ - php: 7.4
+ env:
+ - DEPS=latest
+ - COMPOSER_VERSION=2
before_install:
- if [[ $TEST_COVERAGE != 'true' ]]; then phpenv config-rm xdebug.ini || return 0 ; fi
@@ -45,6 +54,7 @@ before_install:
install:
- travis_retry composer install $COMPOSER_ARGS --ignore-platform-reqs
- if [[ $LEGACY_DEPS != '' ]]; then travis_retry composer update $COMPOSER_ARGS --with-dependencies $LEGACY_DEPS ; fi
+ - travis_retry composer self-update --$COMPOSER_VERSION
- if [[ $DEPS == 'latest' ]]; then travis_retry composer update $COMPOSER_ARGS ; fi
- if [[ $DEPS == 'lowest' ]]; then travis_retry composer update $COMPOSER_ARGS --prefer-lowest --prefer-stable ; fi
- if [[ $TEST_COVERAGE == 'true' ]]; then travis_retry composer require --dev $COMPOSER_ARGS $COVERAGE_DEPS ; fi
diff --git a/CHANGELOG.md b/CHANGELOG.md
index db80f24..7e30b5f 100644
--- a/CHANGELOG.md
+++ b/CHANGELOG.md
@@ -22,7 +22,7 @@ All notable changes to this project will be documented in this file, in reverse
### Fixed
-- Nothing.
+- [#16](https://github.com/laminas/laminas-component-installer/pull/16) Fixed issue with detection packages in composer v2 as dev dependencies.
## 2.3.0 - 2020-09-02
diff --git a/src/ComponentInstaller.php b/src/ComponentInstaller.php
index 21127dd..7c348da 100644
--- a/src/ComponentInstaller.php
+++ b/src/ComponentInstaller.php
@@ -10,7 +10,7 @@
use ArrayObject;
use Composer\Composer;
-use Composer\DependencyResolver\GenericRule;
+use Composer\DependencyResolver\Operation\InstallOperation;
use Composer\EventDispatcher\EventSubscriberInterface;
use Composer\Installer\PackageEvent;
use Composer\IO\IOInterface;
@@ -20,10 +20,10 @@
use Laminas\ComponentInstaller\Injector\AbstractInjector;
use Laminas\ComponentInstaller\Injector\ConfigInjectorChain;
use Laminas\ComponentInstaller\Injector\InjectorInterface;
-
+use Laminas\ComponentInstaller\PackageProvider\PackageProviderDetectionFactory;
+use Laminas\ComponentInstaller\PackageProvider\PackageProviderDetectionInterface;
use function array_filter;
use function array_flip;
-use function array_key_exists;
use function array_keys;
use function array_map;
use function array_unshift;
@@ -121,6 +121,11 @@ class ComponentInstaller implements
*/
private $projectRoot;
+ /**
+ * @var PackageProviderDetectionFactory
+ */
+ private $packageProviderFactory;
+
/**
* Constructor
*
@@ -141,15 +146,17 @@ public function __construct($projectRoot = '')
* Sets internal pointers to Composer and IOInterface instances, and resets
* cached injector map.
*
- * @param Composer $composer
+ * @param Composer $composer
* @param IOInterface $io
+ *
* @return void
*/
public function activate(Composer $composer, IOInterface $io)
{
- $this->composer = $composer;
- $this->io = $io;
+ $this->composer = $composer;
+ $this->io = $io;
$this->cachedInjectors = [];
+ $this->packageProviderFactory = PackageProviderDetectionFactory::create($composer);
}
/**
@@ -160,7 +167,7 @@ public function activate(Composer $composer, IOInterface $io)
public static function getSubscribedEvents()
{
return [
- 'post-package-install' => 'onPostPackageInstall',
+ 'post-package-install' => 'onPostPackageInstall',
'post-package-uninstall' => 'onPostPackageUninstall',
];
}
@@ -182,6 +189,7 @@ public static function getSubscribedEvents()
* writing their values into the `modules` list.
*
* @param PackageEvent $event
+ *
* @return void
*/
public function onPostPackageInstall(PackageEvent $event)
@@ -191,11 +199,11 @@ public function onPostPackageInstall(PackageEvent $event)
return;
}
- /** @var GenericRule $genericRule */
- $genericRule = $event->getOperation()->getReason();
- $package = $event->getOperation()->getPackage();
- $name = $package->getName();
- $extra = $this->getExtraMetadata($package->getExtra());
+ $operation = $event->getOperation();
+ assert($operation instanceof InstallOperation);
+ $package = $operation->getPackage();
+ $name = $package->getName();
+ $extra = $this->getExtraMetadata($package->getExtra());
if (empty($extra)) {
// Package does not define anything of interest; do nothing.
@@ -211,13 +219,12 @@ public function onPostPackageInstall(PackageEvent $event)
return;
}
- $requireDev = $this->isADevDependency($genericRule, $name);
+ $packageProviderDetection = $this->packageProviderFactory->detect($event, $name);
+ $requireDev = $this->isADevDependency($packageProviderDetection, $package);
$dependencies = $this->loadModuleClassesDependencies($package);
$applicationModules = $this->findApplicationModules();
$this->marshalInstallableModules($extra, $options)
- ->each(function ($module) use ($name) {
- })
// Create injectors
->reduce(function ($injectors, $module) use ($options, $packageTypes, $name, $requireDev) {
// Get extra from root package
@@ -232,6 +239,7 @@ public function onPostPackageInstall(PackageEvent $event)
$whitelist,
$requireDev
);
+
return $injectors;
}, new Collection([]))
// Inject modules into configuration
@@ -250,13 +258,15 @@ public function onPostPackageInstall(PackageEvent $event)
* via method `getModuleDependencies` of Module class.
*
* These dependencies are used later
+ *
+ * @param PackageInterface $package
+ *
+ * @return array
* @see \Laminas\ComponentInstaller\Injector\AbstractInjector::injectAfterDependencies
- * to add component in a correct order on the module list - after dependencies.
+ * to add component in a correct order on the module list - after dependencies.
*
* It works with PSR-0, PSR-4, 'classmap' and 'files' composer autoloading.
*
- * @param PackageInterface $package
- * @return array
*/
private function loadModuleClassesDependencies(PackageInterface $package)
{
@@ -313,6 +323,7 @@ private function findApplicationModules()
* removing their values from the `modules` list.
*
* @param PackageEvent $event
+ *
* @return void
*/
public function onPostPackageUninstall(PackageEvent $event)
@@ -334,8 +345,8 @@ public function onPostPackageUninstall(PackageEvent $event)
}
$package = $event->getOperation()->getPackage();
- $name = $package->getName();
- $extra = $this->getExtraMetadata($package->getExtra());
+ $name = $package->getName();
+ $extra = $this->getExtraMetadata($package->getExtra());
$this->removePackageFromConfig($name, $extra, $options);
}
@@ -343,6 +354,7 @@ public function onPostPackageUninstall(PackageEvent $event)
* Retrieve the metadata from the "extra" section
*
* @param array $extra
+ *
* @return array
*/
private function getExtraMetadata(array $extra)
@@ -354,8 +366,7 @@ private function getExtraMetadata(array $extra)
// supports legacy "extra.zf" configuration
return isset($extra['zf']) && is_array($extra['zf'])
? $extra['zf']
- : []
- ;
+ : [];
}
/**
@@ -363,12 +374,14 @@ private function getExtraMetadata(array $extra)
* exposes in the extra configuration.
*
* @param string[] $extra
+ *
* @return Collection Collection of Injector\InjectorInterface::TYPE_* constants.
*/
private function discoverPackageTypes(array $extra)
{
$packageTypes = array_flip($this->packageTypes);
- $knownTypes = array_keys($packageTypes);
+ $knownTypes = array_keys($packageTypes);
+
return Collection::create($extra)
->filter(function ($packages, $type) use ($knownTypes) {
return in_array($type, $knownTypes, true);
@@ -379,6 +392,7 @@ private function discoverPackageTypes(array $extra)
foreach ($packages as $package) {
$discoveredTypes[$package] = $packageTypes[$type];
}
+
return $discoveredTypes;
}, new Collection([]));
}
@@ -387,6 +401,7 @@ private function discoverPackageTypes(array $extra)
* Marshal a collection of defined package types.
*
* @param array $extra extra.laminas value
+ *
* @return Collection
*/
private function marshalPackageTypes(array $extra)
@@ -401,9 +416,10 @@ private function marshalPackageTypes(array $extra)
/**
* Marshal a collection of package modules.
*
- * @param array $extra extra.laminas value
+ * @param array $extra extra.laminas value
* @param Collection $packageTypes
* @param Collection $options ConfigOption instances
+ *
* @return Collection
*/
private function marshalPackageModules(array $extra, Collection $packageTypes, Collection $options)
@@ -421,6 +437,7 @@ private function marshalPackageModules(array $extra, Collection $packageTypes, C
if (! in_array($type, $supportedTypes, true)) {
return $modules;
}
+
return $modules->merge((array) $extra[$configKey]);
}, new Collection([]))
// Make sure the list is unique
@@ -430,9 +447,10 @@ private function marshalPackageModules(array $extra, Collection $packageTypes, C
/**
* Prepare a list of modules to install/register with configuration.
*
- * @param string[] $extra
+ * @param string[] $extra
* @param Collection $options
- * @return string[] List of packages to install
+ *
+ * @return Collection List of packages to install
*/
private function marshalInstallableModules(array $extra, Collection $options)
{
@@ -448,11 +466,12 @@ private function marshalInstallableModules(array $extra, Collection $options)
/**
* Prompt for the user to select a configuration location to update.
*
- * @param string $name
+ * @param string $name
* @param Collection $options
- * @param int $packageType
- * @param string $packageName
- * @param array $whitelist
+ * @param int $packageType
+ * @param string $packageName
+ * @param array $whitelist
+ *
* @return Injector\InjectorInterface
*/
private function promptForConfigOption(
@@ -484,6 +503,7 @@ private function promptForConfigOption(
$index,
$option->getPromptText()
);
+
return $ask;
}, []);
@@ -499,6 +519,7 @@ private function promptForConfigOption(
if (is_numeric($answer) && isset($options[(int) $answer])) {
$injector = $options[(int) $answer]->getInjector();
$this->promptToRememberOption($injector, $packageType);
+
return $injector;
}
@@ -509,10 +530,11 @@ private function promptForConfigOption(
/**
* Prompt the user to determine if the selection should be remembered for later packages.
*
- * @todo Will need to store selection in filesystem and remove when all packages are complete
* @param Injector\InjectorInterface $injector
- * @param int $packageType
+ * @param int $packageType
* return void
+ *
+ * @todo Will need to store selection in filesystem and remove when all packages are complete
*/
private function promptToRememberOption(Injector\InjectorInterface $injector, $packageType)
{
@@ -524,6 +546,7 @@ private function promptToRememberOption(Injector\InjectorInterface $injector, $p
switch ($answer) {
case 'y':
$this->cacheInjector($injector, $packageType);
+
return;
case 'n':
// intentionally fall-through
@@ -536,10 +559,11 @@ private function promptToRememberOption(Injector\InjectorInterface $injector, $p
/**
* Inject a module into available configuration.
*
- * @param string $package Package name
- * @param string $module Module to install in configuration
+ * @param string $package Package name
+ * @param string $module Module to install in configuration
* @param Injector\InjectorInterface $injector Injector to use.
- * @param int $packageType
+ * @param int $packageType
+ *
* @return void
*/
private function injectModuleIntoConfig($package, $module, Injector\InjectorInterface $injector, $packageType)
@@ -561,10 +585,11 @@ private function injectModuleIntoConfig($package, $module, Injector\InjectorInte
/**
* Remove a package from configuration.
*
- * @param string $package Package name
- * @param array $metadata Metadata pulled from extra.laminas
+ * @param string $package Package name
+ * @param array $metadata Metadata pulled from extra.laminas
* @param Collection $configOptions Discovered configuration options from
- * which to remove package.
+ * which to remove package.
+ *
* @return void
*/
private function removePackageFromConfig($package, array $metadata, Collection $configOptions)
@@ -595,9 +620,10 @@ private function removePackageFromConfig($package, array $metadata, Collection $
/**
* Remove an individual module defined in a package from configuration.
*
- * @param string $module Module to remove
- * @param string $package Package in which module is defined
+ * @param string $module Module to remove
+ * @param string $package Package in which module is defined
* @param Collection $injectors Injectors to use for removal
+ *
* @return void
*/
private function removeModuleFromConfig($module, $package, Collection $injectors)
@@ -616,6 +642,7 @@ private function removeModuleFromConfig($module, $package, Collection $injectors
/**
* @param InjectorInterface $injector
+ *
* @return string
* @todo remove after InjectorInterface has getConfigName defined
*/
@@ -632,6 +659,7 @@ private function getInjectorConfigFileName(InjectorInterface $injector)
/**
* @param ConfigInjectorChain $injector
+ *
* @return string
* @todo remove after InjectorInterface has getConfigName defined
*/
@@ -644,6 +672,7 @@ private function getInjectorChainConfigFileName(ConfigInjectorChain $injector)
/**
* @param AbstractInjector $injector
+ *
* @return string
* @todo remove after InjectorInterface has getConfigName defined
*/
@@ -656,6 +685,7 @@ private function getAbstractInjectorConfigFileName(AbstractInjector $injector)
* Is a given module name valid?
*
* @param string $module
+ *
* @return bool
*/
private function moduleIsValid($module)
@@ -667,7 +697,8 @@ private function moduleIsValid($module)
* Is a given metadata value (extra.laminas.*) valid?
*
* @param string $key Key to examine in metadata
- * @param array $metadata
+ * @param array $metadata
+ *
* @return bool
*/
private function metadataForKeyIsValid($key, array $metadata)
@@ -689,6 +720,7 @@ private function metadataForKeyIsValid($key, array $metadata)
if (false === $valid) {
return $valid;
}
+
return $this->moduleIsValid($value);
}, null);
}
@@ -697,6 +729,7 @@ private function metadataForKeyIsValid($key, array $metadata)
* Attempt to retrieve a cached injector for the current package type.
*
* @param int $packageType
+ *
* @return null|Injector\InjectorInterface
*/
private function getCachedInjector($packageType)
@@ -712,7 +745,8 @@ private function getCachedInjector($packageType)
* Cache an injector for later use.
*
* @param Injector\InjectorInterface $injector
- * @param int $packageType
+ * @param int $packageType
+ *
* @return void
*/
private function cacheInjector(Injector\InjectorInterface $injector, $packageType)
@@ -723,9 +757,10 @@ private function cacheInjector(Injector\InjectorInterface $injector, $packageTyp
/**
* Iterate through each autoloader type to find dependencies.
*
- * @param array $autoload List of autoloader types and associated autoloader definitions.
+ * @param array $autoload List of autoloader types and associated autoloader definitions.
* @param ArrayObject $dependencies Module dependencies defined by the module.
- * @param string $packagePath Path to the package on the filesystem.
+ * @param string $packagePath Path to the package on the filesystem.
+ *
* @return void
*/
private function mapAutoloaders(array $autoload, ArrayObject $dependencies, $packagePath)
@@ -738,10 +773,11 @@ private function mapAutoloaders(array $autoload, ArrayObject $dependencies, $pac
/**
* Iterate through a single autolaoder type to find dependencies.
*
- * @param array $map Map of namespace => path(s) pairs.
- * @param string $type Type of autoloader being iterated.
+ * @param array $map Map of namespace => path(s) pairs.
+ * @param string $type Type of autoloader being iterated.
* @param ArrayObject $dependencies Module dependencies defined by the module.
- * @param string $packagePath Path to the package on the filesystem.
+ * @param string $packagePath Path to the package on the filesystem.
+ *
* @return void
*/
private function mapType(array $map, $type, ArrayObject $dependencies, $packagePath)
@@ -755,11 +791,12 @@ private function mapType(array $map, $type, ArrayObject $dependencies, $packageP
/**
* Iterate through the paths defined for a given namespace.
*
- * @param array $paths Paths defined for the given namespace.
- * @param string $namespace PHP namespace to which the paths map.
- * @param string $type Type of autoloader being iterated.
+ * @param array $paths Paths defined for the given namespace.
+ * @param string $namespace PHP namespace to which the paths map.
+ * @param string $type Type of autoloader being iterated.
* @param ArrayObject $dependencies Module dependencies defined by the module.
- * @param string $packagePath Path to the package on the filesystem.
+ * @param string $packagePath Path to the package on the filesystem.
+ *
* @return void
*/
private function mapNamespacePaths(array $paths, $namespace, $type, ArrayObject $dependencies, $packagePath)
@@ -772,11 +809,12 @@ private function mapNamespacePaths(array $paths, $namespace, $type, ArrayObject
/**
* Find module dependencies for a given namespace for a given path.
*
- * @param string $path Path to inspect.
- * @param string $namespace PHP namespace to which the paths map.
- * @param string $type Type of autoloader being iterated.
+ * @param string $path Path to inspect.
+ * @param string $namespace PHP namespace to which the paths map.
+ * @param string $type Type of autoloader being iterated.
* @param ArrayObject $dependencies Module dependencies defined by the module.
- * @param string $packagePath Path to the package on the filesystem.
+ * @param string $packagePath Path to the package on the filesystem.
+ *
* @return void
*/
private function mapPath($path, $namespace, $type, ArrayObject $dependencies, $packagePath)
@@ -834,6 +872,7 @@ private function mapPath($path, $namespace, $type, ArrayObject $dependencies, $p
/**
* @param string $file
+ *
* @return array
*/
private function getModuleDependencies($file)
@@ -859,17 +898,30 @@ private function getModuleDependencies($file)
return [];
}
- private function isADevDependency(GenericRule $genericRule, string $name): bool
- {
- if (array_key_exists($name, $this->composer->getPackage()->getDevRequires())) {
+ private function isADevDependency(
+ PackageProviderDetectionInterface $packageProviderDetection,
+ PackageInterface $package
+ ): bool {
+ $packageName = $package->getName();
+ $devRequirements = $this->composer->getPackage()->getDevRequires();
+ if (isset($devRequirements[$packageName])) {
return true;
}
- $dependentFor = is_string($genericRule->getReasonData())
- ? $genericRule->getReasonData()
- : $genericRule->getReasonData()->getSource();
+ $packages = $packageProviderDetection->whatProvides($packageName);
+ if (empty($packages)) {
+ return false;
+ }
+
+ $requirements = $this->composer->getPackage()->getRequires();
+ foreach ($packages as $parent) {
+ // Package is required by any package which is NOT a dev-requirement
+ if (isset($requirements[$parent->getName()])) {
+ return false;
+ }
+ }
- return array_key_exists($dependentFor, $this->composer->getPackage()->getDevRequires());
+ return true;
}
public function deactivate(Composer $composer, IOInterface $io)
diff --git a/src/PackageProvider/ComposerV1.php b/src/PackageProvider/ComposerV1.php
new file mode 100644
index 0000000..7b49856
--- /dev/null
+++ b/src/PackageProvider/ComposerV1.php
@@ -0,0 +1,32 @@
+pool = $pool;
+ }
+
+ public function whatProvides(string $packageName): array
+ {
+ return $this->pool->whatProvides($packageName);
+ }
+}
diff --git a/src/PackageProvider/ComposerV2.php b/src/PackageProvider/ComposerV2.php
new file mode 100644
index 0000000..cbb2c66
--- /dev/null
+++ b/src/PackageProvider/ComposerV2.php
@@ -0,0 +1,32 @@
+installedRepository = $installedRepository;
+ }
+
+ public function whatProvides(string $packageName): array
+ {
+ return $this->installedRepository->findPackagesWithReplacersAndProviders($packageName);
+ }
+}
diff --git a/src/PackageProvider/PackageProviderDetectionFactory.php b/src/PackageProvider/PackageProviderDetectionFactory.php
new file mode 100644
index 0000000..d643459
--- /dev/null
+++ b/src/PackageProvider/PackageProviderDetectionFactory.php
@@ -0,0 +1,77 @@
+composer = $composer;
+ if (false === self::isComposerV1()) {
+ $this->packageRepository = new RootPackageRepository($composer->getPackage());
+ }
+ }
+
+ public static function create(Composer $composer): self
+ {
+ return new self($composer);
+ }
+
+ public static function isComposerV1(): bool
+ {
+ return version_compare(PluginInterface::PLUGIN_API_VERSION, '2.0.0', '<') === true;
+ }
+
+ public function detect(PackageEvent $event, string $packageName): PackageProviderDetectionInterface
+ {
+ if (self::isComposerV1()) {
+ return new ComposerV1($event->getPool());
+ }
+
+ $platformOverrides = $this->composer->getConfig()->get('platform') ?? [];
+
+ $installedRepo = new InstalledRepository([
+ $this->packageRepository,
+ $this->composer->getRepositoryManager()->getLocalRepository(),
+ new PlatformRepository([], $platformOverrides),
+ ]);
+
+ $defaultRepos = new CompositeRepository(RepositoryFactory::defaultRepos(new NullIO()));
+ if (($match = $defaultRepos->findPackage($packageName, '*'))
+ && false === $installedRepo->hasPackage($match)
+ ) {
+ $installedRepo->addRepository(new InstalledArrayRepository([clone $match]));
+ }
+
+ return new ComposerV2($installedRepo);
+ }
+}
diff --git a/src/PackageProvider/PackageProviderDetectionInterface.php b/src/PackageProvider/PackageProviderDetectionInterface.php
new file mode 100644
index 0000000..34d6126
--- /dev/null
+++ b/src/PackageProvider/PackageProviderDetectionInterface.php
@@ -0,0 +1,21 @@
+projectRoot = vfsStream::setup('project');
- $this->installer = new ComponentInstaller(vfsStream::url('project'));
+ $this->installer = new ComponentInstaller(
+ vfsStream::url('project')
+ );
$this->composer = $this->prophesize(Composer::class);
$this->rootPackage = $this->prophesize(RootPackageInterface::class);
$this->io = $this->prophesize(IOInterface::class);
- $this->composer->getPackage()->willReturn($this->rootPackage->reveal());
- $this->rootPackage->getExtra()->willReturn([]);
$this->rootPackage->getDevRequires()->willReturn([]);
+ $this->rootPackage->getExtra()->willReturn([]);
+ if (false === PackageProviderDetectionFactory::isComposerV1()) {
+ $config = $this->prophesize(Config::class);
+ $this->composer->getConfig()->willReturn($config->reveal());
+ $repositoryManager = $this->prophesize(RepositoryManager::class);
+ $localRepository = $this->prophesize(PlatformRepository::class);
+ $localRepository->getPackages()->willReturn([]);
+ $repositoryManager->getLocalRepository()->willReturn($localRepository->reveal());
+ $this->composer->getRepositoryManager()->willReturn($repositoryManager->reveal());
+ $this->rootPackage->getProvides()->willReturn([]);
+ $this->rootPackage->getReplaces()->willReturn([]);
+ $this->rootPackage->setRepository(Argument::type(RootPackageRepository::class))->willReturn([]);
+ }
+ $this->composer->getPackage()->willReturn($this->rootPackage->reveal());
$this->installer->activate(
$this->composer->reveal(),
$this->io->reveal()
@@ -176,16 +195,21 @@ public function getModuleDependencies()
$this->installationManager->getInstallPath(Argument::exact($package->reveal()))
->willReturn(vfsStream::url('project/' . $installPath));
- $genericRule = $this->prophesize(GenericRule::class);
- $genericRule->getReasonData()->willReturn('some/component');
-
$operation = $this->prophesize(InstallOperation::class);
$operation->getPackage()->willReturn($package->reveal());
- $operation->getReason()->willReturn($genericRule->reveal());
$event = $this->prophesize(PackageEvent::class);
$event->isDevMode()->willReturn(true);
$event->getOperation()->willReturn($operation->reveal());
+ $this->prepareEventForPackageProviderDetection($event, 'some/component');
+
+ $this->rootPackage
+ ->getName()
+ ->willReturn('some/component');
+
+ $this->rootPackage
+ ->getRequires()
+ ->willReturn([]);
$this->io->ask(Argument::that(function ($argument) {
return ComponentInstallerTest::assertPrompt($argument, 'SomeComponent');
@@ -528,15 +552,18 @@ public function getModuleDependencies()
$this->installationManager->getInstallPath(Argument::exact($package->reveal()))
->willReturn(vfsStream::url('project/' . $installPath));
- $genericRule = $this->prophesize(GenericRule::class);
- $genericRule->getReasonData()->willReturn('some/component');
$operation = $this->prophesize(InstallOperation::class);
$operation->getPackage()->willReturn($package->reveal());
- $operation->getReason()->willReturn($genericRule->reveal());
$event = $this->prophesize(PackageEvent::class);
$event->isDevMode()->willReturn(true);
$event->getOperation()->willReturn($operation->reveal());
+ $this->prepareEventForPackageProviderDetection($event, 'some/component');
+
+ $this->rootPackage->getRequires()->willReturn([]);
+ $this->rootPackage
+ ->getName()
+ ->willReturn('some/component');
$this->io->ask(Argument::that(function ($argument) use ($packageName) {
return ComponentInstallerTest::assertPrompt($argument, $packageName);
@@ -627,15 +654,18 @@ public function testModuleBeforeApplicationModules(array $availableModules, arra
]);
$package->getAutoload()->willReturn([]);
- $genericRule = $this->prophesize(GenericRule::class);
- $genericRule->getReasonData()->willReturn('some/module');
$operation = $this->prophesize(InstallOperation::class);
$operation->getPackage()->willReturn($package->reveal());
- $operation->getReason()->willReturn($genericRule->reveal());
$event = $this->prophesize(PackageEvent::class);
$event->isDevMode()->willReturn(true);
$event->getOperation()->willReturn($operation->reveal());
+ $this->prepareEventForPackageProviderDetection($event, 'some/module');
+ $this->prepareEventForPackageProviderDetection($event, 'some/module');
+
+
+ $this->rootPackage->getRequires()->willReturn([]);
+ $this->rootPackage->getName()->willReturn('some/component');
$this->io->ask(Argument::that(function ($argument) {
return ComponentInstallerTest::assertPrompt($argument, 'SomeModule');
@@ -679,11 +709,8 @@ public function testPostPackageInstallDoesNothingIfComposerExtraIsEmpty()
$package->getName()->willReturn('some/component');
$package->getExtra()->willReturn([]);
- $genericRule = $this->prophesize(GenericRule::class);
- $genericRule->getReasonData()->willReturn('some/component');
$operation = $this->prophesize(InstallOperation::class);
$operation->getPackage()->willReturn($package->reveal());
- $operation->getReason()->willReturn($genericRule->reveal());
$event = $this->prophesize(PackageEvent::class);
$event->isDevMode()->willReturn(true);
@@ -702,11 +729,8 @@ public function testOnPostPackageInstallReturnsEarlyIfApplicationConfigIsMissing
'module' => 'Some\\Component',
]]);
- $genericRule = $this->prophesize(GenericRule::class);
- $genericRule->getReasonData()->willReturn('some/component');
$operation = $this->prophesize(InstallOperation::class);
$operation->getPackage()->willReturn($package->reveal());
- $operation->getReason()->willReturn($genericRule->reveal());
$event = $this->prophesize(PackageEvent::class);
$event->isDevMode()->willReturn(true);
@@ -721,11 +745,8 @@ public function testPostPackageInstallDoesNothingIfLaminasExtraSectionDoesNotCon
$package->getName()->willReturn('some/component');
$package->getExtra()->willReturn(['laminas' => []]);
- $genericRule = $this->prophesize(GenericRule::class);
- $genericRule->getReasonData()->willReturn('some/component');
$operation = $this->prophesize(InstallOperation::class);
$operation->getPackage()->willReturn($package->reveal());
- $operation->getReason()->willReturn($genericRule->reveal());
$event = $this->prophesize(PackageEvent::class);
$event->isDevMode()->willReturn(true);
@@ -747,15 +768,15 @@ public function testOnPostPackageInstallDoesNotPromptIfPackageIsAlreadyInConfigu
]]);
$package->getAutoload()->willReturn([]);
- $genericRule = $this->prophesize(GenericRule::class);
- $genericRule->getReasonData()->willReturn('some/component');
$operation = $this->prophesize(InstallOperation::class);
$operation->getPackage()->willReturn($package->reveal());
- $operation->getReason()->willReturn($genericRule->reveal());
$event = $this->prophesize(PackageEvent::class);
$event->isDevMode()->willReturn(true);
$event->getOperation()->willReturn($operation->reveal());
+ $this->prepareEventForPackageProviderDetection($event, 'some/component');
+ $this->rootPackage->getRequires()->willReturn([]);
+ $this->rootPackage->getName()->willReturn('some/component');
$this->io->ask(Argument::any())->shouldNotBeCalled();
@@ -775,15 +796,16 @@ public function testOnPostPackageInstallDoesNotPromptForWhitelistedPackages()
]]);
$package->getAutoload()->willReturn([]);
- $genericRule = $this->prophesize(GenericRule::class);
- $genericRule->getReasonData()->willReturn('some/component');
$operation = $this->prophesize(InstallOperation::class);
$operation->getPackage()->willReturn($package->reveal());
- $operation->getReason()->willReturn($genericRule->reveal());
$event = $this->prophesize(PackageEvent::class);
$event->isDevMode()->willReturn(true);
$event->getOperation()->willReturn($operation->reveal());
+ $this->prepareEventForPackageProviderDetection($event, 'some/component');
+
+ $this->rootPackage->getRequires()->willReturn([]);
+ $this->rootPackage->getName()->willReturn('some/component');
$this->rootPackage->getExtra()->willReturn(['laminas' => [
'component-whitelist' => ['some/component'],
@@ -809,15 +831,16 @@ public function testOnPostPackageInstallPromptsForConfigOptions()
]]);
$package->getAutoload()->willReturn([]);
- $genericRule = $this->prophesize(GenericRule::class);
- $genericRule->getReasonData()->willReturn('some/component');
$operation = $this->prophesize(InstallOperation::class);
$operation->getPackage()->willReturn($package->reveal());
- $operation->getReason()->willReturn($genericRule->reveal());
$event = $this->prophesize(PackageEvent::class);
$event->isDevMode()->willReturn(true);
$event->getOperation()->willReturn($operation->reveal());
+ $this->prepareEventForPackageProviderDetection($event, 'some/component');
+
+ $this->rootPackage->getRequires()->willReturn([]);
+ $this->rootPackage->getName()->willReturn('some/component');
$this->io->ask(Argument::that(function ($argument) {
if (! is_string($argument)) {
@@ -876,15 +899,16 @@ public function testOnPostPackageInstallPromptsForConfigOptionsWhenDefinedAsArra
]]);
$package->getAutoload()->willReturn([]);
- $genericRule = $this->prophesize(GenericRule::class);
- $genericRule->getReasonData()->willReturn('some/component');
$operation = $this->prophesize(InstallOperation::class);
$operation->getPackage()->willReturn($package->reveal());
- $operation->getReason()->willReturn($genericRule->reveal());
$event = $this->prophesize(PackageEvent::class);
$event->isDevMode()->willReturn(true);
$event->getOperation()->willReturn($operation->reveal());
+ $this->prepareEventForPackageProviderDetection($event, 'some/component');
+
+ $this->rootPackage->getRequires()->willReturn([]);
+ $this->rootPackage->getName()->willReturn('some/component');
$this->io->ask(Argument::that(function ($argument) {
if (! is_string($argument)) {
@@ -978,15 +1002,13 @@ public function testMultipleInvocationsOfOnPostPackageInstallCanPromptMultipleTi
]]);
$package->getAutoload()->willReturn([]);
- $genericRule = $this->prophesize(GenericRule::class);
- $genericRule->getReasonData()->willReturn('some/component');
$operation = $this->prophesize(InstallOperation::class);
$operation->getPackage()->willReturn($package->reveal());
- $operation->getReason()->willReturn($genericRule->reveal());
$event = $this->prophesize(PackageEvent::class);
$event->isDevMode()->willReturn(true);
$event->getOperation()->willReturn($operation->reveal());
+ $this->prepareEventForPackageProviderDetection($event, 'some/component');
$this->io->ask(Argument::that(function ($argument) {
if (! is_string($argument)) {
@@ -1038,15 +1060,16 @@ public function testMultipleInvocationsOfOnPostPackageInstallCanPromptMultipleTi
]]);
$package->getAutoload()->willReturn([]);
- $genericRule = $this->prophesize(GenericRule::class);
- $genericRule->getReasonData()->willReturn('some/component');
$operation = $this->prophesize(InstallOperation::class);
$operation->getPackage()->willReturn($package->reveal());
- $operation->getReason()->willReturn($genericRule->reveal());
$event = $this->prophesize(PackageEvent::class);
$event->isDevMode()->willReturn(true);
$event->getOperation()->willReturn($operation->reveal());
+ $this->prepareEventForPackageProviderDetection($event, 'other/component');
+
+ $this->rootPackage->getRequires()->willReturn([]);
+ $this->rootPackage->getName()->willReturn('other/component');
$this->io->ask(Argument::that(function ($argument) {
if (! is_string($argument)) {
@@ -1103,15 +1126,13 @@ public function testMultipleInvocationsOfOnPostPackageInstallCanReuseOptions()
]]);
$package->getAutoload()->willReturn([]);
- $genericRule = $this->prophesize(GenericRule::class);
- $genericRule->getReasonData()->willReturn('some/component');
$operation = $this->prophesize(InstallOperation::class);
$operation->getPackage()->willReturn($package->reveal());
- $operation->getReason()->willReturn($genericRule->reveal());
$event = $this->prophesize(PackageEvent::class);
$event->isDevMode()->willReturn(true);
$event->getOperation()->willReturn($operation->reveal());
+ $this->prepareEventForPackageProviderDetection($event, 'some/component');
$this->io->ask(Argument::that(function ($argument) {
if (! is_string($argument)) {
@@ -1163,15 +1184,16 @@ public function testMultipleInvocationsOfOnPostPackageInstallCanReuseOptions()
]]);
$package->getAutoload()->willReturn([]);
- $genericRule = $this->prophesize(GenericRule::class);
- $genericRule->getReasonData()->willReturn('some/component');
$operation = $this->prophesize(InstallOperation::class);
$operation->getPackage()->willReturn($package->reveal());
- $operation->getReason()->willReturn($genericRule->reveal());
$event = $this->prophesize(PackageEvent::class);
$event->isDevMode()->willReturn(true);
$event->getOperation()->willReturn($operation->reveal());
+ $this->prepareEventForPackageProviderDetection($event, 'other/component');
+
+ $this->rootPackage->getRequires()->willReturn([]);
+ $this->rootPackage->getName()->willReturn('some/component');
$this->io->write(Argument::that(function ($argument) {
return strstr($argument, 'Installing Other\Component from package other/component');
@@ -1213,11 +1235,8 @@ public function testOnPostPackageUninstallRemovesPackageFromConfiguration()
]]);
$package->getAutoload()->willReturn([]);
- $genericRule = $this->prophesize(GenericRule::class);
- $genericRule->getReasonData()->willReturn('some/component');
$operation = $this->prophesize(InstallOperation::class);
$operation->getPackage()->willReturn($package->reveal());
- $operation->getReason()->willReturn($genericRule->reveal());
$event = $this->prophesize(PackageEvent::class);
$event->isDevMode()->willReturn(true);
@@ -1258,16 +1277,15 @@ public function testOnPostPackageUninstallCanRemovePackageArraysFromConfiguratio
]]);
$package->getAutoload()->willReturn([]);
- $genericRule = $this->prophesize(GenericRule::class);
- $genericRule->getReasonData()->willReturn('some/component');
$operation = $this->prophesize(InstallOperation::class);
$operation->getPackage()->willReturn($package->reveal());
- $operation->getReason()->willReturn($genericRule->reveal());
$event = $this->prophesize(PackageEvent::class);
$event->isDevMode()->willReturn(true);
$event->getOperation()->willReturn($operation->reveal());
+ $this->rootPackage->getRequires()->willReturn([]);
+
$this->io
->write(' Removing Some\Component from package some/component')
->shouldBeCalled();
@@ -1304,15 +1322,17 @@ public function testModuleIsAppended()
]]);
$package->getAutoload()->willReturn([]);
- $genericRule = $this->prophesize(GenericRule::class);
- $genericRule->getReasonData()->willReturn('some/component');
$operation = $this->prophesize(InstallOperation::class);
$operation->getPackage()->willReturn($package->reveal());
- $operation->getReason()->willReturn($genericRule->reveal());
$event = $this->prophesize(PackageEvent::class);
$event->isDevMode()->willReturn(true);
$event->getOperation()->willReturn($operation->reveal());
+ $this->prepareEventForPackageProviderDetection($event, 'some/module');
+
+
+ $this->rootPackage->getRequires()->willReturn([]);
+ $this->rootPackage->getName()->willReturn('some/module');
$this->io->ask(Argument::that(function ($argument) {
if (! is_string($argument)) {
@@ -1375,15 +1395,16 @@ public function testAppendModuleAndPrependComponent()
'component' => 'Some\\Component',
]]);
- $genericRule = $this->prophesize(GenericRule::class);
- $genericRule->getReasonData()->willReturn('some/component');
$operation = $this->prophesize(InstallOperation::class);
$operation->getPackage()->willReturn($package->reveal());
- $operation->getReason()->willReturn($genericRule->reveal());
$event = $this->prophesize(PackageEvent::class);
$event->isDevMode()->willReturn(true);
$event->getOperation()->willReturn($operation->reveal());
+ $this->prepareEventForPackageProviderDetection($event, 'some/package');
+
+ $this->rootPackage->getRequires()->willReturn([]);
+ $this->rootPackage->getName()->willReturn('some/package');
$this->io->ask(Argument::that(function ($argument) {
if (! is_string($argument)) {
@@ -1474,15 +1495,18 @@ public function testPrependComponentAndAppendModule()
'module' => 'Some\\Module',
]]);
- $genericRule = $this->prophesize(GenericRule::class);
- $genericRule->getReasonData()->willReturn('some/component');
$operation = $this->prophesize(InstallOperation::class);
$operation->getPackage()->willReturn($package->reveal());
- $operation->getReason()->willReturn($genericRule->reveal());
$event = $this->prophesize(PackageEvent::class);
$event->isDevMode()->willReturn(true);
$event->getOperation()->willReturn($operation->reveal());
+ $this->prepareEventForPackageProviderDetection($event, 'some/package');
+
+ $this->rootPackage->getRequires()->willReturn([]);
+ $this->rootPackage
+ ->getName()
+ ->willReturn('some/package');
$this->io->ask(Argument::that(function ($argument) {
if (! is_string($argument)) {
@@ -1734,6 +1758,8 @@ public function testUninstallMessageWithDifferentInjectors($configContents, arra
$event->isDevMode()->willReturn(true);
$event->getOperation()->willReturn($operation->reveal());
+ $this->rootPackage->getRequires()->willReturn([]);
+
$this->io
->write(' Removing Some\Component from package some/component')
->shouldBeCalled();
@@ -1777,7 +1803,7 @@ public function testInstallWhitelistedDevModuleWithDifferentInjectors()
$this->createConfigFile($configName, $configContents);
}
- $this->rootPackage->getDevRequires()->willReturn(['some/component' => null]);
+ $this->rootPackage->getDevRequires()->willReturn(['some/component' => '*']);
$this->rootPackage->getExtra()->willReturn([
'laminas' => [
"component-whitelist" => [
@@ -1797,15 +1823,15 @@ public function testInstallWhitelistedDevModuleWithDifferentInjectors()
]);
$package->getAutoload()->willReturn([]);
- $genericRule = $this->prophesize(GenericRule::class);
- $genericRule->getReasonData()->willReturn('some/component');
$operation = $this->prophesize(InstallOperation::class);
$operation->getPackage()->willReturn($package->reveal());
- $operation->getReason()->willReturn($genericRule->reveal());
$event = $this->prophesize(PackageEvent::class);
$event->isDevMode()->willReturn(true);
$event->getOperation()->willReturn($operation->reveal());
+ $this->prepareEventForPackageProviderDetection($event, 'some/component');
+
+ $this->rootPackage->getRequires()->willReturn([]);
$this->assertNull($this->installer->onPostPackageInstall($event->reveal()));
$config = include vfsStream::url('project/config/modules.config.php');
@@ -1852,15 +1878,18 @@ public function testInstallWhitelistedDevModuleWithUniqueInjector()
]);
$package->getAutoload()->willReturn([]);
- $genericRule = $this->prophesize(GenericRule::class);
- $genericRule->getReasonData()->willReturn('some/module');
$operation = $this->prophesize(InstallOperation::class);
$operation->getPackage()->willReturn($package->reveal());
- $operation->getReason()->willReturn($genericRule->reveal());
$event = $this->prophesize(PackageEvent::class);
$event->isDevMode()->willReturn(true);
$event->getOperation()->willReturn($operation->reveal());
+ $this->prepareEventForPackageProviderDetection($event, 'some/module');
+
+ $this->rootPackage
+ ->getName()
+ ->willReturn('some/module');
+ $this->rootPackage->getRequires()->willReturn([]);
$this->assertNull($this->installer->onPostPackageInstall($event->reveal()));
$config = include vfsStream::url('project/config/modules.config.php');
@@ -1913,4 +1942,18 @@ private function createConfigFile($name, $contents)
->at($this->projectRoot)
->setContent($contents);
}
+
+ /**
+ * @param ObjectProphecy|PackageEvent $event
+ * @param string $packageName
+ * @return ObjectProphecy
+ */
+ private function prepareEventForPackageProviderDetection(ObjectProphecy $event, string $packageName): void
+ {
+ if (method_exists(PackageEvent::class, 'getPool')) {
+ $pool = $this->prophesize(Pool::class);
+ $pool->whatProvides($packageName)->willReturn([]);
+ $event->getPool()->willReturn($pool->reveal());
+ }
+ }
}