1
0
Fork 0

Add --repository flag to init command, and rename --repository-url to --repository in create-project, fixes #4200, closes #4207, closes #2604, fixes #2920

pull/4980/head
Jordi Boggiano 2016-02-29 17:32:32 +00:00
parent b6b2635f42
commit 1aec1c1fc8
12 changed files with 218 additions and 95 deletions

View File

@ -50,6 +50,11 @@ php composer.phar init
in format `foo/bar:1.0.0`. in format `foo/bar:1.0.0`.
* **--require-dev:** Development requirements, see **--require**. * **--require-dev:** Development requirements, see **--require**.
* **--stability (-s):** Value for the `minimum-stability` field. * **--stability (-s):** Value for the `minimum-stability` field.
* **--repository:** Provide one (or more) custom repositories. They will be stored
in the generated composer.json, and used for auto-completion when prompting for
the list of requires. Every repository can be either an HTTP URL pointing
to a `composer` repository or a JSON string which similar to what the
[repositories](04-schema.md#repositories) key accepts.
## install ## install
@ -541,9 +546,11 @@ By default the command checks for the packages on packagist.org.
### Options ### Options
* **--repository-url:** Provide a custom repository to search for the package, * **--repository:** Provide a custom repository to search for the package,
which will be used instead of packagist. Can be either an HTTP URL pointing which will be used instead of packagist. Can be either an HTTP URL pointing
to a `composer` repository, or a path to a local `packages.json` file. 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.
* **--stability (-s):** Minimum stability of package. Defaults to `stable`. * **--stability (-s):** Minimum stability of package. Defaults to `stable`.
* **--prefer-source:** Install packages from `source` when available. * **--prefer-source:** Install packages from `source` when available.
* **--prefer-dist:** Install packages from `dist` when available. * **--prefer-dist:** Install packages from `dist` when available.

View File

@ -16,6 +16,7 @@ use Composer\Factory;
use Composer\IO\IOInterface; use Composer\IO\IOInterface;
use Composer\Config; use Composer\Config;
use Composer\Repository\CompositeRepository; use Composer\Repository\CompositeRepository;
use Composer\Repository\RepositoryFactory;
use Composer\Script\ScriptEvents; use Composer\Script\ScriptEvents;
use Composer\Plugin\CommandEvent; use Composer\Plugin\CommandEvent;
use Composer\Plugin\PluginEvents; use Composer\Plugin\PluginEvents;
@ -126,7 +127,7 @@ EOT
$localRepo = $composer->getRepositoryManager()->getLocalRepository(); $localRepo = $composer->getRepositoryManager()->getLocalRepository();
$repo = new CompositeRepository(array_merge(array($localRepo), $composer->getRepositoryManager()->getRepositories())); $repo = new CompositeRepository(array_merge(array($localRepo), $composer->getRepositoryManager()->getRepositories()));
} else { } else {
$defaultRepos = Factory::createDefaultRepositories($this->getIO()); $defaultRepos = RepositoryFactory::default($this->getIO());
$io->writeError('No composer.json found in the current directory, searching packages from ' . implode(', ', array_keys($defaultRepos))); $io->writeError('No composer.json found in the current directory, searching packages from ' . implode(', ', array_keys($defaultRepos)));
$repo = new CompositeRepository($defaultRepos); $repo = new CompositeRepository($defaultRepos);
} }

View File

@ -447,10 +447,7 @@ EOT
return $this->configSource->addRepository($matches[1], false); return $this->configSource->addRepository($matches[1], false);
} }
} else { } else {
$value = json_decode($values[0], true); $value = JsonFile::parseJson($values[0]);
if (JSON_ERROR_NONE !== json_last_error()) {
throw new \InvalidArgumentException(sprintf('%s is not valid JSON.', $values[0]));
}
return $this->configSource->addRepository($matches[1], $value); return $this->configSource->addRepository($matches[1], $value);
} }

View File

@ -22,6 +22,7 @@ use Composer\Package\BasePackage;
use Composer\DependencyResolver\Pool; use Composer\DependencyResolver\Pool;
use Composer\DependencyResolver\Operation\InstallOperation; use Composer\DependencyResolver\Operation\InstallOperation;
use Composer\Package\Version\VersionSelector; use Composer\Package\Version\VersionSelector;
use Composer\Repository\RepositoryFactory;
use Composer\Repository\ComposerRepository; use Composer\Repository\ComposerRepository;
use Composer\Repository\CompositeRepository; use Composer\Repository\CompositeRepository;
use Composer\Repository\FilesystemRepository; use Composer\Repository\FilesystemRepository;
@ -60,7 +61,8 @@ class CreateProjectCommand extends BaseCommand
new InputOption('stability', 's', InputOption::VALUE_REQUIRED, 'Minimum-stability allowed (unless a version is specified).'), 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-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('prefer-dist', null, InputOption::VALUE_NONE, 'Forces installation from package dist even for dev versions.'),
new InputOption('repository-url', null, InputOption::VALUE_REQUIRED, 'Pick a different repository url to look for the package.'), 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('dev', null, InputOption::VALUE_NONE, 'Enables installation of require-dev packages (enabled by default, only present for BC).'), 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-dev', null, InputOption::VALUE_NONE, 'Disables installation of require-dev packages.'),
new InputOption('no-plugins', null, InputOption::VALUE_NONE, 'Whether to disable plugins.'), new InputOption('no-plugins', null, InputOption::VALUE_NONE, 'Whether to disable plugins.'),
@ -92,7 +94,7 @@ To setup a developer workable version you should create the project using the so
controlled code by appending the <info>'--prefer-source'</info> flag. controlled code by appending the <info>'--prefer-source'</info> flag.
To install a package from another repository than the default one you To install a package from another repository than the default one you
can pass the <info>'--repository-url=https://myrepository.org'</info> flag. can pass the <info>'--repository=https://myrepository.org'</info> flag.
EOT EOT
) )
@ -125,7 +127,7 @@ EOT
$preferSource, $preferSource,
$preferDist, $preferDist,
!$input->getOption('no-dev'), !$input->getOption('no-dev'),
$input->getOption('repository-url'), $input->getOption('repository') || $input->getOption('repository-url'),
$input->getOption('no-plugins'), $input->getOption('no-plugins'),
$input->getOption('no-scripts'), $input->getOption('no-scripts'),
$input->getOption('keep-vcs'), $input->getOption('keep-vcs'),
@ -135,7 +137,7 @@ EOT
); );
} }
public function installProject(IOInterface $io, Config $config, InputInterface $input, $packageName, $directory = null, $packageVersion = null, $stability = 'stable', $preferSource = false, $preferDist = false, $installDevPackages = false, $repositoryUrl = null, $disablePlugins = false, $noScripts = false, $keepVcs = false, $noProgress = false, $noInstall = false, $ignorePlatformReqs = false) 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, $keepVcs = false, $noProgress = false, $noInstall = false, $ignorePlatformReqs = false)
{ {
$oldCwd = getcwd(); $oldCwd = getcwd();
@ -143,7 +145,7 @@ EOT
$io->loadConfiguration($config); $io->loadConfiguration($config);
if ($packageName !== null) { if ($packageName !== null) {
$installedFromVcs = $this->installRootPackage($io, $config, $packageName, $directory, $packageVersion, $stability, $preferSource, $preferDist, $installDevPackages, $repositoryUrl, $disablePlugins, $noScripts, $keepVcs, $noProgress); $installedFromVcs = $this->installRootPackage($io, $config, $packageName, $directory, $packageVersion, $stability, $preferSource, $preferDist, $installDevPackages, $repository, $disablePlugins, $noScripts, $keepVcs, $noProgress);
} else { } else {
$installedFromVcs = false; $installedFromVcs = false;
} }
@ -239,22 +241,12 @@ EOT
return 0; return 0;
} }
protected function installRootPackage(IOInterface $io, Config $config, $packageName, $directory = null, $packageVersion = null, $stability = 'stable', $preferSource = false, $preferDist = false, $installDevPackages = false, $repositoryUrl = null, $disablePlugins = false, $noScripts = false, $keepVcs = false, $noProgress = false) 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, $keepVcs = false, $noProgress = false)
{ {
if (null === $repositoryUrl) { if (null === $repository) {
$sourceRepo = new CompositeRepository(Factory::createDefaultRepositories($io, $config)); $sourceRepo = new CompositeRepository(RepositoryFactory::default($io, $config));
} elseif ("json" === pathinfo($repositoryUrl, PATHINFO_EXTENSION) && file_exists($repositoryUrl)) {
$json = new JsonFile($repositoryUrl, Factory::createRemoteFilesystem($io, $config));
$data = $json->read();
if (!empty($data['packages']) || !empty($data['includes']) || !empty($data['provider-includes'])) {
$sourceRepo = new ComposerRepository(array('url' => 'file://' . strtr(realpath($repositoryUrl), '\\', '/')), $io, $config);
} else {
$sourceRepo = new FilesystemRepository($json);
}
} elseif (0 === strpos($repositoryUrl, 'http')) {
$sourceRepo = new ComposerRepository(array('url' => $repositoryUrl), $io, $config);
} else { } else {
throw new \InvalidArgumentException("Invalid repository url given. Has to be a .json file or an http url."); $sourceRepo = RepositoryFactory::fromString($io, $config, $repository, true);
} }
$parser = new VersionParser(); $parser = new VersionParser();

View File

@ -16,6 +16,7 @@ use Composer\Factory;
use Composer\Package\CompletePackageInterface; use Composer\Package\CompletePackageInterface;
use Composer\Repository\RepositoryInterface; use Composer\Repository\RepositoryInterface;
use Composer\Repository\ArrayRepository; use Composer\Repository\ArrayRepository;
use Composer\Repository\RepositoryFactory;
use Composer\Util\Platform; use Composer\Util\Platform;
use Composer\Util\ProcessExecutor; use Composer\Util\ProcessExecutor;
use Symfony\Component\Console\Input\InputArgument; use Symfony\Component\Console\Input\InputArgument;
@ -153,8 +154,6 @@ EOT
); );
} }
$defaultRepos = Factory::createDefaultRepositories($this->getIO()); return RepositoryFactory::default($this->getIO());
return $defaultRepos;
} }
} }

View File

@ -15,6 +15,7 @@ namespace Composer\Command;
use Composer\DependencyResolver\Pool; use Composer\DependencyResolver\Pool;
use Composer\Json\JsonFile; use Composer\Json\JsonFile;
use Composer\Factory; use Composer\Factory;
use Composer\Repository\RepositoryFactory;
use Composer\Package\BasePackage; use Composer\Package\BasePackage;
use Composer\Package\Version\VersionParser; use Composer\Package\Version\VersionParser;
use Composer\Package\Version\VersionSelector; use Composer\Package\Version\VersionSelector;
@ -61,6 +62,7 @@ class InitCommand extends BaseCommand
new InputOption('require-dev', null, InputOption::VALUE_IS_ARRAY | InputOption::VALUE_REQUIRED, 'Package to require for development with a version constraint, e.g. foo/bar:1.0.0 or foo/bar=1.0.0 or "foo/bar 1.0.0"'), new InputOption('require-dev', null, InputOption::VALUE_IS_ARRAY | InputOption::VALUE_REQUIRED, 'Package to require for development with a version constraint, e.g. foo/bar:1.0.0 or foo/bar=1.0.0 or "foo/bar 1.0.0"'),
new InputOption('stability', 's', InputOption::VALUE_REQUIRED, 'Minimum stability (empty or one of: '.implode(', ', array_keys(BasePackage::$stabilities)).')'), new InputOption('stability', 's', InputOption::VALUE_REQUIRED, 'Minimum stability (empty or one of: '.implode(', ', array_keys(BasePackage::$stabilities)).')'),
new InputOption('license', 'l', InputOption::VALUE_REQUIRED, 'License of package'), new InputOption('license', 'l', InputOption::VALUE_REQUIRED, 'License of package'),
new InputOption('repository', null, InputOption::VALUE_REQUIRED | InputOption::VALUE_IS_ARRAY, 'Add custom repositories, either by URL or using JSON arrays'),
)) ))
->setHelp(<<<EOT ->setHelp(<<<EOT
The <info>init</info> command creates a basic composer.json file The <info>init</info> command creates a basic composer.json file
@ -78,8 +80,9 @@ EOT
*/ */
protected function execute(InputInterface $input, OutputInterface $output) protected function execute(InputInterface $input, OutputInterface $output)
{ {
$whitelist = array('name', 'description', 'author', 'type', 'homepage', 'require', 'require-dev', 'stability', 'license'); $io = $this->getIO();
$whitelist = array('name', 'description', 'author', 'type', 'homepage', 'require', 'require-dev', 'stability', 'license');
$options = array_filter(array_intersect_key($input->getOptions(), array_flip($whitelist))); $options = array_filter(array_intersect_key($input->getOptions(), array_flip($whitelist)));
if (isset($options['author'])) { if (isset($options['author'])) {
@ -87,6 +90,14 @@ EOT
unset($options['author']); unset($options['author']);
} }
$repositories = $input->getOption('repository');
if ($repositories) {
$config = Factory::createConfig($io);
foreach ($repositories as $repo) {
$options['repositories'][] = RepositoryFactory::configFromString($io, $config, $repo);
}
}
if (isset($options['stability'])) { if (isset($options['stability'])) {
$options['minimum-stability'] = $options['stability']; $options['minimum-stability'] = $options['stability'];
unset($options['stability']); unset($options['stability']);
@ -106,7 +117,6 @@ EOT
$file = new JsonFile('composer.json'); $file = new JsonFile('composer.json');
$json = $file->encode($options); $json = $file->encode($options);
$io = $this->getIO();
if ($input->isInteractive()) { if ($input->isInteractive()) {
$io->writeError(array('', $json, '')); $io->writeError(array('', $json, ''));
@ -145,6 +155,23 @@ EOT
$io = $this->getIO(); $io = $this->getIO();
$formatter = $this->getHelperSet()->get('formatter'); $formatter = $this->getHelperSet()->get('formatter');
// initialize repos if configured
$repositories = $input->getOption('repository');
if ($repositories) {
$config = Factory::createConfig($io);
$repos = array(new PlatformRepository);
foreach ($repositories as $repo) {
$repos[] = RepositoryFactory::fromString($io, $config, $repo);
}
$repos[] = RepositoryFactory::createRepo($io, $config, array(
'type' => 'composer',
'url' => 'https://packagist.org',
));
$this->repos = new CompositeRepository($repos);
unset($repos, $config, $repositories);
}
$io->writeError(array( $io->writeError(array(
'', '',
$formatter->formatBlock('Welcome to the Composer config generator', 'bg=blue;fg=white', true), $formatter->formatBlock('Welcome to the Composer config generator', 'bg=blue;fg=white', true),
@ -318,7 +345,7 @@ EOT
if (!$this->repos) { if (!$this->repos) {
$this->repos = new CompositeRepository(array_merge( $this->repos = new CompositeRepository(array_merge(
array(new PlatformRepository), array(new PlatformRepository),
Factory::createDefaultRepositories($this->getIO()) RepositoryFactory::default($this->getIO())
)); ));
} }

View File

@ -18,6 +18,7 @@ use Symfony\Component\Console\Input\InputOption;
use Symfony\Component\Console\Output\OutputInterface; use Symfony\Component\Console\Output\OutputInterface;
use Composer\Repository\CompositeRepository; use Composer\Repository\CompositeRepository;
use Composer\Repository\PlatformRepository; use Composer\Repository\PlatformRepository;
use Composer\Repository\RepositoryFactory;
use Composer\Repository\RepositoryInterface; use Composer\Repository\RepositoryInterface;
use Composer\Factory; use Composer\Factory;
use Composer\Plugin\CommandEvent; use Composer\Plugin\CommandEvent;
@ -62,7 +63,7 @@ EOT
$installedRepo = new CompositeRepository(array($localRepo, $platformRepo)); $installedRepo = new CompositeRepository(array($localRepo, $platformRepo));
$repos = new CompositeRepository(array_merge(array($installedRepo), $composer->getRepositoryManager()->getRepositories())); $repos = new CompositeRepository(array_merge(array($installedRepo), $composer->getRepositoryManager()->getRepositories()));
} else { } else {
$defaultRepos = Factory::createDefaultRepositories($io); $defaultRepos = RepositoryFactory::default($io);
$io->writeError('No composer.json found in the current directory, showing packages from ' . implode(', ', array_keys($defaultRepos))); $io->writeError('No composer.json found in the current directory, showing packages from ' . implode(', ', array_keys($defaultRepos)));
$installedRepo = $platformRepo; $installedRepo = $platformRepo;
$repos = new CompositeRepository(array_merge(array($installedRepo), $defaultRepos)); $repos = new CompositeRepository(array_merge(array($installedRepo), $defaultRepos));

View File

@ -31,6 +31,7 @@ use Composer\Repository\CompositeRepository;
use Composer\Repository\ComposerRepository; use Composer\Repository\ComposerRepository;
use Composer\Repository\PlatformRepository; use Composer\Repository\PlatformRepository;
use Composer\Repository\RepositoryInterface; use Composer\Repository\RepositoryInterface;
use Composer\Repository\RepositoryFactory;
use Composer\Spdx\SpdxLicenses; use Composer\Spdx\SpdxLicenses;
/** /**
@ -106,7 +107,7 @@ EOT
if ($composer) { if ($composer) {
$repos = new CompositeRepository($composer->getRepositoryManager()->getRepositories()); $repos = new CompositeRepository($composer->getRepositoryManager()->getRepositories());
} else { } else {
$defaultRepos = Factory::createDefaultRepositories($io); $defaultRepos = RepositoryFactory::default($io);
$repos = new CompositeRepository($defaultRepos); $repos = new CompositeRepository($defaultRepos);
$io->writeError('No composer.json found in the current directory, showing available packages from ' . implode(', ', array_keys($defaultRepos))); $io->writeError('No composer.json found in the current directory, showing available packages from ' . implode(', ', array_keys($defaultRepos)));
} }
@ -115,7 +116,7 @@ EOT
$installedRepo = new CompositeRepository(array($localRepo, $platformRepo)); $installedRepo = new CompositeRepository(array($localRepo, $platformRepo));
$repos = new CompositeRepository(array_merge(array($installedRepo), $composer->getRepositoryManager()->getRepositories())); $repos = new CompositeRepository(array_merge(array($installedRepo), $composer->getRepositoryManager()->getRepositories()));
} elseif ($input->getOption('all')) { } elseif ($input->getOption('all')) {
$defaultRepos = Factory::createDefaultRepositories($io); $defaultRepos = RepositoryFactory::default($io);
$io->writeError('No composer.json found in the current directory, showing available packages from ' . implode(', ', array_keys($defaultRepos))); $io->writeError('No composer.json found in the current directory, showing available packages from ' . implode(', ', array_keys($defaultRepos)));
$installedRepo = $platformRepo; $installedRepo = $platformRepo;
$repos = new CompositeRepository(array_merge(array($installedRepo), $defaultRepos)); $repos = new CompositeRepository(array_merge(array($installedRepo), $defaultRepos));

View File

@ -18,6 +18,7 @@ use Composer\IO\IOInterface;
use Composer\Package\Archiver; use Composer\Package\Archiver;
use Composer\Package\Version\VersionGuesser; use Composer\Package\Version\VersionGuesser;
use Composer\Repository\RepositoryManager; use Composer\Repository\RepositoryManager;
use Composer\Repository\RepositoryFactory;
use Composer\Repository\WritableRepositoryInterface; use Composer\Repository\WritableRepositoryInterface;
use Composer\Util\Filesystem; use Composer\Util\Filesystem;
use Composer\Util\Platform; use Composer\Util\Platform;
@ -221,39 +222,12 @@ class Factory
); );
} }
/**
* @deprecated Use Composer\Repository\RepositoryFactory::default instead
*/
public static function createDefaultRepositories(IOInterface $io = null, Config $config = null, RepositoryManager $rm = null) public static function createDefaultRepositories(IOInterface $io = null, Config $config = null, RepositoryManager $rm = null)
{ {
$repos = array(); return RepositoryFactory::default($io, $config, $rm);
if (!$config) {
$config = static::createConfig($io);
}
if (!$rm) {
if (!$io) {
throw new \InvalidArgumentException('This function requires either an IOInterface or a RepositoryManager');
}
$factory = new static;
$rm = $factory->createRepositoryManager($io, $config, null, self::createRemoteFilesystem($io, $config));
}
foreach ($config->getRepositories() as $index => $repo) {
if (is_string($repo)) {
throw new \UnexpectedValueException('"repositories" should be an array of repository definitions, only a single repository was given');
}
if (!is_array($repo)) {
throw new \UnexpectedValueException('Repository "'.$index.'" ('.json_encode($repo).') should be an array, '.gettype($repo).' given');
}
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';
}
$repos[$name] = $rm->createRepository($repo['type'], $repo);
}
return $repos;
} }
/** /**
@ -336,7 +310,7 @@ class Factory
$composer->setEventDispatcher($dispatcher); $composer->setEventDispatcher($dispatcher);
// initialize repository manager // initialize repository manager
$rm = $this->createRepositoryManager($io, $config, $dispatcher, $rfs); $rm = RepositoryFactory::manager($io, $config, $dispatcher, $rfs);
$composer->setRepositoryManager($rm); $composer->setRepositoryManager($rm);
// load local repository // load local repository
@ -399,30 +373,6 @@ class Factory
return $composer; return $composer;
} }
/**
* @param IOInterface $io
* @param Config $config
* @param EventDispatcher $eventDispatcher
* @return Repository\RepositoryManager
*/
protected function createRepositoryManager(IOInterface $io, Config $config, EventDispatcher $eventDispatcher = null, RemoteFilesystem $rfs = null)
{
$rm = new RepositoryManager($io, $config, $eventDispatcher, $rfs);
$rm->setRepositoryClass('composer', 'Composer\Repository\ComposerRepository');
$rm->setRepositoryClass('vcs', 'Composer\Repository\VcsRepository');
$rm->setRepositoryClass('package', 'Composer\Repository\PackageRepository');
$rm->setRepositoryClass('pear', 'Composer\Repository\PearRepository');
$rm->setRepositoryClass('git', 'Composer\Repository\VcsRepository');
$rm->setRepositoryClass('gitlab', 'Composer\Repository\VcsRepository');
$rm->setRepositoryClass('svn', 'Composer\Repository\VcsRepository');
$rm->setRepositoryClass('perforce', 'Composer\Repository\VcsRepository');
$rm->setRepositoryClass('hg', 'Composer\Repository\VcsRepository');
$rm->setRepositoryClass('artifact', 'Composer\Repository\ArtifactRepository');
$rm->setRepositoryClass('path', 'Composer\Repository\PathRepository');
return $rm;
}
/** /**
* @param Repository\RepositoryManager $rm * @param Repository\RepositoryManager $rm
* @param string $vendorDir * @param string $vendorDir

View File

@ -155,13 +155,12 @@ interface IOInterface
* @param string|array $question The question to ask * @param string|array $question The question to ask
* @param array $choices List of choices to pick from * @param array $choices List of choices to pick from
* @param bool|string $default The default answer if the user enters nothing * @param bool|string $default The default answer if the user enters nothing
* @param bool|int $attempts Max number of times to ask before giving up (false by default, which means infinite) * @param bool|int $attempts Max number of times to ask before giving up (false by default, which means infinite)
* @param string $errorMessage Message which will be shown if invalid value from choice list would be picked * @param string $errorMessage Message which will be shown if invalid value from choice list would be picked
* @param bool $multiselect Select more than one value separated by comma * @param bool $multiselect Select more than one value separated by comma
* *
* @return int|string|array The selected value or values (the key of the choices array)
*
* @throws \InvalidArgumentException * @throws \InvalidArgumentException
* @return int|string|array The selected value or values (the key of the choices array)
*/ */
public function select($question, $choices, $default, $attempts = false, $errorMessage = 'Value "%s" is invalid', $multiselect = false); public function select($question, $choices, $default, $attempts = false, $errorMessage = 'Value "%s" is invalid', $multiselect = false);

View File

@ -17,6 +17,7 @@ use Composer\Package\PackageInterface;
use Composer\Package\AliasPackage; use Composer\Package\AliasPackage;
use Composer\Config; use Composer\Config;
use Composer\Factory; use Composer\Factory;
use Composer\Repository\RepositoryFactory;
use Composer\Package\Version\VersionGuesser; use Composer\Package\Version\VersionGuesser;
use Composer\Package\Version\VersionParser; use Composer\Package\Version\VersionParser;
use Composer\Repository\RepositoryManager; use Composer\Repository\RepositoryManager;
@ -141,7 +142,7 @@ class RootPackageLoader extends ArrayLoader
$realPackage->setPreferStable((bool) $config['prefer-stable']); $realPackage->setPreferStable((bool) $config['prefer-stable']);
} }
$repos = Factory::createDefaultRepositories(null, $this->config, $this->manager); $repos = RepositoryFactory::default(null, $this->config, $this->manager);
foreach ($repos as $repo) { foreach ($repos as $repo) {
$this->manager->addRepository($repo); $this->manager->addRepository($repo);
} }

View File

@ -0,0 +1,148 @@
<?php
/*
* This file is part of Composer.
*
* (c) Nils Adermann <naderman@naderman.de>
* Jordi Boggiano <j.boggiano@seld.be>
*
* For the full copyright and license information, please view the LICENSE
* file that was distributed with this source code.
*/
namespace Composer\Repository;
use Composer\Factory;
use Composer\IO\IOInterface;
use Composer\Config;
use Composer\EventDispatcher\EventDispatcher;
use Composer\Util\RemoteFilesystem;
use Composer\Json\JsonFile;
/**
* @author Jordi Boggiano <j.boggiano@seld.be>
*/
class RepositoryFactory
{
/**
* @return array
*/
public static function configFromString(IOInterface $io, Config $config, $repository, $allowFilesystem = false)
{
if ("json" === pathinfo($repository, PATHINFO_EXTENSION)) {
$json = new JsonFile($repository, Factory::createRemoteFilesystem($io, $config));
$data = $json->read();
if (!empty($data['packages']) || !empty($data['includes']) || !empty($data['provider-includes'])) {
$repoConfig = array('type' => 'composer', 'url' => 'file://' . strtr(realpath($repository), '\\', '/'));
} elseif ($allowFilesystem) {
$repoConfig = array('type' => 'filesystem', 'json' => $json);
} else {
throw new \InvalidArgumentException("Invalid repository URL ($repository) given. This file does not contain a valid composer repository.");
}
} elseif (0 === strpos($repository, 'http')) {
$repoConfig = array('type' => 'composer', 'url' => $repository);
} elseif ('{' === substr($repository, 0, 1)) {
// assume it is a json object that makes a repo config
$repoConfig = JsonFile::parseJson($repository);
} else {
throw new \InvalidArgumentException("Invalid repository url ($repository) given. Has to be a .json file, an http url or a JSON object.");
}
return $repoConfig;
}
/**
* @return RepositoryInterface
*/
public static function fromString(IOInterface $io, Config $config, $repository, $allowFilesystem = false)
{
$repoConfig = static::configFromString($io, $config, $repository, $allowFilesystem);
return static::createRepo($io, $config, $repoConfig);
}
/**
* @return RepositoryInterface
*/
public static function createRepo($io, $config, array $repoConfig)
{
$rm = static::manager($io, $config, null, Factory::createRemoteFilesystem($io, $config));
$repos = static::createRepos($rm, array($repoConfig));
return reset($repos);
}
/**
* @return RepositoryInterface[]
*/
public static function default(IOInterface $io = null, Config $config = null, RepositoryManager $rm = null)
{
if (!$config) {
$config = Factory::createConfig($io);
}
if (!$rm) {
if (!$io) {
throw new \InvalidArgumentException('This function requires either an IOInterface or a RepositoryManager');
}
$rm = static::manager($io, $config, null, Factory::createRemoteFilesystem($io, $config));
}
return static::createRepos($rm, $config->getRepositories());
}
/**
* @param IOInterface $io
* @param Config $config
* @param EventDispatcher $eventDispatcher
* @param RemoteFilesystem $rfs
* @return RepositoryManager
*/
public static function manager(IOInterface $io, Config $config, EventDispatcher $eventDispatcher = null, RemoteFilesystem $rfs = null)
{
$rm = new RepositoryManager($io, $config, $eventDispatcher, $rfs);
$rm->setRepositoryClass('composer', 'Composer\Repository\ComposerRepository');
$rm->setRepositoryClass('vcs', 'Composer\Repository\VcsRepository');
$rm->setRepositoryClass('package', 'Composer\Repository\PackageRepository');
$rm->setRepositoryClass('pear', 'Composer\Repository\PearRepository');
$rm->setRepositoryClass('git', 'Composer\Repository\VcsRepository');
$rm->setRepositoryClass('gitlab', 'Composer\Repository\VcsRepository');
$rm->setRepositoryClass('svn', 'Composer\Repository\VcsRepository');
$rm->setRepositoryClass('perforce', 'Composer\Repository\VcsRepository');
$rm->setRepositoryClass('hg', 'Composer\Repository\VcsRepository');
$rm->setRepositoryClass('artifact', 'Composer\Repository\ArtifactRepository');
$rm->setRepositoryClass('path', 'Composer\Repository\PathRepository');
return $rm;
}
/**
* @return RepositoryInterface[]
*/
private static function createRepos(RepositoryManager $rm, array $repoConfigs)
{
$repos = array();
foreach ($repoConfigs as $index => $repo) {
if (is_string($repo)) {
throw new \UnexpectedValueException('"repositories" should be an array of repository definitions, only a single repository was given');
}
if (!is_array($repo)) {
throw new \UnexpectedValueException('Repository "'.$index.'" ('.json_encode($repo).') should be an array, '.gettype($repo).' given');
}
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';
}
if ($repo['type'] === 'filesystem') {
$repos[$name] = new FilesystemRepository($repo['json']);
} else {
$repos[$name] = $rm->createRepository($repo['type'], $repo);
}
}
return $repos;
}
}