1
0
Fork 0

Add types to `Downloader` (#10193)

pull/10211/head
Martin Herndl 2021-10-25 10:25:39 +02:00 committed by GitHub
parent b99e21259c
commit fa4d4e20e9
No known key found for this signature in database
GPG Key ID: 4AEE18F83AFDEB23
12 changed files with 161 additions and 19 deletions

View File

@ -54,9 +54,13 @@ abstract class ArchiveDownloader extends FileDownloader
/** /**
* {@inheritDoc} * {@inheritDoc}
*
* @param bool $output
*
* @return PromiseInterface
*
* @throws \RuntimeException * @throws \RuntimeException
* @throws \UnexpectedValueException * @throws \UnexpectedValueException
* @return PromiseInterface
*/ */
public function install(PackageInterface $package, $path, $output = true) public function install(PackageInterface $package, $path, $output = true)
{ {

View File

@ -81,7 +81,8 @@ class DownloadManager
/** /**
* Sets fine tuned preference settings for package level source/dist selection. * Sets fine tuned preference settings for package level source/dist selection.
* *
* @param array $preferences array of preferences by package patterns * @param array<string, string> $preferences array of preferences by package patterns
*
* @return DownloadManager * @return DownloadManager
*/ */
public function setPreferences(array $preferences) 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 * 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 * @return string
*/ */
private function normalizeTargetDir($dir) private function normalizeTargetDir($dir)

View File

@ -102,6 +102,8 @@ class FileDownloader implements DownloaderInterface, ChangeReportInterface
/** /**
* {@inheritDoc} * {@inheritDoc}
*
* @param bool $output
*/ */
public function download(PackageInterface $package, $path, PackageInterface $prevPackage = null, $output = true) public function download(PackageInterface $package, $path, PackageInterface $prevPackage = null, $output = true)
{ {
@ -324,6 +326,8 @@ class FileDownloader implements DownloaderInterface, ChangeReportInterface
/** /**
* {@inheritDoc} * {@inheritDoc}
*
* @param bool $output
*/ */
public function install(PackageInterface $package, $path, $output = true) public function install(PackageInterface $package, $path, $output = true)
{ {
@ -351,6 +355,8 @@ class FileDownloader implements DownloaderInterface, ChangeReportInterface
/** /**
* TODO mark private in v3 * TODO mark private in v3
* @protected This is public due to PHP 5.3 * @protected This is public due to PHP 5.3
*
* @return void
*/ */
public function clearLastCacheWrite(PackageInterface $package) public function clearLastCacheWrite(PackageInterface $package)
{ {
@ -363,6 +369,10 @@ class FileDownloader implements DownloaderInterface, ChangeReportInterface
/** /**
* TODO mark private in v3 * TODO mark private in v3
* @protected This is public due to PHP 5.3 * @protected This is public due to PHP 5.3
*
* @param string $path
*
* @return void
*/ */
public function addCleanupPath(PackageInterface $package, $path) public function addCleanupPath(PackageInterface $package, $path)
{ {
@ -372,6 +382,10 @@ class FileDownloader implements DownloaderInterface, ChangeReportInterface
/** /**
* TODO mark private in v3 * TODO mark private in v3
* @protected This is public due to PHP 5.3 * @protected This is public due to PHP 5.3
*
* @param string $path
*
* @return void
*/ */
public function removeCleanupPath(PackageInterface $package, $path) public function removeCleanupPath(PackageInterface $package, $path)
{ {
@ -406,6 +420,8 @@ class FileDownloader implements DownloaderInterface, ChangeReportInterface
/** /**
* {@inheritDoc} * {@inheritDoc}
*
* @param bool $output
*/ */
public function remove(PackageInterface $package, $path, $output = true) public function remove(PackageInterface $package, $path, $output = true)
{ {

View File

@ -19,6 +19,11 @@ namespace Composer\Downloader;
*/ */
class FilesystemException extends \Exception class FilesystemException extends \Exception
{ {
/**
* @param string $message
* @param int $code
* @param \Exception|null $previous
*/
public function __construct($message = '', $code = 0, \Exception $previous = null) public function __construct($message = '', $code = 0, \Exception $previous = null)
{ {
parent::__construct("Filesystem exception: \n".$message, $code, $previous); parent::__construct("Filesystem exception: \n".$message, $code, $previous);

View File

@ -21,6 +21,7 @@ use Composer\Util\Url;
use Composer\Util\Platform; use Composer\Util\Platform;
use Composer\Util\ProcessExecutor; use Composer\Util\ProcessExecutor;
use Composer\Cache; use Composer\Cache;
use React\Promise\PromiseInterface;
/** /**
* @author Jordi Boggiano <j.boggiano@seld.be> * @author Jordi Boggiano <j.boggiano@seld.be>
@ -119,8 +120,9 @@ class GitDownloader extends VcsDownloader implements DvcsDownloaderInterface
}; };
$this->gitUtil->runCommand($commandCallable, $url, $path, true); $this->gitUtil->runCommand($commandCallable, $url, $path, true);
if ($url !== $package->getSourceUrl()) { $sourceUrl = $package->getSourceUrl();
$this->updateOriginUrl($path, $package->getSourceUrl()); if ($url !== $sourceUrl && $sourceUrl !== null) {
$this->updateOriginUrl($path, $sourceUrl);
} else { } else {
$this->setPushUrl($path, $url); $this->setPushUrl($path, $url);
} }
@ -193,7 +195,7 @@ class GitDownloader extends VcsDownloader implements DvcsDownloaderInterface
$updateOriginUrl = true; $updateOriginUrl = true;
} }
} }
if ($updateOriginUrl) { if ($updateOriginUrl && $target->getSourceUrl() !== null) {
$this->updateOriginUrl($path, $target->getSourceUrl()); $this->updateOriginUrl($path, $target->getSourceUrl());
} }
@ -329,7 +331,7 @@ class GitDownloader extends VcsDownloader implements DvcsDownloaderInterface
} }
if (!$changes = $this->getLocalChanges($package, $path)) { if (!$changes = $this->getLocalChanges($package, $path)) {
return; return \React\Promise\resolve();
} }
if (!$this->io->isInteractive()) { if (!$this->io->isInteractive()) {
@ -398,6 +400,8 @@ class GitDownloader extends VcsDownloader implements DvcsDownloaderInterface
break; 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())); 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) protected function updateOriginUrl($path, $url)
{ {
$this->process->execute(sprintf('git remote set-url origin -- %s', ProcessExecutor::escape($url)), $output, $path); $this->process->execute(sprintf('git remote set-url origin -- %s', ProcessExecutor::escape($url)), $output, $path);
$this->setPushUrl($path, $url); $this->setPushUrl($path, $url);
} }
/**
* @param string $path
* @param string $url
*
* @return void
*/
protected function setPushUrl($path, $url) protected function setPushUrl($path, $url)
{ {
// set push url for github projects // 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 * @throws \RuntimeException
*/ */
protected function discardChanges($path) protected function discardChanges($path)
@ -532,10 +551,15 @@ class GitDownloader extends VcsDownloader implements DvcsDownloaderInterface
} }
$this->hasDiscardedChanges[$path] = true; $this->hasDiscardedChanges[$path] = true;
return \React\Promise\resolve();
} }
/** /**
* @param string $path * @param string $path
*
* @return PromiseInterface
*
* @throws \RuntimeException * @throws \RuntimeException
*/ */
protected function stashChanges($path) protected function stashChanges($path)
@ -546,10 +570,15 @@ class GitDownloader extends VcsDownloader implements DvcsDownloaderInterface
} }
$this->hasStashedChanges[$path] = true; $this->hasStashedChanges[$path] = true;
return \React\Promise\resolve();
} }
/** /**
* @param string $path * @param string $path
*
* @return void
*
* @throws \RuntimeException * @throws \RuntimeException
*/ */
protected function viewDiff($path) protected function viewDiff($path)
@ -562,6 +591,11 @@ class GitDownloader extends VcsDownloader implements DvcsDownloaderInterface
$this->io->writeError($output); $this->io->writeError($output);
} }
/**
* @param string $path
*
* @return string
*/
protected function normalizePath($path) protected function normalizePath($path)
{ {
if (Platform::isWindows() && strlen($path) > 0) { if (Platform::isWindows() && strlen($path) > 0) {

View File

@ -53,6 +53,12 @@ class GzipDownloader extends ArchiveDownloader
return \React\Promise\resolve(); return \React\Promise\resolve();
} }
/**
* @param string $file
* @param string $targetFilepath
*
* @return void
*/
private function extractUsingExt($file, $targetFilepath) private function extractUsingExt($file, $targetFilepath)
{ {
$archiveFile = gzopen($file, 'rb'); $archiveFile = gzopen($file, 'rb');

View File

@ -244,6 +244,11 @@ class PathDownloader extends FileDownloader implements VcsCapableDownloaderInter
return ': Mirroring from '.$package->getDistUrl(); return ': Mirroring from '.$package->getDistUrl();
} }
/**
* @param mixed[] $transportOptions
*
* @phpstan-return array{self::STRATEGY_*, non-empty-list<self::STRATEGY_*>}
*/
private function computeAllowedStrategies(array $transportOptions) private function computeAllowedStrategies(array $transportOptions)
{ {
// When symlink transport option is null, both symlink and mirror are allowed // When symlink transport option is null, both symlink and mirror are allowed

View File

@ -38,7 +38,7 @@ class PerforceDownloader extends VcsDownloader
public function doInstall(PackageInterface $package, $path, $url) public function doInstall(PackageInterface $package, $path, $url)
{ {
$ref = $package->getSourceReference(); $ref = $package->getSourceReference();
$label = $this->getLabelFromSourceReference($ref); $label = $this->getLabelFromSourceReference((string) $ref);
$this->io->writeError('Cloning ' . $ref); $this->io->writeError('Cloning ' . $ref);
$this->initPerforce($package, $path, $url); $this->initPerforce($package, $path, $url);
@ -53,6 +53,8 @@ class PerforceDownloader extends VcsDownloader
} }
/** /**
* @param string $ref
*
* @return string|null * @return string|null
*/ */
private function getLabelFromSourceReference($ref) private function getLabelFromSourceReference($ref)
@ -65,6 +67,12 @@ class PerforceDownloader extends VcsDownloader
return null; return null;
} }
/**
* @param string $path
* @param string $url
*
* @return void
*/
public function initPerforce(PackageInterface $package, $path, $url) public function initPerforce(PackageInterface $package, $path, $url)
{ {
if (!empty($this->perforce)) { if (!empty($this->perforce)) {
@ -115,7 +123,10 @@ class PerforceDownloader extends VcsDownloader
return $this->perforce->getCommitLogs($fromReference, $toReference); return $this->perforce->getCommitLogs($fromReference, $toReference);
} }
public function setPerforce($perforce) /**
* @return void
*/
public function setPerforce(Perforce $perforce)
{ {
$this->perforce = $perforce; $this->perforce = $perforce;
} }

View File

@ -16,6 +16,7 @@ use Composer\Package\PackageInterface;
use Composer\Util\Svn as SvnUtil; use Composer\Util\Svn as SvnUtil;
use Composer\Repository\VcsRepository; use Composer\Repository\VcsRepository;
use Composer\Util\ProcessExecutor; use Composer\Util\ProcessExecutor;
use React\Promise\PromiseInterface;
/** /**
* @author Ben Bieker <mail@ben-bieker.de> * @author Ben Bieker <mail@ben-bieker.de>
@ -131,7 +132,7 @@ class SvnDownloader extends VcsDownloader
protected function cleanChanges(PackageInterface $package, $path, $update) protected function cleanChanges(PackageInterface $package, $path, $update)
{ {
if (!$changes = $this->getLocalChanges($package, $path)) { if (!$changes = $this->getLocalChanges($package, $path)) {
return; return \React\Promise\resolve();
} }
if (!$this->io->isInteractive()) { if (!$this->io->isInteractive()) {
@ -182,6 +183,8 @@ class SvnDownloader extends VcsDownloader
break; 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"; return "Could not retrieve changes between $fromReference and $toReference due to missing revision information";
} }
/**
* @param string $path
*
* @return PromiseInterface
*/
protected function discardChanges($path) protected function discardChanges($path)
{ {
if (0 !== $this->process->execute('svn revert -R .', $output, $path)) { if (0 !== $this->process->execute('svn revert -R .', $output, $path)) {
throw new \RuntimeException("Could not reset changes\n\n:".$this->process->getErrorOutput()); throw new \RuntimeException("Could not reset changes\n\n:".$this->process->getErrorOutput());
} }
return \React\Promise\resolve();
} }
/** /**

View File

@ -17,47 +17,71 @@ namespace Composer\Downloader;
*/ */
class TransportException extends \RuntimeException class TransportException extends \RuntimeException
{ {
/** @var ?array<string, string> */ /** @var ?array<string> */
protected $headers; protected $headers;
/** @var ?string */ /** @var ?string */
protected $response; protected $response;
/** @var ?int */ /** @var ?int */
protected $statusCode; protected $statusCode;
/** @var ?array<mixed> */ /** @var array<mixed> */
protected $responseInfo = array(); protected $responseInfo = array();
/**
* @param array<string> $headers
*
* @return void
*/
public function setHeaders($headers) public function setHeaders($headers)
{ {
$this->headers = $headers; $this->headers = $headers;
} }
/**
* @return ?array<string>
*/
public function getHeaders() public function getHeaders()
{ {
return $this->headers; return $this->headers;
} }
/**
* @param ?string $response
*
* @return void
*/
public function setResponse($response) public function setResponse($response)
{ {
$this->response = $response; $this->response = $response;
} }
/**
* @return ?string
*/
public function getResponse() public function getResponse()
{ {
return $this->response; return $this->response;
} }
/**
* @param ?int $statusCode
*
* @return void
*/
public function setStatusCode($statusCode) public function setStatusCode($statusCode)
{ {
$this->statusCode = $statusCode; $this->statusCode = $statusCode;
} }
/**
* @return ?int
*/
public function getStatusCode() public function getStatusCode()
{ {
return $this->statusCode; return $this->statusCode;
} }
/** /**
* @return array * @return array<mixed>
*/ */
public function getResponseInfo() public function getResponseInfo()
{ {
@ -65,7 +89,9 @@ class TransportException extends \RuntimeException
} }
/** /**
* @param array $responseInfo * @param array<mixed> $responseInfo
*
* @return void
*/ */
public function setResponseInfo(array $responseInfo) public function setResponseInfo(array $responseInfo)
{ {

View File

@ -259,6 +259,9 @@ abstract class VcsDownloader implements DownloaderInterface, ChangeReportInterfa
* @param string $path * @param string $path
* @param bool $update if true (update) the changes can be stashed and reapplied after an update, * @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 * 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 * @throws \RuntimeException in case the operation must be aborted
*/ */
protected function cleanChanges(PackageInterface $package, $path, $update) 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) * 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 * @throws \RuntimeException in case the operation must be aborted or the patch does not apply cleanly
*/ */
protected function reapplyChanges($path) protected function reapplyChanges($path)
@ -336,6 +342,8 @@ abstract class VcsDownloader implements DownloaderInterface, ChangeReportInterfa
abstract protected function hasMetadataRepository($path); abstract protected function hasMetadataRepository($path);
/** /**
* @param string[] $urls
*
* @return string[] * @return string[]
*/ */
private function prepareUrls(array $urls) private function prepareUrls(array $urls)

View File

@ -324,7 +324,7 @@ class RemoteFilesystem
try { try {
$e->setResponse($this->decodeResult($result, $http_response_header)); $e->setResponse($this->decodeResult($result, $http_response_header));
} catch (\Exception $discarded) { } 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); $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|false $result
* @param string[] $http_response_header * @param string[] $http_response_header
* *
* @return string|false * @return string|null
*/ */
private function decodeResult($result, $http_response_header) 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; return $result;
} }
} }