@ -28,6 +28,7 @@ use Composer\Util\Loop;
use Composer\Util\Silencer;
use Composer\Plugin\PluginEvents;
use Composer\EventDispatcher\Event;
use Phar;
use Seld\JsonLint\DuplicateKeyException;
use Symfony\Component\Console\Formatter\OutputFormatter;
use Symfony\Component\Console\Formatter\OutputFormatterStyle;
@ -39,6 +40,7 @@ use Composer\Downloader\TransportException;
use Composer\Json\JsonValidationException;
use Composer\Repository\InstalledRepositoryInterface;
use Seld\JsonLint\JsonParser;
use ZipArchive;
/**
* Creates a configured instance of composer.
@ -52,9 +54,8 @@ class Factory
{
/**
* @throws \RuntimeException
* @return string
*/
protected static function getHomeDir()
protected static function getHomeDir(): string
{
$home = Platform::getEnv('COMPOSER_HOME');
if ($home) {
@ -95,11 +96,7 @@ class Factory
return $dirs[0];
}
/**
* @param string $home
* @return string
*/
protected static function getCacheDir($home)
protected static function getCacheDir(string $home): string
{
$cacheDir = Platform::getEnv('COMPOSER_CACHE_DIR');
if ($cacheDir) {
@ -144,11 +141,7 @@ class Factory
return $home . '/cache';
}
/**
* @param string $home
* @return string
*/
protected static function getDataDir($home)
protected static function getDataDir(string $home): string
{
$homeEnv = Platform::getEnv('COMPOSER_HOME');
if ($homeEnv) {
@ -169,12 +162,7 @@ class Factory
return $home;
}
/**
* @param string|null $cwd
*
* @return Config
*/
public static function createConfig(IOInterface $io = null, $cwd = null)
public static function createConfig(IOInterface $io = null, ?string $cwd = null): Config
{
$cwd = $cwd ?: (string) getcwd();
@ -243,20 +231,12 @@ class Factory
return $config;
}
/**
* @return string
*/
public static function getComposerFile()
public static function getComposerFile(): string
{
return trim((string) Platform::getEnv('COMPOSER')) ?: './composer.json';
}
/**
* @param string $composerFile
*
* @return string
*/
public static function getLockFile($composerFile)
public static function getLockFile(string $composerFile): string
{
return "json" === pathinfo($composerFile, PATHINFO_EXTENSION)
? substr($composerFile, 0, -4).'lock'
@ -266,7 +246,7 @@ class Factory
/**
* @return array{highlight: OutputFormatterStyle, warning: OutputFormatterStyle}
*/
public static function createAdditionalStyles()
public static function createAdditionalStyles(): array
{
return array(
'highlight' => new OutputFormatterStyle('red'),
@ -274,12 +254,7 @@ class Factory
);
}
/**
* Creates a ConsoleOutput instance
*
* @return ConsoleOutput
*/
public static function createOutput()
public static function createOutput(): ConsoleOutput
{
$styles = self::createAdditionalStyles();
$formatter = new OutputFormatter(false, $styles);
@ -299,9 +274,9 @@ class Factory
* @param bool $fullLoad Whether to initialize everything or only main project stuff (used when loading the global composer)
* @throws \InvalidArgumentException
* @throws \UnexpectedValueException
* @return Composer
* @return Composer|PartialComposer Composer if $fullLoad is true, otherwise PartialComposer
*/
public function createComposer(IOInterface $io, $localConfig = null, $disablePlugins = false, $cwd = null, $fullLoad = true, $disableScripts = false)
public function createComposer(IOInterface $io, $localConfig = null, bool $disablePlugins = false, ?string $cwd = null, bool $fullLoad = true, bool $disableScripts = false)
{
$cwd = $cwd ?: (string) getcwd();
@ -363,7 +338,7 @@ class Factory
$vendorDir = $config->get('vendor-dir');
// initialize composer
$composer = new Composer();
$composer = $fullLoad ? new Composer() : new Partial Composer();
$composer->setConfig($config);
if ($fullLoad) {
@ -410,7 +385,7 @@ class Factory
$im = $this->createInstallationManager($loop, $io, $dispatcher);
$composer->setInstallationManager($im);
if ($fullLoad ) {
if ($composer instanceof Composer ) {
// initialize download manager
$dm = $this->createDownloadManager($io, $config, $httpDownloader, $process, $dispatcher);
$composer->setDownloadManager($dm);
@ -427,7 +402,7 @@ class Factory
// add installers to the manager (must happen after download manager is created since they read it out of $composer)
$this->createDefaultInstallers($im, $composer, $io, $process);
if ($fullLoad ) {
if ($composer instanceof Composer ) {
$globalComposer = null;
if (realpath($config->get('home')) !== $cwd) {
$globalComposer = $this->createGlobalComposer($io, $config, $disablePlugins, $disableScripts);
@ -440,7 +415,7 @@ class Factory
}
// init locker if possible
if ($fullLoad & & isset($composerFile)) {
if ($composer instanceof Composer & & isset($composerFile)) {
$lockFile = self::getLockFile($composerFile);
$locker = new Package\Locker($io, new JsonFile($lockFile, null, $io), $im, file_get_contents($composerFile), $process);
@ -460,16 +435,17 @@ class Factory
}
/**
* @param IOInterface $io IO instance
* @param bool $disablePlugins Whether plugins should not be loaded
* @param bool $disableScripts Whether scripts should not be executed
* @return Composer|null
*/
public static function createGlobal(IOInterface $io, $disablePlugins = false, $disableScripts = false)
public static function createGlobal(IOInterface $io, bool $disablePlugins = false, bool $disableScripts = false): ?Composer
{
$factory = new static();
return $factory->createGlobalComposer($io, static::createConfig($io), $disablePlugins, $disableScripts, true);
$composer = $factory->createGlobalComposer($io, static::createConfig($io), $disablePlugins, $disableScripts, true);
assert(null === $composer || $composer instanceof Composer);
return $composer;
}
/**
@ -478,7 +454,7 @@ class Factory
*
* @return void
*/
protected function addLocalRepository(IOInterface $io, RepositoryManager $rm, $vendorDir, RootPackageInterface $rootPackage, ProcessExecutor $process = null)
protected function addLocalRepository(IOInterface $io, RepositoryManager $rm, $vendorDir, RootPackageInterface $rootPackage, ProcessExecutor $process = null): void
{
$fs = null;
if ($process) {
@ -489,13 +465,9 @@ class Factory
}
/**
* @param bool $disablePlugins
* @param bool $disableScripts
* @param bool $fullLoad
*
* @return Composer|null
* @return PartialComposer|Composer|null By default PartialComposer, but Composer if $fullLoad is set to true
*/
protected function createGlobalComposer(IOInterface $io, Config $config, $disablePlugins, $disableScripts, $fullLoad = false)
protected function createGlobalComposer(IOInterface $io, Config $config, bool $disablePlugins, bool $disableScripts, bool $fullLoad = false): ?PartialComposer
{
$composer = null;
try {
@ -513,7 +485,7 @@ class Factory
* @param EventDispatcher $eventDispatcher
* @return Downloader\DownloadManager
*/
public function createDownloadManager(IOInterface $io, Config $config, HttpDownloader $httpDownloader, ProcessExecutor $process, EventDispatcher $eventDispatcher = null)
public function createDownloadManager(IOInterface $io, Config $config, HttpDownloader $httpDownloader, ProcessExecutor $process, EventDispatcher $eventDispatcher = null): Downloader\DownloadManager
{
$cache = null;
if ($config->get('cache-files-ttl') > 0) {
@ -566,20 +538,20 @@ class Factory
public function createArchiveManager(Config $config, Downloader\DownloadManager $dm, Loop $loop)
{
$am = new Archiver\ArchiveManager($dm, $loop);
$am->addArchiver(new Archiver\ZipArchiver);
$am->addArchiver(new Archiver\PharArchiver);
if (class_exists(ZipArchive::class)) {
$am->addArchiver(new Archiver\ZipArchiver);
}
if (class_exists(Phar::class)) {
$am->addArchiver(new Archiver\PharArchiver);
}
return $am;
}
/**
* @param IOInterface $io
* @param Composer $composer
* @param Composer $globalComposer
* @param bool $disablePlugins
* @return Plugin\PluginManager
*/
protected function createPluginManager(IOInterface $io, Composer $composer, Composer $globalComposer = null, $disablePlugins = false)
protected function createPluginManager(IOInterface $io, Composer $composer, PartialComposer $globalComposer = null, bool $disablePlugins = false): Plugin\PluginManager
{
return new Plugin\PluginManager($io, $composer, $globalComposer, $disablePlugins);
}
@ -587,7 +559,7 @@ class Factory
/**
* @return Installer\InstallationManager
*/
public function createInstallationManager(Loop $loop, IOInterface $io, EventDispatcher $eventDispatcher = null)
public function createInstallationManager(Loop $loop, IOInterface $io, EventDispatcher $eventDispatcher = null): Installer\InstallationManager
{
return new Installer\InstallationManager($loop, $io, $eventDispatcher);
}
@ -595,7 +567,7 @@ class Factory
/**
* @return void
*/
protected function createDefaultInstallers(Installer\InstallationManager $im, Composer $composer, IOInterface $io, ProcessExecutor $process = null)
protected function createDefaultInstallers(Installer\InstallationManager $im, Partial Composer $composer, IOInterface $io, ProcessExecutor $process = null): void
{
$fs = new Filesystem($process);
$binaryInstaller = new Installer\BinaryInstaller($io, rtrim($composer->getConfig()->get('bin-dir'), '/'), $composer->getConfig()->get('bin-compat'), $fs, rtrim($composer->getConfig()->get('vendor-dir'), '/'));
@ -608,10 +580,8 @@ class Factory
/**
* @param InstalledRepositoryInterface $repo repository to purge packages from
* @param Installer\InstallationManager $im manager to check whether packages are still installed
*
* @return void
*/
protected function purgePackages(InstalledRepositoryInterface $repo, Installer\InstallationManager $im)
protected function purgePackages(InstalledRepositoryInterface $repo, Installer\InstallationManager $im): void
{
foreach ($repo->getPackages() as $package) {
if (!$im->isPackageInstalled($repo, $package)) {
@ -620,10 +590,7 @@ class Factory
}
}
/**
* @return Package\Loader\RootPackageLoader
*/
protected function loadRootPackage(RepositoryManager $rm, Config $config, VersionParser $parser, VersionGuesser $guesser, IOInterface $io)
protected function loadRootPackage(RepositoryManager $rm, Config $config, VersionParser $parser, VersionGuesser $guesser, IOInterface $io): Package\Loader\RootPackageLoader
{
return new Package\Loader\RootPackageLoader($rm, $config, $parser, $guesser, $io);
}
@ -636,11 +603,14 @@ class Factory
* @param bool $disableScripts Whether scripts should not be run
* @return Composer
*/
public static function create(IOInterface $io, $config = null, $disablePlugins = false, $disableScripts = false)
public static function create(IOInterface $io, $config = null, bool $disablePlugins = false, bool $disableScripts = false): Composer
{
$factory = new static();
return $factory->createComposer($io, $config, $disablePlugins, null, true, $disableScripts);
$composer = $factory->createComposer($io, $config, $disablePlugins, null, true, $disableScripts);
assert($composer instanceof Composer);
return $composer;
}
/**
@ -651,7 +621,7 @@ class Factory
* @param mixed[] $options Array of options passed directly to HttpDownloader constructor
* @return HttpDownloader
*/
public static function createHttpDownloader(IOInterface $io, Config $config, $options = array())
public static function createHttpDownloader(IOInterface $io, Config $config, $options = array()): HttpDownloader
{
static $warned = false;
$disableTls = false;
@ -693,9 +663,6 @@ class Factory
return $httpDownloader;
}
/**
* @return bool
*/
private static function useXdg(): bool
{
foreach (array_keys($_SERVER) as $key) {
@ -713,7 +680,6 @@ class Factory
/**
* @throws \RuntimeException
* @return string
*/
private static function getUserDir(): string
{