Browse Source

Merge pull request #8565 from glaubinix/t/create-project-add-repository

Create project: add option to add the repository to the composer.json
Jordi Boggiano 5 years ago
parent
commit
02433c3659

+ 1 - 0
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

+ 22 - 2
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('<error>Adding a repository when creating a project that provides a composer.lock file is not supported</error>');
+
+                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();

+ 12 - 4
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;
+    }
 }

+ 20 - 0
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'),
+        );
+    }
 }