diff --git a/src/Composer/Command/InstallCommand.php b/src/Composer/Command/InstallCommand.php
index b992758bb..df1edf062 100644
--- a/src/Composer/Command/InstallCommand.php
+++ b/src/Composer/Command/InstallCommand.php
@@ -98,7 +98,7 @@ EOT
$composer = $this->requireComposer();
- if ((!$composer->getLocker() || !$composer->getLocker()->isLocked()) && !HttpDownloader::isCurlEnabled()) {
+ if (!$composer->getLocker()->isLocked() && !HttpDownloader::isCurlEnabled()) {
$io->writeError('Composer is operating significantly slower than normal because you do not have the PHP curl extension enabled.');
}
diff --git a/src/Composer/Composer.php b/src/Composer/Composer.php
index 6bdc54908..8913397b6 100644
--- a/src/Composer/Composer.php
+++ b/src/Composer/Composer.php
@@ -12,15 +12,10 @@
namespace Composer;
-use Composer\Package\RootPackageInterface;
use Composer\Package\Locker;
use Composer\Pcre\Preg;
-use Composer\Util\Loop;
-use Composer\Repository\RepositoryManager;
-use Composer\Installer\InstallationManager;
use Composer\Plugin\PluginManager;
use Composer\Downloader\DownloadManager;
-use Composer\EventDispatcher\EventDispatcher;
use Composer\Autoload\AutoloadGenerator;
use Composer\Package\Archiver\ArchiveManager;
@@ -29,7 +24,7 @@ use Composer\Package\Archiver\ArchiveManager;
* @author Konstantin Kudryashiv
* @author Nils Adermann
*/
-class Composer
+class Composer extends PartialComposer
{
/*
* Examples of the following constants in the various configurations they can be in
@@ -87,220 +82,76 @@ class Composer
}
/**
- * @var RootPackageInterface
+ * @var Locker
*/
- private $package;
+ private $locker;
/**
- * @var Locker|null
+ * @var Downloader\DownloadManager
*/
- private $locker = null;
+ private $downloadManager;
/**
- * @var Loop
+ * @var Plugin\PluginManager
*/
- private $loop;
+ private $pluginManager;
/**
- * @var Repository\RepositoryManager
+ * @var Autoload\AutoloadGenerator
*/
- private $repositoryManager;
+ private $autoloadGenerator;
/**
- * @var Downloader\DownloadManager|null
+ * @var ArchiveManager
*/
- private $downloadManager = null;
+ private $archiveManager;
- /**
- * @var Installer\InstallationManager
- */
- private $installationManager;
-
- /**
- * @var Plugin\PluginManager|null
- */
- private $pluginManager = null;
-
- /**
- * @var Config
- */
- private $config;
-
- /**
- * @var EventDispatcher
- */
- private $eventDispatcher;
-
- /**
- * @var Autoload\AutoloadGenerator|null
- */
- private $autoloadGenerator = null;
-
- /**
- * @var ArchiveManager|null
- */
- private $archiveManager = null;
-
- /**
- * @return void
- */
- public function setPackage(RootPackageInterface $package): void
- {
- $this->package = $package;
- }
-
- /**
- * @return RootPackageInterface
- */
- public function getPackage(): RootPackageInterface
- {
- return $this->package;
- }
-
- /**
- * @return void
- */
- public function setConfig(Config $config): void
- {
- $this->config = $config;
- }
-
- /**
- * @return Config
- */
- public function getConfig(): Config
- {
- return $this->config;
- }
-
- /**
- * @return void
- */
public function setLocker(Locker $locker): void
{
$this->locker = $locker;
}
- /**
- * @return ?Locker
- */
- public function getLocker(): ?Locker
+ public function getLocker(): Locker
{
return $this->locker;
}
- /**
- * @return void
- */
- public function setLoop(Loop $loop): void
- {
- $this->loop = $loop;
- }
-
- /**
- * @return Loop
- */
- public function getLoop(): Loop
- {
- return $this->loop;
- }
-
- /**
- * @return void
- */
- public function setRepositoryManager(RepositoryManager $manager): void
- {
- $this->repositoryManager = $manager;
- }
-
- /**
- * @return RepositoryManager
- */
- public function getRepositoryManager(): RepositoryManager
- {
- return $this->repositoryManager;
- }
-
- /**
- * @return void
- */
public function setDownloadManager(DownloadManager $manager): void
{
$this->downloadManager = $manager;
}
- public function getDownloadManager(): ?DownloadManager
+ public function getDownloadManager(): DownloadManager
{
return $this->downloadManager;
}
- /**
- * @return void
- */
public function setArchiveManager(ArchiveManager $manager): void
{
$this->archiveManager = $manager;
}
- public function getArchiveManager(): ?ArchiveManager
+ public function getArchiveManager(): ArchiveManager
{
return $this->archiveManager;
}
- /**
- * @return void
- */
- public function setInstallationManager(InstallationManager $manager): void
- {
- $this->installationManager = $manager;
- }
-
- /**
- * @return InstallationManager
- */
- public function getInstallationManager(): InstallationManager
- {
- return $this->installationManager;
- }
-
- /**
- * @return void
- */
public function setPluginManager(PluginManager $manager): void
{
$this->pluginManager = $manager;
}
- public function getPluginManager(): ?PluginManager
+ public function getPluginManager(): PluginManager
{
return $this->pluginManager;
}
- /**
- * @return void
- */
- public function setEventDispatcher(EventDispatcher $eventDispatcher): void
- {
- $this->eventDispatcher = $eventDispatcher;
- }
-
- /**
- * @return EventDispatcher
- */
- public function getEventDispatcher(): EventDispatcher
- {
- return $this->eventDispatcher;
- }
-
- /**
- * @return void
- */
public function setAutoloadGenerator(AutoloadGenerator $autoloadGenerator): void
{
$this->autoloadGenerator = $autoloadGenerator;
}
- public function getAutoloadGenerator(): ?AutoloadGenerator
+ public function getAutoloadGenerator(): AutoloadGenerator
{
return $this->autoloadGenerator;
}
diff --git a/src/Composer/Console/Application.php b/src/Composer/Console/Application.php
index 24811b34b..0d1b19ce1 100644
--- a/src/Composer/Console/Application.php
+++ b/src/Composer/Console/Application.php
@@ -560,7 +560,7 @@ class Application extends BaseApplication
$composer = $this->getComposer(false, false);
if (null === $composer) {
- $composer = Factory::createGlobal($this->io);
+ $composer = Factory::createGlobal($this->io, $this->disablePluginsByDefault, $this->disableScriptsByDefault);
}
if (null !== $composer) {
diff --git a/src/Composer/EventDispatcher/EventDispatcher.php b/src/Composer/EventDispatcher/EventDispatcher.php
index 704c1e403..ea6d51792 100644
--- a/src/Composer/EventDispatcher/EventDispatcher.php
+++ b/src/Composer/EventDispatcher/EventDispatcher.php
@@ -12,10 +12,12 @@
namespace Composer\EventDispatcher;
+use Composer\Autoload\AutoloadGenerator;
use Composer\DependencyResolver\Transaction;
use Composer\Installer\InstallerEvent;
use Composer\IO\IOInterface;
use Composer\Composer;
+use Composer\PartialComposer;
use Composer\Pcre\Preg;
use Composer\Util\Platform;
use Composer\DependencyResolver\Operation\OperationInterface;
@@ -44,7 +46,7 @@ use Symfony\Component\Process\ExecutableFinder;
*/
class EventDispatcher
{
- /** @var Composer */
+ /** @var PartialComposer */
protected $composer;
/** @var IOInterface */
protected $io;
@@ -62,11 +64,11 @@ class EventDispatcher
/**
* Constructor.
*
- * @param Composer $composer The composer instance
+ * @param PartialComposer $composer The composer instance
* @param IOInterface $io The IOInterface instance
* @param ProcessExecutor $process
*/
- public function __construct(Composer $composer, IOInterface $io, ProcessExecutor $process = null)
+ public function __construct(PartialComposer $composer, IOInterface $io, ProcessExecutor $process = null)
{
$this->composer = $composer;
$this->io = $io;
@@ -116,6 +118,8 @@ class EventDispatcher
*/
public function dispatchScript($eventName, $devMode = false, $additionalArgs = array(), $flags = array())
{
+ assert($this->composer instanceof Composer, new \LogicException('This should only be reached with a fully loaded Composer'));
+
return $this->doDispatch(new Script\Event($eventName, $this->composer, $this->io, $devMode, $additionalArgs, $flags));
}
@@ -133,6 +137,8 @@ class EventDispatcher
*/
public function dispatchPackageEvent($eventName, $devMode, RepositoryInterface $localRepo, array $operations, OperationInterface $operation)
{
+ assert($this->composer instanceof Composer, new \LogicException('This should only be reached with a fully loaded Composer'));
+
return $this->doDispatch(new PackageEvent($eventName, $this->composer, $this->io, $devMode, $localRepo, $operations, $operation));
}
@@ -149,6 +155,8 @@ class EventDispatcher
*/
public function dispatchInstallerEvent($eventName, $devMode, $executeOperations, Transaction $transaction)
{
+ assert($this->composer instanceof Composer, new \LogicException('This should only be reached with a fully loaded Composer'));
+
return $this->doDispatch(new InstallerEvent($eventName, $this->composer, $this->io, $devMode, $executeOperations, $transaction));
}
@@ -486,6 +494,8 @@ class EventDispatcher
return array();
}
+ assert($this->composer instanceof Composer, new \LogicException('This should only be reached with a fully loaded Composer'));
+
if ($this->loader) {
$this->loader->unregister();
}
diff --git a/src/Composer/Factory.php b/src/Composer/Factory.php
index 4f7c6fb2d..e6ef47563 100644
--- a/src/Composer/Factory.php
+++ b/src/Composer/Factory.php
@@ -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 PartialComposer();
$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, PartialComposer $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
{
diff --git a/src/Composer/Installer/LibraryInstaller.php b/src/Composer/Installer/LibraryInstaller.php
index 7490e11a5..8fff84d46 100644
--- a/src/Composer/Installer/LibraryInstaller.php
+++ b/src/Composer/Installer/LibraryInstaller.php
@@ -14,6 +14,7 @@ namespace Composer\Installer;
use Composer\Composer;
use Composer\IO\IOInterface;
+use Composer\PartialComposer;
use Composer\Pcre\Preg;
use Composer\Repository\InstalledRepositoryInterface;
use Composer\Package\PackageInterface;
@@ -31,11 +32,11 @@ use Composer\Downloader\DownloadManager;
*/
class LibraryInstaller implements InstallerInterface, BinaryPresenceInterface
{
- /** @var Composer */
+ /** @var PartialComposer */
protected $composer;
/** @var string */
protected $vendorDir;
- /** @var DownloadManager */
+ /** @var DownloadManager|null */
protected $downloadManager;
/** @var IOInterface */
protected $io;
@@ -50,15 +51,15 @@ class LibraryInstaller implements InstallerInterface, BinaryPresenceInterface
* Initializes library installer.
*
* @param IOInterface $io
- * @param Composer $composer
+ * @param PartialComposer $composer
* @param string|null $type
* @param Filesystem $filesystem
* @param BinaryInstaller $binaryInstaller
*/
- public function __construct(IOInterface $io, Composer $composer, $type = 'library', Filesystem $filesystem = null, BinaryInstaller $binaryInstaller = null)
+ public function __construct(IOInterface $io, PartialComposer $composer, $type = 'library', Filesystem $filesystem = null, BinaryInstaller $binaryInstaller = null)
{
$this->composer = $composer;
- $this->downloadManager = $composer->getDownloadManager();
+ $this->downloadManager = $composer instanceof Composer ? $composer->getDownloadManager() : null;
$this->io = $io;
$this->type = $type;
@@ -101,7 +102,7 @@ class LibraryInstaller implements InstallerInterface, BinaryPresenceInterface
$this->initializeVendorDir();
$downloadPath = $this->getInstallPath($package);
- return $this->downloadManager->download($package, $downloadPath, $prevPackage);
+ return $this->getDownloadManager()->download($package, $downloadPath, $prevPackage);
}
/**
@@ -112,7 +113,7 @@ class LibraryInstaller implements InstallerInterface, BinaryPresenceInterface
$this->initializeVendorDir();
$downloadPath = $this->getInstallPath($package);
- return $this->downloadManager->prepare($type, $package, $downloadPath, $prevPackage);
+ return $this->getDownloadManager()->prepare($type, $package, $downloadPath, $prevPackage);
}
/**
@@ -123,7 +124,7 @@ class LibraryInstaller implements InstallerInterface, BinaryPresenceInterface
$this->initializeVendorDir();
$downloadPath = $this->getInstallPath($package);
- return $this->downloadManager->cleanup($type, $package, $downloadPath, $prevPackage);
+ return $this->getDownloadManager()->cleanup($type, $package, $downloadPath, $prevPackage);
}
/**
@@ -266,7 +267,7 @@ class LibraryInstaller implements InstallerInterface, BinaryPresenceInterface
{
$downloadPath = $this->getInstallPath($package);
- return $this->downloadManager->install($package, $downloadPath);
+ return $this->getDownloadManager()->install($package, $downloadPath);
}
/**
@@ -295,7 +296,7 @@ class LibraryInstaller implements InstallerInterface, BinaryPresenceInterface
$this->filesystem->rename($initialDownloadPath, $targetDownloadPath);
}
- return $this->downloadManager->update($initial, $target, $targetDownloadPath);
+ return $this->getDownloadManager()->update($initial, $target, $targetDownloadPath);
}
/**
@@ -305,7 +306,7 @@ class LibraryInstaller implements InstallerInterface, BinaryPresenceInterface
{
$downloadPath = $this->getPackageBasePath($package);
- return $this->downloadManager->remove($package, $downloadPath);
+ return $this->getDownloadManager()->remove($package, $downloadPath);
}
/**
@@ -316,4 +317,11 @@ class LibraryInstaller implements InstallerInterface, BinaryPresenceInterface
$this->filesystem->ensureDirectoryExists($this->vendorDir);
$this->vendorDir = realpath($this->vendorDir);
}
+
+ protected function getDownloadManager(): DownloadManager
+ {
+ assert($this->downloadManager instanceof DownloadManager, new \LogicException(self::class.' should be initialized with a fully loaded Composer instance to be able to install/... packages'));
+
+ return $this->downloadManager;
+ }
}
diff --git a/src/Composer/Installer/PluginInstaller.php b/src/Composer/Installer/PluginInstaller.php
index e4d0f0404..ce4c75933 100644
--- a/src/Composer/Installer/PluginInstaller.php
+++ b/src/Composer/Installer/PluginInstaller.php
@@ -14,8 +14,10 @@ namespace Composer\Installer;
use Composer\Composer;
use Composer\IO\IOInterface;
+use Composer\PartialComposer;
use Composer\Repository\InstalledRepositoryInterface;
use Composer\Package\PackageInterface;
+use Composer\Plugin\PluginManager;
use Composer\Util\Filesystem;
use Composer\Util\Platform;
use React\Promise\PromiseInterface;
@@ -28,13 +30,7 @@ use React\Promise\PromiseInterface;
*/
class PluginInstaller extends LibraryInstaller
{
- /**
- * Initializes Plugin installer.
- *
- * @param IOInterface $io
- * @param Composer $composer
- */
- public function __construct(IOInterface $io, Composer $composer, Filesystem $fs = null, BinaryInstaller $binaryInstaller = null)
+ public function __construct(IOInterface $io, PartialComposer $composer, Filesystem $fs = null, BinaryInstaller $binaryInstaller = null)
{
parent::__construct($io, $composer, 'composer-plugin', $fs, $binaryInstaller);
}
@@ -73,7 +69,7 @@ class PluginInstaller extends LibraryInstaller
return $promise->then(function () use ($package, $repo) {
try {
Platform::workaroundFilesystemIssues();
- $this->composer->getPluginManager()->registerPackage($package, true);
+ $this->getPluginManager()->registerPackage($package, true);
} catch (\Exception $e) {
$this->rollbackInstall($e, $repo, $package);
}
@@ -93,8 +89,8 @@ class PluginInstaller extends LibraryInstaller
return $promise->then(function () use ($initial, $target, $repo) {
try {
Platform::workaroundFilesystemIssues();
- $this->composer->getPluginManager()->deactivatePackage($initial);
- $this->composer->getPluginManager()->registerPackage($target, true);
+ $this->getPluginManager()->deactivatePackage($initial);
+ $this->getPluginManager()->registerPackage($target, true);
} catch (\Exception $e) {
$this->rollbackInstall($e, $repo, $target);
}
@@ -103,7 +99,7 @@ class PluginInstaller extends LibraryInstaller
public function uninstall(InstalledRepositoryInterface $repo, PackageInterface $package)
{
- $this->composer->getPluginManager()->uninstallPackage($package);
+ $this->getPluginManager()->uninstallPackage($package);
return parent::uninstall($repo, $package);
}
@@ -114,4 +110,12 @@ class PluginInstaller extends LibraryInstaller
parent::uninstall($repo, $package);
throw $e;
}
+
+ protected function getPluginManager(): PluginManager
+ {
+ assert($this->composer instanceof Composer, new \LogicException(self::class.' should be initialized with a fully loaded Composer instance.'));
+ $pluginManager = $this->composer->getPluginManager();
+
+ return $pluginManager;
+ }
}
diff --git a/src/Composer/PartialComposer.php b/src/Composer/PartialComposer.php
index fead62258..891175066 100644
--- a/src/Composer/PartialComposer.php
+++ b/src/Composer/PartialComposer.php
@@ -1,8 +1,151 @@
+ * Jordi Boggiano
+ *
+ * For the full copyright and license information, please view the LICENSE
+ * file that was distributed with this source code.
+ */
+
namespace Composer;
+use Composer\Package\RootPackageInterface;
+use Composer\Util\Loop;
+use Composer\Repository\RepositoryManager;
+use Composer\Installer\InstallationManager;
+use Composer\EventDispatcher\EventDispatcher;
+
+/**
+ * @author Jordi Boggiano
+ */
class PartialComposer
{
+ /**
+ * @var RootPackageInterface
+ */
+ private $package;
+ /**
+ * @var Loop
+ */
+ private $loop;
+
+ /**
+ * @var Repository\RepositoryManager
+ */
+ private $repositoryManager;
+
+ /**
+ * @var Installer\InstallationManager
+ */
+ private $installationManager;
+
+ /**
+ * @var Config
+ */
+ private $config;
+
+ /**
+ * @var EventDispatcher
+ */
+ private $eventDispatcher;
+
+ /**
+ * @return void
+ */
+ public function setPackage(RootPackageInterface $package): void
+ {
+ $this->package = $package;
+ }
+
+ /**
+ * @return RootPackageInterface
+ */
+ public function getPackage(): RootPackageInterface
+ {
+ return $this->package;
+ }
+
+ /**
+ * @return void
+ */
+ public function setConfig(Config $config): void
+ {
+ $this->config = $config;
+ }
+
+ /**
+ * @return Config
+ */
+ public function getConfig(): Config
+ {
+ return $this->config;
+ }
+
+ /**
+ * @return void
+ */
+ public function setLoop(Loop $loop): void
+ {
+ $this->loop = $loop;
+ }
+
+ /**
+ * @return Loop
+ */
+ public function getLoop(): Loop
+ {
+ return $this->loop;
+ }
+
+ /**
+ * @return void
+ */
+ public function setRepositoryManager(RepositoryManager $manager): void
+ {
+ $this->repositoryManager = $manager;
+ }
+
+ /**
+ * @return RepositoryManager
+ */
+ public function getRepositoryManager(): RepositoryManager
+ {
+ return $this->repositoryManager;
+ }
+
+ /**
+ * @return void
+ */
+ public function setInstallationManager(InstallationManager $manager): void
+ {
+ $this->installationManager = $manager;
+ }
+
+ /**
+ * @return InstallationManager
+ */
+ public function getInstallationManager(): InstallationManager
+ {
+ return $this->installationManager;
+ }
+
+ /**
+ * @return void
+ */
+ public function setEventDispatcher(EventDispatcher $eventDispatcher): void
+ {
+ $this->eventDispatcher = $eventDispatcher;
+ }
+
+ /**
+ * @return EventDispatcher
+ */
+ public function getEventDispatcher(): EventDispatcher
+ {
+ return $this->eventDispatcher;
+ }
}
diff --git a/src/Composer/Plugin/PluginManager.php b/src/Composer/Plugin/PluginManager.php
index 296fb06f4..b849de107 100644
--- a/src/Composer/Plugin/PluginManager.php
+++ b/src/Composer/Plugin/PluginManager.php
@@ -13,6 +13,7 @@
namespace Composer\Plugin;
use Composer\Composer;
+use Composer\Autoload\AutoloadGenerator;
use Composer\EventDispatcher\EventSubscriberInterface;
use Composer\Installer\InstallerInterface;
use Composer\IO\IOInterface;
@@ -20,6 +21,7 @@ use Composer\Package\BasePackage;
use Composer\Package\CompletePackage;
use Composer\Package\Package;
use Composer\Package\Version\VersionParser;
+use Composer\PartialComposer;
use Composer\Pcre\Preg;
use Composer\Repository\RepositoryInterface;
use Composer\Repository\InstalledRepository;
@@ -42,7 +44,7 @@ class PluginManager
protected $composer;
/** @var IOInterface */
protected $io;
- /** @var ?Composer */
+ /** @var PartialComposer|null */
protected $globalComposer;
/** @var VersionParser */
protected $versionParser;
@@ -67,15 +69,7 @@ class PluginManager
/** @var int */
private static $classCounter = 0;
- /**
- * Initializes plugin manager
- *
- * @param IOInterface $io
- * @param Composer $composer
- * @param Composer $globalComposer
- * @param bool $disablePlugins
- */
- public function __construct(IOInterface $io, Composer $composer, Composer $globalComposer = null, $disablePlugins = false)
+ public function __construct(IOInterface $io, Composer $composer, PartialComposer $globalComposer = null, bool $disablePlugins = false)
{
$this->io = $io;
$this->composer = $composer;
@@ -118,10 +112,9 @@ class PluginManager
}
$repo = $this->composer->getRepositoryManager()->getLocalRepository();
- $globalRepo = $this->globalComposer ? $this->globalComposer->getRepositoryManager()->getLocalRepository() : null;
$this->deactivateRepository($repo, false);
- if ($globalRepo) {
- $this->deactivateRepository($globalRepo, true);
+ if ($this->globalComposer !== null) {
+ $this->deactivateRepository($this->globalComposer->getRepositoryManager()->getLocalRepository(), true);
}
}
@@ -137,10 +130,8 @@ class PluginManager
/**
* Gets global composer or null when main composer is not fully loaded
- *
- * @return Composer|null
*/
- public function getGlobalComposer(): ?Composer
+ public function getGlobalComposer(): ?PartialComposer
{
return $this->globalComposer;
}
@@ -558,6 +549,7 @@ class PluginManager
return $this->composer->getInstallationManager()->getInstallPath($package);
}
+ assert(null !== $this->globalComposer);
return $this->globalComposer->getInstallationManager()->getInstallPath($package);
}
diff --git a/tests/Composer/Test/Json/JsonValidationExceptionTest.php b/tests/Composer/Test/Json/JsonValidationExceptionTest.php
index 0d6feb050..7f959ae93 100644
--- a/tests/Composer/Test/Json/JsonValidationExceptionTest.php
+++ b/tests/Composer/Test/Json/JsonValidationExceptionTest.php
@@ -19,10 +19,10 @@ class JsonValidationExceptionTest extends TestCase
{
/**
* @dataProvider errorProvider
- * @param string|null $message
- * @param string[]|null $errors
+ * @param string[] $errors
+ * @param string[] $expectedErrors
*/
- public function testGetErrors($message, $errors, $expectedMessage, $expectedErrors): void
+ public function testGetErrors(?string $message, array $errors, string $expectedMessage, array $expectedErrors): void
{
$object = new JsonValidationException($message, $errors);
$this->assertSame($expectedMessage, $object->getMessage());
diff --git a/tests/Composer/Test/Mock/FactoryMock.php b/tests/Composer/Test/Mock/FactoryMock.php
index 127720666..8db24fe11 100644
--- a/tests/Composer/Test/Mock/FactoryMock.php
+++ b/tests/Composer/Test/Mock/FactoryMock.php
@@ -17,6 +17,7 @@ use Composer\Package\Loader\RootPackageLoader;
use Composer\Composer;
use Composer\Config;
use Composer\Factory;
+use Composer\PartialComposer;
use Composer\Repository\RepositoryManager;
use Composer\Package\Version\VersionGuesser;
use Composer\Package\Version\VersionParser;
@@ -32,7 +33,7 @@ use Composer\Util\ProcessExecutor;
class FactoryMock extends Factory
{
- public static function createConfig(IOInterface $io = null, $cwd = null): Config
+ public static function createConfig(IOInterface $io = null, ?string $cwd = null): Config
{
$config = new Config(true, $cwd);
@@ -59,7 +60,7 @@ class FactoryMock extends Factory
return new InstallationManagerMock();
}
- protected function createDefaultInstallers(InstallationManager $im, Composer $composer, IOInterface $io, ProcessExecutor $process = null): void
+ protected function createDefaultInstallers(InstallationManager $im, PartialComposer $composer, IOInterface $io, ProcessExecutor $process = null): void
{
}