From d3c176ec696c2aaf98e482fed44edf92e8975c34 Mon Sep 17 00:00:00 2001 From: Jordi Boggiano Date: Sat, 21 Aug 2021 17:41:52 +0200 Subject: [PATCH] PHPStan Level 5 (#10070) * Bump PHPStan to level 5 * Update seld/phar-utils to latest * Add phpstan-setup / phpstan scripts --- composer.json | 13 +- composer.lock | 12 +- phpstan/baseline.neon | 284 +----------------- phpstan/config.neon | 8 +- src/Composer/Autoload/AutoloadGenerator.php | 4 +- src/Composer/Autoload/ClassMapGenerator.php | 28 +- src/Composer/Command/ArchiveCommand.php | 2 +- src/Composer/Command/BaseCommand.php | 3 +- src/Composer/Command/DiagnoseCommand.php | 6 +- src/Composer/Command/InitCommand.php | 5 +- src/Composer/Command/RequireCommand.php | 2 +- src/Composer/Command/ShowCommand.php | 13 +- src/Composer/Command/UpdateCommand.php | 1 + src/Composer/Compiler.php | 24 +- src/Composer/Composer.php | 6 +- src/Composer/Console/Application.php | 9 +- .../DependencyResolver/GenericRule.php | 9 +- .../DependencyResolver/LockTransaction.php | 25 +- src/Composer/DependencyResolver/Pool.php | 2 +- .../DependencyResolver/PoolBuilder.php | 9 +- src/Composer/DependencyResolver/Problem.php | 3 +- src/Composer/Downloader/DownloadManager.php | 2 +- src/Composer/Downloader/FileDownloader.php | 4 +- src/Composer/Factory.php | 15 +- src/Composer/IO/ConsoleIO.php | 7 - src/Composer/InstalledVersions.php | 10 +- src/Composer/Installer.php | 7 +- .../Installer/InstallationManager.php | 3 +- src/Composer/Json/JsonFile.php | 4 +- src/Composer/Package/AliasPackage.php | 7 +- src/Composer/Package/BasePackage.php | 1 + src/Composer/Package/Link.php | 15 +- src/Composer/Package/Loader/ArrayLoader.php | 40 +-- src/Composer/Package/Locker.php | 6 +- src/Composer/Package/Package.php | 49 ++- src/Composer/Package/PackageInterface.php | 40 +-- src/Composer/Package/RootAliasPackage.php | 12 +- src/Composer/Plugin/PluginManager.php | 9 +- src/Composer/Plugin/PostFileDownloadEvent.php | 1 + src/Composer/Repository/ArrayRepository.php | 16 +- .../Repository/ComposerRepository.php | 1 + .../Repository/InstalledRepository.php | 4 +- .../Repository/PlatformRepository.php | 2 +- .../Repository/RepositoryInterface.php | 8 +- src/Composer/Repository/RepositorySet.php | 9 +- .../Repository/Vcs/BitbucketDriver.php | 6 + .../Repository/Vcs/HgBitbucketDriver.php | 2 - src/Composer/Repository/Vcs/VcsDriver.php | 1 + src/Composer/Util/Http/CurlDownloader.php | 1 + src/Composer/Util/HttpDownloader.php | 1 + src/Composer/Util/NoProxyPattern.php | 8 +- src/Composer/Util/StreamContextFactory.php | 2 +- src/Composer/Util/SyncHelper.php | 2 +- tests/Composer/Test/AllFunctionalTest.php | 19 +- .../Test/Autoload/AutoloadGeneratorTest.php | 94 +++--- .../Composer/Test/Command/InitCommandTest.php | 2 +- .../Test/DependencyResolver/RuleSetTest.php | 3 +- tests/Composer/Test/IO/BufferIOTest.php | 4 +- tests/Composer/Test/IO/ConsoleIOTest.php | 4 +- tests/Composer/Test/IO/NullIOTest.php | 4 +- .../Test/Installer/LibraryInstallerTest.php | 2 +- .../Installer/MetapackageInstallerTest.php | 2 +- .../SuggestedPackagesReporterTest.php | 2 +- tests/Composer/Test/Mock/FactoryMock.php | 6 +- .../Test/Mock/ProcessExecutorMock.php | 2 +- .../Package/Archiver/ArchiveManagerTest.php | 3 +- .../Test/Package/Dumper/ArrayDumperTest.php | 2 +- .../Test/Package/Loader/ArrayLoaderTest.php | 5 +- .../Test/Package/RootAliasPackageTest.php | 10 +- .../Test/Plugin/PluginInstallerTest.php | 4 +- .../Repository/PlatformRepositoryTest.php | 3 +- tests/Composer/Test/TestCase.php | 2 +- .../Test/Util/MetadataMinifierTest.php | 4 +- .../Composer/Test/Util/PackageSorterTest.php | 2 +- 74 files changed, 395 insertions(+), 547 deletions(-) diff --git a/composer.json b/composer.json index 20704951c..9225f2e5f 100644 --- a/composer.json +++ b/composer.json @@ -78,11 +78,20 @@ ], "scripts": { "compile": "@php -dphar.readonly=0 bin/compile", - "test": "simple-phpunit" + "test": "simple-phpunit", + "phpstan-setup": [ + "@composer config platform --unset", + "@php composer.phar update", + "@composer require --dev phpstan/phpstan:^0.12.93 phpstan/phpstan-phpunit:^0.12.17 phpunit/phpunit:^7.5.20 --with-all-dependencies", + "git checkout composer.json composer.lock" + ], + "phpstan": "@php vendor/bin/phpstan analyse --configuration=phpstan/config.neon" }, "scripts-descriptions": { "compile": "Compile composer.phar", - "test": "Run all tests" + "test": "Run all tests", + "phpstan-setup": "Prepare environment to run PHPStan locally (must be run with PHP7.4)", + "phpstan": "Runs PHPStan (after phpstan-setup was executed, must be run with PHP7.4)" }, "support": { "issues": "https://github.com/composer/composer/issues", diff --git a/composer.lock b/composer.lock index 4a9a22073..b953e70c9 100644 --- a/composer.lock +++ b/composer.lock @@ -608,16 +608,16 @@ }, { "name": "seld/phar-utils", - "version": "1.1.1", + "version": "1.1.2", "source": { "type": "git", "url": "https://github.com/Seldaek/phar-utils.git", - "reference": "8674b1d84ffb47cc59a101f5d5a3b61e87d23796" + "reference": "749042a2315705d2dfbbc59234dd9ceb22bf3ff0" }, "dist": { "type": "zip", - "url": "https://api.github.com/repos/Seldaek/phar-utils/zipball/8674b1d84ffb47cc59a101f5d5a3b61e87d23796", - "reference": "8674b1d84ffb47cc59a101f5d5a3b61e87d23796", + "url": "https://api.github.com/repos/Seldaek/phar-utils/zipball/749042a2315705d2dfbbc59234dd9ceb22bf3ff0", + "reference": "749042a2315705d2dfbbc59234dd9ceb22bf3ff0", "shasum": "" }, "require": { @@ -650,9 +650,9 @@ ], "support": { "issues": "https://github.com/Seldaek/phar-utils/issues", - "source": "https://github.com/Seldaek/phar-utils/tree/master" + "source": "https://github.com/Seldaek/phar-utils/tree/1.1.2" }, - "time": "2020-07-07T18:42:57+00:00" + "time": "2021-08-19T21:01:38+00:00" }, { "name": "symfony/console", diff --git a/phpstan/baseline.neon b/phpstan/baseline.neon index e747a8e40..9d3580e48 100644 --- a/phpstan/baseline.neon +++ b/phpstan/baseline.neon @@ -1,277 +1,11 @@ parameters: - ignoreErrors: - - - message: "#^Else branch is unreachable because ternary operator condition is always true\\.$#" - count: 1 - path: ../src/Composer/Autoload/AutoloadGenerator.php - - - - message: "#^Left side of && is always true\\.$#" - count: 1 - path: ../src/Composer/Autoload/AutoloadGenerator.php - - - - message: "#^If condition is always true\\.$#" - count: 1 - path: ../src/Composer/Autoload/ClassMapGenerator.php - - - - message: "#^Else branch is unreachable because previous condition is always true\\.$#" - count: 1 - path: ../src/Composer/Command/BaseCommand.php - - - - message: "#^Elseif branch is unreachable because previous condition is always true\\.$#" - count: 1 - path: ../src/Composer/Command/BaseCommand.php - - - - message: "#^Result of && is always false\\.$#" - count: 1 - path: ../src/Composer/Command/DiagnoseCommand.php - - - - message: "#^Strict comparison using \\!\\=\\= between '@package_version@' and '@package_version@' will always evaluate to false\\.$#" - count: 1 - path: ../src/Composer/Command/DiagnoseCommand.php - - - - message: "#^Ternary operator condition is always true\\.$#" - count: 1 - path: ../src/Composer/Command/DiagnoseCommand.php - - - - message: "#^Negated boolean expression is always false\\.$#" - count: 1 - path: ../src/Composer/Command/InitCommand.php - - - - message: "#^Negated boolean expression is always false\\.$#" - count: 1 - path: ../src/Composer/Command/InstallCommand.php - - - - message: "#^Call to function is_array\\(\\) with string will always evaluate to false\\.$#" - count: 1 - path: ../src/Composer/Command/ShowCommand.php - - - - message: "#^Elseif branch is unreachable because previous condition is always true\\.$#" - count: 1 - path: ../src/Composer/Command/ShowCommand.php - - - - message: "#^Negated boolean expression is always false\\.$#" - count: 1 - path: ../src/Composer/Command/ShowCommand.php - - - - message: "#^Unreachable statement \\- code above always terminates\\.$#" - count: 1 - path: ../src/Composer/Composer.php - - - - message: "#^If condition is always true\\.$#" - count: 1 - path: ../src/Composer/Console/Application.php - - - - message: "#^Left side of && is always true\\.$#" - count: 2 - path: ../src/Composer/Console/Application.php - - - - message: "#^Strict comparison using \\!\\=\\= between '@package_branch…' and '@package_branch…' will always evaluate to false\\.$#" - count: 1 - path: ../src/Composer/Console/Application.php - - - - message: "#^Strict comparison using \\=\\=\\= between null and Composer\\\\Composer will always evaluate to false\\.$#" - count: 1 - path: ../src/Composer/Console/Application.php - - - - message: "#^Instanceof between mixed and Composer\\\\Package\\\\RootAliasPackage will always evaluate to false\\.$#" - count: 1 - path: ../src/Composer/DependencyResolver/LockTransaction.php - - - - message: "#^If condition is always true\\.$#" - count: 1 - path: ../src/Composer/DependencyResolver/PoolBuilder.php - - - - message: "#^Ternary operator condition is always true\\.$#" - count: 1 - path: ../src/Composer/DependencyResolver/Problem.php - - - - message: "#^If condition is always true\\.$#" - count: 2 - path: ../src/Composer/Downloader/FileDownloader.php - - - - message: "#^Left side of && is always true\\.$#" - count: 3 - path: ../src/Composer/Downloader/FileDownloader.php - - - - message: "#^Comparison operation \"\\>\" between 0 and 6 is always false\\.$#" - count: 1 - path: ../src/Composer/Downloader/PathDownloader.php - - - - message: "#^Comparison operation \"\\>\\=\" between 0 and 1 is always false\\.$#" - count: 1 - path: ../src/Composer/Downloader/PathDownloader.php - - - - message: "#^Result of && is always false\\.$#" - count: 2 - path: ../src/Composer/Downloader/PathDownloader.php - - - - message: "#^Result of \\|\\| is always false\\.$#" - count: 1 - path: ../src/Composer/Downloader/PathDownloader.php - - - - message: "#^Strict comparison using \\=\\=\\= between 0 and 6 will always evaluate to false\\.$#" - count: 1 - path: ../src/Composer/Downloader/PathDownloader.php - - - - message: "#^If condition is always true\\.$#" - count: 1 - path: ../src/Composer/Factory.php - - - - message: "#^Left side of && is always true\\.$#" - count: 3 - path: ../src/Composer/Factory.php - - - - message: "#^Strict comparison using \\=\\=\\= between 16 and 0 will always evaluate to false\\.$#" - count: 1 - path: ../src/Composer/IO/ConsoleIO.php - - - - message: "#^Result of && is always false\\.$#" - count: 1 - path: ../src/Composer/InstalledVersions.php - - - - message: "#^If condition is always true\\.$#" - count: 2 - path: ../src/Composer/Installer.php - - - - message: "#^Negated boolean expression is always false\\.$#" - count: 1 - path: ../src/Composer/Installer.php - - - - message: "#^Empty array passed to foreach\\.$#" - count: 1 - path: ../src/Composer/Installer/InstallationManager.php - - - - message: "#^Right side of && is always true\\.$#" - count: 2 - path: ../src/Composer/Installer/InstallationManager.php - - - - message: "#^Strict comparison using \\=\\=\\= between null and string will always evaluate to false\\.$#" - count: 1 - path: ../src/Composer/Json/JsonFile.php - - - - message: "#^If condition is always true\\.$#" - count: 1 - path: ../src/Composer/Package/Dumper/ArrayDumper.php - - - - message: "#^Ternary operator condition is always true\\.$#" - count: 1 - path: ../src/Composer/Package/Link.php - - - - message: "#^Unreachable statement \\- code above always terminates\\.$#" - count: 1 - path: ../src/Composer/Package/Loader/ArrayLoader.php - - - - message: "#^Else branch is unreachable because previous condition is always true\\.$#" - count: 1 - path: ../src/Composer/Package/Locker.php - - - - message: "#^If condition is always true\\.$#" - count: 3 - path: ../src/Composer/Plugin/PluginManager.php - - - - message: "#^Left side of && is always true\\.$#" - count: 1 - path: ../src/Composer/Plugin/PluginManager.php - - - - message: "#^Ternary operator condition is always true\\.$#" - count: 2 - path: ../src/Composer/Plugin/PluginManager.php - - - - message: "#^Instanceof between string and Composer\\\\Package\\\\PackageInterface will always evaluate to false\\.$#" - count: 1 - path: ../src/Composer/Plugin/PostFileDownloadEvent.php - - - - message: "#^Result of && is always false\\.$#" - count: 1 - path: ../src/Composer/Plugin/PostFileDownloadEvent.php - - - - message: "#^Negated boolean expression is always false\\.$#" - count: 1 - path: ../src/Composer/Repository/ArrayRepository.php - - - - message: "#^Strict comparison using \\=\\=\\= between null and Composer\\\\Repository\\\\RepositoryInterface will always evaluate to false\\.$#" - count: 1 - path: ../src/Composer/Repository/ArrayRepository.php - - - - message: "#^If condition is always false\\.$#" - count: 1 - path: ../src/Composer/Repository/ComposerRepository.php - - - - message: "#^Negated boolean expression is always false\\.$#" - count: 1 - path: ../src/Composer/Repository/ComposerRepository.php - - - - message: "#^Negated boolean expression is always true\\.$#" - count: 1 - path: ../src/Composer/Repository/InstalledRepository.php - - - - message: "#^Negated boolean expression is always true\\.$#" - count: 1 - path: ../src/Composer/Repository/Vcs/GitBitbucketDriver.php - - - - message: "#^Unreachable statement \\- code above always terminates\\.$#" - count: 1 - path: ../src/Composer/Repository/Vcs/GitBitbucketDriver.php - - - - message: "#^Negated boolean expression is always false\\.$#" - count: 1 - path: ../src/Composer/Repository/Vcs/GitLabDriver.php - - - - message: "#^Right side of && is always true\\.$#" - count: 1 - path: ../src/Composer/Repository/Vcs/GitLabDriver.php + ignoreErrors: + - + message: "#^Parameter \\#1 \\$autoload_function of function spl_autoload_register expects callable\\(string\\)\\: void, array\\(\\$this\\(Composer\\\\Autoload\\\\ClassLoader\\), 'loadClass'\\) given\\.$#" + count: 1 + path: ../src/Composer/Autoload/ClassLoader.php + - + message: "#^Parameter \\#2 \\$capabilityClassName of method Composer\\\\Plugin\\\\PluginManager\\:\\:getPluginCapability\\(\\) expects class\\-string\\, string given\\.$#" + count: 2 + path: ../tests/Composer/Test/Plugin/PluginInstallerTest.php diff --git a/phpstan/config.neon b/phpstan/config.neon index 9f934ddea..6458aac46 100644 --- a/phpstan/config.neon +++ b/phpstan/config.neon @@ -3,7 +3,7 @@ includes: - ./baseline.neon parameters: - level: 4 + level: 5 excludes_analyse: - '../tests/Composer/Test/Fixtures/*' - '../tests/Composer/Test/Autoload/Fixtures/*' @@ -42,5 +42,11 @@ parameters: - ../src - ../tests + dynamicConstantNames: + - Composer\Composer::BRANCH_ALIAS_VERSION + - Composer\Composer::VERSION + - Composer\Composer::RELEASE_DATE + - Composer\Composer::SOURCE_VERSION + rules: - Composer\PHPStanRules\AnonymousFunctionWithThisRule diff --git a/src/Composer/Autoload/AutoloadGenerator.php b/src/Composer/Autoload/AutoloadGenerator.php index 6a8848976..47c888ab7 100644 --- a/src/Composer/Autoload/AutoloadGenerator.php +++ b/src/Composer/Autoload/AutoloadGenerator.php @@ -41,7 +41,7 @@ class AutoloadGenerator private $eventDispatcher; /** - * @var IOInterface + * @var ?IOInterface */ private $io; @@ -667,7 +667,7 @@ EOF; $baseDir = "'phar://' . " . $baseDir; } - return $baseDir . (($path !== false) ? var_export($path, true) : ""); + return $baseDir . var_export($path, true); } protected function getPlatformCheck(array $packageMap, array $ignorePlatformReqs, $checkPlatform, array $devPackageNames) diff --git a/src/Composer/Autoload/ClassMapGenerator.php b/src/Composer/Autoload/ClassMapGenerator.php index 33c2d48c8..085136f0e 100644 --- a/src/Composer/Autoload/ClassMapGenerator.php +++ b/src/Composer/Autoload/ClassMapGenerator.php @@ -33,8 +33,8 @@ class ClassMapGenerator /** * Generate a class map file * - * @param \Traversable $dirs Directories or a single path to search in - * @param string $file The name of the class map file + * @param \Traversable|array $dirs Directories or a single path to search in + * @param string $file The name of the class map file */ public static function dump($dirs, $file) { @@ -50,11 +50,11 @@ class ClassMapGenerator /** * Iterate over all files in the given directory searching for classes * - * @param \Iterator|string $path The path to search in or an iterator - * @param string $excluded Regex that matches file paths to be excluded from the classmap - * @param IOInterface $io IO object - * @param string $namespace Optional namespace prefix to filter by - * @param string $autoloadType psr-0|psr-4 Optional autoload standard to use mapping rules + * @param \Traversable|string $path The path to search in or an iterator + * @param string $excluded Regex that matches file paths to be excluded from the classmap + * @param ?IOInterface $io IO object + * @param ?string $namespace Optional namespace prefix to filter by + * @param ?string $autoloadType psr-0|psr-4 Optional autoload standard to use mapping rules * * @throws \RuntimeException When the path is neither an existing file nor directory * @return array A class map array @@ -147,13 +147,13 @@ class ClassMapGenerator /** * Remove classes which could not have been loaded by namespace autoloaders * - * @param array $classes found classes in given file - * @param string $filePath current file - * @param string $baseNamespace prefix of given autoload mapping - * @param string $namespaceType psr-0|psr-4 - * @param string $basePath root directory of given autoload mapping - * @param IOInterface $io IO object - * @return array valid classes + * @param array $classes found classes in given file + * @param string $filePath current file + * @param string $baseNamespace prefix of given autoload mapping + * @param string $namespaceType psr-0|psr-4 + * @param string $basePath root directory of given autoload mapping + * @param ?IOInterface $io IO object + * @return array valid classes */ private static function filterByNamespace($classes, $filePath, $baseNamespace, $namespaceType, $basePath, $io) { diff --git a/src/Composer/Command/ArchiveCommand.php b/src/Composer/Command/ArchiveCommand.php index 6f30d5f24..3acf4fd04 100644 --- a/src/Composer/Command/ArchiveCommand.php +++ b/src/Composer/Command/ArchiveCommand.php @@ -49,7 +49,7 @@ class ArchiveCommand extends BaseCommand new InputOption('dir', null, InputOption::VALUE_REQUIRED, 'Write the archive to this directory'), new InputOption('file', null, InputOption::VALUE_REQUIRED, 'Write the archive with the given file name.' .' Note that the format will be appended.'), - new InputOption('ignore-filters', false, InputOption::VALUE_NONE, 'Ignore filters when saving package'), + new InputOption('ignore-filters', null, InputOption::VALUE_NONE, 'Ignore filters when saving package'), )) ->setHelp( <<composer = $application->getComposer($required, $disablePlugins); + /** @phpstan-ignore-next-line */ } elseif ($required) { throw new \RuntimeException( 'Could not create a Composer\Composer instance, you must inject '. @@ -109,8 +110,8 @@ abstract class BaseCommand extends Command if (null === $this->io) { $application = $this->getApplication(); if ($application instanceof Application) { - /* @var $application Application */ $this->io = $application->getIO(); + /** @phpstan-ignore-next-line */ } else { $this->io = new NullIO(); } diff --git a/src/Composer/Command/DiagnoseCommand.php b/src/Composer/Command/DiagnoseCommand.php index e70815fc6..2fdd99bf2 100644 --- a/src/Composer/Command/DiagnoseCommand.php +++ b/src/Composer/Command/DiagnoseCommand.php @@ -304,9 +304,11 @@ EOT try { $url = $domain === 'github.com' ? 'https://api.'.$domain.'/' : 'https://'.$domain.'/api/v3/'; - return $this->httpDownloader->get($url, array( + $this->httpDownloader->get($url, array( 'retry-auth-failure' => false, - )) ? true : 'Unexpected error'; + )); + + return true; } catch (\Exception $e) { if ($e instanceof TransportException && $e->getCode() === 401) { return 'The oauth token for '.$domain.' seems invalid, run "composer config --global --unset github-oauth.'.$domain.'" to remove it'; diff --git a/src/Composer/Command/InitCommand.php b/src/Composer/Command/InitCommand.php index c710c4e63..e6ebadd25 100644 --- a/src/Composer/Command/InitCommand.php +++ b/src/Composer/Command/InitCommand.php @@ -43,7 +43,7 @@ use Symfony\Component\Console\Helper\FormatterHelper; */ class InitCommand extends BaseCommand { - /** @var CompositeRepository */ + /** @var ?CompositeRepository */ protected $repos; /** @var array */ @@ -705,10 +705,11 @@ EOT $finder = new ExecutableFinder(); $gitBin = $finder->find('git'); - // TODO in v3 always call with an array + // TODO in v2.3 always call with an array if (method_exists('Symfony\Component\Process\Process', 'fromShellCommandline')) { $cmd = new Process(array($gitBin, 'config', '-l')); } else { + // @phpstan-ignore-next-line $cmd = new Process(sprintf('%s config -l', ProcessExecutor::escape($gitBin))); } $cmd->run(); diff --git a/src/Composer/Command/RequireCommand.php b/src/Composer/Command/RequireCommand.php index c502cabf2..094b5df55 100644 --- a/src/Composer/Command/RequireCommand.php +++ b/src/Composer/Command/RequireCommand.php @@ -320,7 +320,7 @@ EOT 'require-dev' => $rootPackage->getDevRequires(), ); $loader = new ArrayLoader(); - $newLinks = $loader->parseLinks($rootPackage->getName(), $rootPackage->getPrettyVersion(), BasePackage::$supportedLinkTypes[$requireKey]['description'], $requirements); + $newLinks = $loader->parseLinks($rootPackage->getName(), $rootPackage->getPrettyVersion(), BasePackage::$supportedLinkTypes[$requireKey]['method'], $requirements); $links[$requireKey] = array_merge($links[$requireKey], $newLinks); foreach ($requirements as $package => $constraint) { unset($links[$removeKey][$package]); diff --git a/src/Composer/Command/ShowCommand.php b/src/Composer/Command/ShowCommand.php index 765788772..dd26bbe7c 100644 --- a/src/Composer/Command/ShowCommand.php +++ b/src/Composer/Command/ShowCommand.php @@ -54,7 +54,7 @@ class ShowCommand extends BaseCommand protected $versionParser; protected $colors; - /** @var RepositorySet */ + /** @var ?RepositorySet */ private $repositorySet; protected function configure() @@ -311,12 +311,6 @@ EOT return 0; } - if ($repos instanceof CompositeRepository) { - $repos = $repos->getRepositories(); - } elseif (!is_array($repos)) { - $repos = array($repos); - } - // list packages $packages = array(); $packageFilterRegex = null; @@ -334,7 +328,7 @@ EOT $input->setOption('path', false); } - foreach ($repos as $repo) { + foreach ($repos->getRepositories() as $repo) { if ($repo === $platformRepo) { $type = 'platform'; } elseif ($lockedRepo !== null && $repo === $lockedRepo) { @@ -1245,6 +1239,9 @@ EOT return $candidate; } + /** + * @return RepositorySet + */ private function getRepositorySet(Composer $composer) { if (!$this->repositorySet) { diff --git a/src/Composer/Command/UpdateCommand.php b/src/Composer/Command/UpdateCommand.php index 86167c1b3..0fe582299 100644 --- a/src/Composer/Command/UpdateCommand.php +++ b/src/Composer/Command/UpdateCommand.php @@ -315,6 +315,7 @@ EOT $link->getSource(), $link->getTarget(), $newConstraint, + /** @phpstan-ignore-next-line */ $link->getDescription(), $link->getPrettyConstraint() . ', ' . $constraint ); diff --git a/src/Composer/Compiler.php b/src/Composer/Compiler.php index 1bec4a513..a0f303f9f 100644 --- a/src/Composer/Compiler.php +++ b/src/Composer/Compiler.php @@ -43,13 +43,25 @@ class Compiler unlink($pharFile); } - $process = new Process('git log --pretty="%H" -n1 HEAD', __DIR__); + // TODO in v2.3 always call with an array + if (method_exists('Symfony\Component\Process\Process', 'fromShellCommandline')) { + $process = new Process(array('git', 'log', '--pretty="%H"', '-n1', 'HEAD'), __DIR__); + } else { + // @phpstan-ignore-next-line + $process = new Process('git log --pretty="%H" -n1 HEAD', __DIR__); + } if ($process->run() != 0) { throw new \RuntimeException('Can\'t run git log. You must ensure to run compile from composer git repository clone and that git binary is available.'); } $this->version = trim($process->getOutput()); - $process = new Process('git log -n1 --pretty=%ci HEAD', __DIR__); + // TODO in v2.3 always call with an array + if (method_exists('Symfony\Component\Process\Process', 'fromShellCommandline')) { + $process = new Process(array('git', 'log', '-n1', '--pretty=%ci', 'HEAD'), __DIR__); + } else { + // @phpstan-ignore-next-line + $process = new Process('git log -n1 --pretty=%ci HEAD', __DIR__); + } if ($process->run() != 0) { throw new \RuntimeException('Can\'t run git log. You must ensure to run compile from composer git repository clone and that git binary is available.'); } @@ -57,7 +69,13 @@ class Compiler $this->versionDate = new \DateTime(trim($process->getOutput())); $this->versionDate->setTimezone(new \DateTimeZone('UTC')); - $process = new Process('git describe --tags --exact-match HEAD'); + // TODO in v2.3 always call with an array + if (method_exists('Symfony\Component\Process\Process', 'fromShellCommandline')) { + $process = new Process(array('git', 'describe', '--tags', '--exact-match', 'HEAD'), __DIR__); + } else { + // @phpstan-ignore-next-line + $process = new Process('git describe --tags --exact-match HEAD'); + } if ($process->run() == 0) { $this->version = trim($process->getOutput()); } else { diff --git a/src/Composer/Composer.php b/src/Composer/Composer.php index 16f29f113..e2bcc0225 100644 --- a/src/Composer/Composer.php +++ b/src/Composer/Composer.php @@ -88,9 +88,9 @@ class Composer private $package; /** - * @var Locker + * @var ?Locker */ - private $locker; + private $locker = null; /** * @var Loop @@ -179,7 +179,7 @@ class Composer } /** - * @return Locker + * @return ?Locker */ public function getLocker() { diff --git a/src/Composer/Console/Application.php b/src/Composer/Console/Application.php index 245547f6e..c4a93d10f 100644 --- a/src/Composer/Console/Application.php +++ b/src/Composer/Console/Application.php @@ -77,8 +77,8 @@ class Application extends BaseApplication static $shutdownRegistered = false; if (function_exists('ini_set') && extension_loaded('xdebug')) { - ini_set('xdebug.show_exception_trace', false); - ini_set('xdebug.scream', false); + ini_set('xdebug.show_exception_trace', '0'); + ini_set('xdebug.scream', '0'); } if (function_exists('date_default_timezone_set') && function_exists('date_default_timezone_get')) { @@ -408,7 +408,8 @@ class Application extends BaseApplication * @param bool $required * @param bool|null $disablePlugins * @throws JsonValidationException - * @return \Composer\Composer + * @throws \InvalidArgumentException + * @return ?\Composer\Composer If $required is true then the return value is guaranteed */ public function getComposer($required = true, $disablePlugins = null) { @@ -444,7 +445,7 @@ class Application extends BaseApplication public function resetComposer() { $this->composer = null; - if ($this->getIO() && method_exists($this->getIO(), 'resetAuthentications')) { + if (method_exists($this->getIO(), 'resetAuthentications')) { $this->getIO()->resetAuthentications(); } } diff --git a/src/Composer/DependencyResolver/GenericRule.php b/src/Composer/DependencyResolver/GenericRule.php index 10ea9c335..39c4783ed 100644 --- a/src/Composer/DependencyResolver/GenericRule.php +++ b/src/Composer/DependencyResolver/GenericRule.php @@ -14,6 +14,7 @@ namespace Composer\DependencyResolver; use Composer\Package\BasePackage; use Composer\Package\Link; +use Composer\Semver\Constraint\ConstraintInterface; /** * @author Nils Adermann @@ -23,9 +24,11 @@ class GenericRule extends Rule protected $literals; /** - * @param array $literals - * @param int|null $reason A RULE_* constant describing the reason for generating this rule - * @param Link|BasePackage|int|null $reasonData + * @param array $literals + * @param int|null $reason A RULE_* constant describing the reason for generating this rule + * @param Link|BasePackage|int|null|array $reasonData + * + * @phpstan-param Link|BasePackage|int|null|array{packageName: string, constraint: ConstraintInterface} $reasonData */ public function __construct(array $literals, $reason, $reasonData) { diff --git a/src/Composer/DependencyResolver/LockTransaction.php b/src/Composer/DependencyResolver/LockTransaction.php index eb5dead6b..3a3d94505 100644 --- a/src/Composer/DependencyResolver/LockTransaction.php +++ b/src/Composer/DependencyResolver/LockTransaction.php @@ -13,7 +13,8 @@ namespace Composer\DependencyResolver; use Composer\Package\AliasPackage; -use Composer\Package\RootAliasPackage; +use Composer\Package\BasePackage; +use Composer\Package\Package; /** * @author Nils Adermann @@ -23,22 +24,32 @@ class LockTransaction extends Transaction { /** * packages in current lock file, platform repo or otherwise present - * @var array + * + * Indexed by spl_object_hash + * + * @var array */ protected $presentMap; /** * Packages which cannot be mapped, platform repo, root package, other fixed repos - * @var array + * + * Indexed by package id + * + * @var array */ protected $unlockableMap; /** - * @var array + * @var array{dev: BasePackage[], non-dev: BasePackage[], all: BasePackage[]} */ protected $resultPackages; - public function __construct(Pool $pool, $presentMap, $unlockableMap, $decisions) + /** + * @param array $presentMap + * @param array $unlockableMap + */ + public function __construct(Pool $pool, array $presentMap, array $unlockableMap, Decisions $decisions) { $this->presentMap = $presentMap; $this->unlockableMap = $unlockableMap; @@ -88,7 +99,7 @@ class LockTransaction extends Transaction { $packages = array(); foreach ($this->resultPackages[$devMode ? 'dev' : 'non-dev'] as $package) { - if (!($package instanceof AliasPackage) && !($package instanceof RootAliasPackage)) { + if (!$package instanceof AliasPackage) { // if we're just updating mirrors we need to reset references to the same as currently "present" packages' references to keep the lock file as-is // we do not reset references if the currently present package didn't have any, or if the type of VCS has changed if ($updateMirrors && !isset($this->presentMap[spl_object_hash($package)])) { @@ -97,7 +108,7 @@ class LockTransaction extends Transaction if ($presentPackage->getSourceReference() && $presentPackage->getSourceType() === $package->getSourceType()) { $package->setSourceDistReferences($presentPackage->getSourceReference()); } - if ($presentPackage->getReleaseDate()) { + if ($presentPackage->getReleaseDate() && $package instanceof Package) { $package->setReleaseDate($presentPackage->getReleaseDate()); } } diff --git a/src/Composer/DependencyResolver/Pool.php b/src/Composer/DependencyResolver/Pool.php index ceb8777ee..5fd5ff607 100644 --- a/src/Composer/DependencyResolver/Pool.php +++ b/src/Composer/DependencyResolver/Pool.php @@ -202,7 +202,7 @@ class Pool implements \Countable $str = "Pool:\n"; foreach ($this->packages as $package) { - $str .= '- '.str_pad($package->id, 6, ' ', STR_PAD_LEFT).': '.$package->getName()."\n"; + $str .= '- '.str_pad((string) $package->id, 6, ' ', STR_PAD_LEFT).': '.$package->getName()."\n"; } return $str; diff --git a/src/Composer/DependencyResolver/PoolBuilder.php b/src/Composer/DependencyResolver/PoolBuilder.php index f4500cc0d..a8a4ecbee 100644 --- a/src/Composer/DependencyResolver/PoolBuilder.php +++ b/src/Composer/DependencyResolver/PoolBuilder.php @@ -17,6 +17,7 @@ use Composer\IO\IOInterface; use Composer\Package\AliasPackage; use Composer\Package\BasePackage; use Composer\Package\CompleteAliasPackage; +use Composer\Package\CompletePackage; use Composer\Package\CompletePackageInterface; use Composer\Package\PackageInterface; use Composer\Package\Version\StabilityFilter; @@ -38,10 +39,12 @@ class PoolBuilder { /** * @var int[] + * @phpstan-var array */ private $acceptableStabilities; /** * @var int[] + * @phpstan-var array */ private $stabilityFlags; /** @@ -55,7 +58,7 @@ class PoolBuilder */ private $rootReferences; /** - * @var EventDispatcher + * @var ?EventDispatcher */ private $eventDispatcher; /** @@ -340,7 +343,7 @@ class PoolBuilder } } - private function loadPackage(Request $request, PackageInterface $package, $propagateUpdate = true) + private function loadPackage(Request $request, BasePackage $package, $propagateUpdate = true) { $index = $this->indexCounter++; $this->packages[$index] = $package; @@ -370,7 +373,7 @@ class PoolBuilder } else { $basePackage = $package; } - if ($basePackage instanceof CompletePackageInterface) { + if ($basePackage instanceof CompletePackage) { $aliasPackage = new CompleteAliasPackage($basePackage, $alias['alias_normalized'], $alias['alias']); } else { $aliasPackage = new AliasPackage($basePackage, $alias['alias_normalized'], $alias['alias']); diff --git a/src/Composer/DependencyResolver/Problem.php b/src/Composer/DependencyResolver/Problem.php index 5248dbadf..6a490dd1d 100644 --- a/src/Composer/DependencyResolver/Problem.php +++ b/src/Composer/DependencyResolver/Problem.php @@ -18,6 +18,7 @@ use Composer\Package\RootPackageInterface; use Composer\Repository\RepositorySet; use Composer\Repository\LockArrayRepository; use Composer\Semver\Constraint\Constraint; +use Composer\Semver\Constraint\ConstraintInterface; use Composer\Package\Version\VersionParser; /** @@ -459,7 +460,7 @@ class Problem /** * Turns a constraint into text usable in a sentence describing a request * - * @param \Composer\Semver\Constraint\ConstraintInterface $constraint + * @param ?ConstraintInterface $constraint * @return string */ protected static function constraintToText($constraint) diff --git a/src/Composer/Downloader/DownloadManager.php b/src/Composer/Downloader/DownloadManager.php index f55cb9a28..736baf920 100644 --- a/src/Composer/Downloader/DownloadManager.php +++ b/src/Composer/Downloader/DownloadManager.php @@ -401,7 +401,7 @@ class DownloadManager } /** - * @return string[] + * @return array<'dist'|'source'>&non-empty-array */ private function getAvailableSources(PackageInterface $package, PackageInterface $prevPackage = null) { diff --git a/src/Composer/Downloader/FileDownloader.php b/src/Composer/Downloader/FileDownloader.php index b732cad9b..7683d3d21 100644 --- a/src/Composer/Downloader/FileDownloader.php +++ b/src/Composer/Downloader/FileDownloader.php @@ -51,9 +51,9 @@ class FileDownloader implements DownloaderInterface, ChangeReportInterface protected $httpDownloader; /** @var Filesystem */ protected $filesystem; - /** @var Cache */ + /** @var ?Cache */ protected $cache; - /** @var EventDispatcher */ + /** @var ?EventDispatcher */ protected $eventDispatcher; /** @var ProcessExecutor */ protected $process; diff --git a/src/Composer/Factory.php b/src/Composer/Factory.php index 6aed45454..d67ccf29a 100644 --- a/src/Composer/Factory.php +++ b/src/Composer/Factory.php @@ -38,6 +38,7 @@ use Composer\Autoload\AutoloadGenerator; use Composer\Package\Version\VersionParser; use Composer\Downloader\TransportException; use Composer\Json\JsonValidationException; +use Composer\Repository\InstalledRepositoryInterface; use Seld\JsonLint\JsonParser; /** @@ -434,9 +435,7 @@ class Factory // once everything is initialized we can // purge packages from local repos if they have been deleted on the filesystem - if ($rm->getLocalRepository()) { - $this->purgePackages($rm->getLocalRepository(), $im); - } + $this->purgePackages($rm->getLocalRepository(), $im); } return $composer; @@ -585,10 +584,10 @@ class Factory } /** - * @param WritableRepositoryInterface $repo repository to purge packages from + * @param InstalledRepositoryInterface $repo repository to purge packages from * @param Installer\InstallationManager $im manager to check whether packages are still installed */ - protected function purgePackages(WritableRepositoryInterface $repo, Installer\InstallationManager $im) + protected function purgePackages(InstalledRepositoryInterface $repo, Installer\InstallationManager $im) { foreach ($repo->getPackages() as $package) { if (!$im->isPackageInstalled($repo, $package)) { @@ -632,7 +631,7 @@ class Factory if (isset($_SERVER['argv']) && in_array('disable-tls', $_SERVER['argv']) && (in_array('conf', $_SERVER['argv']) || in_array('config', $_SERVER['argv']))) { $warned = true; $disableTls = !extension_loaded('openssl'); - } elseif ($config && $config->get('disable-tls') === true) { + } elseif ($config->get('disable-tls') === true) { if (!$warned) { $io->writeError('You are running Composer with SSL/TLS protection disabled.'); } @@ -644,10 +643,10 @@ class Factory } $httpDownloaderOptions = array(); if ($disableTls === false) { - if ($config && $config->get('cafile')) { + if ($config->get('cafile')) { $httpDownloaderOptions['ssl']['cafile'] = $config->get('cafile'); } - if ($config && $config->get('capath')) { + if ($config->get('capath')) { $httpDownloaderOptions['ssl']['capath'] = $config->get('capath'); } $httpDownloaderOptions = array_replace_recursive($httpDownloaderOptions, $options); diff --git a/src/Composer/IO/ConsoleIO.php b/src/Composer/IO/ConsoleIO.php index 1b790ad5e..d6aa538c1 100644 --- a/src/Composer/IO/ConsoleIO.php +++ b/src/Composer/IO/ConsoleIO.php @@ -159,13 +159,6 @@ class ConsoleIO extends BaseIO return; } - // hack to keep our usage BC with symfony<2.8 versions - // this removes the quiet output but there is no way around it - // see https://github.com/composer/composer/pull/4913 - if (OutputInterface::VERBOSITY_QUIET === 0) { - $sfVerbosity = OutputInterface::OUTPUT_NORMAL; - } - if ($raw) { if ($sfVerbosity === OutputInterface::OUTPUT_NORMAL) { $sfVerbosity = OutputInterface::OUTPUT_RAW; diff --git a/src/Composer/InstalledVersions.php b/src/Composer/InstalledVersions.php index b3a4e1611..9809a2190 100644 --- a/src/Composer/InstalledVersions.php +++ b/src/Composer/InstalledVersions.php @@ -228,7 +228,7 @@ class InstalledVersions /** * @return array - * @psalm-return array{name: string, version: string, reference: string, pretty_version: string, aliases: string[], dev: bool, install_path: string} + * @psalm-return array{name: string, version: string, reference: string, pretty_version: string, aliases: string[], dev: bool, install_path: string, type: string} */ public static function getRootPackage() { @@ -242,7 +242,7 @@ class InstalledVersions * * @deprecated Use getAllRawData() instead which returns all datasets for all autoloaders present in the process. getRawData only returns the first dataset loaded, which may not be what you expect. * @return array[] - * @psalm-return array{root: array{name: string, version: string, reference: string, pretty_version: string, aliases: string[], dev: bool, install_path: string}, versions: array} + * @psalm-return array{root: array{name: string, version: string, reference: string, pretty_version: string, aliases: string[], dev: bool, install_path: string, type: string}, versions: array} */ public static function getRawData() { @@ -265,7 +265,7 @@ class InstalledVersions * Returns the raw data of all installed.php which are currently loaded for custom implementations * * @return array[] - * @psalm-return list}> + * @psalm-return list}> */ public static function getAllRawData() { @@ -288,7 +288,7 @@ class InstalledVersions * @param array[] $data A vendor/composer/installed.php data set * @return void * - * @psalm-param array{root: array{name: string, version: string, reference: string, pretty_version: string, aliases: string[], dev: bool, install_path: string}, versions: array} $data + * @psalm-param array{root: array{name: string, version: string, reference: string, pretty_version: string, aliases: string[], dev: bool, install_path: string, type: string}, versions: array} $data */ public static function reload($data) { @@ -298,7 +298,7 @@ class InstalledVersions /** * @return array[] - * @psalm-return list}> + * @psalm-return list}> */ private static function getInstalled() { diff --git a/src/Composer/Installer.php b/src/Composer/Installer.php index 6cf057172..d04005132 100644 --- a/src/Composer/Installer.php +++ b/src/Composer/Installer.php @@ -152,7 +152,7 @@ class Installer protected $suggestedPackagesReporter; /** - * @var RepositoryInterface + * @var ?RepositoryInterface */ protected $additionalFixedRepository; @@ -180,6 +180,7 @@ class Installer $this->installationManager = $installationManager; $this->eventDispatcher = $eventDispatcher; $this->autoloadGenerator = $autoloadGenerator; + $this->suggestedPackagesReporter = new SuggestedPackagesReporter($this->io); $this->writeLock = $config->get('lock'); } @@ -238,10 +239,6 @@ class Installer $localRepo = $this->repositoryManager->getLocalRepository(); - if (!$this->suggestedPackagesReporter) { - $this->suggestedPackagesReporter = new SuggestedPackagesReporter($this->io); - } - try { if ($this->update) { $res = $this->doUpdate($localRepo, $this->install); diff --git a/src/Composer/Installer/InstallationManager.php b/src/Composer/Installer/InstallationManager.php index fb3e28f78..c7f43a5bf 100644 --- a/src/Composer/Installer/InstallationManager.php +++ b/src/Composer/Installer/InstallationManager.php @@ -47,7 +47,7 @@ class InstallationManager private $loop; /** @var IOInterface */ private $io; - /** @var EventDispatcher */ + /** @var ?EventDispatcher */ private $eventDispatcher; /** @var bool */ private $outputProgress; @@ -179,6 +179,7 @@ class InstallationManager */ public function execute(InstalledRepositoryInterface $repo, array $operations, $devMode = true, $runScripts = true) { + /** @var PromiseInterface[] */ $cleanupPromises = array(); $loop = $this->loop; diff --git a/src/Composer/Json/JsonFile.php b/src/Composer/Json/JsonFile.php index 1b662fa91..53cf5534f 100644 --- a/src/Composer/Json/JsonFile.php +++ b/src/Composer/Json/JsonFile.php @@ -291,7 +291,7 @@ class JsonFile /** * Parses json string and returns hash. * - * @param string $json json string + * @param ?string $json json string * @param string $file the json file * * @throws ParsingException @@ -300,7 +300,7 @@ class JsonFile public static function parseJson($json, $file = null) { if (null === $json) { - return; + return null; } $data = json_decode($json, true); if (null === $data && JSON_ERROR_NONE !== json_last_error()) { diff --git a/src/Composer/Package/AliasPackage.php b/src/Composer/Package/AliasPackage.php index 42d38b6b6..c993230c6 100644 --- a/src/Composer/Package/AliasPackage.php +++ b/src/Composer/Package/AliasPackage.php @@ -113,6 +113,7 @@ class AliasPackage extends BasePackage /** * {@inheritDoc} + * @return array */ public function getConflicts() { @@ -121,6 +122,7 @@ class AliasPackage extends BasePackage /** * {@inheritDoc} + * @return array */ public function getProvides() { @@ -129,6 +131,7 @@ class AliasPackage extends BasePackage /** * {@inheritDoc} + * @return array */ public function getReplaces() { @@ -167,8 +170,8 @@ class AliasPackage extends BasePackage } /** - * @param Link[] $links - * @param string $linkType + * @param Link[] $links + * @param Link::TYPE_* $linkType * * @return Link[] */ diff --git a/src/Composer/Package/BasePackage.php b/src/Composer/Package/BasePackage.php index f8199a0bb..04a57f5bc 100644 --- a/src/Composer/Package/BasePackage.php +++ b/src/Composer/Package/BasePackage.php @@ -24,6 +24,7 @@ abstract class BasePackage implements PackageInterface { /** * @phpstan-var array + * @internal */ public static $supportedLinkTypes = array( 'require' => array('description' => 'requires', 'method' => Link::TYPE_REQUIRE), diff --git a/src/Composer/Package/Link.php b/src/Composer/Package/Link.php index 955eb8e97..af08705df 100644 --- a/src/Composer/Package/Link.php +++ b/src/Composer/Package/Link.php @@ -26,6 +26,12 @@ class Link const TYPE_PROVIDE = 'provides'; const TYPE_CONFLICT = 'conflicts'; const TYPE_REPLACE = 'replaces'; + + /** + * Special type + * @internal + */ + const TYPE_DOES_NOT_REQUIRE = 'does not require'; /** * TODO should be marked private once 5.3 is dropped * @private @@ -37,6 +43,7 @@ class Link * * @internal * @var string[] + * @phpstan-var array */ public static $TYPES = array( self::TYPE_REQUIRE, @@ -63,12 +70,12 @@ class Link /** * @var string - * @phpstan-var self::TYPE_* $description + * @phpstan-var string $description */ protected $description; /** - * @var string|null + * @var ?string */ protected $prettyConstraint; @@ -91,7 +98,7 @@ class Link $this->source = strtolower($source); $this->target = strtolower($target); $this->constraint = $constraint; - $this->description = $description; + $this->description = self::TYPE_DEV_REQUIRE === $description ? 'requires (for development)' : $description; $this->prettyConstraint = $prettyConstraint; } @@ -154,6 +161,6 @@ class Link */ public function getPrettyString(PackageInterface $sourcePackage) { - return $sourcePackage->getPrettyString().' '.$this->description.' '.$this->target.($this->constraint ? ' '.$this->constraint->getPrettyString() : ''); + return $sourcePackage->getPrettyString().' '.$this->description.' '.$this->target.' '.$this->constraint->getPrettyString(); } } diff --git a/src/Composer/Package/Loader/ArrayLoader.php b/src/Composer/Package/Loader/ArrayLoader.php index 1f3843f3e..4367b9a3a 100644 --- a/src/Composer/Package/Loader/ArrayLoader.php +++ b/src/Composer/Package/Loader/ArrayLoader.php @@ -45,9 +45,12 @@ class ArrayLoader implements LoaderInterface /** * @template PackageClass of CompletePackageInterface - * @param array $config package data - * @param string $class FQCN to be instantiated - * @return CompletePackage|CompleteAliasPackage + * + * @param array $config package data + * @param string $class FQCN to be instantiated + * + * @return CompletePackage|CompleteAliasPackage|RootPackage|RootAliasPackage + * * @phpstan-param class-string $class */ public function load(array $config, $class = 'Composer\Package\CompletePackage') @@ -65,7 +68,7 @@ class ArrayLoader implements LoaderInterface $this->parseLinks( $package->getName(), $package->getPrettyVersion(), - $opts['description'], + $opts['method'], $config[$type] ) ); @@ -78,23 +81,16 @@ class ArrayLoader implements LoaderInterface } /** - * @template PackageClass of CompletePackageInterface * @param array $versions - * @param string $class FQCN to be instantiated * @return list - * @phpstan-param class-string $class */ - public function loadPackages(array $versions, $class = 'Composer\Package\CompletePackage') + public function loadPackages(array $versions) { - if ($class !== 'Composer\Package\CompletePackage') { - trigger_error('The $class arg is deprecated, please reach out to Composer maintainers ASAP if you still need this.', E_USER_DEPRECATED); - } - $packages = array(); $linkCache = array(); foreach ($versions as $version) { - $package = $this->createObject($version, $class); + $package = $this->createObject($version, 'Composer\Package\CompletePackage'); $this->configureCachedLinks($linkCache, $package, $version); $package = $this->configureObject($package, $version); @@ -137,14 +133,14 @@ class ArrayLoader implements LoaderInterface } /** - * @param CompletePackageInterface $package + * @param CompletePackage $package * @param array $config package data * @return RootPackage|RootAliasPackage|CompletePackage|CompleteAliasPackage */ private function configureObject(PackageInterface $package, array $config) { - if (!$package instanceof Package) { - throw new \LogicException('ArrayLoader expects instances of the Composer\Package\Package class to function correctly'); + if (!$package instanceof CompletePackage) { + throw new \LogicException('ArrayLoader expects instances of the Composer\Package\CompletePackage class to function correctly'); } $package->setType(isset($config['type']) ? strtolower($config['type']) : 'library'); @@ -302,15 +298,11 @@ class ArrayLoader implements LoaderInterface if ($aliasNormalized = $this->getBranchAlias($config)) { $prettyAlias = preg_replace('{(\.9{7})+}', '.x', $aliasNormalized); - if ($package instanceof RootPackageInterface) { + if ($package instanceof RootPackage) { return new RootAliasPackage($package, $aliasNormalized, $prettyAlias); } - if ($package instanceof CompletePackageInterface) { - return new CompleteAliasPackage($package, $aliasNormalized, $prettyAlias); - } - - return new AliasPackage($package, $aliasNormalized, $prettyAlias); + return new CompleteAliasPackage($package, $aliasNormalized, $prettyAlias); } return $package; @@ -335,10 +327,10 @@ class ArrayLoader implements LoaderInterface foreach ($config[$type] as $prettyTarget => $constraint) { $target = strtolower($prettyTarget); if ($constraint === 'self.version') { - $links[$target] = $this->createLink($name, $prettyVersion, $opts['description'], $target, $constraint); + $links[$target] = $this->createLink($name, $prettyVersion, $opts['method'], $target, $constraint); } else { if (!isset($linkCache[$name][$type][$target][$constraint])) { - $linkCache[$name][$type][$target][$constraint] = array($target, $this->createLink($name, $prettyVersion, $opts['description'], $target, $constraint)); + $linkCache[$name][$type][$target][$constraint] = array($target, $this->createLink($name, $prettyVersion, $opts['method'], $target, $constraint)); } list($target, $link) = $linkCache[$name][$type][$target][$constraint]; diff --git a/src/Composer/Package/Locker.php b/src/Composer/Package/Locker.php index 4bbbb1d4c..2ab1e2052 100644 --- a/src/Composer/Package/Locker.php +++ b/src/Composer/Package/Locker.php @@ -186,11 +186,7 @@ class Locker if (isset($lockData['aliases'])) { foreach ($lockData['aliases'] as $alias) { if (isset($packageByName[$alias['package']])) { - if ($packageByName[$alias['package']] instanceof CompletePackageInterface) { - $aliasPkg = new CompleteAliasPackage($packageByName[$alias['package']], $alias['alias_normalized'], $alias['alias']); - } else { - $aliasPkg = new AliasPackage($packageByName[$alias['package']], $alias['alias_normalized'], $alias['alias']); - } + $aliasPkg = new CompleteAliasPackage($packageByName[$alias['package']], $alias['alias_normalized'], $alias['alias']); $aliasPkg->setRootPackageAlias(true); $packages->addPackage($aliasPkg); } diff --git a/src/Composer/Package/Package.php b/src/Composer/Package/Package.php index 9afbd6429..2b3ccb1aa 100644 --- a/src/Composer/Package/Package.php +++ b/src/Composer/Package/Package.php @@ -22,46 +22,68 @@ use Composer\Util\ComposerMirror; */ class Package extends BasePackage { + /** @var string */ protected $type; + /** @var ?string */ protected $targetDir; + /** @var 'source'|'dist'|null */ protected $installationSource; + /** @var ?string */ protected $sourceType; + /** @var ?string */ protected $sourceUrl; /** @var ?string */ protected $sourceReference; + /** @var ?array */ protected $sourceMirrors; + /** @var ?string */ protected $distType; + /** @var ?string */ protected $distUrl; /** @var ?string */ protected $distReference; /** @var ?string */ protected $distSha1Checksum; + /** @var ?array */ protected $distMirrors; + /** @var string */ protected $version; + /** @var string */ protected $prettyVersion; + /** @var ?\DateTime */ protected $releaseDate; + /** @var mixed[] */ protected $extra = array(); + /** @var string[] */ protected $binaries = array(); + /** @var bool */ protected $dev; + /** @var string */ protected $stability; + /** @var ?string */ protected $notificationUrl; - /** @var Link[] */ + /** @var array */ protected $requires = array(); - /** @var Link[] */ + /** @var array */ protected $conflicts = array(); - /** @var Link[] */ + /** @var array */ protected $provides = array(); - /** @var Link[] */ + /** @var array */ protected $replaces = array(); - /** @var Link[] */ + /** @var array */ protected $devRequires = array(); + /** @var array */ protected $suggests = array(); + /** @var array{psr-0?: array, psr-4?: array, classmap?: list, files?: list} */ protected $autoload = array(); + /** @var array{psr-0?: array, psr-4?: array, classmap?: list, files?: list} */ protected $devAutoload = array(); + /** @var string[] */ protected $includePaths = array(); + /** @var bool */ protected $isDefaultBranch = false; - /** @var array */ + /** @var mixed[] */ protected $transportOptions = array(); /** @@ -395,7 +417,7 @@ class Package extends BasePackage /** * Set the required packages * - * @param Link[] $requires A set of package links + * @param array $requires A set of package links */ public function setRequires(array $requires) { @@ -413,7 +435,7 @@ class Package extends BasePackage /** * Set the conflicting packages * - * @param Link[] $conflicts A set of package links + * @param array $conflicts A set of package links */ public function setConflicts(array $conflicts) { @@ -422,6 +444,7 @@ class Package extends BasePackage /** * {@inheritDoc} + * @return array */ public function getConflicts() { @@ -431,7 +454,7 @@ class Package extends BasePackage /** * Set the provided virtual packages * - * @param Link[] $provides A set of package links + * @param array $provides A set of package links */ public function setProvides(array $provides) { @@ -440,6 +463,7 @@ class Package extends BasePackage /** * {@inheritDoc} + * @return array */ public function getProvides() { @@ -449,7 +473,7 @@ class Package extends BasePackage /** * Set the packages this one replaces * - * @param Link[] $replaces A set of package links + * @param array $replaces A set of package links */ public function setReplaces(array $replaces) { @@ -458,6 +482,7 @@ class Package extends BasePackage /** * {@inheritDoc} + * @return array */ public function getReplaces() { @@ -467,7 +492,7 @@ class Package extends BasePackage /** * Set the recommended packages * - * @param Link[] $devRequires A set of package links + * @param array $devRequires A set of package links */ public function setDevRequires(array $devRequires) { @@ -485,7 +510,7 @@ class Package extends BasePackage /** * Set the suggested packages * - * @param array $suggests A set of package names/comments + * @param array $suggests A set of package names/comments */ public function setSuggests(array $suggests) { diff --git a/src/Composer/Package/PackageInterface.php b/src/Composer/Package/PackageInterface.php index 355cf49f0..c3df0fd63 100644 --- a/src/Composer/Package/PackageInterface.php +++ b/src/Composer/Package/PackageInterface.php @@ -82,14 +82,14 @@ interface PackageInterface /** * Returns the package targetDir property * - * @return string|null The package targetDir + * @return ?string The package targetDir */ public function getTargetDir(); /** * Returns the package extra data * - * @return array The package extra data + * @return mixed[] The package extra data */ public function getExtra(); @@ -97,27 +97,29 @@ interface PackageInterface * Sets source from which this package was installed (source/dist). * * @param string $type source/dist + * @phpstan-param 'source'|'dist'|null $type */ public function setInstallationSource($type); /** * Returns source from which this package was installed (source/dist). * - * @return string source/dist + * @return ?string source/dist + * @phpstan-return 'source'|'dist'|null */ public function getInstallationSource(); /** * Returns the repository type of this package, e.g. git, svn * - * @return string The repository type + * @return ?string The repository type */ public function getSourceType(); /** * Returns the repository url of this package, e.g. git://github.com/naderman/composer.git * - * @return string The repository url + * @return ?string The repository url */ public function getSourceUrl(); @@ -138,12 +140,12 @@ interface PackageInterface /** * Returns the source mirrors of this package * - * @return array|null + * @return ?array */ public function getSourceMirrors(); /** - * @param array|null $mirrors + * @param ?array $mirrors * @return void */ public function setSourceMirrors($mirrors); @@ -151,14 +153,14 @@ interface PackageInterface /** * Returns the type of the distribution archive of this version, e.g. zip, tarball * - * @return string The repository type + * @return ?string The repository type */ public function getDistType(); /** * Returns the url of the distribution archive of this version * - * @return string + * @return ?string */ public function getDistUrl(); @@ -186,12 +188,12 @@ interface PackageInterface /** * Returns the dist mirrors of this package * - * @return array|null + * @return ?array */ public function getDistMirrors(); /** - * @param array|null $mirrors + * @param ?array $mirrors * @return void */ public function setDistMirrors($mirrors); @@ -226,7 +228,7 @@ interface PackageInterface /** * Returns the release date of the package * - * @return \DateTime + * @return ?\DateTime */ public function getReleaseDate(); @@ -241,7 +243,7 @@ interface PackageInterface * Returns a set of links to packages which need to be installed before * this package can be installed * - * @return Link[] An array of package links defining required packages + * @return array An array of package links defining required packages */ public function getRequires(); @@ -273,7 +275,7 @@ interface PackageInterface * Returns a set of links to packages which are required to develop * this package. These are installed if in dev mode. * - * @return Link[] An array of package links defining packages required for development + * @return array An array of package links defining packages required for development */ public function getDevRequires(); @@ -295,7 +297,7 @@ interface PackageInterface * directories for autoloading using the type specified. * * @return array Mapping of autoloading rules - * @phpstan-return array{psr-0?: array, psr-4?: array, classmap?: list, files?: list} + * @phpstan-return array{psr-0?: array, psr-4?: array, classmap?: list, files?: list} */ public function getAutoload(); @@ -308,7 +310,7 @@ interface PackageInterface * directories for autoloading using the type specified. * * @return array Mapping of dev autoloading rules - * @phpstan-return array{psr-0?: array, psr-4?: array, classmap?: list, files?: list} + * @phpstan-return array{psr-0?: array, psr-4?: array, classmap?: list, files?: list} */ public function getDevAutoload(); @@ -330,7 +332,7 @@ interface PackageInterface /** * Returns a reference to the repository that owns the package * - * @return RepositoryInterface + * @return ?RepositoryInterface */ public function getRepository(); @@ -351,7 +353,7 @@ interface PackageInterface /** * Returns the package notification url * - * @return string + * @return ?string */ public function getNotificationUrl(); @@ -377,7 +379,7 @@ interface PackageInterface /** * Returns a list of options to download package dist files * - * @return array + * @return mixed[] */ public function getTransportOptions(); diff --git a/src/Composer/Package/RootAliasPackage.php b/src/Composer/Package/RootAliasPackage.php index 6a71ba740..78139eb02 100644 --- a/src/Composer/Package/RootAliasPackage.php +++ b/src/Composer/Package/RootAliasPackage.php @@ -17,23 +17,23 @@ namespace Composer\Package; */ class RootAliasPackage extends CompleteAliasPackage implements RootPackageInterface { - /** @var RootPackageInterface */ + /** @var RootPackage */ protected $aliasOf; /** * All descendants' constructors should call this parent constructor * - * @param RootPackageInterface $aliasOf The package this package is an alias of - * @param string $version The version the alias must report - * @param string $prettyVersion The alias's non-normalized version + * @param RootPackage $aliasOf The package this package is an alias of + * @param string $version The version the alias must report + * @param string $prettyVersion The alias's non-normalized version */ - public function __construct(RootPackageInterface $aliasOf, $version, $prettyVersion) + public function __construct(RootPackage $aliasOf, $version, $prettyVersion) { parent::__construct($aliasOf, $version, $prettyVersion); } /** - * @return RootPackageInterface + * @return RootPackage */ public function getAliasOf() { diff --git a/src/Composer/Plugin/PluginManager.php b/src/Composer/Plugin/PluginManager.php index cd85ac2d3..eb13aad0e 100644 --- a/src/Composer/Plugin/PluginManager.php +++ b/src/Composer/Plugin/PluginManager.php @@ -39,7 +39,7 @@ class PluginManager protected $composer; /** @var IOInterface */ protected $io; - /** @var Composer */ + /** @var ?Composer */ protected $globalComposer; /** @var VersionParser */ protected $versionParser; @@ -82,9 +82,7 @@ class PluginManager $repo = $this->composer->getRepositoryManager()->getLocalRepository(); $globalRepo = $this->globalComposer ? $this->globalComposer->getRepositoryManager()->getLocalRepository() : null; - if ($repo) { - $this->loadRepository($repo, false); - } + $this->loadRepository($repo, false); if ($globalRepo) { $this->loadRepository($globalRepo, true); } @@ -259,6 +257,7 @@ class PluginManager } if ($oldInstallerPlugin) { + /** @var \Composer\Installer\InstallerInterface $installer */ $installer = $this->registeredPlugins[$package->getName()]; unset($this->registeredPlugins[$package->getName()]); $this->composer->getInstallationManager()->removeInstaller($installer); @@ -469,7 +468,7 @@ class PluginManager array_key_exists($capability, $capabilities) && (empty($capabilities[$capability]) || !is_string($capabilities[$capability]) || !trim($capabilities[$capability])) ) { - throw new \UnexpectedValueException('Plugin '.get_class($plugin).' provided invalid capability class name(s), got '.var_export($capabilities[$capability], 1)); + throw new \UnexpectedValueException('Plugin '.get_class($plugin).' provided invalid capability class name(s), got '.var_export($capabilities[$capability], true)); } return null; diff --git a/src/Composer/Plugin/PostFileDownloadEvent.php b/src/Composer/Plugin/PostFileDownloadEvent.php index c30e00c89..7be34d728 100644 --- a/src/Composer/Plugin/PostFileDownloadEvent.php +++ b/src/Composer/Plugin/PostFileDownloadEvent.php @@ -59,6 +59,7 @@ class PostFileDownloadEvent extends Event */ public function __construct($name, $fileName, $checksum, $url, $type, $context = null) { + /** @phpstan-ignore-next-line */ if ($context === null && $type instanceof PackageInterface) { $context = $type; $type = 'package'; diff --git a/src/Composer/Repository/ArrayRepository.php b/src/Composer/Repository/ArrayRepository.php index 07aa04db1..8b44547a1 100644 --- a/src/Composer/Repository/ArrayRepository.php +++ b/src/Composer/Repository/ArrayRepository.php @@ -13,7 +13,9 @@ namespace Composer\Repository; use Composer\Package\AliasPackage; +use Composer\Package\BasePackage; use Composer\Package\CompleteAliasPackage; +use Composer\Package\CompletePackage; use Composer\Package\PackageInterface; use Composer\Package\CompletePackageInterface; use Composer\Package\Version\VersionParser; @@ -28,11 +30,11 @@ use Composer\Semver\Constraint\Constraint; */ class ArrayRepository implements RepositoryInterface { - /** @var ?PackageInterface[] */ + /** @var ?array */ protected $packages = null; /** - * @var ?PackageInterface[] indexed by package unique name and used to cache hasPackage calls + * @var ?array indexed by package unique name and used to cache hasPackage calls */ protected $packageMap = null; @@ -232,13 +234,17 @@ class ArrayRepository implements RepositoryInterface return $result; } + /** + * @phpstan-param PackageInterface&BasePackage $package + * @return AliasPackage|CompleteAliasPackage + */ protected function createAliasPackage(PackageInterface $package, $alias, $prettyAlias) { while ($package instanceof AliasPackage) { $package = $package->getAliasOf(); } - if ($package instanceof CompletePackageInterface) { + if ($package instanceof CompletePackage) { return new CompleteAliasPackage($package, $alias, $prettyAlias); } @@ -275,6 +281,10 @@ class ArrayRepository implements RepositoryInterface $this->initialize(); } + if (null === $this->packages) { + throw new \LogicException('initialize failed to initialize the packages array'); + } + return $this->packages; } diff --git a/src/Composer/Repository/ComposerRepository.php b/src/Composer/Repository/ComposerRepository.php index b5dea04b4..0aaf458db 100644 --- a/src/Composer/Repository/ComposerRepository.php +++ b/src/Composer/Repository/ComposerRepository.php @@ -49,6 +49,7 @@ class ComposerRepository extends ArrayRepository implements ConfigurableReposito private $url; private $baseUrl; private $io; + /** @var HttpDownloader */ private $httpDownloader; private $loop; protected $cache; diff --git a/src/Composer/Repository/InstalledRepository.php b/src/Composer/Repository/InstalledRepository.php index 7405a30bb..13c5fddbb 100644 --- a/src/Composer/Repository/InstalledRepository.php +++ b/src/Composer/Repository/InstalledRepository.php @@ -114,7 +114,7 @@ class InstalledRepository extends CompositeRepository foreach ($package->getReplaces() as $link) { foreach ($needles as $needle) { if ($link->getSource() === $needle) { - if ($constraint === null || ($link->getConstraint()->matches($constraint) === !$invert)) { + if ($constraint === null || ($link->getConstraint()->matches($constraint) === true)) { // already displayed this node's dependencies, cutting short if (in_array($link->getTarget(), $packagesInTree)) { $results[] = array($package, $link, false); @@ -221,7 +221,7 @@ class InstalledRepository extends CompositeRepository } $results[] = array($package, $link, false); - $results[] = array($rootPackage, new Link($rootPackage->getName(), $link->getTarget(), new MatchAllConstraint, 'does not require', 'but ' . $pkg->getPrettyVersion() . ' is installed'), false); + $results[] = array($rootPackage, new Link($rootPackage->getName(), $link->getTarget(), new MatchAllConstraint, Link::TYPE_DOES_NOT_REQUIRE, 'but ' . $pkg->getPrettyVersion() . ' is installed'), false); } else { // no root so let's just print whatever we found $results[] = array($package, $link, false); diff --git a/src/Composer/Repository/PlatformRepository.php b/src/Composer/Repository/PlatformRepository.php index 3b08b3e2c..095c86a8a 100644 --- a/src/Composer/Repository/PlatformRepository.php +++ b/src/Composer/Repository/PlatformRepository.php @@ -566,7 +566,7 @@ class PlatformRepository extends ArrayRepository if ($name === 'uuid') { $ext->setReplaces(array( - new Link('ext-uuid', 'lib-uuid', new Constraint('=', $version), Link::TYPE_REPLACE, $ext->getPrettyVersion()), + 'lib-uuid' => new Link('ext-uuid', 'lib-uuid', new Constraint('=', $version), Link::TYPE_REPLACE, $ext->getPrettyVersion()), )); } diff --git a/src/Composer/Repository/RepositoryInterface.php b/src/Composer/Repository/RepositoryInterface.php index f5f1204d0..3b0760e0e 100644 --- a/src/Composer/Repository/RepositoryInterface.php +++ b/src/Composer/Repository/RepositoryInterface.php @@ -44,6 +44,7 @@ interface RepositoryInterface extends \Countable * @param string|ConstraintInterface $constraint package version or version constraint to match against * * @return PackageInterface|null + * @phpstan-return (BasePackage&PackageInterface)|null */ public function findPackage($name, $constraint); @@ -54,6 +55,7 @@ interface RepositoryInterface extends \Countable * @param string|ConstraintInterface $constraint package version or version constraint to match against * * @return PackageInterface[] + * @phpstan-return array */ public function findPackages($name, $constraint = null); @@ -61,6 +63,7 @@ interface RepositoryInterface extends \Countable * Returns list of registered packages. * * @return PackageInterface[] + * @phpstan-return array */ public function getPackages(); @@ -75,7 +78,10 @@ interface RepositoryInterface extends \Countable * @param array $stabilityFlags an array of package name => BasePackage::STABILITY_* value * @param array> $alreadyLoaded an array of package name => package version => package * - * @return array{namesFound: string[], packages: PackageInterface[]} + * @return array + * + * @phpstan-param array $packageNameMap + * @phpstan-return array{namesFound: string[], packages: array} */ public function loadPackages(array $packageNameMap, array $acceptableStabilities, array $stabilityFlags, array $alreadyLoaded = array()); diff --git a/src/Composer/Repository/RepositorySet.php b/src/Composer/Repository/RepositorySet.php index 66db56833..ae7e2cba8 100644 --- a/src/Composer/Repository/RepositorySet.php +++ b/src/Composer/Repository/RepositorySet.php @@ -21,6 +21,7 @@ use Composer\IO\NullIO; use Composer\Package\BasePackage; use Composer\Package\AliasPackage; use Composer\Package\CompleteAliasPackage; +use Composer\Package\CompletePackage; use Composer\Package\CompletePackageInterface; use Composer\Semver\Constraint\ConstraintInterface; use Composer\Package\Version\StabilityFilter; @@ -56,13 +57,13 @@ class RepositorySet /** * @var int[] array of stability => BasePackage::STABILITY_* value - * @phpstan-var array + * @phpstan-var array */ private $acceptableStabilities; /** * @var int[] array of package name => BasePackage::STABILITY_* value - * @phpstan-var array + * @phpstan-var array */ private $stabilityFlags; @@ -80,7 +81,7 @@ class RepositorySet * * @param string $minimumStability * @param int[] $stabilityFlags an array of package name => BasePackage::STABILITY_* value - * @phpstan-param array $stabilityFlags + * @phpstan-param array $stabilityFlags * @param array[] $rootAliases * @phpstan-param list $rootAliases * @param string[] $rootReferences an array of package name => source reference @@ -254,7 +255,7 @@ class RepositorySet while ($package instanceof AliasPackage) { $package = $package->getAliasOf(); } - if ($package instanceof CompletePackageInterface) { + if ($package instanceof CompletePackage) { $aliasPackage = new CompleteAliasPackage($package, $alias['alias_normalized'], $alias['alias']); } else { $aliasPackage = new AliasPackage($package, $alias['alias_normalized'], $alias['alias']); diff --git a/src/Composer/Repository/Vcs/BitbucketDriver.php b/src/Composer/Repository/Vcs/BitbucketDriver.php index 1a9a8f6d8..96b4c3298 100644 --- a/src/Composer/Repository/Vcs/BitbucketDriver.php +++ b/src/Composer/Repository/Vcs/BitbucketDriver.php @@ -77,6 +77,7 @@ abstract class BitbucketDriver extends VcsDriver * sets some parameters which are used in other methods * * @return bool + * @phpstan-impure */ protected function getRepoData() { @@ -363,6 +364,8 @@ abstract class BitbucketDriver extends VcsDriver * @param bool $fetchingRepoData * * @return Response The result + * + * @phpstan-impure */ protected function fetchWithOAuthCredentials($url, $fetchingRepoData = false) { @@ -396,6 +399,9 @@ abstract class BitbucketDriver extends VcsDriver */ abstract protected function generateSshUrl(); + /** + * @phpstan-impure + */ protected function attemptCloneFallback() { try { diff --git a/src/Composer/Repository/Vcs/HgBitbucketDriver.php b/src/Composer/Repository/Vcs/HgBitbucketDriver.php index 42adcb918..71505cf52 100644 --- a/src/Composer/Repository/Vcs/HgBitbucketDriver.php +++ b/src/Composer/Repository/Vcs/HgBitbucketDriver.php @@ -31,12 +31,10 @@ class HgBitbucketDriver extends BitbucketDriver if (null === $this->rootIdentifier) { if (!$this->getRepoData()) { - // @phpstan-ignore-next-line if (!$this->fallbackDriver) { throw new \LogicException('A fallback driver should be setup if getRepoData returns false'); } - // @phpstan-ignore-next-line return $this->fallbackDriver->getRootIdentifier(); } diff --git a/src/Composer/Repository/Vcs/VcsDriver.php b/src/Composer/Repository/Vcs/VcsDriver.php index 8927a0dcc..ae86e44a7 100644 --- a/src/Composer/Repository/Vcs/VcsDriver.php +++ b/src/Composer/Repository/Vcs/VcsDriver.php @@ -157,6 +157,7 @@ abstract class VcsDriver implements VcsDriverInterface * @param string $url The URL of content * * @return Response + * @throws TransportException */ protected function getContents($url) { diff --git a/src/Composer/Util/Http/CurlDownloader.php b/src/Composer/Util/Http/CurlDownloader.php index e8c57908e..e412f52e6 100644 --- a/src/Composer/Util/Http/CurlDownloader.php +++ b/src/Composer/Util/Http/CurlDownloader.php @@ -142,6 +142,7 @@ class CurlDownloader if ($copyTo) { $errorMessage = ''; + // @phpstan-ignore-next-line set_error_handler(function ($code, $msg) use (&$errorMessage) { if ($errorMessage) { $errorMessage .= "\n"; diff --git a/src/Composer/Util/HttpDownloader.php b/src/Composer/Util/HttpDownloader.php index 4610a29b2..809ac2b1a 100644 --- a/src/Composer/Util/HttpDownloader.php +++ b/src/Composer/Util/HttpDownloader.php @@ -481,6 +481,7 @@ class HttpDownloader /** * @internal + * @return bool */ public static function isCurlEnabled() { diff --git a/src/Composer/Util/NoProxyPattern.php b/src/Composer/Util/NoProxyPattern.php index b8175f3c9..7e0b5cce0 100644 --- a/src/Composer/Util/NoProxyPattern.php +++ b/src/Composer/Util/NoProxyPattern.php @@ -264,8 +264,8 @@ class NoProxyPattern /** * Returns the binary network mask mapped to IPv6 * - * @param string $prefix CIDR prefix-length - * @param int $size Byte size of in_addr + * @param int $prefix CIDR prefix-length + * @param int $size Byte size of in_addr * * @return string */ @@ -274,7 +274,7 @@ class NoProxyPattern $mask = ''; if ($ones = floor($prefix / 8)) { - $mask = str_repeat(chr(255), $ones); + $mask = str_repeat(chr(255), (int) $ones); } if ($remainder = $prefix % 8) { @@ -291,7 +291,7 @@ class NoProxyPattern * * @param string $rangeIp IP in_addr * @param int $size Byte size of in_addr - * @param string $prefix CIDR prefix-length + * @param int $prefix CIDR prefix-length * * @return string[] network in_addr, binary mask */ diff --git a/src/Composer/Util/StreamContextFactory.php b/src/Composer/Util/StreamContextFactory.php index 3542d55ed..4e6997155 100644 --- a/src/Composer/Util/StreamContextFactory.php +++ b/src/Composer/Util/StreamContextFactory.php @@ -31,7 +31,7 @@ final class StreamContextFactory * Creates a context supporting HTTP proxies * * @param string $url URL the context is to be used for - * @phpstan-param array{http?: array{follow_location?: int, max_redirects?: int, header?: string|array}} $defaultOptions + * @phpstan-param array{http?: array{follow_location?: int, max_redirects?: int, header?: string|array}} $defaultOptions * @param array $defaultOptions Options to merge with the default * @param array $defaultParams Parameters to specify on the context * @throws \RuntimeException if https proxy required and OpenSSL uninstalled diff --git a/src/Composer/Util/SyncHelper.php b/src/Composer/Util/SyncHelper.php index a970028a9..9db7f3365 100644 --- a/src/Composer/Util/SyncHelper.php +++ b/src/Composer/Util/SyncHelper.php @@ -39,7 +39,7 @@ class SyncHelper self::await($loop, $downloader->prepare($type, $package, $path, $prevPackage)); if ($type === 'update') { - self::await($loop, $downloader->update($package, $path, $prevPackage)); + self::await($loop, $downloader->update($package, $prevPackage, $path)); } else { self::await($loop, $downloader->install($package, $path)); } diff --git a/tests/Composer/Test/AllFunctionalTest.php b/tests/Composer/Test/AllFunctionalTest.php index 1cbf16ecc..22cea755d 100644 --- a/tests/Composer/Test/AllFunctionalTest.php +++ b/tests/Composer/Test/AllFunctionalTest.php @@ -78,7 +78,13 @@ class AllFunctionalTest extends TestCase } } - $proc = new Process((defined('PHP_BINARY') ? escapeshellcmd(PHP_BINARY) : 'php').' -dphar.readonly=0 '.escapeshellarg('./bin/compile'), $target); + // TODO in v2.3 always call with an array + if (method_exists('Symfony\Component\Process\Process', 'fromShellCommandline')) { + $proc = new Process(array((defined('PHP_BINARY') ? PHP_BINARY : 'php'), '-dphar.readonly=0', './bin/compile'), $target); + } else { + // @phpstan-ignore-next-line + $proc = new Process((defined('PHP_BINARY') ? escapeshellcmd(PHP_BINARY) : 'php').' -dphar.readonly=0 '.escapeshellarg('./bin/compile'), $target); + } $exitcode = $proc->run(); if ($exitcode !== 0 || trim($proc->getOutput())) { @@ -110,8 +116,15 @@ class AllFunctionalTest extends TestCase 'COMPOSER_CACHE_DIR' => $this->testDir.'cache', ); - $cmd = (defined('PHP_BINARY') ? escapeshellcmd(PHP_BINARY) : 'php') .' '.escapeshellarg(self::$pharPath).' --no-ansi '.$testData['RUN']; - $proc = new Process($cmd, $this->testDir, $env, null, 300); + // TODO in v2.3 always call with an array + if (method_exists('Symfony\Component\Process\Process', 'fromShellCommandline')) { + $cmd = array((defined('PHP_BINARY') ? PHP_BINARY : 'php'), self::$pharPath, '--no-ansi', $testData['RUN']); + $proc = new Process($cmd, $this->testDir, $env, null, 300); + } else { + $cmd = (defined('PHP_BINARY') ? escapeshellcmd(PHP_BINARY) : 'php') .' '.escapeshellarg(self::$pharPath).' --no-ansi '.$testData['RUN']; + // @phpstan-ignore-next-line + $proc = new Process($cmd, $this->testDir, $env, null, 300); + } $output = ''; $exitcode = $proc->run(function ($type, $buffer) use (&$output) { diff --git a/tests/Composer/Test/Autoload/AutoloadGeneratorTest.php b/tests/Composer/Test/Autoload/AutoloadGeneratorTest.php index 134ebd6b8..0e571f81a 100644 --- a/tests/Composer/Test/Autoload/AutoloadGeneratorTest.php +++ b/tests/Composer/Test/Autoload/AutoloadGeneratorTest.php @@ -371,8 +371,8 @@ class AutoloadGeneratorTest extends TestCase { $package = new RootPackage('root/a', '1.0', '1.0'); $package->setRequires(array( - new Link('a', 'a/a', new MatchAllConstraint()), - new Link('a', 'b/b', new MatchAllConstraint()), + 'a/a' => new Link('a', 'a/a', new MatchAllConstraint()), + 'b/b' => new Link('a', 'b/b', new MatchAllConstraint()), )); $packages = array(); @@ -400,7 +400,7 @@ class AutoloadGeneratorTest extends TestCase { $package = new RootPackage('root/a', '1.0', '1.0'); $package->setRequires(array( - new Link('a', 'a/a', new MatchAllConstraint()), + 'a/a' => new Link('a', 'a/a', new MatchAllConstraint()), )); $packages = array(); @@ -408,11 +408,11 @@ class AutoloadGeneratorTest extends TestCase $packages[] = $b = new Package('b/b', '1.0', '1.0'); $a->setAutoload(array('psr-0' => array('A' => 'src/', 'A\\B' => 'lib/'))); $a->setRequires(array( - new Link('a/a', 'b/b', new MatchAllConstraint()), + 'b/b' => new Link('a/a', 'b/b', new MatchAllConstraint()), )); $b->setAutoload(array('psr-0' => array('B\\Sub\\Name' => 'src/'))); $b->setRequires(array( - new Link('b/b', 'a/a', new MatchAllConstraint()), + 'a/a' => new Link('b/b', 'a/a', new MatchAllConstraint()), )); $this->repository->expects($this->once()) @@ -432,17 +432,17 @@ class AutoloadGeneratorTest extends TestCase public function testNonDevAutoloadShouldIncludeReplacedPackages() { $package = new RootPackage('root/a', '1.0', '1.0'); - $package->setRequires(array(new Link('a', 'a/a', new MatchAllConstraint()))); + $package->setRequires(array('a/a' => new Link('a', 'a/a', new MatchAllConstraint()))); $packages = array(); $packages[] = $a = new Package('a/a', '1.0', '1.0'); $packages[] = $b = new Package('b/b', '1.0', '1.0'); - $a->setRequires(array(new Link('a/a', 'b/c', new MatchAllConstraint()))); + $a->setRequires(array('b/c' => new Link('a/a', 'b/c', new MatchAllConstraint()))); $b->setAutoload(array('psr-4' => array('B\\' => 'src/'))); $b->setReplaces( - array(new Link('b/b', 'b/c', new Constraint('==', '1.0'), Link::TYPE_REPLACE)) + array('b/c' => new Link('b/b', 'b/c', new Constraint('==', '1.0'), Link::TYPE_REPLACE)) ); $this->repository->expects($this->once()) @@ -467,7 +467,7 @@ class AutoloadGeneratorTest extends TestCase { $package = new RootPackage('root/a', '1.0', '1.0'); $package->setRequires(array( - new Link('a', 'a/a', new MatchAllConstraint()), + 'a/a' => new Link('a', 'a/a', new MatchAllConstraint()), )); $packages = array(); @@ -475,11 +475,11 @@ class AutoloadGeneratorTest extends TestCase $packages[] = $b = new Package('b/b', '1.0', '1.0'); $a->setAutoload(array('psr-0' => array('A' => 'src/', 'A\\B' => 'lib/'))); $a->setRequires(array( - new Link('a/a', 'c/c', new MatchAllConstraint()), + 'c/c' => new Link('a/a', 'c/c', new MatchAllConstraint()), )); $b->setAutoload(array('psr-0' => array('B\\Sub\\Name' => 'src/'))); $b->setReplaces(array( - new Link('b/b', 'c/c', new MatchAllConstraint()), + 'c/c' => new Link('b/b', 'c/c', new MatchAllConstraint()), )); $this->repository->expects($this->once()) @@ -500,7 +500,7 @@ class AutoloadGeneratorTest extends TestCase { $package = new RootPackage('root/a', '1.0', '1.0'); $package->setRequires(array( - new Link('a', 'a/a', new MatchAllConstraint()), + 'a/a' => new Link('a', 'a/a', new MatchAllConstraint()), )); $packages = array(); @@ -511,18 +511,18 @@ class AutoloadGeneratorTest extends TestCase $packages[] = $e = new Package('e/e', '1.0', '1.0'); $a->setAutoload(array('classmap' => array('src/A.php'))); $a->setRequires(array( - new Link('a/a', 'b/b', new MatchAllConstraint()), + 'b/b' => new Link('a/a', 'b/b', new MatchAllConstraint()), )); $b->setAutoload(array('classmap' => array('src/B.php'))); $b->setRequires(array( - new Link('b/b', 'e/e', new MatchAllConstraint()), + 'e/e' => new Link('b/b', 'e/e', new MatchAllConstraint()), )); $c->setAutoload(array('classmap' => array('src/C.php'))); $c->setReplaces(array( - new Link('c/c', 'b/b', new MatchAllConstraint()), + 'b/b' => new Link('c/c', 'b/b', new MatchAllConstraint()), )); $c->setRequires(array( - new Link('c/c', 'd/d', new MatchAllConstraint()), + 'd/d' => new Link('c/c', 'd/d', new MatchAllConstraint()), )); $d->setAutoload(array('classmap' => array('src/D.php'))); $e->setAutoload(array('classmap' => array('src/E.php'))); @@ -552,7 +552,7 @@ class AutoloadGeneratorTest extends TestCase { $package = new RootPackage('root/a', '1.0', '1.0'); $package->setRequires(array( - new Link('a', 'a/a', new MatchAllConstraint()), + 'a/a' => new Link('a', 'a/a', new MatchAllConstraint()), )); $package->setAutoload(array( @@ -657,8 +657,8 @@ EOF; { $package = new RootPackage('root/a', '1.0', '1.0'); $package->setRequires(array( - new Link('a', 'a/a', new MatchAllConstraint()), - new Link('a', 'b/b', new MatchAllConstraint()), + 'a/a' => new Link('a', 'a/a', new MatchAllConstraint()), + 'b/b' => new Link('a', 'b/b', new MatchAllConstraint()), )); $packages = array(); @@ -697,8 +697,8 @@ EOF; { $package = new RootPackage('root/a', '1.0', '1.0'); $package->setRequires(array( - new Link('a', 'a/a', new MatchAllConstraint()), - new Link('a', 'b/b', new MatchAllConstraint()), + 'a/a' => new Link('a', 'a/a', new MatchAllConstraint()), + 'b/b' => new Link('a', 'b/b', new MatchAllConstraint()), )); $packages = array(); @@ -737,9 +737,9 @@ EOF; { $package = new RootPackage('root/a', '1.0', '1.0'); $package->setRequires(array( - new Link('a', 'a/a', new MatchAllConstraint()), - new Link('a', 'b/b', new MatchAllConstraint()), - new Link('a', 'c/c', new MatchAllConstraint()), + 'a/a' => new Link('a', 'a/a', new MatchAllConstraint()), + 'b/b' => new Link('a', 'b/b', new MatchAllConstraint()), + 'c/c' => new Link('a', 'c/c', new MatchAllConstraint()), )); $packages = array(); @@ -782,9 +782,9 @@ EOF; { $package = new RootPackage('root/a', '1.0', '1.0'); $package->setRequires(array( - new Link('a', 'a/a', new MatchAllConstraint()), - new Link('a', 'b/b', new MatchAllConstraint()), - new Link('a', 'c/c', new MatchAllConstraint()), + 'a/a' => new Link('a', 'a/a', new MatchAllConstraint()), + 'b/b' => new Link('a', 'b/b', new MatchAllConstraint()), + 'c/c' => new Link('a', 'c/c', new MatchAllConstraint()), )); $packages = array(); @@ -831,9 +831,9 @@ EOF; { $package = new RootPackage('root/a', '1.0', '1.0'); $package->setRequires(array( - new Link('a', 'a/a', new MatchAllConstraint()), - new Link('a', 'b/b', new MatchAllConstraint()), - new Link('a', 'c/c', new MatchAllConstraint()), + 'a/a' => new Link('a', 'a/a', new MatchAllConstraint()), + 'b/b' => new Link('a', 'b/b', new MatchAllConstraint()), + 'c/c' => new Link('a', 'c/c', new MatchAllConstraint()), )); $packages = array(); @@ -881,9 +881,9 @@ EOF; $package = new RootPackage('root/a', '1.0', '1.0'); $package->setAutoload(array('files' => array('root.php'))); $package->setRequires(array( - new Link('a', 'a/a', new MatchAllConstraint()), - new Link('a', 'b/b', new MatchAllConstraint()), - new Link('a', 'c/c', new MatchAllConstraint()), + 'a/a' => new Link('a', 'a/a', new MatchAllConstraint()), + 'b/b' => new Link('a', 'b/b', new MatchAllConstraint()), + 'c/c' => new Link('a', 'c/c', new MatchAllConstraint()), )); $packages = array(); @@ -932,9 +932,9 @@ EOF; $notAutoloadPackage = new RootPackage('root/a', '1.0', '1.0'); $requires = array( - new Link('a', 'a/a', new MatchAllConstraint()), - new Link('a', 'b/b', new MatchAllConstraint()), - new Link('a', 'c/c', new MatchAllConstraint()), + 'a/a' => new Link('a', 'a/a', new MatchAllConstraint()), + 'b/b' => new Link('a', 'b/b', new MatchAllConstraint()), + 'c/c' => new Link('a', 'c/c', new MatchAllConstraint()), ); $autoloadPackage->setRequires($requires); $notAutoloadPackage->setRequires($requires); @@ -1003,10 +1003,10 @@ EOF; $package = new RootPackage('root/a', '1.0', '1.0'); $package->setAutoload(array('files' => array('root2.php'))); $package->setRequires(array( - new Link('a', 'z/foo', new MatchAllConstraint()), - new Link('a', 'b/bar', new MatchAllConstraint()), - new Link('a', 'd/d', new MatchAllConstraint()), - new Link('a', 'e/e', new MatchAllConstraint()), + 'z/foo' => new Link('a', 'z/foo', new MatchAllConstraint()), + 'b/bar' => new Link('a', 'b/bar', new MatchAllConstraint()), + 'd/d' => new Link('a', 'd/d', new MatchAllConstraint()), + 'e/e' => new Link('a', 'e/e', new MatchAllConstraint()), )); $packages = array(); @@ -1017,18 +1017,18 @@ EOF; $packages[] = $e = new Package('e/e', '1.0', '1.0'); $z->setAutoload(array('files' => array('testA.php'))); - $z->setRequires(array(new Link('z/foo', 'c/lorem', new MatchAllConstraint()))); + $z->setRequires(array('c/lorem' => new Link('z/foo', 'c/lorem', new MatchAllConstraint()))); $b->setAutoload(array('files' => array('testB.php'))); - $b->setRequires(array(new Link('b/bar', 'c/lorem', new MatchAllConstraint()), new Link('b/bar', 'd/d', new MatchAllConstraint()))); + $b->setRequires(array('c/lorem' => new Link('b/bar', 'c/lorem', new MatchAllConstraint()), 'd/d' => new Link('b/bar', 'd/d', new MatchAllConstraint()))); $c->setAutoload(array('files' => array('testC.php'))); $d->setAutoload(array('files' => array('testD.php'))); - $d->setRequires(array(new Link('d/d', 'c/lorem', new MatchAllConstraint()))); + $d->setRequires(array('c/lorem' => new Link('d/d', 'c/lorem', new MatchAllConstraint()))); $e->setAutoload(array('files' => array('testE.php'))); - $e->setRequires(array(new Link('e/e', 'c/lorem', new MatchAllConstraint()))); + $e->setRequires(array('c/lorem' => new Link('e/e', 'c/lorem', new MatchAllConstraint()))); $this->repository->expects($this->once()) ->method('getCanonicalPackages') @@ -1076,8 +1076,8 @@ EOF; 'classmap' => array($this->workingDir.'/src'), )); $rootPackage->setRequires(array( - new Link('z', 'a/a', new MatchAllConstraint()), - new Link('z', 'b/b', new MatchAllConstraint()), + 'a/a' => new Link('z', 'a/a', new MatchAllConstraint()), + 'b/b' => new Link('z', 'b/b', new MatchAllConstraint()), )); $packages = array(); @@ -1339,7 +1339,7 @@ EOF; 'files' => array('test.php'), )); $package->setRequires(array( - new Link('a', 'b/b', new MatchAllConstraint()), + 'b/b' => new Link('a', 'b/b', new MatchAllConstraint()), )); $vendorPackage = new Package('b/b', '1.0', '1.0'); diff --git a/tests/Composer/Test/Command/InitCommandTest.php b/tests/Composer/Test/Command/InitCommandTest.php index 1c2014195..8006fe106 100644 --- a/tests/Composer/Test/Command/InitCommandTest.php +++ b/tests/Composer/Test/Command/InitCommandTest.php @@ -110,7 +110,7 @@ class InitCommandTest extends TestCase public function testNamespaceFromMissingPackageName() { $command = new InitCommand; - $namespace = $command->namespaceFromPackageName(null); + $namespace = $command->namespaceFromPackageName(''); $this->assertNull($namespace); } } diff --git a/tests/Composer/Test/DependencyResolver/RuleSetTest.php b/tests/Composer/Test/DependencyResolver/RuleSetTest.php index 9ccb25c09..7ffe6ac49 100644 --- a/tests/Composer/Test/DependencyResolver/RuleSetTest.php +++ b/tests/Composer/Test/DependencyResolver/RuleSetTest.php @@ -16,6 +16,7 @@ use Composer\DependencyResolver\GenericRule; use Composer\DependencyResolver\Rule; use Composer\DependencyResolver\RuleSet; use Composer\DependencyResolver\Pool; +use Composer\Semver\Constraint\MatchNoneConstraint; use Composer\Test\TestCase; class RuleSetTest extends TestCase @@ -144,7 +145,7 @@ class RuleSetTest extends TestCase $ruleSet = new RuleSet; $literal = $p->getId(); - $rule = new GenericRule(array($literal), Rule::RULE_ROOT_REQUIRE, array('packageName' => 'foo/bar', 'constraint' => null)); + $rule = new GenericRule(array($literal), Rule::RULE_ROOT_REQUIRE, array('packageName' => 'foo/bar', 'constraint' => new MatchNoneConstraint)); $ruleSet->add($rule, RuleSet::TYPE_REQUEST); diff --git a/tests/Composer/Test/IO/BufferIOTest.php b/tests/Composer/Test/IO/BufferIOTest.php index 013a3c100..7b8bf2f41 100644 --- a/tests/Composer/Test/IO/BufferIOTest.php +++ b/tests/Composer/Test/IO/BufferIOTest.php @@ -36,8 +36,8 @@ class BufferIOTest extends TestCase '', )); - $this->assertTrue($bufferIO->askConfirmation('Please say yes!', 'no')); - $this->assertFalse($bufferIO->askConfirmation('Now please say no!', 'yes')); + $this->assertTrue($bufferIO->askConfirmation('Please say yes!', false)); + $this->assertFalse($bufferIO->askConfirmation('Now please say no!', true)); $this->assertSame('default', $bufferIO->ask('Empty string last', 'default')); } } diff --git a/tests/Composer/Test/IO/ConsoleIOTest.php b/tests/Composer/Test/IO/ConsoleIOTest.php index 1ff86170c..b89932bd4 100644 --- a/tests/Composer/Test/IO/ConsoleIOTest.php +++ b/tests/Composer/Test/IO/ConsoleIOTest.php @@ -191,7 +191,7 @@ class ConsoleIOTest extends TestCase ; $consoleIO = new ConsoleIO($inputMock, $outputMock, $setMock); - $consoleIO->askConfirmation('Why?', 'default'); + $consoleIO->askConfirmation('Why?', false); } public function testAskAndValidate() @@ -250,7 +250,7 @@ class ConsoleIOTest extends TestCase ; $consoleIO = new ConsoleIO($inputMock, $outputMock, $setMock); - $result = $consoleIO->select('Select item', array("item1", "item2"), null, false, "Error message", true); + $result = $consoleIO->select('Select item', array("item1", "item2"), 'item1', false, "Error message", true); $this->assertEquals(array('1'), $result); } diff --git a/tests/Composer/Test/IO/NullIOTest.php b/tests/Composer/Test/IO/NullIOTest.php index 11430379b..2a66807d3 100644 --- a/tests/Composer/Test/IO/NullIOTest.php +++ b/tests/Composer/Test/IO/NullIOTest.php @@ -58,14 +58,14 @@ class NullIOTest extends TestCase { $io = new NullIO(); - $this->assertEquals('foo', $io->askConfirmation('bar', 'foo')); + $this->assertEquals(false, $io->askConfirmation('bar', false)); } public function testAskAndValidate() { $io = new NullIO(); - $this->assertEquals('foo', $io->askAndValidate('question', 'validator', false, 'foo')); + $this->assertEquals('foo', $io->askAndValidate('question', function ($x) { return true; }, null, 'foo')); } public function testSelect() diff --git a/tests/Composer/Test/Installer/LibraryInstallerTest.php b/tests/Composer/Test/Installer/LibraryInstallerTest.php index cff4fbc34..967b40db0 100644 --- a/tests/Composer/Test/Installer/LibraryInstallerTest.php +++ b/tests/Composer/Test/Installer/LibraryInstallerTest.php @@ -288,7 +288,7 @@ class LibraryInstallerTest extends TestCase protected function createPackageMock() { return $this->getMockBuilder('Composer\Package\Package') - ->setConstructorArgs(array(md5(mt_rand()), '1.0.0.0', '1.0.0')) + ->setConstructorArgs(array(md5((string) mt_rand()), '1.0.0.0', '1.0.0')) ->getMock(); } } diff --git a/tests/Composer/Test/Installer/MetapackageInstallerTest.php b/tests/Composer/Test/Installer/MetapackageInstallerTest.php index 481de79da..4ba65991f 100644 --- a/tests/Composer/Test/Installer/MetapackageInstallerTest.php +++ b/tests/Composer/Test/Installer/MetapackageInstallerTest.php @@ -101,7 +101,7 @@ class MetapackageInstallerTest extends TestCase private function createPackageMock() { return $this->getMockBuilder('Composer\Package\Package') - ->setConstructorArgs(array(md5(mt_rand()), '1.0.0.0', '1.0.0')) + ->setConstructorArgs(array(md5((string) mt_rand()), '1.0.0.0', '1.0.0')) ->getMock(); } } diff --git a/tests/Composer/Test/Installer/SuggestedPackagesReporterTest.php b/tests/Composer/Test/Installer/SuggestedPackagesReporterTest.php index fb8003306..fad4d1235 100644 --- a/tests/Composer/Test/Installer/SuggestedPackagesReporterTest.php +++ b/tests/Composer/Test/Installer/SuggestedPackagesReporterTest.php @@ -279,7 +279,7 @@ class SuggestedPackagesReporterTest extends TestCase private function createPackageMock() { return $this->getMockBuilder('Composer\Package\Package') - ->setConstructorArgs(array(md5(mt_rand()), '1.0.0.0', '1.0.0')) + ->setConstructorArgs(array(md5((string) mt_rand()), '1.0.0.0', '1.0.0')) ->getMock(); } } diff --git a/tests/Composer/Test/Mock/FactoryMock.php b/tests/Composer/Test/Mock/FactoryMock.php index c095bc639..79b50e19d 100644 --- a/tests/Composer/Test/Mock/FactoryMock.php +++ b/tests/Composer/Test/Mock/FactoryMock.php @@ -16,13 +16,14 @@ use Composer\Composer; use Composer\Config; use Composer\Factory; use Composer\Repository\RepositoryManager; -use Composer\Repository\WritableRepositoryInterface; use Composer\Package\Version\VersionGuesser; use Composer\Package\Version\VersionParser; use Composer\Package\RootPackageInterface; use Composer\Installer; use Composer\EventDispatcher\EventDispatcher; use Composer\IO\IOInterface; +use Composer\Repository\InstalledArrayRepository; +use Composer\Repository\InstalledRepositoryInterface; use Composer\Test\TestCase; use Composer\Util\Loop; use Composer\Util\ProcessExecutor; @@ -48,6 +49,7 @@ class FactoryMock extends Factory protected function addLocalRepository(IOInterface $io, RepositoryManager $rm, $vendorDir, RootPackageInterface $rootPackage, ProcessExecutor $process = null) { + $rm->setLocalRepository(new InstalledArrayRepository); } public function createInstallationManager(Loop $loop, IOInterface $io, EventDispatcher $dispatcher = null) @@ -59,7 +61,7 @@ class FactoryMock extends Factory { } - protected function purgePackages(WritableRepositoryInterface $repo, Installer\InstallationManager $im) + protected function purgePackages(InstalledRepositoryInterface $repo, Installer\InstallationManager $im) { } } diff --git a/tests/Composer/Test/Mock/ProcessExecutorMock.php b/tests/Composer/Test/Mock/ProcessExecutorMock.php index 1d1889f0f..4010e0f4c 100644 --- a/tests/Composer/Test/Mock/ProcessExecutorMock.php +++ b/tests/Composer/Test/Mock/ProcessExecutorMock.php @@ -30,7 +30,7 @@ class ProcessExecutorMock extends ProcessExecutor private $log = array(); /** - * @param array $expectations + * @param array $expectations * @param bool $strict set to true if you want to provide *all* expected commands, and not just a subset you are interested in testing * @param array{return: int, stdout?: string, stderr?: string} $defaultHandler default command handler for undefined commands if not in strict mode */ diff --git a/tests/Composer/Test/Package/Archiver/ArchiveManagerTest.php b/tests/Composer/Test/Package/Archiver/ArchiveManagerTest.php index 2c99ac61c..a9f281975 100644 --- a/tests/Composer/Test/Package/Archiver/ArchiveManagerTest.php +++ b/tests/Composer/Test/Package/Archiver/ArchiveManagerTest.php @@ -15,6 +15,7 @@ namespace Composer\Test\Package\Archiver; use Composer\IO\NullIO; use Composer\Factory; use Composer\Package\Archiver\ArchiveManager; +use Composer\Package\CompletePackage; use Composer\Package\PackageInterface; use Composer\Util\Loop; use Composer\Test\Mock\FactoryMock; @@ -95,7 +96,7 @@ class ArchiveManagerTest extends ArchiverTest unlink($target); } - protected function getTargetName(PackageInterface $package, $format, $fileName = null) + protected function getTargetName(CompletePackage $package, $format, $fileName = null) { if (null === $fileName) { $packageName = $this->manager->getPackageFilename($package); diff --git a/tests/Composer/Test/Package/Dumper/ArrayDumperTest.php b/tests/Composer/Test/Package/Dumper/ArrayDumperTest.php index dbcdf848f..39f1b0a0b 100644 --- a/tests/Composer/Test/Package/Dumper/ArrayDumperTest.php +++ b/tests/Composer/Test/Package/Dumper/ArrayDumperTest.php @@ -178,7 +178,7 @@ class ArrayDumperTest extends TestCase ), array( 'require-dev', - array(new Link('foo', 'foo/bar', new Constraint('=', '1.0.0.0'), 'requires (for development)', '1.0.0')), + array(new Link('foo', 'foo/bar', new Constraint('=', '1.0.0.0'), Link::TYPE_DEV_REQUIRE, '1.0.0')), 'devRequires', array('foo/bar' => '1.0.0'), ), diff --git a/tests/Composer/Test/Package/Loader/ArrayLoaderTest.php b/tests/Composer/Test/Package/Loader/ArrayLoaderTest.php index 1d4f8661b..285dd13e4 100644 --- a/tests/Composer/Test/Package/Loader/ArrayLoaderTest.php +++ b/tests/Composer/Test/Package/Loader/ArrayLoaderTest.php @@ -14,6 +14,7 @@ namespace Composer\Test\Package\Loader; use Composer\Package\Loader\ArrayLoader; use Composer\Package\Dumper\ArrayDumper; +use Composer\Package\Link; use Composer\Test\TestCase; class ArrayLoaderTest extends TestCase @@ -287,7 +288,7 @@ class ArrayLoaderTest extends TestCase */ public function testPluginApiVersionAreKeptAsDeclared($apiVersion) { - $links = $this->loader->parseLinks('Plugin', '9.9.9', '', array('composer-plugin-api' => $apiVersion)); + $links = $this->loader->parseLinks('Plugin', '9.9.9', Link::TYPE_REQUIRE, array('composer-plugin-api' => $apiVersion)); $this->assertArrayHasKey('composer-plugin-api', $links); $this->assertSame($apiVersion, $links['composer-plugin-api']->getConstraint()->getPrettyString()); @@ -295,7 +296,7 @@ class ArrayLoaderTest extends TestCase public function testPluginApiVersionDoesSupportSelfVersion() { - $links = $this->loader->parseLinks('Plugin', '6.6.6', '', array('composer-plugin-api' => 'self.version')); + $links = $this->loader->parseLinks('Plugin', '6.6.6', Link::TYPE_REQUIRE, array('composer-plugin-api' => 'self.version')); $this->assertArrayHasKey('composer-plugin-api', $links); $this->assertSame('6.6.6', $links['composer-plugin-api']->getConstraint()->getPrettyString()); diff --git a/tests/Composer/Test/Package/RootAliasPackageTest.php b/tests/Composer/Test/Package/RootAliasPackageTest.php index f3db670a7..00ca7fa05 100644 --- a/tests/Composer/Test/Package/RootAliasPackageTest.php +++ b/tests/Composer/Test/Package/RootAliasPackageTest.php @@ -27,7 +27,7 @@ class RootAliasPackageTest extends TestCase $alias = new RootAliasPackage($root->reveal(), '1.0', '1.0.0.0'); $this->assertEmpty($alias->getRequires()); - $links = array(new Link('a', 'b', new MatchAllConstraint(), 'foo', 'self.version')); + $links = array(new Link('a', 'b', new MatchAllConstraint(), Link::TYPE_REQUIRE, 'self.version')); $alias->setRequires($links); $this->assertNotEmpty($alias->getRequires()); } @@ -39,7 +39,7 @@ class RootAliasPackageTest extends TestCase $alias = new RootAliasPackage($root->reveal(), '1.0', '1.0.0.0'); $this->assertEmpty($alias->getDevRequires()); - $links = array(new Link('a', 'b', new MatchAllConstraint(), 'foo', 'self.version')); + $links = array(new Link('a', 'b', new MatchAllConstraint(), Link::TYPE_DEV_REQUIRE, 'self.version')); $alias->setDevRequires($links); $this->assertNotEmpty($alias->getDevRequires()); } @@ -51,7 +51,7 @@ class RootAliasPackageTest extends TestCase $alias = new RootAliasPackage($root->reveal(), '1.0', '1.0.0.0'); $this->assertEmpty($alias->getConflicts()); - $links = array(new Link('a', 'b', new MatchAllConstraint(), 'foo', 'self.version')); + $links = array(new Link('a', 'b', new MatchAllConstraint(), Link::TYPE_CONFLICT, 'self.version')); $alias->setConflicts($links); $this->assertNotEmpty($alias->getConflicts()); } @@ -63,7 +63,7 @@ class RootAliasPackageTest extends TestCase $alias = new RootAliasPackage($root->reveal(), '1.0', '1.0.0.0'); $this->assertEmpty($alias->getProvides()); - $links = array(new Link('a', 'b', new MatchAllConstraint(), 'foo', 'self.version')); + $links = array(new Link('a', 'b', new MatchAllConstraint(), Link::TYPE_PROVIDE, 'self.version')); $alias->setProvides($links); $this->assertNotEmpty($alias->getProvides()); } @@ -75,7 +75,7 @@ class RootAliasPackageTest extends TestCase $alias = new RootAliasPackage($root->reveal(), '1.0', '1.0.0.0'); $this->assertEmpty($alias->getReplaces()); - $links = array(new Link('a', 'b', new MatchAllConstraint(), 'foo', 'self.version')); + $links = array(new Link('a', 'b', new MatchAllConstraint(), Link::TYPE_REPLACE, 'self.version')); $alias->setReplaces($links); $this->assertNotEmpty($alias->getReplaces()); } diff --git a/tests/Composer/Test/Plugin/PluginInstallerTest.php b/tests/Composer/Test/Plugin/PluginInstallerTest.php index 9af15a41a..2aa709e53 100644 --- a/tests/Composer/Test/Plugin/PluginInstallerTest.php +++ b/tests/Composer/Test/Plugin/PluginInstallerTest.php @@ -54,12 +54,12 @@ class PluginInstallerTest extends TestCase protected $directory; /** - * @var \PHPUnit\Framework\MockObject\MockObject + * @var \PHPUnit\Framework\MockObject\MockObject&\Composer\Installer\InstallationManager */ protected $im; /** - * @var \PHPUnit\Framework\MockObject\MockObject + * @var \PHPUnit\Framework\MockObject\MockObject&\Composer\Repository\InstalledRepositoryInterface */ protected $repository; diff --git a/tests/Composer/Test/Repository/PlatformRepositoryTest.php b/tests/Composer/Test/Repository/PlatformRepositoryTest.php index e2ba60806..30a464b24 100644 --- a/tests/Composer/Test/Repository/PlatformRepositoryTest.php +++ b/tests/Composer/Test/Repository/PlatformRepositoryTest.php @@ -13,6 +13,7 @@ namespace Composer\Test\Repository; use Composer\Package\Package; +use Composer\Package\PackageInterface; use Composer\Repository\PlatformRepository; use Composer\Test\TestCase; use PHPUnit\Framework\Assert; @@ -1189,7 +1190,7 @@ Linked Version => 1.2.11', } } - private function assertPackageLinks($context, array $expectedLinks, Package $sourcePackage, array $links) + private function assertPackageLinks($context, array $expectedLinks, PackageInterface $sourcePackage, array $links) { self::assertCount(count($expectedLinks), $links, sprintf('%s: expected package count to match', $context)); diff --git a/tests/Composer/Test/TestCase.php b/tests/Composer/Test/TestCase.php index c511e67bb..0b38c6d73 100644 --- a/tests/Composer/Test/TestCase.php +++ b/tests/Composer/Test/TestCase.php @@ -94,7 +94,7 @@ abstract class TestCase extends PolyfillTestCase $arrayLoader->parseLinks( $package->getName(), $package->getPrettyVersion(), - $opts['description'], + $opts['method'], $config[$type] ) ); diff --git a/tests/Composer/Test/Util/MetadataMinifierTest.php b/tests/Composer/Test/Util/MetadataMinifierTest.php index 043c3356c..fa69e928d 100644 --- a/tests/Composer/Test/Util/MetadataMinifierTest.php +++ b/tests/Composer/Test/Util/MetadataMinifierTest.php @@ -22,7 +22,7 @@ class MetadataMinifierTest extends TestCase public function testMinifyExpand() { $package1 = new CompletePackage('foo/bar', '2.0.0.0', '2.0.0'); - $package1->setScripts(array('foo' => 'bar')); + $package1->setScripts(array('foo' => array('bar'))); $package1->setLicense(array('MIT')); $package2 = new CompletePackage('foo/bar', '1.2.0.0', '1.2.0'); $package2->setLicense(array('GPL')); @@ -32,7 +32,7 @@ class MetadataMinifierTest extends TestCase $dumper = new ArrayDumper(); $minified = array( - array('name' => 'foo/bar', 'version' => '2.0.0', 'version_normalized' => '2.0.0.0', 'type' => 'library', 'scripts' => array('foo' => 'bar'), 'license' => array('MIT')), + array('name' => 'foo/bar', 'version' => '2.0.0', 'version_normalized' => '2.0.0.0', 'type' => 'library', 'scripts' => array('foo' => array('bar')), 'license' => array('MIT')), array('version' => '1.2.0', 'version_normalized' => '1.2.0.0', 'license' => array('GPL'), 'homepage' => 'https://example.org', 'scripts' => '__unset'), array('version' => '1.0.0', 'version_normalized' => '1.0.0.0', 'homepage' => '__unset'), ); diff --git a/tests/Composer/Test/Util/PackageSorterTest.php b/tests/Composer/Test/Util/PackageSorterTest.php index 3dc1535ec..23f5996a6 100644 --- a/tests/Composer/Test/Util/PackageSorterTest.php +++ b/tests/Composer/Test/Util/PackageSorterTest.php @@ -123,7 +123,7 @@ class PackageSorterTest extends TestCase $links = array(); foreach ($requires as $requireName) { - $links[] = new Link($package->getName(), $requireName, new MatchAllConstraint); + $links[$requireName] = new Link($package->getName(), $requireName, new MatchAllConstraint); } $package->setRequires($links);