Add return types to closures (#9)

main
Alexander Schranz 2 years ago committed by GitHub
parent 7b1fc4b2c8
commit 1321bfca36
No known key found for this signature in database
GPG Key ID: 4AEE18F83AFDEB23

@ -290,7 +290,7 @@ EOF;
$mainAutoload = $rootPackage->getAutoload();
if ($rootPackage->getTargetDir() && !empty($mainAutoload['psr-0'])) {
$levels = substr_count($filesystem->normalizePath($rootPackage->getTargetDir()), '/') + 1;
$prefixes = implode(', ', array_map(function ($prefix) {
$prefixes = implode(', ', array_map(function ($prefix): string {
return var_export($prefix, true);
}, array_keys($mainAutoload['psr-0'])));
$baseDirFromTargetDirCode = $filesystem->findShortestPathCode($targetDir, $basePath, true);
@ -554,7 +554,7 @@ EOF;
{
$rootPackageMap = array_shift($packageMap);
if (is_array($filteredDevPackages)) {
$packageMap = array_filter($packageMap, function ($item) use ($filteredDevPackages) {
$packageMap = array_filter($packageMap, function ($item) use ($filteredDevPackages): bool {
return !in_array($item[0]->getName(), $filteredDevPackages, true);
});
} elseif ($filteredDevPackages) {
@ -808,7 +808,7 @@ EOF;
ksort($requiredExtensions);
$formatToPhpVersionId = function (Bound $bound) {
$formatToPhpVersionId = function (Bound $bound): int {
if ($bound->isZero()) {
return 0;
}
@ -1229,7 +1229,7 @@ INITIALIZER;
$updir = null;
$path = Preg::replaceCallback(
'{^((?:(?:\\\\\\.){1,2}+/)+)}',
function ($matches) use (&$updir) {
function ($matches) use (&$updir): string {
if (isset($matches[1])) {
// undo preg_quote for the matched string
$updir = str_replace('\\.', '.', $matches[1]);
@ -1300,7 +1300,7 @@ INITIALIZER;
}
}
$add = function (PackageInterface $package) use (&$add, $packages, &$include, $replacedBy) {
$add = function (PackageInterface $package) use (&$add, $packages, &$include, $replacedBy): void {
foreach ($package->getRequires() as $link) {
$target = $link->getTarget();
if (isset($replacedBy[$target])) {
@ -1318,7 +1318,7 @@ INITIALIZER;
return array_filter(
$packageMap,
function ($item) use ($include) {
function ($item) use ($include): bool {
$package = $item[0];
foreach ($package->getNames() as $name) {
if (isset($include[$name])) {

@ -168,7 +168,7 @@ EOT
if (count($packages) > 1) {
$package = reset($packages);
$io->writeError('<info>Found multiple matches, selected '.$package->getPrettyString().'.</info>');
$io->writeError('Alternatives were '.implode(', ', array_map(function ($p) {
$io->writeError('Alternatives were '.implode(', ', array_map(function ($p): string {
return $p->getPrettyString();
}, $packages)).'.');
$io->writeError('<comment>Please use a more specific constraint to pick a different package.</comment>');

@ -90,7 +90,7 @@ class BaseDependencyCommand extends BaseCommand
$needles = array($needle);
if ($inverted) {
foreach ($packages as $package) {
$needles = array_merge($needles, array_map(function (Link $link) {
$needles = array_merge($needles, array_map(function (Link $link): string {
return $link->getTarget();
}, $package->getReplaces()));
}

@ -318,10 +318,10 @@ EOT
$values = $input->getArgument('setting-value'); // what the user is trying to add/change
$booleanValidator = function ($val) {
$booleanValidator = function ($val): bool {
return in_array($val, array('true', 'false', '1', '0'), true);
};
$booleanNormalizer = function ($val) {
$booleanNormalizer = function ($val): bool {
return $val !== 'false' && (bool) $val;
};
@ -331,7 +331,7 @@ EOT
'use-include-path' => array($booleanValidator, $booleanNormalizer),
'use-github-api' => array($booleanValidator, $booleanNormalizer),
'preferred-install' => array(
function ($val) {
function ($val): bool {
return in_array($val, array('auto', 'source', 'dist'), true);
},
function ($val) {
@ -339,7 +339,7 @@ EOT
},
),
'gitlab-protocol' => array(
function ($val) {
function ($val): bool {
return in_array($val, array('git', 'http', 'https'), true);
},
function ($val) {
@ -347,7 +347,7 @@ EOT
},
),
'store-auths' => array(
function ($val) {
function ($val): bool {
return in_array($val, array('true', 'false', 'prompt'), true);
},
function ($val) {
@ -389,7 +389,7 @@ EOT
'cache-ttl' => array('is_numeric', 'intval'),
'cache-files-ttl' => array('is_numeric', 'intval'),
'cache-files-maxsize' => array(
function ($val) {
function ($val): bool {
return Preg::isMatch('/^\s*([0-9.]+)\s*(?:([kmg])(?:i?b)?)?\s*$/i', $val);
},
function ($val) {
@ -397,7 +397,7 @@ EOT
},
),
'bin-compat' => array(
function ($val) {
function ($val): bool {
return in_array($val, array('auto', 'full', 'symlink'));
},
function ($val) {
@ -405,7 +405,7 @@ EOT
},
),
'discard-changes' => array(
function ($val) {
function ($val): bool {
return in_array($val, array('stash', 'true', 'false', '1', '0'), true);
},
function ($val) {
@ -427,7 +427,7 @@ EOT
'disable-tls' => array($booleanValidator, $booleanNormalizer),
'secure-http' => array($booleanValidator, $booleanNormalizer),
'cafile' => array(
function ($val) {
function ($val): bool {
return file_exists($val) && Filesystem::isReadable($val);
},
function ($val) {
@ -435,7 +435,7 @@ EOT
},
),
'capath' => array(
function ($val) {
function ($val): bool {
return is_dir($val) && Filesystem::isReadable($val);
},
function ($val) {
@ -447,7 +447,7 @@ EOT
'lock' => array($booleanValidator, $booleanNormalizer),
'allow-plugins' => array($booleanValidator, $booleanNormalizer),
'platform-check' => array(
function ($val) {
function ($val): bool {
return in_array($val, array('php-only', 'true', 'false', '1', '0'), true);
},
function ($val) {
@ -459,7 +459,7 @@ EOT
},
),
'use-parent-dir' => array(
function ($val) {
function ($val): bool {
return in_array($val, array('true', 'false', 'prompt'), true);
},
function ($val) {
@ -593,10 +593,10 @@ EOT
return $val;
}),
'minimum-stability' => array(
function ($val) {
function ($val): bool {
return isset(BasePackage::$stabilities[VersionParser::normalizeStability($val)]);
},
function ($val) {
function ($val): string {
return VersionParser::normalizeStability($val);
},
),

@ -511,7 +511,7 @@ EOT
private function checkPlatform()
{
$output = '';
$out = function ($msg, $style) use (&$output) {
$out = function ($msg, $style) use (&$output): void {
$output .= '<'.$style.'>'.$msg.'</'.$style.'>'.PHP_EOL;
};

@ -511,7 +511,7 @@ EOT
}
$namespace = array_map(
function ($part) {
function ($part): string {
$part = Preg::replace('/[^a-z0-9]/i', ' ', $part);
$part = ucwords($part);

@ -170,7 +170,7 @@ EOT
$packageListNames = array_keys($bucket);
$packages = array_filter(
$repo->getPackages(),
function ($package) use ($requires, $packageListNames) {
function ($package) use ($requires, $packageListNames): bool {
return in_array($package->getName(), $requires) && !in_array($package->getName(), $packageListNames);
}
);

@ -123,7 +123,7 @@ EOT
$installOrder[$op->getPackage()->getName()] = $index;
}
}
usort($uninstallOperations, function ($a, $b) use ($installOrder) {
usort($uninstallOperations, function ($a, $b) use ($installOrder): int {
return $installOrder[$b->getPackage()->getName()] - $installOrder[$a->getPackage()->getName()];
});

@ -116,7 +116,7 @@ EOT
if (count($input->getArgument('packages')) === 0) {
$this->getIO()->writeError('<info>No unused packages to remove</info>');
$this->setCode(function () {
$this->setCode(function (): int {
return 0;
});
}

@ -354,7 +354,7 @@ TAGSPUBKEY
$io->write('Open <info>https://composer.github.io/pubkeys.html</info> to find the latest keys');
$validator = function ($value) {
$validator = function ($value): string {
if (!Preg::isMatch('{^-----BEGIN PUBLIC KEY-----$}', trim($value))) {
throw new \UnexpectedValueException('Invalid input');
}

@ -223,7 +223,7 @@ EOT
if ($input->getOption('no-dev')) {
$packages = $this->filterRequiredPackages($installedRepo, $rootPkg);
$repos = $installedRepo = new InstalledRepository(array(new InstalledArrayRepository(array_map(function ($pkg) {
$repos = $installedRepo = new InstalledRepository(array(new InstalledArrayRepository(array_map(function ($pkg): \Composer\Package\PackageInterface {
return clone $pkg;
}, $packages))));
}
@ -320,7 +320,7 @@ EOT
if ($input->getOption('tree')) {
$rootRequires = $this->getRootRequires();
$packages = $installedRepo->getPackages();
usort($packages, function (BasePackage $a, BasePackage $b) {
usort($packages, function (BasePackage $a, BasePackage $b): int {
return strcmp((string) $a, (string) $b);
});
$arrayTree = array();

@ -163,7 +163,7 @@ EOT
foreach ($errors as $path => $changes) {
if ($input->getOption('verbose')) {
$indentedChanges = implode("\n", array_map(function ($line) {
$indentedChanges = implode("\n", array_map(function ($line): string {
return ' ' . ltrim($line);
}, explode("\n", $changes)));
$io->write('<info>'.$path.'</info>:');
@ -179,7 +179,7 @@ EOT
foreach ($unpushedChanges as $path => $changes) {
if ($input->getOption('verbose')) {
$indentedChanges = implode("\n", array_map(function ($line) {
$indentedChanges = implode("\n", array_map(function ($line): string {
return ' ' . ltrim($line);
}, explode("\n", $changes)));
$io->write('<info>'.$path.'</info>:');

@ -129,7 +129,7 @@ EOT
// extract --with shorthands from the allowlist
if (count($packages) > 0) {
$allowlistPackagesWithRequirements = array_filter($packages, function ($pkg) {
$allowlistPackagesWithRequirements = array_filter($packages, function ($pkg): bool {
return Preg::isMatch('{\S+[ =:]\S+}', $pkg);
});
foreach ($this->formatRequirements($allowlistPackagesWithRequirements) as $package => $constraint) {
@ -180,7 +180,7 @@ EOT
// the arguments lock/nothing/mirrors are not package names but trigger a mirror update instead
// they are further mutually exclusive with listing actual package names
$filteredPackages = array_filter($packages, function ($package) {
$filteredPackages = array_filter($packages, function ($package): bool {
return !in_array($package, array('lock', 'nothing', 'mirrors'), true);
});
$updateMirrors = $input->getOption('lock') || count($filteredPackages) != count($packages);

@ -193,13 +193,13 @@ EOT
}
if ($errors) {
$errors = array_map(function ($err) {
$errors = array_map(function ($err): string {
return '- ' . $err;
}, $errors);
array_unshift($errors, '# General errors');
}
if ($warnings) {
$warnings = array_map(function ($err) {
$warnings = array_map(function ($err): string {
return '- ' . $err;
}, $warnings);
array_unshift($warnings, '# General warnings');
@ -210,7 +210,7 @@ EOT
// If checking publish errors, display them as errors, otherwise just show them as warnings
if ($publishErrors) {
$publishErrors = array_map(function ($err) {
$publishErrors = array_map(function ($err): string {
return '- ' . $err;
}, $publishErrors);

@ -82,7 +82,7 @@ class Compiler
$phar->startBuffering();
$finderSort = function ($a, $b) {
$finderSort = function ($a, $b): int {
return strcmp(strtr($a->getRealPath(), '\\', '/'), strtr($b->getRealPath(), '\\', '/'));
};

@ -62,7 +62,7 @@ class JsonConfigSource implements ConfigSourceInterface
*/
public function addRepository($name, $config, $append = true)
{
$this->manipulateJson('addRepository', function (&$config, $repo, $repoConfig) use ($append) {
$this->manipulateJson('addRepository', function (&$config, $repo, $repoConfig) use ($append): void {
// if converting from an array format to hashmap format, and there is a {"packagist.org":false} repo, we have
// to convert it to "packagist.org": false key on the hashmap otherwise it fails schema validation
if (isset($config['repositories'])) {
@ -91,7 +91,7 @@ class JsonConfigSource implements ConfigSourceInterface
*/
public function removeRepository($name)
{
$this->manipulateJson('removeRepository', function (&$config, $repo) {
$this->manipulateJson('removeRepository', function (&$config, $repo): void {
unset($config['repositories'][$repo]);
}, $name);
}
@ -102,7 +102,7 @@ class JsonConfigSource implements ConfigSourceInterface
public function addConfigSetting($name, $value)
{
$authConfig = $this->authConfig;
$this->manipulateJson('addConfigSetting', function (&$config, $key, $val) use ($authConfig) {
$this->manipulateJson('addConfigSetting', function (&$config, $key, $val) use ($authConfig): void {
if (Preg::isMatch('{^(bitbucket-oauth|github-oauth|gitlab-oauth|gitlab-token|bearer|http-basic|platform)\.}', $key)) {
list($key, $host) = explode('.', $key, 2);
if ($authConfig) {
@ -122,7 +122,7 @@ class JsonConfigSource implements ConfigSourceInterface
public function removeConfigSetting($name)
{
$authConfig = $this->authConfig;
$this->manipulateJson('removeConfigSetting', function (&$config, $key) use ($authConfig) {
$this->manipulateJson('removeConfigSetting', function (&$config, $key) use ($authConfig): void {
if (Preg::isMatch('{^(bitbucket-oauth|github-oauth|gitlab-oauth|gitlab-token|bearer|http-basic|platform)\.}', $key)) {
list($key, $host) = explode('.', $key, 2);
if ($authConfig) {
@ -141,7 +141,7 @@ class JsonConfigSource implements ConfigSourceInterface
*/
public function addProperty($name, $value)
{
$this->manipulateJson('addProperty', function (&$config, $key, $val) {
$this->manipulateJson('addProperty', function (&$config, $key, $val): void {
if (strpos($key, 'extra.') === 0 || strpos($key, 'scripts.') === 0) {
$bits = explode('.', $key);
$last = array_pop($bits);
@ -164,7 +164,7 @@ class JsonConfigSource implements ConfigSourceInterface
*/
public function removeProperty($name)
{
$this->manipulateJson('removeProperty', function (&$config, $key) {
$this->manipulateJson('removeProperty', function (&$config, $key): void {
if (strpos($key, 'extra.') === 0 || strpos($key, 'scripts.') === 0) {
$bits = explode('.', $key);
$last = array_pop($bits);
@ -187,7 +187,7 @@ class JsonConfigSource implements ConfigSourceInterface
*/
public function addLink($type, $name, $value)
{
$this->manipulateJson('addLink', function (&$config, $type, $name, $value) {
$this->manipulateJson('addLink', function (&$config, $type, $name, $value): void {
$config[$type][$name] = $value;
}, $type, $name, $value);
}
@ -197,10 +197,10 @@ class JsonConfigSource implements ConfigSourceInterface
*/
public function removeLink($type, $name)
{
$this->manipulateJson('removeSubNode', function (&$config, $type, $name) {
$this->manipulateJson('removeSubNode', function (&$config, $type, $name): void {
unset($config[$type][$name]);
}, $type, $name);
$this->manipulateJson('removeMainKeyIfEmpty', function (&$config, $type) {
$this->manipulateJson('removeMainKeyIfEmpty', function (&$config, $type): void {
if (0 === count($config[$type])) {
unset($config[$type]);
}

@ -94,14 +94,14 @@ class Application extends BaseApplication
if (!$shutdownRegistered) {
if (function_exists('pcntl_async_signals') && function_exists('pcntl_signal')) {
pcntl_async_signals(true);
pcntl_signal(SIGINT, function ($sig) {
pcntl_signal(SIGINT, function ($sig): void {
exit(130);
});
}
$shutdownRegistered = true;
register_shutdown_function(function () {
register_shutdown_function(function (): void {
$lastError = error_get_last();
if ($lastError && $lastError['message'] &&
@ -291,7 +291,7 @@ class Application extends BaseApplication
}
// Check system temp folder for usability as it can cause weird runtime issues otherwise
Silencer::call(function () use ($io) {
Silencer::call(function () use ($io): void {
$tempfile = sys_get_temp_dir() . '/temp-' . md5(microtime());
if (!(file_put_contents($tempfile, __FILE__) && (file_get_contents($tempfile) == __FILE__) && unlink($tempfile) && !file_exists($tempfile))) {
$io->writeError(sprintf('<error>PHP temp directory (%s) does not exist or is not writable to Composer. Set sys_temp_dir in your php.ini</error>', sys_get_temp_dir()));

@ -66,7 +66,7 @@ class DefaultPolicy implements PolicyInterface
$packages = $this->groupLiteralsByName($pool, $literals);
foreach ($packages as &$nameLiterals) {
usort($nameLiterals, function ($a, $b) use ($pool, $requiredPackage) {
usort($nameLiterals, function ($a, $b) use ($pool, $requiredPackage): int {
return $this->compareByPriority($pool, $pool->literalToPackage($a), $pool->literalToPackage($b), $requiredPackage, true);
});
}
@ -79,7 +79,7 @@ class DefaultPolicy implements PolicyInterface
$selected = \call_user_func_array('array_merge', array_values($packages));
// now sort the result across all packages to respect replaces across packages
usort($selected, function ($a, $b) use ($pool, $requiredPackage) {
usort($selected, function ($a, $b) use ($pool, $requiredPackage): int {
return $this->compareByPriority($pool, $pool->literalToPackage($a), $pool->literalToPackage($b), $requiredPackage);
});

@ -152,7 +152,7 @@ class LockTransaction extends Transaction
}
}
usort($usedAliases, function ($a, $b) {
usort($usedAliases, function ($a, $b): int {
return strcmp($a['package'], $b['package']);
});

@ -520,7 +520,7 @@ class PoolBuilder
$matches = array();
if (isset($rootRequires[$name])) {
return array_map(function (PackageInterface $package) use ($name) {
return array_map(function (PackageInterface $package) use ($name): string {
if ($name !== $package->getName()) {
return $package->getName() .' (via replace of '.$name.')';
}

@ -286,7 +286,7 @@ class Problem
if ($packages = $repositorySet->findPackages($packageName, $constraint)) {
$rootReqs = $repositorySet->getRootRequires();
if (isset($rootReqs[$packageName])) {
$filtered = array_filter($packages, function ($p) use ($rootReqs, $packageName) {
$filtered = array_filter($packages, function ($p) use ($rootReqs, $packageName): bool {
return $rootReqs[$packageName]->matches(new Constraint('==', $p->getVersion()));
});
if (0 === count($filtered)) {
@ -296,7 +296,7 @@ class Problem
if ($lockedPackage) {
$fixedConstraint = new Constraint('==', $lockedPackage->getVersion());
$filtered = array_filter($packages, function ($p) use ($fixedConstraint) {
$filtered = array_filter($packages, function ($p) use ($fixedConstraint): bool {
return $fixedConstraint->matches(new Constraint('==', $p->getVersion()));
});
if (0 === count($filtered)) {
@ -304,7 +304,7 @@ class Problem
}
}
$nonLockedPackages = array_filter($packages, function ($p) {
$nonLockedPackages = array_filter($packages, function ($p): bool {
return !$p->getRepository() instanceof LockArrayRepository;
});
@ -360,7 +360,7 @@ class Problem
if ($providers = $repositorySet->getProviders($packageName)) {
$maxProviders = 20;
$providersStr = implode(array_map(function ($p) {
$providersStr = implode(array_map(function ($p): string {
$description = $p['description'] ? ' '.substr($p['description'], 0, 100) : '';
return " - ${p['name']}".$description."\n";

@ -281,7 +281,7 @@ abstract class Rule
return 'No package found to satisfy root composer.json require '.$packageName.($constraint ? ' '.$constraint->getPrettyString() : '');
}
$packagesNonAlias = array_values(array_filter($packages, function ($p) {
$packagesNonAlias = array_values(array_filter($packages, function ($p): bool {
return !($p instanceof AliasPackage);
}));
if (count($packagesNonAlias) === 1) {

@ -110,7 +110,7 @@ class RuleWatchGraph
if (!$node->getRule()->isDisabled() && !$decisions->satisfy($otherWatch)) {
$ruleLiterals = $node->getRule()->getLiterals();
$alternativeLiterals = array_filter($ruleLiterals, function ($ruleLiteral) use ($literal, $otherWatch, $decisions) {
$alternativeLiterals = array_filter($ruleLiterals, function ($ruleLiteral) use ($literal, $otherWatch, $decisions): bool {
return $literal !== $ruleLiteral &&
$otherWatch !== $ruleLiteral &&
!$decisions->conflict($ruleLiteral);

@ -71,7 +71,7 @@ class Transaction
*/
private function setResultPackageMaps($resultPackages): void
{
$packageSort = function (PackageInterface $a, PackageInterface $b) {
$packageSort = function (PackageInterface $a, PackageInterface $b): int {
// sort alias packages by the same name behind their non alias version
if ($a->getName() == $b->getName()) {
if ($a instanceof AliasPackage != $b instanceof AliasPackage) {
@ -289,7 +289,7 @@ class Transaction
// is this a downloads modifying plugin or a dependency of one?
if ($isDownloadsModifyingPlugin || count(array_intersect($package->getNames(), $dlModifyingPluginRequires))) {
// get the package's requires, but filter out any platform requirements
$requires = array_filter(array_keys($package->getRequires()), function ($req) {
$requires = array_filter(array_keys($package->getRequires()), function ($req): bool {
return !PlatformRepository::isPlatformPackage($req);
});
@ -314,7 +314,7 @@ class Transaction
// is this a plugin or a dependency of a plugin?
if ($isPlugin || count(array_intersect($package->getNames(), $pluginRequires))) {
// get the package's requires, but filter out any platform requirements
$requires = array_filter(array_keys($package->getRequires()), function ($req) {
$requires = array_filter(array_keys($package->getRequires()), function ($req): bool {
return !PlatformRepository::isPlatformPackage($req);
});

@ -116,7 +116,7 @@ abstract class ArchiveDownloader extends FileDownloader
$promise = \React\Promise\resolve();
}
return $promise->then(function () use ($package, $filesystem, $fileName, $temporaryDir, $path) {
return $promise->then(function () use ($package, $filesystem, $fileName, $temporaryDir, $path): \React\Promise\PromiseInterface {
$filesystem->unlink($fileName);
/**
@ -125,7 +125,7 @@ abstract class ArchiveDownloader extends FileDownloader
* @param string $dir Directory
* @return \SplFileInfo[]
*/
$getFolderContent = function ($dir) {
$getFolderContent = function ($dir): array {
$finder = Finder::create()
->ignoreVCS(false)
->ignoreDotFiles(false)

@ -330,9 +330,14 @@ class DownloadManager
// if downloader type changed, or update failed and user asks for reinstall,
// we wipe the dir and do a new install instead of updating it
$promise = $initialDownloader->remove($initial, $targetDir);
if ($promise) {
return $promise->then(function ($res) use ($target, $targetDir) {
return $this->install($target, $targetDir);
if ($promise instanceof PromiseInterface) {
return $promise->then(function ($res) use ($target, $targetDir): PromiseInterface {
$promise = $this->install($target, $targetDir);
if ($promise instanceof PromiseInterface) {
return $promise;
}
return \React\Promise\resolve();
});
}
@ -432,7 +437,7 @@ class DownloadManager
&& !(!$prevPackage->isDev() && $prevPackage->getInstallationSource() === 'dist' && $package->isDev())
) {
$prevSource = $prevPackage->getInstallationSource();
usort($sources, function ($a, $b) use ($prevSource) {
usort($sources, function ($a, $b) use ($prevSource): int {
return $a === $prevSource ? -1 : 1;
});

@ -118,7 +118,7 @@ class FileDownloader implements DownloaderInterface, ChangeReportInterface
throw new \InvalidArgumentException('The given package is missing url information');
}
$cacheKeyGenerator = function (PackageInterface $package, $key) {
$cacheKeyGenerator = function (PackageInterface $package, $key): string {
$cacheKey = sha1($key);
return $package->getName().'/'.$cacheKey.'.'.$package->getDistType();
@ -195,7 +195,7 @@ class FileDownloader implements DownloaderInterface, ChangeReportInterface
->then($accept, $reject);
}
return $result->then(function ($result) use ($fileName, $checksum, $url, $package, $eventDispatcher) {
return $result->then(function ($result) use ($fileName, $checksum, $url, $package, $eventDispatcher): string {
// in case of retry, the first call's Promise chain finally calls this twice at the end,
// once with $result being the returned $fileName from $accept, and then once for every
// failed request with a null result, which can be skipped.
@ -221,7 +221,7 @@ class FileDownloader implements DownloaderInterface, ChangeReportInterface
});
};
$accept = function ($response) use ($cache, $package, $fileName, &$urls) {
$accept = function ($response) use ($cache, $package, $fileName, &$urls): string {
$url = reset($urls);
$cacheKey = $url['cacheKey'];
FileDownloader::$downloadMetadata[$package->getName()] = @filesize($fileName) ?: $response->getHeader('Content-Length') ?: '?';
@ -407,10 +407,13 @@ class FileDownloader implements DownloaderInterface, ChangeReportInterface
$promise = \React\Promise\resolve();
}
return $promise->then(function () use ($target, $path) {
return $promise->then(function () use ($target, $path): PromiseInterface {
$promise = $this->install($target, $path, false);
if ($promise instanceof PromiseInterface) {
return $promise;
}
return $promise;
return \React\Promise\resolve();
});
}
@ -426,7 +429,7 @@ class FileDownloader implements DownloaderInterface, ChangeReportInterface
}
$promise = $this->filesystem->removeDirectoryAsync($path);
return $promise->then(function ($result) use ($path) {
return $promise->then(function ($result) use ($path): void {
if (!$result) {
throw new \RuntimeException('Could not completely delete '.$path.', aborting.');
}

@ -114,7 +114,7 @@ class GitDownloader extends VcsDownloader implements DvcsDownloaderInterface
$this->io->writeError($msg);
$commandCallable = function ($url) use ($path, $command, $cachePath) {
$commandCallable = function ($url) use ($path, $command, $cachePath): string {
return str_replace(
array('%url%', '%path%', '%cachePath%', '%sanitizedUrl%'),
array(
@ -172,7 +172,7 @@ class GitDownloader extends VcsDownloader implements DvcsDownloaderInterface
$this->io->writeError($msg);
$commandCallable = function ($url) use ($ref, $command, $cachePath) {
$commandCallable = function ($url) use ($ref, $command, $cachePath): string {
return str_replace(
array('%url%', '%ref%', '%cachePath%', '%sanitizedUrl%'),
array(
@ -358,7 +358,7 @@ class GitDownloader extends VcsDownloader implements DvcsDownloaderInterface
return parent::cleanChanges($package, $path, $update);
}
$changes = array_map(function ($elem) {
$changes = array_map(function ($elem): string {
return ' '.$elem;
}, Preg::split('{\s*\r?\n\s*}', $changes));
$this->io->writeError(' <error>'.$package->getPrettyName().' has modified files:</error>');

@ -41,7 +41,7 @@ class HgDownloader extends VcsDownloader
{
$hgUtils = new HgUtils($this->io, $this->config, $this->process);
$cloneCommand = function ($url) use ($path) {
$cloneCommand = function ($url) use ($path): string {
return sprintf('hg clone -- %s %s', ProcessExecutor::escape($url), ProcessExecutor::escape($path));
};
@ -70,7 +70,7 @@ class HgDownloader extends VcsDownloader
throw new \RuntimeException('The .hg directory is missing from '.$path.', see https://getcomposer.org/commit-deps for more information');
}
$command = function ($url) use ($ref) {
$command = function ($url) use ($ref): string {
return sprintf('hg pull -- %s && hg up -- %s', ProcessExecutor::escape($url), ProcessExecutor::escape($ref));
};

@ -144,7 +144,7 @@ class SvnDownloader extends VcsDownloader
return parent::cleanChanges($package, $path, $update);
}
$changes = array_map(function ($elem) {
$changes = array_map(function ($elem): string {
return ' '.$elem;
}, Preg::split('{\s*\r?\n\s*}', $changes));
$countChanges = count($changes);

@ -200,7 +200,7 @@ abstract class VcsDownloader implements DownloaderInterface, ChangeReportInterfa
}
if (trim($logs)) {
$logs = implode("\n", array_map(function ($line) {
$logs = implode("\n", array_map(function ($line): string {
return ' ' . $line;
}, explode("\n", $logs)));

@ -127,7 +127,7 @@ class ZipDownloader extends ArchiveDownloader
$executable = $commandSpec[0];
$io = $this->io;
$tryFallback = function ($processError) use ($isLastChance, $io, $file, $path, $package, $executable) {
$tryFallback = function ($processError) use ($isLastChance, $io, $file, $path, $package, $executable): \React\Promise\PromiseInterface {
if ($isLastChance) {
throw $processError;
}

@ -56,7 +56,7 @@ class BufferIO extends ConsoleIO
$output = stream_get_contents($this->output->getStream());
$output = Preg::replaceCallback("{(?<=^|\n|\x08)(.+?)(\x08+)}", function ($matches) {
$output = Preg::replaceCallback("{(?<=^|\n|\x08)(.+?)(\x08+)}", function ($matches): string {
$pre = strip_tags($matches[1]);
if (strlen($pre) === strlen($matches[2])) {

@ -175,7 +175,7 @@ class ConsoleIO extends BaseIO
if (null !== $this->startTime) {
$memoryUsage = memory_get_usage() / 1024 / 1024;
$timeSpent = microtime(true) - $this->startTime;
$messages = array_map(function ($message) use ($memoryUsage, $timeSpent) {
$messages = array_map(function ($message) use ($memoryUsage, $timeSpent): string {
return sprintf('[%.1fMiB/%.2fs] %s', $memoryUsage, $timeSpent, $message);
}, (array) $messages);
}

@ -522,7 +522,7 @@ class Installer
}
}
$sortByName = function ($a, $b) {
$sortByName = function ($a, $b): int {
if ($a instanceof UpdateOperation) {
$a = $a->getTargetPackage()->getName();
} else {

@ -199,18 +199,18 @@ class InstallationManager
$loop = $this->loop;
$io = $this->io;
$runCleanup = function () use (&$cleanupPromises, $loop) {
$runCleanup = function () use (&$cleanupPromises, $loop): void {
$promises = array();
$loop->abortJobs();
foreach ($cleanupPromises as $cleanup) {
$promises[] = new \React\Promise\Promise(function ($resolve, $reject) use ($cleanup) {
$promises[] = new \React\Promise\Promise(function ($resolve, $reject) use ($cleanup): void {
$promise = $cleanup();
if (!$promise instanceof PromiseInterface) {
$resolve();
} else {
$promise->then(function () use ($resolve) {
$promise->then(function () use ($resolve): void {
$resolve();
});
}
@ -229,7 +229,7 @@ class InstallationManager
if ($handleInterruptsUnix) {
pcntl_async_signals(true);
$prevHandler = pcntl_signal_get_handler(SIGINT);
pcntl_signal(SIGINT, function ($sig) use ($runCleanup, $prevHandler, $io) {
pcntl_signal(SIGINT, function ($sig) use ($runCleanup, $prevHandler, $io): void {
$io->writeError('Received SIGINT, aborting', true, IOInterface::DEBUG);
$runCleanup();
@ -241,7 +241,7 @@ class InstallationManager
});
}
if ($handleInterruptsWindows) {
$windowsHandler = function ($event) use ($runCleanup, $io) {
$windowsHandler = function ($event) use ($runCleanup, $io): void {
if ($event !== PHP_WINDOWS_EVENT_CTRL_C) {
return;
}
@ -446,15 +446,15 @@ class InstallationManager
$promise = $promise->then(function () use ($opType, $repo, $operation) {
return $this->$opType($repo, $operation);
})->then($cleanupPromises[$index])
->then(function () use ($devMode, $repo) {
->then(function () use ($devMode, $repo): void {
$repo->write($devMode, $this);
}, function ($e) use ($opType, $package, $io) {
}, function ($e) use ($opType, $package, $io): void {
$io->writeError(' <error>' . ucfirst($opType) .' of '.$package->getPrettyName().' failed</error>');
throw $e;
});
$postExecCallbacks[] = function () use ($opType, $runScripts, $dispatcher, $devMode, $repo, $allOperations, $operation) {
$postExecCallbacks[] = function () use ($opType, $runScripts, $dispatcher, $devMode, $repo, $allOperations, $operation): void {
$event = 'Composer\Installer\PackageEvents::POST_PACKAGE_'.strtoupper($opType);
if (defined($event) && $runScripts && $dispatcher) {
$dispatcher->dispatchPackageEvent(constant($event), $devMode, $repo, $allOperations, $operation);
@ -548,8 +548,13 @@ class InstallationManager
}
$installer = $this->getInstaller($targetType);
$promise = $promise->then(function () use ($installer, $repo, $target) {
return $installer->install($repo, $target);
$promise = $promise->then(function () use ($installer, $repo, $target): PromiseInterface {
$promise = $installer->install($repo, $target);
if ($promise instanceof PromiseInterface) {
return $promise;
}
return \React\Promise\resolve();
});
}

@ -148,7 +148,7 @@ class LibraryInstaller implements InstallerInterface, BinaryPresenceInterface
$binaryInstaller = $this->binaryInstaller;
$installPath = $this->getInstallPath($package);
return $promise->then(function () use ($binaryInstaller, $installPath, $package, $repo) {
return $promise->then(function () use ($binaryInstaller, $installPath, $package, $repo): void {
$binaryInstaller->installBinaries($package, $installPath);
if (!$repo->hasPackage($package)) {
$repo->addPackage(clone $package);
@ -176,7 +176,7 @@ class LibraryInstaller implements InstallerInterface, BinaryPresenceInterface
$binaryInstaller = $this->binaryInstaller;
$installPath = $this->getInstallPath($target);
return $promise->then(function () use ($binaryInstaller, $installPath, $target, $initial, $repo) {
return $promise->then(function () use ($binaryInstaller, $installPath, $target, $initial, $repo): void {
$binaryInstaller->installBinaries($target, $installPath);
$repo->removePackage($initial);
if (!$repo->hasPackage($target)) {
@ -203,7 +203,7 @@ class LibraryInstaller implements InstallerInterface, BinaryPresenceInterface
$downloadPath = $this->getPackageBasePath($package);
$filesystem = $this->filesystem;
return $promise->then(function () use ($binaryInstaller, $filesystem, $downloadPath, $package, $repo) {
return $promise->then(function () use ($binaryInstaller, $filesystem, $downloadPath, $package, $repo): void {
$binaryInstaller->removeBinaries($package);
$repo->removePackage($package);
@ -288,8 +288,13 @@ class LibraryInstaller implements InstallerInterface, BinaryPresenceInterface
$promise = \React\Promise\resolve();
}
return $promise->then(function () use ($target) {
return $this->installCode($target);
return $promise->then(function () use ($target): PromiseInterface {
$promise = $this->installCode($target);
if ($promise instanceof PromiseInterface) {
return $promise;
}
return \React\Promise\resolve();
});
}

@ -66,7 +66,7 @@ class PluginInstaller extends LibraryInstaller
$promise = \React\Promise\resolve();
}
return $promise->then(function () use ($package, $repo) {
return $promise->then(function () use ($package, $repo): void {
try {
Platform::workaroundFilesystemIssues();
$this->getPluginManager()->registerPackage($package, true);
@ -86,7 +86,7 @@ class PluginInstaller extends LibraryInstaller
$promise = \React\Promise\resolve();
}
return $promise->then(function () use ($initial, $target, $repo) {
return $promise->then(function () use ($initial, $target, $repo): void {
try {
Platform::workaroundFilesystemIssues();
$this->getPluginManager()->deactivatePackage($initial);

@ -198,7 +198,7 @@ class SuggestedPackagesReporter
$sourceFilter = array();
if ($onlyDependentsOf) {
$sourceFilter = array_map(function ($link) {
$sourceFilter = array_map(function ($link): string {
return $link->getTarget();
}, array_merge($onlyDependentsOf->getRequires(), $onlyDependentsOf->getDevRequires()));
$sourceFilter[] = $onlyDependentsOf->getName();

@ -94,7 +94,7 @@ class JsonManipulator
// update existing link
$existingPackage = $packageMatches['package'];
$packageRegex = str_replace('/', '\\\\?/', preg_quote($existingPackage));
$links = Preg::replaceCallback('{'.self::$DEFINES.'"'.$packageRegex.'"(?P<separator>\s*:\s*)(?&string)}ix', function ($m) use ($existingPackage, $constraint) {
$links = Preg::replaceCallback('{'.self::$DEFINES.'"'.$packageRegex.'"(?P<separator>\s*:\s*)(?&string)}ix', function ($m) use ($existingPackage, $constraint): string {
return JsonFile::encode(str_replace('\\/', '/', $existingPackage)) . $m['separator'] . '"' . $constraint . '"';
}, $links);
} else {
@ -135,7 +135,7 @@ class JsonManipulator
*/
private function sortPackages(array &$packages = array()): void
{
$prefix = function ($requirement) {
$prefix = function ($requirement): string {
if (PlatformRepository::isPlatformPackage($requirement)) {
return Preg::replace(
array(
@ -159,7 +159,7 @@ class JsonManipulator
return '5-'.$requirement;
};
uksort($packages, function ($a, $b) use ($prefix) {
uksort($packages, function ($a, $b) use ($prefix): int {
return strnatcmp($prefix($a), $prefix($b));
});
}
@ -297,7 +297,7 @@ class JsonManipulator
// child exists
$childRegex = '{'.self::$DEFINES.'(?P<start>"'.preg_quote($name).'"\s*:\s*)(?P<content>(?&json))(?P<end>,?)}x';
if (Preg::isMatch($childRegex, $children, $matches)) {
$children = Preg::replaceCallback($childRegex, function ($matches) use ($subName, $value) {
$children = Preg::replaceCallback($childRegex, function ($matches) use ($subName, $value): string {
if ($subName !== null) {
$curVal = json_decode($matches['content'], true);
if (!is_array($curVal)) {
@ -351,7 +351,7 @@ class JsonManipulator
}
}
$this->contents = Preg::replaceCallback($nodeRegex, function ($m) use ($children) {
$this->contents = Preg::replaceCallback($nodeRegex, function ($m) use ($children): string {
return $m['start'] . $children . $m['end'];
}, $this->contents);
@ -436,7 +436,7 @@ class JsonManipulator
$newline = $this->newline;
$indent = $this->indent;
$this->contents = Preg::replaceCallback($nodeRegex, function ($matches) use ($indent, $newline) {
$this->contents = Preg::replaceCallback($nodeRegex, function ($matches) use ($indent, $newline): string {
return $matches['start'] . '{' . $newline . $indent . '}' . $matches['end'];
}, $this->contents);
@ -450,7 +450,7 @@ class JsonManipulator
return true;
}
$this->contents = Preg::replaceCallback($nodeRegex, function ($matches) use ($name, $subName, $childrenClean) {
$this->contents = Preg::replaceCallback($nodeRegex, function ($matches) use ($name, $subName, $childrenClean): string {
if ($subName !== null) {
$curVal = json_decode($matches['content'], true);
unset($curVal[$name][$subName]);

@ -57,7 +57,7 @@ class ArchivableFilesFinder extends \FilterIterator
$this->finder = new Finder();
$filter = function (\SplFileInfo $file) use ($sources, $filters, $fs) {
$filter = function (\SplFileInfo $file) use ($sources, $filters, $fs): bool {
if ($file->isLink() && strpos($file->getRealPath(), $sources) !== 0) {
return false;
}

@ -101,7 +101,7 @@ class ArchiveManager
$nameParts[] = substr(sha1($package->getSourceReference()), 0, 6);
}
$name = implode('-', array_filter($nameParts, function ($p) {
$name = implode('-', array_filter($nameParts, function ($p): bool {
return !empty($p);
}));

@ -95,7 +95,7 @@ abstract class BaseExcludeFilter
},
$lines
),
function ($pattern) {
function ($pattern): bool {
return $pattern !== null;
}
);

@ -274,7 +274,7 @@ abstract class BasePackage implements PackageInterface
public static function packageNamesToRegexp(array $packageNames, $wrap = '{^(?:%s)$}iD')
{
$packageNames = array_map(
function ($packageName) {
function ($packageName): string {
return BasePackage::packageNameToRegexp($packageName, '%s');
},
$packageNames

@ -357,7 +357,7 @@ class Locker
{
// keep old default branch names normalized to DEFAULT_BRANCH_ALIAS for BC as that is how Composer 1 outputs the lock file
// when loading the lock file the version is anyway ignored in Composer 2, so it has no adverse effect
$aliases = array_map(function ($alias) {
$aliases = array_map(function ($alias): array {
if (in_array($alias['version'], array('dev-master', 'dev-trunk', 'dev-default'), true)) {
$alias['version'] = VersionParser::DEFAULT_BRANCH_ALIAS;
}

@ -296,7 +296,7 @@ class VersionGuesser
// sort local branches first then remote ones
// and sort numeric branches below named ones, to make sure if the branch has the same distance from main and 1.10 and 1.9 for example, main is picked
// and sort using natural sort so that 1.10 will appear before 1.9
usort($branches, function ($a, $b) {
usort($branches, function ($a, $b): int {
$aRemote = 0 === strpos($a, 'remotes/');
$bRemote = 0 === strpos($b, 'remotes/');

@ -87,7 +87,7 @@ class VersionSelector
if ($this->platformConstraints && !($platformRequirementFilter instanceof IgnoreAllPlatformRequirementFilter)) {
$platformConstraints = $this->platformConstraints;
$candidates = array_filter($candidates, function ($pkg) use ($platformConstraints, $platformRequirementFilter) {
$candidates = array_filter($candidates, function ($pkg) use ($platformConstraints, $platformRequirementFilter): bool {
$reqs = $pkg->getRequires();
foreach ($reqs as $name => $link) {

@ -86,7 +86,7 @@ class StrictConfirmationQuestion extends Question
*/
private function getDefaultValidator(): callable
{
return function ($answer) {
return function ($answer): bool {
if (!is_bool($answer)) {
throw new InvalidArgumentException('Please answer yes, y, no, or n.');
}

@ -350,7 +350,7 @@ class ComposerRepository extends ArrayRepository implements ConfigurableReposito
* @param list<string> $results
* @return list<string>
*/
function (array $results) {
function (array $results): array {
return $results;
}
;
@ -361,7 +361,7 @@ class ComposerRepository extends ArrayRepository implements ConfigurableReposito
* @param list<string> $results
* @return list<string>
*/
function (array $results) use ($packageFilterRegex) {
function (array $results) use ($packageFilterRegex): array {
/** @var list<string> $results */
return Preg::grep($packageFilterRegex, $results);
}
@ -905,7 +905,7 @@ class ComposerRepository extends ArrayRepository implements ConfigurableReposito
}
$promises[] = $this->asyncFetchFile($url, $cacheKey, $lastModified)
->then(function ($response) use (&$packages, &$namesFound, $url, $cacheKey, $contents, $realName, $constraint, $acceptableStabilities, $stabilityFlags, $alreadyLoaded) {
->then(function ($response) use (&$packages, &$namesFound, $url, $cacheKey, $contents, $realName, $constraint, $acceptableStabilities, $stabilityFlags, $alreadyLoaded): void {
$packagesSource = 'downloaded file ('.Url::sanitize($url).')';
if (true === $response) {
@ -1095,7 +1095,7 @@ class ComposerRepository extends ArrayRepository implements ConfigurableReposito
// Disables lazy-provider behavior as with available-packages, but may allow much more compact expression of packages covered by this repository.
// Over-specifying covered packages is safe, but may result in increased traffic to your repository.
if (!empty($data['available-package-patterns'])) {
$this->availablePackagePatterns = array_map(function ($pattern) {
$this->availablePackagePatterns = array_map(function ($pattern): string {
return BasePackage::packageNameToRegexp($pattern);
}, $data['available-package-patterns']);
$this->hasAvailablePackageList = true;
@ -1493,6 +1493,9 @@ class ComposerRepository extends ArrayRepository implements ConfigurableReposito
$degradedMode = &$this->degradedMode;
$eventDispatcher = $this->eventDispatcher;
/**
* @return array<mixed>|true true if the response was a 304 and the cache is fresh
*/
$accept = function ($response) use ($io, $url, $filename, $cache, $cacheKey, $eventDispatcher) {
// package not found is acceptable for a v2 protocol repository
if ($response->getStatusCode() === 404) {

@ -42,7 +42,7 @@ class CompositeRepository implements RepositoryInterface
public function getRepoName(): string
{
return 'composite repo ('.implode(', ', array_map(function ($repo) {
return 'composite repo ('.implode(', ', array_map(function ($repo): string {
return $repo->getRepoName();
}, $this->repositories)).')';
}

@ -150,7 +150,7 @@ class FilesystemRepository extends WritableArrayRepository
}
sort($data['dev-package-names']);
usort($data['packages'], function ($a, $b) {
usort($data['packages'], function ($a, $b): int {
return strcmp($a['name'], $b['name']);
});

@ -251,7 +251,7 @@ class InstalledRepository extends CompositeRepository
public function getRepoName(): string
{
return 'installed repo ('.implode(', ', array_map(function ($repo) {
return 'installed repo ('.implode(', ', array_map(function ($repo): string {
return $repo->getRepoName();
}, $this->getRepositories())).')';
}

@ -251,7 +251,7 @@ class PathRepository extends ArrayRepository implements ConfigurableRepositoryIn
}
// Ensure environment-specific path separators are normalized to URL separators
return array_map(function ($val) {
return array_map(function ($val): string {
return rtrim(str_replace(DIRECTORY_SEPARATOR, '/', $val), '/');
}, glob($this->url, $flags));
}

@ -365,7 +365,7 @@ class PlatformRepository extends ArrayRepository
case 'libxml':
// ext/dom, ext/simplexml, ext/xmlreader and ext/xmlwriter use the same libxml as the ext/libxml
$libxmlProvides = array_map(function ($extension) {
$libxmlProvides = array_map(function ($extension): string {
return $extension . '-libxml';
}, array_intersect($loadedExtensions, array('dom', 'simplexml', 'xml', 'xmlreader', 'xmlwriter')));
$this->addLibrary($name, $this->runtime->getConstant('LIBXML_DOTTED_VERSION'), 'libxml library version', array(), $libxmlProvides);

@ -234,7 +234,7 @@ class GitDriver extends VcsDriver
GitUtil::cleanEnv();
try {
$gitUtil->runCommand(function ($url) {
$gitUtil->runCommand(function ($url): string {
return 'git ls-remote --heads -- ' . ProcessExecutor::escape($url);
}, $url, sys_get_temp_dir());
} catch (\RuntimeException $e) {

@ -71,7 +71,7 @@ class HgDriver extends VcsDriver
$fs->removeDirectory($this->repoDir);
$repoDir = $this->repoDir;
$command = function ($url) use ($repoDir) {
$command = function ($url) use ($repoDir): string {
return sprintf('hg clone --noupdate -- %s %s', ProcessExecutor::escape($url), ProcessExecutor::escape($repoDir));
};

@ -50,7 +50,7 @@ class AuthHelper
} elseif ($storeAuth === 'prompt') {
$answer = $this->io->askAndValidate(
'Do you want to store credentials for '.$origin.' in '.$configSource->getName().' ? [Yn] ',
function ($value) {
function ($value): string {
$input = strtolower(substr(trim($value), 0, 1));
if (in_array($input, array('y','n'))) {
return $input;

@ -56,7 +56,7 @@ class ErrorHandler
self::$io->writeError('<warning>Deprecation Notice: '.$message.' in '.$file.':'.$line.'</warning>');
if (self::$io->isVerbose()) {
self::$io->writeError('<warning>Stack trace:</warning>');
self::$io->writeError(array_filter(array_map(function ($a) {
self::$io->writeError(array_filter(array_map(function ($a): ?string {
if (isset($a['line'], $a['file'])) {
return '<warning> '.$a['file'].':'.$a['line'].'</warning>';
}

@ -283,7 +283,7 @@ class Git
// update the repo if it is a valid git repository
if (is_dir($dir) && 0 === $this->process->execute('git rev-parse --git-dir', $output, $dir) && trim($output) === '.') {
try {
$commandCallable = function ($url) {
$commandCallable = function ($url): string {
$sanitizedUrl = Preg::replace('{://([^@]+?):(.+?)@}', '://', $url);
return sprintf('git remote set-url origin -- %s && git remote update --prune origin && git remote set-url origin -- %s && git gc --auto', ProcessExecutor::escape($url), ProcessExecutor::escape($sanitizedUrl));
@ -301,7 +301,7 @@ class Git
// clean up directory and do a fresh clone into it
$this->filesystem->removeDirectory($dir);
$commandCallable = function ($url) use ($dir) {
$commandCallable = function ($url) use ($dir): string {
return sprintf('git clone --mirror -- %s %s', ProcessExecutor::escape($url), ProcessExecutor::escape($dir));
};

@ -216,13 +216,13 @@ class HttpDownloader
$rfs = $this->rfs;
if ($this->canUseCurl($job)) {
$resolver = function ($resolve, $reject) use (&$job) {
$resolver = function ($resolve, $reject) use (&$job): void {
$job['status'] = HttpDownloader::STATUS_QUEUED;
$job['resolve'] = $resolve;
$job['reject'] = $reject;
};
} else {
$resolver = function ($resolve, $reject) use (&$job, $rfs) {
$resolver = function ($resolve, $reject) use (&$job, $rfs): void {
// start job
$url = $job['request']['url'];
$options = $job['request']['options'];
@ -248,7 +248,7 @@ class HttpDownloader
$curl = $this->curl;
$canceler = function () use (&$job, $curl) {
$canceler = function () use (&$job, $curl): void {
if ($job['status'] === HttpDownloader::STATUS_QUEUED) {
$job['status'] = HttpDownloader::STATUS_ABORTED;
}
@ -270,7 +270,7 @@ class HttpDownloader
$this->markJobDone();
return $response;
}, function ($e) use (&$job) {
}, function ($e) use (&$job): void {
$job['status'] = HttpDownloader::STATUS_FAILED;
$job['exception'] = $e;

@ -82,7 +82,7 @@ class Platform
return self::getUserDirectory() . substr($path, 1);
}
return Preg::replaceCallback('#^(\$|(?P<percent>%))(?P<var>\w++)(?(percent)%)(?P<path>.*)#', function ($matches) {
return Preg::replaceCallback('#^(\$|(?P<percent>%))(?P<var>\w++)(?(percent)%)(?P<path>.*)#', function ($matches): string {
// Treat HOME as an alias for USERPROFILE on Windows for legacy reasons
if (Platform::isWindows() && $matches['var'] == 'HOME') {
return (Platform::getEnv('HOME') ?: Platform::getEnv('USERPROFILE')) . $matches['path'];

@ -153,13 +153,13 @@ class ProcessExecutor
'cwd' => $cwd,
);
$resolver = function ($resolve, $reject) use (&$job) {
$resolver = function ($resolve, $reject) use (&$job): void {
$job['status'] = ProcessExecutor::STATUS_QUEUED;
$job['resolve'] = $resolve;
$job['reject'] = $reject;
};
$canceler = function () use (&$job) {
$canceler = function () use (&$job): void {
if ($job['status'] === ProcessExecutor::STATUS_QUEUED) {
$job['status'] = ProcessExecutor::STATUS_ABORTED;
}
@ -190,7 +190,7 @@ class ProcessExecutor
$this->markJobDone();
return $job['process'];
}, function ($e) use (&$job) {
}, function ($e) use (&$job): void {
$job['status'] = ProcessExecutor::STATUS_FAILED;
$this->markJobDone();
@ -407,7 +407,7 @@ class ProcessExecutor
}
$commandString = is_string($command) ? $command : implode(' ', array_map(self::class.'::escape', $command));
$safeCommand = Preg::replaceCallback('{://(?P<user>[^:/\s]+):(?P<password>[^@\s/]+)@}i', function ($m) {
$safeCommand = Preg::replaceCallback('{://(?P<user>[^:/\s]+):(?P<password>[^@\s/]+)@}i', function ($m): string {
// if the username looks like a long (12char+) hex string, or a modern github token (e.g. ghp_xxx) we obfuscate that
if (Preg::isMatch('{^([a-f0-9]{12,}|gh[a-z]_[a-zA-Z0-9_]+)$}', $m['user'])) {
return '://***:***@';

@ -290,7 +290,7 @@ class RemoteFilesystem
$errorMessage = '';
$errorCode = 0;
$result = false;
set_error_handler(function ($code, $msg) use (&$errorMessage) {
set_error_handler(function ($code, $msg) use (&$errorMessage): bool {
if ($errorMessage) {
$errorMessage .= "\n";
}
@ -445,7 +445,7 @@ class RemoteFilesystem
}
$errorMessage = '';
set_error_handler(function ($code, $msg) use (&$errorMessage) {
set_error_handler(function ($code, $msg) use (&$errorMessage): bool {
if ($errorMessage) {
$errorMessage .= "\n";
}

@ -245,7 +245,7 @@ final class StreamContextFactory
if (!is_array($header)) {
$header = explode("\r\n", $header);
}
uasort($header, function ($el) {
uasort($header, function ($el): int {
return stripos($el, 'content-type') === 0 ? 1 : -1;
});

@ -78,7 +78,7 @@ final class TlsHelper
if (isset($info['extensions']['subjectAltName'])) {
$subjectAltNames = Preg::split('{\s*,\s*}', $info['extensions']['subjectAltName']);
$subjectAltNames = array_filter(array_map(function ($name) {
$subjectAltNames = array_filter(array_map(function ($name): ?string {
if (0 === strpos($name, 'DNS:')) {
return strtolower(ltrim(substr($name, 4)));
}
@ -179,7 +179,7 @@ final class TlsHelper
if (0 === $wildcards) {
// Literal match.
return function ($hostname) use ($certName) {
return function ($hostname) use ($certName): bool {
return $hostname === $certName;
};
}
@ -203,7 +203,7 @@ final class TlsHelper
$wildcardRegex = str_replace('\\*', '[a-z0-9-]+', $wildcardRegex);
$wildcardRegex = "{^{$wildcardRegex}$}";
return function ($hostname) use ($wildcardRegex) {
return function ($hostname) use ($wildcardRegex): bool {
return Preg::isMatch($wildcardRegex, $hostname);
};
}

@ -114,7 +114,7 @@ class Url
// e.g. https://api.github.com/repositories/9999999999?access_token=github_token
$url = Preg::replace('{([&?]access_token=)[^&]+}', '$1***', $url);
$url = Preg::replaceCallback('{^(?P<prefix>[a-z0-9]+://)?(?P<user>[^:/\s@]+):(?P<password>[^@\s/]+)@}i', function ($m) {
$url = Preg::replaceCallback('{^(?P<prefix>[a-z0-9]+://)?(?P<user>[^:/\s@]+):(?P<password>[^@\s/]+)@}i', function ($m): string {
// if the username looks like a long (12char+) hex string, or a modern github token (e.g. ghp_xxx) we obfuscate that
if (Preg::isMatch('{^([a-f0-9]{12,}|gh[a-z]_[a-zA-Z0-9_]+)$}', $m['user'])) {
return $m['prefix'].'***:***@';

Loading…
Cancel
Save