From 88e1f0f9b58e677a85ac2661f632926a439ee7e8 Mon Sep 17 00:00:00 2001 From: Jordi Boggiano Date: Tue, 24 May 2022 21:32:36 +0200 Subject: [PATCH] Make sure repos are always initialized with a repo manager if possible, and make sure async is always enabled on the process executor, fixes #10783 (#10799) --- src/Composer/Command/ArchiveCommand.php | 2 +- .../Command/BaseDependencyCommand.php | 3 +- src/Composer/Command/HomeCommand.php | 2 +- src/Composer/Command/InitCommand.php | 7 +++- .../Command/PackageDiscoveryTrait.php | 2 +- src/Composer/Command/ShowCommand.php | 4 +- src/Composer/Repository/RepositoryFactory.php | 37 ++++++++++++++++--- .../DependencyResolver/PoolBuilderTest.php | 4 +- 8 files changed, 46 insertions(+), 15 deletions(-) diff --git a/src/Composer/Command/ArchiveCommand.php b/src/Composer/Command/ArchiveCommand.php index fa450a6da..a35f3aecf 100644 --- a/src/Composer/Command/ArchiveCommand.php +++ b/src/Composer/Command/ArchiveCommand.php @@ -159,7 +159,7 @@ EOT $localRepo = $composer->getRepositoryManager()->getLocalRepository(); $repo = new CompositeRepository(array_merge(array($localRepo), $composer->getRepositoryManager()->getRepositories())); } else { - $defaultRepos = RepositoryFactory::defaultRepos($this->getIO()); + $defaultRepos = RepositoryFactory::defaultReposWithDefaultManager($io); $io->writeError('No composer.json found in the current directory, searching packages from ' . implode(', ', array_keys($defaultRepos))); $repo = new CompositeRepository($defaultRepos); } diff --git a/src/Composer/Command/BaseDependencyCommand.php b/src/Composer/Command/BaseDependencyCommand.php index 7222319ff..2d4dea40f 100644 --- a/src/Composer/Command/BaseDependencyCommand.php +++ b/src/Composer/Command/BaseDependencyCommand.php @@ -18,6 +18,7 @@ use Composer\Package\CompletePackageInterface; use Composer\Package\RootPackage; use Composer\Repository\InstalledArrayRepository; use Composer\Repository\CompositeRepository; +use Composer\Repository\RepositoryInterface; use Composer\Repository\RootPackageRepository; use Composer\Repository\InstalledRepository; use Composer\Repository\PlatformRepository; @@ -80,7 +81,7 @@ abstract class BaseDependencyCommand extends BaseCommand // If the version we ask for is not installed then we need to locate it in remote repos and add it. // This is needed for why-not to resolve conflicts from an uninstalled version against installed packages. if (!$installedRepo->findPackage($needle, $textConstraint)) { - $defaultRepos = new CompositeRepository(RepositoryFactory::defaultRepos($this->getIO())); + $defaultRepos = new CompositeRepository(RepositoryFactory::defaultRepos($this->getIO(), $composer->getConfig(), $composer->getRepositoryManager())); if ($match = $defaultRepos->findPackage($needle, $textConstraint)) { $installedRepo->addRepository(new InstalledArrayRepository(array(clone $match))); } diff --git a/src/Composer/Command/HomeCommand.php b/src/Composer/Command/HomeCommand.php index dad4e3a75..c4457ac4c 100644 --- a/src/Composer/Command/HomeCommand.php +++ b/src/Composer/Command/HomeCommand.php @@ -170,6 +170,6 @@ EOT ); } - return RepositoryFactory::defaultRepos($this->getIO()); + return RepositoryFactory::defaultReposWithDefaultManager($this->getIO()); } } diff --git a/src/Composer/Command/InitCommand.php b/src/Composer/Command/InitCommand.php index f923f6929..ae8bc6c9b 100644 --- a/src/Composer/Command/InitCommand.php +++ b/src/Composer/Command/InitCommand.php @@ -225,6 +225,9 @@ EOT $repositories = $input->getOption('repository'); if (count($repositories) > 0) { $config = Factory::createConfig($io); + $io->loadConfiguration($config); + $repoManager = RepositoryFactory::manager($io, $config); + $repos = array(new PlatformRepository); $createDefaultPackagistRepo = true; foreach ($repositories as $repo) { @@ -236,14 +239,14 @@ EOT $createDefaultPackagistRepo = false; continue; } - $repos[] = RepositoryFactory::createRepo($io, $config, $repoConfig); + $repos[] = RepositoryFactory::createRepo($io, $config, $repoConfig, $repoManager); } if ($createDefaultPackagistRepo) { $repos[] = RepositoryFactory::createRepo($io, $config, array( 'type' => 'composer', 'url' => 'https://repo.packagist.org', - )); + ), $repoManager); } $this->repos = new CompositeRepository($repos); diff --git a/src/Composer/Command/PackageDiscoveryTrait.php b/src/Composer/Command/PackageDiscoveryTrait.php index 99fb0f39b..5e210bd7c 100644 --- a/src/Composer/Command/PackageDiscoveryTrait.php +++ b/src/Composer/Command/PackageDiscoveryTrait.php @@ -47,7 +47,7 @@ trait PackageDiscoveryTrait if (null === $this->repos) { $this->repos = new CompositeRepository(array_merge( array(new PlatformRepository), - RepositoryFactory::defaultRepos($this->getIO()) + RepositoryFactory::defaultReposWithDefaultManager($this->getIO()) )); } diff --git a/src/Composer/Command/ShowCommand.php b/src/Composer/Command/ShowCommand.php index 0194662b7..72242073b 100644 --- a/src/Composer/Command/ShowCommand.php +++ b/src/Composer/Command/ShowCommand.php @@ -194,7 +194,7 @@ EOT $repos = new CompositeRepository($composer->getRepositoryManager()->getRepositories()); $installedRepo->addRepository($composer->getRepositoryManager()->getLocalRepository()); } else { - $defaultRepos = RepositoryFactory::defaultRepos($io); + $defaultRepos = RepositoryFactory::defaultReposWithDefaultManager($io); $repos = new CompositeRepository($defaultRepos); $io->writeError('No composer.json found in the current directory, showing available packages from ' . implode(', ', array_keys($defaultRepos))); } @@ -209,7 +209,7 @@ EOT } $repos = new CompositeRepository(array_merge(array(new FilterRepository($installedRepo, array('canonical' => false))), $composer->getRepositoryManager()->getRepositories())); } elseif ($input->getOption('all')) { - $defaultRepos = RepositoryFactory::defaultRepos($io); + $defaultRepos = RepositoryFactory::defaultReposWithDefaultManager($io); $io->writeError('No composer.json found in the current directory, showing available packages from ' . implode(', ', array_keys($defaultRepos))); $installedRepo = new InstalledRepository(array($platformRepo)); $repos = new CompositeRepository(array_merge(array($installedRepo), $defaultRepos)); diff --git a/src/Composer/Repository/RepositoryFactory.php b/src/Composer/Repository/RepositoryFactory.php index b31f77530..e24fa1596 100644 --- a/src/Composer/Repository/RepositoryFactory.php +++ b/src/Composer/Repository/RepositoryFactory.php @@ -80,7 +80,8 @@ class RepositoryFactory public static function createRepo(IOInterface $io, Config $config, array $repoConfig, RepositoryManager $rm = null): RepositoryInterface { if (!$rm) { - $rm = static::manager($io, $config, Factory::createHttpDownloader($io, $config)); + @trigger_error('Not passing a repository manager when calling createRepo is deprecated since Composer 2.3.6', E_USER_DEPRECATED); + $rm = static::manager($io, $config); } $repos = self::createRepos($rm, array($repoConfig)); @@ -95,14 +96,18 @@ class RepositoryFactory */ public static function defaultRepos(IOInterface $io = null, Config $config = null, RepositoryManager $rm = null): array { - if (!$config) { + if (null === $rm) { + @trigger_error('Not passing a repository manager when calling defaultRepos is deprecated since Composer 2.3.6, use defaultReposWithDefaultManager() instead if you cannot get a manager.', E_USER_DEPRECATED); + } + + if (null === $config) { $config = Factory::createConfig($io); } - if ($io) { + if (null !== $io) { $io->loadConfiguration($config); } - if (!$rm) { - if (!$io) { + if (null === $rm) { + if (null === $io) { throw new \InvalidArgumentException('This function requires either an IOInterface or a RepositoryManager'); } $rm = static::manager($io, $config, Factory::createHttpDownloader($io, $config)); @@ -118,8 +123,16 @@ class RepositoryFactory * @param HttpDownloader $httpDownloader * @return RepositoryManager */ - public static function manager(IOInterface $io, Config $config, HttpDownloader $httpDownloader, EventDispatcher $eventDispatcher = null, ProcessExecutor $process = null): RepositoryManager + public static function manager(IOInterface $io, Config $config, HttpDownloader $httpDownloader = null, EventDispatcher $eventDispatcher = null, ProcessExecutor $process = null): RepositoryManager { + if ($httpDownloader === null) { + $httpDownloader = Factory::createHttpDownloader($io, $config); + } + if ($process === null) { + $process = new ProcessExecutor($io); + $process->enableAsync(); + } + $rm = new RepositoryManager($io, $config, $httpDownloader, $eventDispatcher, $process); $rm->setRepositoryClass('composer', 'Composer\Repository\ComposerRepository'); $rm->setRepositoryClass('vcs', 'Composer\Repository\VcsRepository'); @@ -140,6 +153,18 @@ class RepositoryFactory return $rm; } + /** + * @return RepositoryInterface[] + */ + public static function defaultReposWithDefaultManager(IOInterface $io): array + { + $manager = RepositoryFactory::manager($io, $config = Factory::createConfig($io)); + $io->loadConfiguration($config); + + return RepositoryFactory::defaultRepos($io, $config, $manager); + } + + /** * @param array $repoConfigs * diff --git a/tests/Composer/Test/DependencyResolver/PoolBuilderTest.php b/tests/Composer/Test/DependencyResolver/PoolBuilderTest.php index 7e6249113..316fd82b5 100644 --- a/tests/Composer/Test/DependencyResolver/PoolBuilderTest.php +++ b/tests/Composer/Test/DependencyResolver/PoolBuilderTest.php @@ -87,9 +87,11 @@ class PoolBuilderTest extends TestCase chdir(__DIR__.'/Fixtures/poolbuilder/'); $repositorySet = new RepositorySet($minimumStability, $stabilityFlags, $rootAliases, $rootReferences); + $config = new Config(false); + $rm = RepositoryFactory::manager($io = new NullIO(), $config); foreach ($packageRepos as $packages) { if (isset($packages['type'])) { - $repo = RepositoryFactory::createRepo(new NullIO, new Config(false), $packages); + $repo = RepositoryFactory::createRepo($io, $config, $packages, $rm); $repositorySet->addRepository($repo); continue; }