function CreateProjectCommand::installRootPackage
Parameters
array<string>|null $repositories:
Throws
\Exception
1 call to CreateProjectCommand::installRootPackage()
- CreateProjectCommand::installProject in vendor/
composer/ composer/ src/ Composer/ Command/ CreateProjectCommand.php
File
-
vendor/
composer/ composer/ src/ Composer/ Command/ CreateProjectCommand.php, line 331
Class
- CreateProjectCommand
- Install a package as new project into new directory.
Namespace
Composer\CommandCode
protected function installRootPackage(InputInterface $input, IOInterface $io, Config $config, string $packageName, PlatformRequirementFilterInterface $platformRequirementFilter, ?string $directory = null, ?string $packageVersion = null, ?string $stability = 'stable', bool $preferSource = false, bool $preferDist = false, bool $installDevPackages = false, ?array $repositories = null, bool $disablePlugins = false, bool $disableScripts = false, bool $noProgress = false, bool $secureHttp = true) : bool {
$parser = new VersionParser();
$requirements = $parser->parseNameVersionPairs([
$packageName,
]);
$name = strtolower($requirements[0]['name']);
if (!$packageVersion && isset($requirements[0]['version'])) {
$packageVersion = $requirements[0]['version'];
}
// if no directory was specified, use the 2nd part of the package name
if (null === $directory) {
$parts = explode("/", $name, 2);
$directory = Platform::getCwd() . DIRECTORY_SEPARATOR . array_pop($parts);
}
$directory = rtrim($directory, '/\\');
$process = new ProcessExecutor($io);
$fs = new Filesystem($process);
if (!$fs->isAbsolutePath($directory)) {
$directory = Platform::getCwd() . DIRECTORY_SEPARATOR . $directory;
}
if ('' === $directory) {
throw new \UnexpectedValueException('Got an empty target directory, something went wrong');
}
// set the base dir to ensure $config->all() below resolves the correct absolute paths to vendor-dir etc
$config->setBaseDir($directory);
if (!$secureHttp) {
$config->merge([
'config' => [
'secure-http' => false,
],
], Config::SOURCE_COMMAND);
}
$io->writeError('<info>Creating a "' . $packageName . '" project at "' . $fs->findShortestPath(Platform::getCwd(), $directory, true) . '"</info>');
if (file_exists($directory)) {
if (!is_dir($directory)) {
throw new \InvalidArgumentException('Cannot create project directory at "' . $directory . '", it exists as a file.');
}
if (!$fs->isDirEmpty($directory)) {
throw new \InvalidArgumentException('Project directory "' . $directory . '" is not empty.');
}
}
if (null === $stability) {
if (null === $packageVersion) {
$stability = 'stable';
}
elseif (Preg::isMatchStrictGroups('{^[^,\\s]*?@(' . implode('|', array_keys(BasePackage::STABILITIES)) . ')$}i', $packageVersion, $match)) {
$stability = $match[1];
}
else {
$stability = VersionParser::parseStability($packageVersion);
}
}
$stability = VersionParser::normalizeStability($stability);
if (!isset(BasePackage::STABILITIES[$stability])) {
throw new \InvalidArgumentException('Invalid stability provided (' . $stability . '), must be one of: ' . implode(', ', array_keys(BasePackage::STABILITIES)));
}
$composer = $this->createComposerInstance($input, $io, $config->all(), $disablePlugins, $disableScripts);
$config = $composer->getConfig();
// set the base dir here again on the new config instance, as otherwise in case the vendor dir is defined in an env var for example it would still override the value set above by $config->all()
$config->setBaseDir($directory);
$rm = $composer->getRepositoryManager();
$repositorySet = new RepositorySet($stability);
if (null === $repositories) {
$repositorySet->addRepository(new CompositeRepository(RepositoryFactory::defaultRepos($io, $config, $rm)));
}
else {
foreach ($repositories as $repo) {
$repoConfig = RepositoryFactory::configFromString($io, $config, $repo, true);
if (isset($repoConfig['packagist']) && $repoConfig === [
'packagist' => false,
] || isset($repoConfig['packagist.org']) && $repoConfig === [
'packagist.org' => false,
]) {
continue;
}
$repositorySet->addRepository(RepositoryFactory::createRepo($io, $config, $repoConfig, $rm));
}
}
$platformOverrides = $config->get('platform');
$platformRepo = new PlatformRepository([], $platformOverrides);
// find the latest version if there are multiple
$versionSelector = new VersionSelector($repositorySet, $platformRepo);
$package = $versionSelector->findBestCandidate($name, $packageVersion, $stability, $platformRequirementFilter, 0, $io);
if (!$package) {
$errorMessage = "Could not find package {$name} with " . ($packageVersion ? "version {$packageVersion}" : "stability {$stability}");
if (!$platformRequirementFilter instanceof IgnoreAllPlatformRequirementFilter && $versionSelector->findBestCandidate($name, $packageVersion, $stability, PlatformRequirementFilterFactory::ignoreAll())) {
throw new \InvalidArgumentException($errorMessage . ' in a version installable using your PHP version, PHP extensions and Composer version.');
}
throw new \InvalidArgumentException($errorMessage . '.');
}
// handler Ctrl+C aborts gracefully
@mkdir($directory, 0777, true);
if (false !== ($realDir = realpath($directory))) {
$signalHandler = SignalHandler::create([
SignalHandler::SIGINT,
SignalHandler::SIGTERM,
SignalHandler::SIGHUP,
], function (string $signal, SignalHandler $handler) use ($realDir) {
$this->getIO()
->writeError('Received ' . $signal . ', aborting', true, IOInterface::DEBUG);
$fs = new Filesystem();
$fs->removeDirectory($realDir);
$handler->exitWithLastSignal();
});
}
// avoid displaying 9999999-dev as version if default-branch was selected
if ($package instanceof AliasPackage && $package->getPrettyVersion() === VersionParser::DEFAULT_BRANCH_ALIAS) {
$package = $package->getAliasOf();
}
$io->writeError('<info>Installing ' . $package->getName() . ' (' . $package->getFullPrettyVersion(false) . ')</info>');
if ($disablePlugins) {
$io->writeError('<info>Plugins have been disabled.</info>');
}
if ($package instanceof AliasPackage) {
$package = $package->getAliasOf();
}
$dm = $composer->getDownloadManager();
$dm->setPreferSource($preferSource)
->setPreferDist($preferDist);
$projectInstaller = new ProjectInstaller($directory, $dm, $fs);
$im = $composer->getInstallationManager();
$im->setOutputProgress(!$noProgress);
$im->addInstaller($projectInstaller);
$im->execute(new InstalledArrayRepository(), [
new InstallOperation($package),
]);
$im->notifyInstalls($io);
// collect suggestions
$this->suggestedPackagesReporter
->addSuggestionsFromPackage($package);
$installedFromVcs = 'source' === $package->getInstallationSource();
$io->writeError('<info>Created project in ' . $directory . '</info>');
chdir($directory);
// ensure that the env var being set does not interfere with create-project
// as it is probably not meant to be used here, so we do not use it if a composer.json can be found
// in the project
if (file_exists($directory . '/composer.json') && Platform::getEnv('COMPOSER') !== false) {
Platform::clearEnv('COMPOSER');
}
Platform::putEnv('COMPOSER_ROOT_VERSION', $package->getPrettyVersion());
// once the root project is fully initialized, we do not need to wipe everything on user abort anymore even if it happens during deps install
if (isset($signalHandler)) {
$signalHandler->unregister();
}
return $installedFromVcs;
}