From fa4d4e20e9cafcb76c3b3703b330a266d7e79158 Mon Sep 17 00:00:00 2001 From: Martin Herndl Date: Mon, 25 Oct 2021 10:25:39 +0200 Subject: [PATCH] Add types to `Downloader` (#10193) --- src/Composer/Downloader/ArchiveDownloader.php | 6 ++- src/Composer/Downloader/DownloadManager.php | 5 +- src/Composer/Downloader/FileDownloader.php | 16 +++++++ .../Downloader/FilesystemException.php | 5 ++ src/Composer/Downloader/GitDownloader.php | 48 ++++++++++++++++--- src/Composer/Downloader/GzipDownloader.php | 6 +++ src/Composer/Downloader/PathDownloader.php | 5 ++ .../Downloader/PerforceDownloader.php | 15 +++++- src/Composer/Downloader/SvnDownloader.php | 12 ++++- .../Downloader/TransportException.php | 34 +++++++++++-- src/Composer/Downloader/VcsDownloader.php | 10 +++- src/Composer/Util/RemoteFilesystem.php | 18 ++++++- 12 files changed, 161 insertions(+), 19 deletions(-) diff --git a/src/Composer/Downloader/ArchiveDownloader.php b/src/Composer/Downloader/ArchiveDownloader.php index 6e168369f..3fe66a693 100644 --- a/src/Composer/Downloader/ArchiveDownloader.php +++ b/src/Composer/Downloader/ArchiveDownloader.php @@ -54,9 +54,13 @@ abstract class ArchiveDownloader extends FileDownloader /** * {@inheritDoc} + * + * @param bool $output + * + * @return PromiseInterface + * * @throws \RuntimeException * @throws \UnexpectedValueException - * @return PromiseInterface */ public function install(PackageInterface $package, $path, $output = true) { diff --git a/src/Composer/Downloader/DownloadManager.php b/src/Composer/Downloader/DownloadManager.php index fb119be0c..fe737d1b5 100644 --- a/src/Composer/Downloader/DownloadManager.php +++ b/src/Composer/Downloader/DownloadManager.php @@ -81,7 +81,8 @@ class DownloadManager /** * Sets fine tuned preference settings for package level source/dist selection. * - * @param array $preferences array of preferences by package patterns + * @param array $preferences array of preferences by package patterns + * * @return DownloadManager */ public function setPreferences(array $preferences) @@ -453,6 +454,8 @@ class DownloadManager * * If any Installer provides a path with a trailing slash, this can cause bugs so make sure we remove them * + * @param string $dir + * * @return string */ private function normalizeTargetDir($dir) diff --git a/src/Composer/Downloader/FileDownloader.php b/src/Composer/Downloader/FileDownloader.php index e915d6995..d55c992ca 100644 --- a/src/Composer/Downloader/FileDownloader.php +++ b/src/Composer/Downloader/FileDownloader.php @@ -102,6 +102,8 @@ class FileDownloader implements DownloaderInterface, ChangeReportInterface /** * {@inheritDoc} + * + * @param bool $output */ public function download(PackageInterface $package, $path, PackageInterface $prevPackage = null, $output = true) { @@ -324,6 +326,8 @@ class FileDownloader implements DownloaderInterface, ChangeReportInterface /** * {@inheritDoc} + * + * @param bool $output */ public function install(PackageInterface $package, $path, $output = true) { @@ -351,6 +355,8 @@ class FileDownloader implements DownloaderInterface, ChangeReportInterface /** * TODO mark private in v3 * @protected This is public due to PHP 5.3 + * + * @return void */ public function clearLastCacheWrite(PackageInterface $package) { @@ -363,6 +369,10 @@ class FileDownloader implements DownloaderInterface, ChangeReportInterface /** * TODO mark private in v3 * @protected This is public due to PHP 5.3 + * + * @param string $path + * + * @return void */ public function addCleanupPath(PackageInterface $package, $path) { @@ -372,6 +382,10 @@ class FileDownloader implements DownloaderInterface, ChangeReportInterface /** * TODO mark private in v3 * @protected This is public due to PHP 5.3 + * + * @param string $path + * + * @return void */ public function removeCleanupPath(PackageInterface $package, $path) { @@ -406,6 +420,8 @@ class FileDownloader implements DownloaderInterface, ChangeReportInterface /** * {@inheritDoc} + * + * @param bool $output */ public function remove(PackageInterface $package, $path, $output = true) { diff --git a/src/Composer/Downloader/FilesystemException.php b/src/Composer/Downloader/FilesystemException.php index 891ab5e4b..f297e4b98 100644 --- a/src/Composer/Downloader/FilesystemException.php +++ b/src/Composer/Downloader/FilesystemException.php @@ -19,6 +19,11 @@ namespace Composer\Downloader; */ class FilesystemException extends \Exception { + /** + * @param string $message + * @param int $code + * @param \Exception|null $previous + */ public function __construct($message = '', $code = 0, \Exception $previous = null) { parent::__construct("Filesystem exception: \n".$message, $code, $previous); diff --git a/src/Composer/Downloader/GitDownloader.php b/src/Composer/Downloader/GitDownloader.php index 770a3f0b8..cdb222c35 100644 --- a/src/Composer/Downloader/GitDownloader.php +++ b/src/Composer/Downloader/GitDownloader.php @@ -21,6 +21,7 @@ use Composer\Util\Url; use Composer\Util\Platform; use Composer\Util\ProcessExecutor; use Composer\Cache; +use React\Promise\PromiseInterface; /** * @author Jordi Boggiano @@ -119,8 +120,9 @@ class GitDownloader extends VcsDownloader implements DvcsDownloaderInterface }; $this->gitUtil->runCommand($commandCallable, $url, $path, true); - if ($url !== $package->getSourceUrl()) { - $this->updateOriginUrl($path, $package->getSourceUrl()); + $sourceUrl = $package->getSourceUrl(); + if ($url !== $sourceUrl && $sourceUrl !== null) { + $this->updateOriginUrl($path, $sourceUrl); } else { $this->setPushUrl($path, $url); } @@ -193,7 +195,7 @@ class GitDownloader extends VcsDownloader implements DvcsDownloaderInterface $updateOriginUrl = true; } } - if ($updateOriginUrl) { + if ($updateOriginUrl && $target->getSourceUrl() !== null) { $this->updateOriginUrl($path, $target->getSourceUrl()); } @@ -329,7 +331,7 @@ class GitDownloader extends VcsDownloader implements DvcsDownloaderInterface } if (!$changes = $this->getLocalChanges($package, $path)) { - return; + return \React\Promise\resolve(); } if (!$this->io->isInteractive()) { @@ -398,6 +400,8 @@ class GitDownloader extends VcsDownloader implements DvcsDownloaderInterface break; } } + + return \React\Promise\resolve(); } /** @@ -485,12 +489,24 @@ class GitDownloader extends VcsDownloader implements DvcsDownloaderInterface throw new \RuntimeException(Url::sanitize('Failed to execute ' . $command . "\n\n" . $this->process->getErrorOutput())); } + /** + * @param string $path + * @param string $url + * + * @return void + */ protected function updateOriginUrl($path, $url) { $this->process->execute(sprintf('git remote set-url origin -- %s', ProcessExecutor::escape($url)), $output, $path); $this->setPushUrl($path, $url); } + /** + * @param string $path + * @param string $url + * + * @return void + */ protected function setPushUrl($path, $url) { // set push url for github projects @@ -521,7 +537,10 @@ class GitDownloader extends VcsDownloader implements DvcsDownloaderInterface } /** - * @param string $path + * @param string $path + * + * @return PromiseInterface + * * @throws \RuntimeException */ protected function discardChanges($path) @@ -532,10 +551,15 @@ class GitDownloader extends VcsDownloader implements DvcsDownloaderInterface } $this->hasDiscardedChanges[$path] = true; + + return \React\Promise\resolve(); } /** - * @param string $path + * @param string $path + * + * @return PromiseInterface + * * @throws \RuntimeException */ protected function stashChanges($path) @@ -546,10 +570,15 @@ class GitDownloader extends VcsDownloader implements DvcsDownloaderInterface } $this->hasStashedChanges[$path] = true; + + return \React\Promise\resolve(); } /** - * @param string $path + * @param string $path + * + * @return void + * * @throws \RuntimeException */ protected function viewDiff($path) @@ -562,6 +591,11 @@ class GitDownloader extends VcsDownloader implements DvcsDownloaderInterface $this->io->writeError($output); } + /** + * @param string $path + * + * @return string + */ protected function normalizePath($path) { if (Platform::isWindows() && strlen($path) > 0) { diff --git a/src/Composer/Downloader/GzipDownloader.php b/src/Composer/Downloader/GzipDownloader.php index df0cc908e..8b5caf474 100644 --- a/src/Composer/Downloader/GzipDownloader.php +++ b/src/Composer/Downloader/GzipDownloader.php @@ -53,6 +53,12 @@ class GzipDownloader extends ArchiveDownloader return \React\Promise\resolve(); } + /** + * @param string $file + * @param string $targetFilepath + * + * @return void + */ private function extractUsingExt($file, $targetFilepath) { $archiveFile = gzopen($file, 'rb'); diff --git a/src/Composer/Downloader/PathDownloader.php b/src/Composer/Downloader/PathDownloader.php index be1b1262d..3c04a0767 100644 --- a/src/Composer/Downloader/PathDownloader.php +++ b/src/Composer/Downloader/PathDownloader.php @@ -244,6 +244,11 @@ class PathDownloader extends FileDownloader implements VcsCapableDownloaderInter return ': Mirroring from '.$package->getDistUrl(); } + /** + * @param mixed[] $transportOptions + * + * @phpstan-return array{self::STRATEGY_*, non-empty-list} + */ private function computeAllowedStrategies(array $transportOptions) { // When symlink transport option is null, both symlink and mirror are allowed diff --git a/src/Composer/Downloader/PerforceDownloader.php b/src/Composer/Downloader/PerforceDownloader.php index 9172fa3ca..8a97dea53 100644 --- a/src/Composer/Downloader/PerforceDownloader.php +++ b/src/Composer/Downloader/PerforceDownloader.php @@ -38,7 +38,7 @@ class PerforceDownloader extends VcsDownloader public function doInstall(PackageInterface $package, $path, $url) { $ref = $package->getSourceReference(); - $label = $this->getLabelFromSourceReference($ref); + $label = $this->getLabelFromSourceReference((string) $ref); $this->io->writeError('Cloning ' . $ref); $this->initPerforce($package, $path, $url); @@ -53,6 +53,8 @@ class PerforceDownloader extends VcsDownloader } /** + * @param string $ref + * * @return string|null */ private function getLabelFromSourceReference($ref) @@ -65,6 +67,12 @@ class PerforceDownloader extends VcsDownloader return null; } + /** + * @param string $path + * @param string $url + * + * @return void + */ public function initPerforce(PackageInterface $package, $path, $url) { if (!empty($this->perforce)) { @@ -115,7 +123,10 @@ class PerforceDownloader extends VcsDownloader return $this->perforce->getCommitLogs($fromReference, $toReference); } - public function setPerforce($perforce) + /** + * @return void + */ + public function setPerforce(Perforce $perforce) { $this->perforce = $perforce; } diff --git a/src/Composer/Downloader/SvnDownloader.php b/src/Composer/Downloader/SvnDownloader.php index f36b04917..948e63aad 100644 --- a/src/Composer/Downloader/SvnDownloader.php +++ b/src/Composer/Downloader/SvnDownloader.php @@ -16,6 +16,7 @@ use Composer\Package\PackageInterface; use Composer\Util\Svn as SvnUtil; use Composer\Repository\VcsRepository; use Composer\Util\ProcessExecutor; +use React\Promise\PromiseInterface; /** * @author Ben Bieker @@ -131,7 +132,7 @@ class SvnDownloader extends VcsDownloader protected function cleanChanges(PackageInterface $package, $path, $update) { if (!$changes = $this->getLocalChanges($package, $path)) { - return; + return \React\Promise\resolve(); } if (!$this->io->isInteractive()) { @@ -182,6 +183,8 @@ class SvnDownloader extends VcsDownloader break; } } + + return \React\Promise\resolve(); } /** @@ -227,11 +230,18 @@ class SvnDownloader extends VcsDownloader return "Could not retrieve changes between $fromReference and $toReference due to missing revision information"; } + /** + * @param string $path + * + * @return PromiseInterface + */ protected function discardChanges($path) { if (0 !== $this->process->execute('svn revert -R .', $output, $path)) { throw new \RuntimeException("Could not reset changes\n\n:".$this->process->getErrorOutput()); } + + return \React\Promise\resolve(); } /** diff --git a/src/Composer/Downloader/TransportException.php b/src/Composer/Downloader/TransportException.php index a478e5807..92be261a6 100644 --- a/src/Composer/Downloader/TransportException.php +++ b/src/Composer/Downloader/TransportException.php @@ -17,47 +17,71 @@ namespace Composer\Downloader; */ class TransportException extends \RuntimeException { - /** @var ?array */ + /** @var ?array */ protected $headers; /** @var ?string */ protected $response; /** @var ?int */ protected $statusCode; - /** @var ?array */ + /** @var array */ protected $responseInfo = array(); + /** + * @param array $headers + * + * @return void + */ public function setHeaders($headers) { $this->headers = $headers; } + /** + * @return ?array + */ public function getHeaders() { return $this->headers; } + /** + * @param ?string $response + * + * @return void + */ public function setResponse($response) { $this->response = $response; } + /** + * @return ?string + */ public function getResponse() { return $this->response; } + /** + * @param ?int $statusCode + * + * @return void + */ public function setStatusCode($statusCode) { $this->statusCode = $statusCode; } + /** + * @return ?int + */ public function getStatusCode() { return $this->statusCode; } /** - * @return array + * @return array */ public function getResponseInfo() { @@ -65,7 +89,9 @@ class TransportException extends \RuntimeException } /** - * @param array $responseInfo + * @param array $responseInfo + * + * @return void */ public function setResponseInfo(array $responseInfo) { diff --git a/src/Composer/Downloader/VcsDownloader.php b/src/Composer/Downloader/VcsDownloader.php index 53c573679..d4e637a46 100644 --- a/src/Composer/Downloader/VcsDownloader.php +++ b/src/Composer/Downloader/VcsDownloader.php @@ -259,6 +259,9 @@ abstract class VcsDownloader implements DownloaderInterface, ChangeReportInterfa * @param string $path * @param bool $update if true (update) the changes can be stashed and reapplied after an update, * if false (remove) the changes should be assumed to be lost if the operation is not aborted + * + * @return PromiseInterface + * * @throws \RuntimeException in case the operation must be aborted */ protected function cleanChanges(PackageInterface $package, $path, $update) @@ -274,7 +277,10 @@ abstract class VcsDownloader implements DownloaderInterface, ChangeReportInterfa /** * Reapply previously stashes changes if applicable, only called after an update (regardless if successful or not) * - * @param string $path + * @param string $path + * + * @return void + * * @throws \RuntimeException in case the operation must be aborted or the patch does not apply cleanly */ protected function reapplyChanges($path) @@ -336,6 +342,8 @@ abstract class VcsDownloader implements DownloaderInterface, ChangeReportInterfa abstract protected function hasMetadataRepository($path); /** + * @param string[] $urls + * * @return string[] */ private function prepareUrls(array $urls) diff --git a/src/Composer/Util/RemoteFilesystem.php b/src/Composer/Util/RemoteFilesystem.php index 77942cafe..205c34a53 100644 --- a/src/Composer/Util/RemoteFilesystem.php +++ b/src/Composer/Util/RemoteFilesystem.php @@ -324,7 +324,7 @@ class RemoteFilesystem try { $e->setResponse($this->decodeResult($result, $http_response_header)); } catch (\Exception $discarded) { - $e->setResponse($result); + $e->setResponse($this->normalizeResult($result)); } $this->io->writeError('Content-Length mismatch, received '.Platform::strlen($result).' out of '.$contentLength.' bytes: (' . base64_encode($result).')', true, IOInterface::DEBUG); @@ -868,7 +868,7 @@ class RemoteFilesystem * @param string|false $result * @param string[] $http_response_header * - * @return string|false + * @return string|null */ private function decodeResult($result, $http_response_header) { @@ -891,6 +891,20 @@ class RemoteFilesystem } } + return $this->normalizeResult($result); + } + + /** + * @param string|false $result + * + * @return string|null + */ + private function normalizeResult($result) + { + if ($result === false) { + return null; + } + return $result; } }