diff --git a/doc/03-cli.md b/doc/03-cli.md index eccafbcc0..2b2c9b192 100644 --- a/doc/03-cli.md +++ b/doc/03-cli.md @@ -665,6 +665,7 @@ By default the command checks for the packages on packagist.org. 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. * **--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 diff --git a/src/Composer/Command/CreateProjectCommand.php b/src/Composer/Command/CreateProjectCommand.php index 2ebf3f8c0..61fe740ee 100644 --- a/src/Composer/Command/CreateProjectCommand.php +++ b/src/Composer/Command/CreateProjectCommand.php @@ -69,6 +69,7 @@ class CreateProjectCommand extends BaseCommand 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-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('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.'), @@ -142,11 +143,12 @@ EOT $input->getOption('no-progress'), $input->getOption('no-install'), $input->getOption('ignore-platform-reqs'), - !$input->getOption('no-secure-http') + !$input->getOption('no-secure-http'), + $input->getOption('add-repository') ); } - 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) + 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) { $oldCwd = getcwd(); @@ -162,6 +164,24 @@ EOT } $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'); + + return false; + } + + $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); + } + $composer->getDownloadManager()->setOutputProgress(!$noProgress); $fs = new Filesystem(); diff --git a/src/Composer/Repository/RepositoryFactory.php b/src/Composer/Repository/RepositoryFactory.php index 5d3a2a61f..9bca0bd07 100644 --- a/src/Composer/Repository/RepositoryFactory.php +++ b/src/Composer/Repository/RepositoryFactory.php @@ -153,10 +153,8 @@ class RepositoryFactory if (!isset($repo['type'])) { throw new \UnexpectedValueException('Repository "'.$index.'" ('.json_encode($repo).') must have a type defined'); } - $name = is_int($index) && isset($repo['url']) ? preg_replace('{^https?://}i', '', $repo['url']) : $index; - while (isset($repos[$name])) { - $name .= '2'; - } + + $name = self::generateRepositoryName($index, $repo, $repos); if ($repo['type'] === 'filesystem') { $repos[$name] = new FilesystemRepository($repo['json']); } else { @@ -166,4 +164,14 @@ class RepositoryFactory return $repos; } + + public static function generateRepositoryName($index, array $repo, array $existingRepos) + { + $name = is_int($index) && isset($repo['url']) ? preg_replace('{^https?://}i', '', $repo['url']) : $index; + while (isset($existingRepos[$name])) { + $name .= '2'; + } + + return $name; + } } diff --git a/tests/Composer/Test/Repository/RepositoryFactoryTest.php b/tests/Composer/Test/Repository/RepositoryFactoryTest.php index e54624415..acd666430 100644 --- a/tests/Composer/Test/Repository/RepositoryFactoryTest.php +++ b/tests/Composer/Test/Repository/RepositoryFactoryTest.php @@ -46,4 +46,24 @@ class RepositoryFactoryTest extends TestCase 'path', ), array_keys($repositoryClasses)); } + + /** + * @dataProvider generateRepositoryNameProvider + */ + public function testGenerateRepositoryName($index, array $config, array $existingRepos, $expected) + { + $this->assertSame($expected, RepositoryFactory::generateRepositoryName($index, $config, $existingRepos)); + } + + public function generateRepositoryNameProvider() + { + return array( + array(0, array(), array(), 0), + array(0, array(), array(array()), '02'), + array(0, array('url' => 'https://example.org'), array(), 'example.org'), + array(0, array('url' => 'https://example.org'), array('example.org' => array()), 'example.org2'), + array('example.org', array('url' => 'https://example.org/repository'), array(), 'example.org'), + array('example.org', array('url' => 'https://example.org/repository'), array('example.org' => array()), 'example.org2'), + ); + } }