From a2ab6f2b543a706be12b719fe3c9a5201e8c01fe Mon Sep 17 00:00:00 2001 From: Jordi Boggiano Date: Fri, 17 Jul 2020 10:38:46 +0200 Subject: [PATCH] Add support for multiple --repository additions in create-project, and make --add-repository delete the lock file, fixes #8853 --- doc/03-cli.md | 7 +- src/Composer/Command/CreateProjectCommand.php | 67 ++++++++++++------- src/Composer/Repository/RepositoryFactory.php | 2 +- 3 files changed, 48 insertions(+), 28 deletions(-) diff --git a/doc/03-cli.md b/doc/03-cli.md index 76f0125f8..ec119d24c 100644 --- a/doc/03-cli.md +++ b/doc/03-cli.md @@ -724,8 +724,9 @@ By default the command checks for the packages on packagist.org. which will be used instead of packagist. Can be either an HTTP URL pointing to a `composer` repository, a path to a local `packages.json` file, or a JSON string which similar to what the [repositories](04-schema.md#repositories) - key accepts. -* **--add-repository:** Add the repository option to the composer.json. + key accepts. You can use this multiple times to configure multiple repositories. +* **--add-repository:** Add the custom repository in the composer.json. If a lock + file is present it will be deleted and an update will be run instead of install. * **--dev:** Install packages listed in `require-dev`. * **--no-dev:** Disables installation of require-dev packages. * **--no-scripts:** Disables the execution of the scripts defined in the root @@ -966,7 +967,7 @@ commands) to finish executing. The default value is 300 seconds (5 minutes). ### COMPOSER_ROOT_VERSION -By setting this var you can specify the version of the root package, if it +By setting this var you can specify the version of the root package, if it cannot be guessed from VCS info and is not present in `composer.json`. ### COMPOSER_VENDOR_DIR diff --git a/src/Composer/Command/CreateProjectCommand.php b/src/Composer/Command/CreateProjectCommand.php index c0470e096..d633e1519 100644 --- a/src/Composer/Command/CreateProjectCommand.php +++ b/src/Composer/Command/CreateProjectCommand.php @@ -69,9 +69,9 @@ class CreateProjectCommand extends BaseCommand new InputOption('stability', 's', InputOption::VALUE_REQUIRED, 'Minimum-stability allowed (unless a version is specified).'), new InputOption('prefer-source', null, InputOption::VALUE_NONE, 'Forces installation from package sources when possible, including VCS information.'), new InputOption('prefer-dist', null, InputOption::VALUE_NONE, 'Forces installation from package dist even for dev versions.'), - new InputOption('repository', null, InputOption::VALUE_REQUIRED, 'Pick a different repository (as url or json config) to look for the package.'), + new InputOption('repository', null, InputOption::VALUE_REQUIRED | InputOption::VALUE_IS_ARRAY, 'Add custom repositories to look the package up, either by URL or using JSON arrays'), new InputOption('repository-url', null, InputOption::VALUE_REQUIRED, 'DEPRECATED: Use --repository instead.'), - new InputOption('add-repository', null, InputOption::VALUE_NONE, 'Add the repository option to the composer.json.'), + new InputOption('add-repository', null, InputOption::VALUE_NONE, 'Add the custom repository in the composer.json. If a lock file is present it will be deleted and an update will be run instead of install.'), new InputOption('dev', null, InputOption::VALUE_NONE, 'Enables installation of require-dev packages (enabled by default, only present for BC).'), new InputOption('no-dev', null, InputOption::VALUE_NONE, 'Disables installation of require-dev packages.'), new InputOption('no-custom-installers', null, InputOption::VALUE_NONE, 'DEPRECATED: Use no-plugins instead.'), @@ -153,38 +153,50 @@ EOT ); } - public function installProject(IOInterface $io, Config $config, InputInterface $input, $packageName, $directory = null, $packageVersion = null, $stability = 'stable', $preferSource = false, $preferDist = false, $installDevPackages = false, $repository = null, $disablePlugins = false, $noScripts = false, $noProgress = false, $noInstall = false, $ignorePlatformReqs = false, $secureHttp = true, $addRepository = false) + public function installProject(IOInterface $io, Config $config, InputInterface $input, $packageName, $directory = null, $packageVersion = null, $stability = 'stable', $preferSource = false, $preferDist = false, $installDevPackages = false, $repositories = null, $disablePlugins = false, $noScripts = false, $noProgress = false, $noInstall = false, $ignorePlatformReqs = false, $secureHttp = true, $addRepository = false) { $oldCwd = getcwd(); + if ($repositories !== null && !is_array($repositories)) { + $repositories = (array) $repositories; + } + // we need to manually load the configuration to pass the auth credentials to the io interface! $io->loadConfiguration($config); $this->suggestedPackagesReporter = new SuggestedPackagesReporter($io); if ($packageName !== null) { - $installedFromVcs = $this->installRootPackage($io, $config, $packageName, $directory, $packageVersion, $stability, $preferSource, $preferDist, $installDevPackages, $repository, $disablePlugins, $noScripts, $noProgress, $ignorePlatformReqs, $secureHttp); + $installedFromVcs = $this->installRootPackage($io, $config, $packageName, $directory, $packageVersion, $stability, $preferSource, $preferDist, $installDevPackages, $repositories, $disablePlugins, $noScripts, $noProgress, $ignorePlatformReqs, $secureHttp); } else { $installedFromVcs = false; } + if ($repositories !== null && $addRepository && is_file('composer.lock')) { + unlink('composer.lock'); + } + $composer = Factory::create($io, null, $disablePlugins); // add the repository to the composer.json and use it for the install run later - if ($repository !== null && $addRepository) { - if ($composer->getLocker()->isLocked()) { - $io->writeError('Adding a repository when creating a project that provides a composer.lock file is not supported'); + if ($repositories !== null && $addRepository) { + foreach ($repositories as $index => $repo) { + $repoConfig = RepositoryFactory::configFromString($io, $composer->getConfig(), $repo, true); + $composerJsonRepositoriesConfig = $composer->getConfig()->getRepositories(); + $name = RepositoryFactory::generateRepositoryName($index, $repoConfig, $composerJsonRepositoriesConfig); + $configSource = new JsonConfigSource(new JsonFile('composer.json')); - return false; + if ( + (isset($repoConfig['packagist']) && $repoConfig === array('packagist' => false)) + || (isset($repoConfig['packagist.org']) && $repoConfig === array('packagist.org' => false)) + ) { + $configSource->addRepository('packagist.org', false); + } else { + $configSource->addRepository($name, $repoConfig); + } + + $composer = Factory::create($io, null, $disablePlugins); } - - $repoConfig = RepositoryFactory::configFromString($io, $composer->getConfig(), $repository, true); - $composerJsonRepositoriesConfig = $composer->getConfig()->getRepositories(); - $name = RepositoryFactory::generateRepositoryName(0, $repoConfig, $composerJsonRepositoriesConfig); - $configSource = new JsonConfigSource(new JsonFile('composer.json')); - $configSource->addRepository($name, $repoConfig); - - $composer = Factory::create($io, null, $disablePlugins); } $process = new ProcessExecutor($io); @@ -290,18 +302,12 @@ EOT return 0; } - protected function installRootPackage(IOInterface $io, Config $config, $packageName, $directory = null, $packageVersion = null, $stability = 'stable', $preferSource = false, $preferDist = false, $installDevPackages = false, $repository = null, $disablePlugins = false, $noScripts = false, $noProgress = false, $ignorePlatformReqs = false, $secureHttp = true) + protected function installRootPackage(IOInterface $io, Config $config, $packageName, $directory = null, $packageVersion = null, $stability = 'stable', $preferSource = false, $preferDist = false, $installDevPackages = false, array $repositories = null, $disablePlugins = false, $noScripts = false, $noProgress = false, $ignorePlatformReqs = false, $secureHttp = true) { if (!$secureHttp) { $config->merge(array('config' => array('secure-http' => false))); } - if (null === $repository) { - $sourceRepo = new CompositeRepository(RepositoryFactory::defaultRepos($io, $config)); - } else { - $sourceRepo = RepositoryFactory::fromString($io, $config, $repository, true); - } - $parser = new VersionParser(); $requirements = $parser->parseNameVersionPairs(array($packageName)); $name = strtolower($requirements[0]['name']); @@ -346,7 +352,20 @@ EOT } $repositorySet = new RepositorySet($stability); - $repositorySet->addRepository($sourceRepo); + if (null === $repositories) { + $repositorySet->addRepository(new CompositeRepository(RepositoryFactory::defaultRepos($io, $config))); + } else { + foreach ($repositories as $repo) { + $repoConfig = RepositoryFactory::configFromString($io, $config, $repo); + if ( + (isset($repoConfig['packagist']) && $repoConfig === array('packagist' => false)) + || (isset($repoConfig['packagist.org']) && $repoConfig === array('packagist.org' => false)) + ) { + continue; + } + $repositorySet->addRepository(RepositoryFactory::createRepo($io, $config, $repoConfig)); + } + } $platformOverrides = $config->get('platform') ?: array(); $platformRepo = new PlatformRepository(array(), $platformOverrides); diff --git a/src/Composer/Repository/RepositoryFactory.php b/src/Composer/Repository/RepositoryFactory.php index b36664187..afe1db636 100644 --- a/src/Composer/Repository/RepositoryFactory.php +++ b/src/Composer/Repository/RepositoryFactory.php @@ -173,6 +173,6 @@ class RepositoryFactory $name .= '2'; } - return $name; + return is_numeric((string) $name) ? 'repo'.$name : $name; } }