Fix CS (#11003)
parent
6e205a0c84
commit
131da999ac
|
@ -24,12 +24,12 @@ $config = new PhpCsFixer\Config();
|
||||||
return $config->setRules([
|
return $config->setRules([
|
||||||
'@PSR2' => true,
|
'@PSR2' => true,
|
||||||
'binary_operator_spaces' => true,
|
'binary_operator_spaces' => true,
|
||||||
'blank_line_before_statement' => array('statements' => array('declare', 'return')),
|
'blank_line_before_statement' => ['statements' => ['declare', 'return']],
|
||||||
'cast_spaces' => array('space' => 'single'),
|
'cast_spaces' => ['space' => 'single'],
|
||||||
'header_comment' => array('header' => $header),
|
'header_comment' => ['header' => $header],
|
||||||
'include' => true,
|
'include' => true,
|
||||||
|
|
||||||
'class_attributes_separation' => array('elements' => array('method' => 'one', 'trait_import' => 'none')),
|
'class_attributes_separation' => ['elements' => ['method' => 'one', 'trait_import' => 'none']],
|
||||||
'no_blank_lines_after_class_opening' => true,
|
'no_blank_lines_after_class_opening' => true,
|
||||||
'no_blank_lines_after_phpdoc' => true,
|
'no_blank_lines_after_phpdoc' => true,
|
||||||
'no_empty_statement' => true,
|
'no_empty_statement' => true,
|
||||||
|
@ -40,6 +40,8 @@ return $config->setRules([
|
||||||
'object_operator_without_whitespace' => true,
|
'object_operator_without_whitespace' => true,
|
||||||
//'phpdoc_align' => true,
|
//'phpdoc_align' => true,
|
||||||
'phpdoc_indent' => true,
|
'phpdoc_indent' => true,
|
||||||
|
'no_empty_comment' => true,
|
||||||
|
'no_empty_phpdoc' => true,
|
||||||
'phpdoc_no_access' => true,
|
'phpdoc_no_access' => true,
|
||||||
'phpdoc_no_package' => true,
|
'phpdoc_no_package' => true,
|
||||||
//'phpdoc_order' => true,
|
//'phpdoc_order' => true,
|
||||||
|
@ -62,13 +64,12 @@ return $config->setRules([
|
||||||
'single_import_per_statement' => true,
|
'single_import_per_statement' => true,
|
||||||
|
|
||||||
// PHP 7.2 migration
|
// PHP 7.2 migration
|
||||||
// TODO later once 2.2 is more stable
|
'array_syntax' => true,
|
||||||
// 'array_syntax' => true,
|
'list_syntax' => true,
|
||||||
// 'list_syntax' => true,
|
'regular_callable_call' => true,
|
||||||
// 'regular_callable_call' => true,
|
'static_lambda' => true,
|
||||||
// 'static_lambda' => true,
|
'nullable_type_declaration_for_default_null_value' => true,
|
||||||
// 'nullable_type_declaration_for_default_null_value' => true,
|
'explicit_indirect_variable' => true,
|
||||||
// 'explicit_indirect_variable' => true,
|
|
||||||
'visibility_required' => ['elements' => ['property', 'method', 'const']],
|
'visibility_required' => ['elements' => ['property', 'method', 'const']],
|
||||||
'non_printable_character' => true,
|
'non_printable_character' => true,
|
||||||
'combine_nested_dirname' => true,
|
'combine_nested_dirname' => true,
|
||||||
|
@ -76,6 +77,9 @@ return $config->setRules([
|
||||||
'ternary_to_null_coalescing' => true,
|
'ternary_to_null_coalescing' => true,
|
||||||
'phpdoc_to_param_type' => true,
|
'phpdoc_to_param_type' => true,
|
||||||
'declare_strict_types' => true,
|
'declare_strict_types' => true,
|
||||||
|
'no_superfluous_phpdoc_tags' => [
|
||||||
|
'allow_mixed' => true,
|
||||||
|
],
|
||||||
|
|
||||||
// TODO php 7.4 migration (one day..)
|
// TODO php 7.4 migration (one day..)
|
||||||
// 'phpdoc_to_property_type' => true,
|
// 'phpdoc_to_property_type' => true,
|
||||||
|
|
|
@ -865,11 +865,6 @@ parameters:
|
||||||
count: 2
|
count: 2
|
||||||
path: ../src/Composer/Command/ShowCommand.php
|
path: ../src/Composer/Command/ShowCommand.php
|
||||||
|
|
||||||
-
|
|
||||||
message: "#^Only booleans are allowed in a negated boolean, array\\<string\\> given\\.$#"
|
|
||||||
count: 1
|
|
||||||
path: ../src/Composer/Command/ShowCommand.php
|
|
||||||
|
|
||||||
-
|
-
|
||||||
message: "#^Only booleans are allowed in a negated boolean, array\\<string\\>\\|string given\\.$#"
|
message: "#^Only booleans are allowed in a negated boolean, array\\<string\\>\\|string given\\.$#"
|
||||||
count: 1
|
count: 1
|
||||||
|
@ -1415,6 +1410,16 @@ parameters:
|
||||||
count: 4
|
count: 4
|
||||||
path: ../src/Composer/DependencyResolver/PoolOptimizer.php
|
path: ../src/Composer/DependencyResolver/PoolOptimizer.php
|
||||||
|
|
||||||
|
-
|
||||||
|
message: "#^Cannot access offset 'constraint' on array\\{package\\: Composer\\\\Package\\\\BasePackage\\}\\|array\\{packageName\\: string, constraint\\: Composer\\\\Semver\\\\Constraint\\\\ConstraintInterface\\}\\|Composer\\\\Package\\\\BasePackage\\|Composer\\\\Package\\\\Link\\|int\\|string\\.$#"
|
||||||
|
count: 1
|
||||||
|
path: ../src/Composer/DependencyResolver/Problem.php
|
||||||
|
|
||||||
|
-
|
||||||
|
message: "#^Cannot access offset 'packageName' on array\\{package\\: Composer\\\\Package\\\\BasePackage\\}\\|array\\{packageName\\: string, constraint\\: Composer\\\\Semver\\\\Constraint\\\\ConstraintInterface\\}\\|Composer\\\\Package\\\\BasePackage\\|Composer\\\\Package\\\\Link\\|int\\|string\\.$#"
|
||||||
|
count: 1
|
||||||
|
path: ../src/Composer/DependencyResolver/Problem.php
|
||||||
|
|
||||||
-
|
-
|
||||||
message: "#^Cannot call method getRepoName\\(\\) on Composer\\\\Repository\\\\RepositoryInterface\\|null\\.$#"
|
message: "#^Cannot call method getRepoName\\(\\) on Composer\\\\Repository\\\\RepositoryInterface\\|null\\.$#"
|
||||||
count: 3
|
count: 3
|
||||||
|
@ -1530,6 +1535,11 @@ parameters:
|
||||||
count: 1
|
count: 1
|
||||||
path: ../src/Composer/DependencyResolver/Rule.php
|
path: ../src/Composer/DependencyResolver/Rule.php
|
||||||
|
|
||||||
|
-
|
||||||
|
message: "#^Method Composer\\\\DependencyResolver\\\\Rule\\:\\:getReason\\(\\) should return 2\\|3\\|6\\|7\\|10\\|12\\|13\\|14 but returns int\\.$#"
|
||||||
|
count: 1
|
||||||
|
path: ../src/Composer/DependencyResolver/Rule.php
|
||||||
|
|
||||||
-
|
-
|
||||||
message: "#^Only booleans are allowed in &&, array\\<int, Composer\\\\Package\\\\BasePackage\\> given on the left side\\.$#"
|
message: "#^Only booleans are allowed in &&, array\\<int, Composer\\\\Package\\\\BasePackage\\> given on the left side\\.$#"
|
||||||
count: 1
|
count: 1
|
||||||
|
|
|
@ -1,5 +1,15 @@
|
||||||
<?php declare(strict_types=1);
|
<?php declare(strict_types=1);
|
||||||
|
|
||||||
|
/*
|
||||||
|
* This file is part of Composer.
|
||||||
|
*
|
||||||
|
* (c) Nils Adermann <naderman@naderman.de>
|
||||||
|
* Jordi Boggiano <j.boggiano@seld.be>
|
||||||
|
*
|
||||||
|
* For the full copyright and license information, please view the LICENSE
|
||||||
|
* file that was distributed with this source code.
|
||||||
|
*/
|
||||||
|
|
||||||
namespace Composer\Advisory;
|
namespace Composer\Advisory;
|
||||||
|
|
||||||
use Composer\IO\ConsoleIO;
|
use Composer\IO\ConsoleIO;
|
||||||
|
@ -31,7 +41,6 @@ class Auditor
|
||||||
];
|
];
|
||||||
|
|
||||||
/**
|
/**
|
||||||
* @param IOInterface $io
|
|
||||||
* @param PackageInterface[] $packages
|
* @param PackageInterface[] $packages
|
||||||
* @param self::FORMAT_* $format The format that will be used to output audit results.
|
* @param self::FORMAT_* $format The format that will be used to output audit results.
|
||||||
* @param bool $warningOnly If true, outputs a warning. If false, outputs an error.
|
* @param bool $warningOnly If true, outputs a warning. If false, outputs an error.
|
||||||
|
@ -43,6 +52,7 @@ class Auditor
|
||||||
$advisories = $repoSet->getMatchingSecurityAdvisories($packages, $format === self::FORMAT_SUMMARY);
|
$advisories = $repoSet->getMatchingSecurityAdvisories($packages, $format === self::FORMAT_SUMMARY);
|
||||||
if (self::FORMAT_JSON === $format) {
|
if (self::FORMAT_JSON === $format) {
|
||||||
$io->write(JsonFile::encode(['advisories' => $advisories]));
|
$io->write(JsonFile::encode(['advisories' => $advisories]));
|
||||||
|
|
||||||
return count($advisories);
|
return count($advisories);
|
||||||
}
|
}
|
||||||
|
|
||||||
|
@ -73,14 +83,13 @@ class Auditor
|
||||||
foreach ($advisories as $packageAdvisories) {
|
foreach ($advisories as $packageAdvisories) {
|
||||||
$count += count($packageAdvisories);
|
$count += count($packageAdvisories);
|
||||||
}
|
}
|
||||||
|
|
||||||
return [count($advisories), $count];
|
return [count($advisories), $count];
|
||||||
}
|
}
|
||||||
|
|
||||||
/**
|
/**
|
||||||
* @param IOInterface $io
|
|
||||||
* @param array<string, array<SecurityAdvisory>> $advisories
|
* @param array<string, array<SecurityAdvisory>> $advisories
|
||||||
* @param self::FORMAT_* $format The format that will be used to output audit results.
|
* @param self::FORMAT_* $format The format that will be used to output audit results.
|
||||||
* @return void
|
|
||||||
*/
|
*/
|
||||||
private function outputAdvisories(IOInterface $io, array $advisories, string $format): void
|
private function outputAdvisories(IOInterface $io, array $advisories, string $format): void
|
||||||
{
|
{
|
||||||
|
@ -90,13 +99,16 @@ class Auditor
|
||||||
throw new InvalidArgumentException('Cannot use table format with ' . get_class($io));
|
throw new InvalidArgumentException('Cannot use table format with ' . get_class($io));
|
||||||
}
|
}
|
||||||
$this->outputAvisoriesTable($io, $advisories);
|
$this->outputAvisoriesTable($io, $advisories);
|
||||||
|
|
||||||
return;
|
return;
|
||||||
case self::FORMAT_PLAIN:
|
case self::FORMAT_PLAIN:
|
||||||
$this->outputAdvisoriesPlain($io, $advisories);
|
$this->outputAdvisoriesPlain($io, $advisories);
|
||||||
|
|
||||||
return;
|
return;
|
||||||
case self::FORMAT_SUMMARY:
|
case self::FORMAT_SUMMARY:
|
||||||
// We've already output the number of advisories in audit()
|
// We've already output the number of advisories in audit()
|
||||||
$io->writeError('Run composer audit for a full list of advisories.');
|
$io->writeError('Run composer audit for a full list of advisories.');
|
||||||
|
|
||||||
return;
|
return;
|
||||||
default:
|
default:
|
||||||
throw new InvalidArgumentException('Invalid format "'.$format.'".');
|
throw new InvalidArgumentException('Invalid format "'.$format.'".');
|
||||||
|
@ -104,9 +116,7 @@ class Auditor
|
||||||
}
|
}
|
||||||
|
|
||||||
/**
|
/**
|
||||||
* @param ConsoleIO $io
|
|
||||||
* @param array<string, array<SecurityAdvisory>> $advisories
|
* @param array<string, array<SecurityAdvisory>> $advisories
|
||||||
* @return void
|
|
||||||
*/
|
*/
|
||||||
private function outputAvisoriesTable(ConsoleIO $io, array $advisories): void
|
private function outputAvisoriesTable(ConsoleIO $io, array $advisories): void
|
||||||
{
|
{
|
||||||
|
@ -138,9 +148,7 @@ class Auditor
|
||||||
}
|
}
|
||||||
|
|
||||||
/**
|
/**
|
||||||
* @param IOInterface $io
|
|
||||||
* @param array<string, array<SecurityAdvisory>> $advisories
|
* @param array<string, array<SecurityAdvisory>> $advisories
|
||||||
* @return void
|
|
||||||
*/
|
*/
|
||||||
private function outputAdvisoriesPlain(IOInterface $io, array $advisories): void
|
private function outputAdvisoriesPlain(IOInterface $io, array $advisories): void
|
||||||
{
|
{
|
||||||
|
|
|
@ -1,5 +1,15 @@
|
||||||
<?php declare(strict_types=1);
|
<?php declare(strict_types=1);
|
||||||
|
|
||||||
|
/*
|
||||||
|
* This file is part of Composer.
|
||||||
|
*
|
||||||
|
* (c) Nils Adermann <naderman@naderman.de>
|
||||||
|
* Jordi Boggiano <j.boggiano@seld.be>
|
||||||
|
*
|
||||||
|
* For the full copyright and license information, please view the LICENSE
|
||||||
|
* file that was distributed with this source code.
|
||||||
|
*/
|
||||||
|
|
||||||
namespace Composer\Advisory;
|
namespace Composer\Advisory;
|
||||||
|
|
||||||
use Composer\Semver\Constraint\ConstraintInterface;
|
use Composer\Semver\Constraint\ConstraintInterface;
|
||||||
|
|
|
@ -1,5 +1,15 @@
|
||||||
<?php declare(strict_types=1);
|
<?php declare(strict_types=1);
|
||||||
|
|
||||||
|
/*
|
||||||
|
* This file is part of Composer.
|
||||||
|
*
|
||||||
|
* (c) Nils Adermann <naderman@naderman.de>
|
||||||
|
* Jordi Boggiano <j.boggiano@seld.be>
|
||||||
|
*
|
||||||
|
* For the full copyright and license information, please view the LICENSE
|
||||||
|
* file that was distributed with this source code.
|
||||||
|
*/
|
||||||
|
|
||||||
namespace Composer\Advisory;
|
namespace Composer\Advisory;
|
||||||
|
|
||||||
use Composer\Semver\Constraint\ConstraintInterface;
|
use Composer\Semver\Constraint\ConstraintInterface;
|
||||||
|
@ -41,7 +51,7 @@ class SecurityAdvisory extends PartialSecurityAdvisory
|
||||||
* @param non-empty-array<array{name: string, remoteId: string}> $sources
|
* @param non-empty-array<array{name: string, remoteId: string}> $sources
|
||||||
* @readonly
|
* @readonly
|
||||||
*/
|
*/
|
||||||
public function __construct(string $packageName, string $advisoryId, ConstraintInterface $affectedVersions, string $title, array $sources, \DateTimeImmutable $reportedAt, ?string $cve = null, ?string $link = null)
|
public function __construct(string $packageName, string $advisoryId, ConstraintInterface $affectedVersions, string $title, array $sources, DateTimeImmutable $reportedAt, ?string $cve = null, ?string $link = null)
|
||||||
{
|
{
|
||||||
parent::__construct($packageName, $advisoryId, $affectedVersions);
|
parent::__construct($packageName, $advisoryId, $affectedVersions);
|
||||||
|
|
||||||
|
|
|
@ -80,7 +80,7 @@ class AutoloadGenerator
|
||||||
*/
|
*/
|
||||||
private $platformRequirementFilter;
|
private $platformRequirementFilter;
|
||||||
|
|
||||||
public function __construct(EventDispatcher $eventDispatcher, IOInterface $io = null)
|
public function __construct(EventDispatcher $eventDispatcher, ?IOInterface $io = null)
|
||||||
{
|
{
|
||||||
$this->eventDispatcher = $eventDispatcher;
|
$this->eventDispatcher = $eventDispatcher;
|
||||||
$this->io = $io ?? new NullIO();
|
$this->io = $io ?? new NullIO();
|
||||||
|
@ -89,7 +89,6 @@ class AutoloadGenerator
|
||||||
}
|
}
|
||||||
|
|
||||||
/**
|
/**
|
||||||
* @param bool $devMode
|
|
||||||
* @return void
|
* @return void
|
||||||
*/
|
*/
|
||||||
public function setDevMode(bool $devMode = true)
|
public function setDevMode(bool $devMode = true)
|
||||||
|
@ -100,7 +99,6 @@ class AutoloadGenerator
|
||||||
/**
|
/**
|
||||||
* Whether generated autoloader considers the class map authoritative.
|
* Whether generated autoloader considers the class map authoritative.
|
||||||
*
|
*
|
||||||
* @param bool $classMapAuthoritative
|
|
||||||
* @return void
|
* @return void
|
||||||
*/
|
*/
|
||||||
public function setClassMapAuthoritative(bool $classMapAuthoritative)
|
public function setClassMapAuthoritative(bool $classMapAuthoritative)
|
||||||
|
@ -111,8 +109,6 @@ class AutoloadGenerator
|
||||||
/**
|
/**
|
||||||
* Whether generated autoloader considers APCu caching.
|
* Whether generated autoloader considers APCu caching.
|
||||||
*
|
*
|
||||||
* @param bool $apcu
|
|
||||||
* @param string|null $apcuPrefix
|
|
||||||
* @return void
|
* @return void
|
||||||
*/
|
*/
|
||||||
public function setApcu(bool $apcu, ?string $apcuPrefix = null)
|
public function setApcu(bool $apcu, ?string $apcuPrefix = null)
|
||||||
|
@ -124,7 +120,6 @@ class AutoloadGenerator
|
||||||
/**
|
/**
|
||||||
* Whether to run scripts or not
|
* Whether to run scripts or not
|
||||||
*
|
*
|
||||||
* @param bool $runScripts
|
|
||||||
* @return void
|
* @return void
|
||||||
*/
|
*/
|
||||||
public function setRunScripts(bool $runScripts = true)
|
public function setRunScripts(bool $runScripts = true)
|
||||||
|
@ -160,8 +155,6 @@ class AutoloadGenerator
|
||||||
}
|
}
|
||||||
|
|
||||||
/**
|
/**
|
||||||
* @param string $targetDir
|
|
||||||
* @param bool $scanPsrPackages
|
|
||||||
* @return ClassMap
|
* @return ClassMap
|
||||||
* @throws \Seld\JsonLint\ParsingException
|
* @throws \Seld\JsonLint\ParsingException
|
||||||
* @throws \RuntimeException
|
* @throws \RuntimeException
|
||||||
|
@ -193,9 +186,9 @@ class AutoloadGenerator
|
||||||
Platform::putEnv('COMPOSER_DEV_MODE', $this->devMode ? '1' : '0');
|
Platform::putEnv('COMPOSER_DEV_MODE', $this->devMode ? '1' : '0');
|
||||||
}
|
}
|
||||||
|
|
||||||
$this->eventDispatcher->dispatchScript(ScriptEvents::PRE_AUTOLOAD_DUMP, $this->devMode, array(), array(
|
$this->eventDispatcher->dispatchScript(ScriptEvents::PRE_AUTOLOAD_DUMP, $this->devMode, [], [
|
||||||
'optimize' => $scanPsrPackages,
|
'optimize' => $scanPsrPackages,
|
||||||
));
|
]);
|
||||||
}
|
}
|
||||||
|
|
||||||
$classMapGenerator = new ClassMapGenerator(['php', 'inc', 'hh']);
|
$classMapGenerator = new ClassMapGenerator(['php', 'inc', 'hh']);
|
||||||
|
@ -257,7 +250,7 @@ EOF;
|
||||||
|
|
||||||
// Process the 'psr-0' base directories.
|
// Process the 'psr-0' base directories.
|
||||||
foreach ($autoloads['psr-0'] as $namespace => $paths) {
|
foreach ($autoloads['psr-0'] as $namespace => $paths) {
|
||||||
$exportedPaths = array();
|
$exportedPaths = [];
|
||||||
foreach ($paths as $path) {
|
foreach ($paths as $path) {
|
||||||
$exportedPaths[] = $this->getPathCode($filesystem, $basePath, $vendorPath, $path);
|
$exportedPaths[] = $this->getPathCode($filesystem, $basePath, $vendorPath, $path);
|
||||||
}
|
}
|
||||||
|
@ -269,7 +262,7 @@ EOF;
|
||||||
|
|
||||||
// Process the 'psr-4' base directories.
|
// Process the 'psr-4' base directories.
|
||||||
foreach ($autoloads['psr-4'] as $namespace => $paths) {
|
foreach ($autoloads['psr-4'] as $namespace => $paths) {
|
||||||
$exportedPaths = array();
|
$exportedPaths = [];
|
||||||
foreach ($paths as $path) {
|
foreach ($paths as $path) {
|
||||||
$exportedPaths[] = $this->getPathCode($filesystem, $basePath, $vendorPath, $path);
|
$exportedPaths[] = $this->getPathCode($filesystem, $basePath, $vendorPath, $path);
|
||||||
}
|
}
|
||||||
|
@ -322,12 +315,12 @@ EOF;
|
||||||
}
|
}
|
||||||
|
|
||||||
if ($scanPsrPackages) {
|
if ($scanPsrPackages) {
|
||||||
$namespacesToScan = array();
|
$namespacesToScan = [];
|
||||||
|
|
||||||
// Scan the PSR-0/4 directories for class files, and add them to the class map
|
// Scan the PSR-0/4 directories for class files, and add them to the class map
|
||||||
foreach (array('psr-4', 'psr-0') as $psrType) {
|
foreach (['psr-4', 'psr-0'] as $psrType) {
|
||||||
foreach ($autoloads[$psrType] as $namespace => $paths) {
|
foreach ($autoloads[$psrType] as $namespace => $paths) {
|
||||||
$namespacesToScan[$namespace][] = array('paths' => $paths, 'type' => $psrType);
|
$namespacesToScan[$namespace][] = ['paths' => $paths, 'type' => $psrType];
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
|
|
||||||
|
@ -441,9 +434,9 @@ EOF;
|
||||||
$filesystem->safeCopy(__DIR__.'/../../../LICENSE', $targetDir.'/LICENSE');
|
$filesystem->safeCopy(__DIR__.'/../../../LICENSE', $targetDir.'/LICENSE');
|
||||||
|
|
||||||
if ($this->runScripts) {
|
if ($this->runScripts) {
|
||||||
$this->eventDispatcher->dispatchScript(ScriptEvents::POST_AUTOLOAD_DUMP, $this->devMode, array(), array(
|
$this->eventDispatcher->dispatchScript(ScriptEvents::POST_AUTOLOAD_DUMP, $this->devMode, [], [
|
||||||
'optimize' => $scanPsrPackages,
|
'optimize' => $scanPsrPackages,
|
||||||
));
|
]);
|
||||||
}
|
}
|
||||||
|
|
||||||
return $classMap;
|
return $classMap;
|
||||||
|
@ -479,14 +472,13 @@ EOF;
|
||||||
}
|
}
|
||||||
|
|
||||||
/**
|
/**
|
||||||
* @param InstallationManager $installationManager
|
|
||||||
* @param PackageInterface[] $packages
|
* @param PackageInterface[] $packages
|
||||||
* @return array<int, array{0: PackageInterface, 1: string}>
|
* @return array<int, array{0: PackageInterface, 1: string}>
|
||||||
*/
|
*/
|
||||||
public function buildPackageMap(InstallationManager $installationManager, PackageInterface $rootPackage, array $packages)
|
public function buildPackageMap(InstallationManager $installationManager, PackageInterface $rootPackage, array $packages)
|
||||||
{
|
{
|
||||||
// build package => install path map
|
// build package => install path map
|
||||||
$packageMap = array(array($rootPackage, ''));
|
$packageMap = [[$rootPackage, '']];
|
||||||
|
|
||||||
foreach ($packages as $package) {
|
foreach ($packages as $package) {
|
||||||
if ($package instanceof AliasPackage) {
|
if ($package instanceof AliasPackage) {
|
||||||
|
@ -494,10 +486,10 @@ EOF;
|
||||||
}
|
}
|
||||||
$this->validatePackage($package);
|
$this->validatePackage($package);
|
||||||
|
|
||||||
$packageMap[] = array(
|
$packageMap[] = [
|
||||||
$package,
|
$package,
|
||||||
$installationManager->getInstallPath($package),
|
$installationManager->getInstallPath($package),
|
||||||
);
|
];
|
||||||
}
|
}
|
||||||
|
|
||||||
return $packageMap;
|
return $packageMap;
|
||||||
|
@ -562,20 +554,19 @@ EOF;
|
||||||
krsort($psr0);
|
krsort($psr0);
|
||||||
krsort($psr4);
|
krsort($psr4);
|
||||||
|
|
||||||
return array(
|
return [
|
||||||
'psr-0' => $psr0,
|
'psr-0' => $psr0,
|
||||||
'psr-4' => $psr4,
|
'psr-4' => $psr4,
|
||||||
'classmap' => $classmap,
|
'classmap' => $classmap,
|
||||||
'files' => $files,
|
'files' => $files,
|
||||||
'exclude-from-classmap' => $exclude,
|
'exclude-from-classmap' => $exclude,
|
||||||
);
|
];
|
||||||
}
|
}
|
||||||
|
|
||||||
/**
|
/**
|
||||||
* Registers an autoloader based on an autoload-map returned by parseAutoloads
|
* Registers an autoloader based on an autoload-map returned by parseAutoloads
|
||||||
*
|
*
|
||||||
* @param array<string, mixed[]> $autoloads see parseAutoloads return value
|
* @param array<string, mixed[]> $autoloads see parseAutoloads return value
|
||||||
* @param null|string $vendorDir
|
|
||||||
* @return ClassLoader
|
* @return ClassLoader
|
||||||
*/
|
*/
|
||||||
public function createLoader(array $autoloads, ?string $vendorDir = null)
|
public function createLoader(array $autoloads, ?string $vendorDir = null)
|
||||||
|
@ -619,18 +610,14 @@ EOF;
|
||||||
|
|
||||||
/**
|
/**
|
||||||
* @param array<int, array{0: PackageInterface, 1: string}> $packageMap
|
* @param array<int, array{0: PackageInterface, 1: string}> $packageMap
|
||||||
* @param string $basePath
|
|
||||||
* @param string $vendorPath
|
|
||||||
* @param string $vendorPathCode
|
|
||||||
* @param string $appBaseDirCode
|
|
||||||
* @return ?string
|
* @return ?string
|
||||||
*/
|
*/
|
||||||
protected function getIncludePathsFile(array $packageMap, Filesystem $filesystem, string $basePath, string $vendorPath, string $vendorPathCode, string $appBaseDirCode)
|
protected function getIncludePathsFile(array $packageMap, Filesystem $filesystem, string $basePath, string $vendorPath, string $vendorPathCode, string $appBaseDirCode)
|
||||||
{
|
{
|
||||||
$includePaths = array();
|
$includePaths = [];
|
||||||
|
|
||||||
foreach ($packageMap as $item) {
|
foreach ($packageMap as $item) {
|
||||||
list($package, $installPath) = $item;
|
[$package, $installPath] = $item;
|
||||||
|
|
||||||
if (null !== $package->getTargetDir() && strlen($package->getTargetDir()) > 0) {
|
if (null !== $package->getTargetDir() && strlen($package->getTargetDir()) > 0) {
|
||||||
$installPath = substr($installPath, 0, -strlen('/'.$package->getTargetDir()));
|
$installPath = substr($installPath, 0, -strlen('/'.$package->getTargetDir()));
|
||||||
|
@ -667,10 +654,6 @@ EOF;
|
||||||
|
|
||||||
/**
|
/**
|
||||||
* @param array<string, string> $files
|
* @param array<string, string> $files
|
||||||
* @param string $basePath
|
|
||||||
* @param string $vendorPath
|
|
||||||
* @param string $vendorPathCode
|
|
||||||
* @param string $appBaseDirCode
|
|
||||||
* @return ?string
|
* @return ?string
|
||||||
*/
|
*/
|
||||||
protected function getIncludeFilesFile(array $files, Filesystem $filesystem, string $basePath, string $vendorPath, string $vendorPathCode, string $appBaseDirCode)
|
protected function getIncludeFilesFile(array $files, Filesystem $filesystem, string $basePath, string $vendorPath, string $vendorPathCode, string $appBaseDirCode)
|
||||||
|
@ -700,9 +683,6 @@ EOF;
|
||||||
}
|
}
|
||||||
|
|
||||||
/**
|
/**
|
||||||
* @param string $basePath
|
|
||||||
* @param string $vendorPath
|
|
||||||
* @param string $path
|
|
||||||
* @return string
|
* @return string
|
||||||
*/
|
*/
|
||||||
protected function getPathCode(Filesystem $filesystem, string $basePath, string $vendorPath, string $path)
|
protected function getPathCode(Filesystem $filesystem, string $basePath, string $vendorPath, string $path)
|
||||||
|
@ -740,8 +720,8 @@ EOF;
|
||||||
protected function getPlatformCheck(array $packageMap, $checkPlatform, array $devPackageNames)
|
protected function getPlatformCheck(array $packageMap, $checkPlatform, array $devPackageNames)
|
||||||
{
|
{
|
||||||
$lowestPhpVersion = Bound::zero();
|
$lowestPhpVersion = Bound::zero();
|
||||||
$requiredExtensions = array();
|
$requiredExtensions = [];
|
||||||
$extensionProviders = array();
|
$extensionProviders = [];
|
||||||
|
|
||||||
foreach ($packageMap as $item) {
|
foreach ($packageMap as $item) {
|
||||||
$package = $item[0];
|
$package = $item[0];
|
||||||
|
@ -891,8 +871,6 @@ PLATFORM_CHECK;
|
||||||
}
|
}
|
||||||
|
|
||||||
/**
|
/**
|
||||||
* @param string $vendorPathToTargetDirCode
|
|
||||||
* @param string $suffix
|
|
||||||
* @return string
|
* @return string
|
||||||
*/
|
*/
|
||||||
protected function getAutoloadFile(string $vendorPathToTargetDirCode, string $suffix)
|
protected function getAutoloadFile(string $vendorPathToTargetDirCode, string $suffix)
|
||||||
|
@ -922,16 +900,9 @@ AUTOLOAD;
|
||||||
}
|
}
|
||||||
|
|
||||||
/**
|
/**
|
||||||
* @param bool $useClassMap
|
|
||||||
* @param bool $useIncludePath
|
|
||||||
* @param null|string $targetDirLoader
|
|
||||||
* @param bool $useIncludeFiles
|
|
||||||
* @param string $vendorPathCode unused in this method
|
* @param string $vendorPathCode unused in this method
|
||||||
* @param string $appBaseDirCode unused in this method
|
* @param string $appBaseDirCode unused in this method
|
||||||
* @param string $suffix
|
|
||||||
* @param bool $useGlobalIncludePath
|
|
||||||
* @param string $prependAutoloader 'true'|'false'
|
* @param string $prependAutoloader 'true'|'false'
|
||||||
* @param bool $checkPlatform
|
|
||||||
* @return string
|
* @return string
|
||||||
*/
|
*/
|
||||||
protected function getAutoloadRealFile(bool $useClassMap, bool $useIncludePath, ?string $targetDirLoader, bool $useIncludeFiles, string $vendorPathCode, string $appBaseDirCode, string $suffix, bool $useGlobalIncludePath, string $prependAutoloader, bool $checkPlatform)
|
protected function getAutoloadRealFile(bool $useClassMap, bool $useIncludePath, ?string $targetDirLoader, bool $useIncludeFiles, string $vendorPathCode, string $appBaseDirCode, string $suffix, bool $useGlobalIncludePath, string $prependAutoloader, bool $checkPlatform)
|
||||||
|
@ -1081,8 +1052,6 @@ FOOTER;
|
||||||
}
|
}
|
||||||
|
|
||||||
/**
|
/**
|
||||||
* @param string $suffix
|
|
||||||
* @param string $targetDir
|
|
||||||
* @param string $vendorPath input for findShortestPathCode
|
* @param string $vendorPath input for findShortestPathCode
|
||||||
* @param string $basePath input for findShortestPathCode
|
* @param string $basePath input for findShortestPathCode
|
||||||
* @return string
|
* @return string
|
||||||
|
@ -1134,9 +1103,9 @@ HEADER;
|
||||||
$prefix = "\0Composer\Autoload\ClassLoader\0";
|
$prefix = "\0Composer\Autoload\ClassLoader\0";
|
||||||
$prefixLen = strlen($prefix);
|
$prefixLen = strlen($prefix);
|
||||||
if (file_exists($targetDir . '/autoload_files.php')) {
|
if (file_exists($targetDir . '/autoload_files.php')) {
|
||||||
$maps = array('files' => require $targetDir . '/autoload_files.php');
|
$maps = ['files' => require $targetDir . '/autoload_files.php'];
|
||||||
} else {
|
} else {
|
||||||
$maps = array();
|
$maps = [];
|
||||||
}
|
}
|
||||||
|
|
||||||
foreach ((array) $loader as $prop => $value) {
|
foreach ((array) $loader as $prop => $value) {
|
||||||
|
@ -1148,12 +1117,12 @@ HEADER;
|
||||||
foreach ($maps as $prop => $value) {
|
foreach ($maps as $prop => $value) {
|
||||||
$value = strtr(
|
$value = strtr(
|
||||||
var_export($value, true),
|
var_export($value, true),
|
||||||
array(
|
[
|
||||||
$absoluteVendorPathCode => $vendorPathCode,
|
$absoluteVendorPathCode => $vendorPathCode,
|
||||||
$absoluteVendorPharPathCode => $vendorPharPathCode,
|
$absoluteVendorPharPathCode => $vendorPharPathCode,
|
||||||
$absoluteAppBaseDirCode => $appBaseDirCode,
|
$absoluteAppBaseDirCode => $appBaseDirCode,
|
||||||
$absoluteAppBaseDirPharCode => $appBaseDirPharCode,
|
$absoluteAppBaseDirPharCode => $appBaseDirPharCode,
|
||||||
)
|
]
|
||||||
);
|
);
|
||||||
$value = ltrim(Preg::replace('/^ */m', ' $0$0', $value));
|
$value = ltrim(Preg::replace('/^ */m', ' $0$0', $value));
|
||||||
|
|
||||||
|
@ -1182,10 +1151,10 @@ INITIALIZER;
|
||||||
*/
|
*/
|
||||||
protected function parseAutoloadsType(array $packageMap, string $type, RootPackageInterface $rootPackage)
|
protected function parseAutoloadsType(array $packageMap, string $type, RootPackageInterface $rootPackage)
|
||||||
{
|
{
|
||||||
$autoloads = array();
|
$autoloads = [];
|
||||||
|
|
||||||
foreach ($packageMap as $item) {
|
foreach ($packageMap as $item) {
|
||||||
list($package, $installPath) = $item;
|
[$package, $installPath] = $item;
|
||||||
|
|
||||||
$autoload = $package->getAutoload();
|
$autoload = $package->getAutoload();
|
||||||
if ($this->devMode && $package === $rootPackage) {
|
if ($this->devMode && $package === $rootPackage) {
|
||||||
|
@ -1205,7 +1174,7 @@ INITIALIZER;
|
||||||
if (($type === 'files' || $type === 'classmap' || $type === 'exclude-from-classmap') && $package->getTargetDir() && !Filesystem::isReadable($installPath.'/'.$path)) {
|
if (($type === 'files' || $type === 'classmap' || $type === 'exclude-from-classmap') && $package->getTargetDir() && !Filesystem::isReadable($installPath.'/'.$path)) {
|
||||||
// remove target-dir from file paths of the root package
|
// remove target-dir from file paths of the root package
|
||||||
if ($package === $rootPackage) {
|
if ($package === $rootPackage) {
|
||||||
$targetDir = str_replace('\\<dirsep\\>', '[\\\\/]', preg_quote(str_replace(array('/', '\\'), '<dirsep>', $package->getTargetDir())));
|
$targetDir = str_replace('\\<dirsep\\>', '[\\\\/]', preg_quote(str_replace(['/', '\\'], '<dirsep>', $package->getTargetDir())));
|
||||||
$path = ltrim(Preg::replace('{^'.$targetDir.'}', '', ltrim($path, '\\/')), '\\/');
|
$path = ltrim(Preg::replace('{^'.$targetDir.'}', '', ltrim($path, '\\/')), '\\/');
|
||||||
} else {
|
} else {
|
||||||
// add target-dir from file paths that don't have it
|
// add target-dir from file paths that don't have it
|
||||||
|
@ -1218,7 +1187,7 @@ INITIALIZER;
|
||||||
$path = Preg::replace('{/+}', '/', preg_quote(trim(strtr($path, '\\', '/'), '/')));
|
$path = Preg::replace('{/+}', '/', preg_quote(trim(strtr($path, '\\', '/'), '/')));
|
||||||
|
|
||||||
// add support for wildcards * and **
|
// add support for wildcards * and **
|
||||||
$path = strtr($path, array('\\*\\*' => '.+?', '\\*' => '[^/]+?'));
|
$path = strtr($path, ['\\*\\*' => '.+?', '\\*' => '[^/]+?']);
|
||||||
|
|
||||||
// add support for up-level relative paths
|
// add support for up-level relative paths
|
||||||
$updir = null;
|
$updir = null;
|
||||||
|
@ -1266,7 +1235,6 @@ INITIALIZER;
|
||||||
}
|
}
|
||||||
|
|
||||||
/**
|
/**
|
||||||
* @param string $path
|
|
||||||
* @return string
|
* @return string
|
||||||
*/
|
*/
|
||||||
protected function getFileIdentifier(PackageInterface $package, string $path)
|
protected function getFileIdentifier(PackageInterface $package, string $path)
|
||||||
|
@ -1278,16 +1246,15 @@ INITIALIZER;
|
||||||
* Filters out dev-dependencies
|
* Filters out dev-dependencies
|
||||||
*
|
*
|
||||||
* @param array<int, array{0: PackageInterface, 1: string}> $packageMap
|
* @param array<int, array{0: PackageInterface, 1: string}> $packageMap
|
||||||
* @param RootPackageInterface $rootPackage
|
|
||||||
* @return array<int, array{0: PackageInterface, 1: string}>
|
* @return array<int, array{0: PackageInterface, 1: string}>
|
||||||
*
|
*
|
||||||
* @phpstan-param array<int, array{0: PackageInterface, 1: string}> $packageMap
|
* @phpstan-param array<int, array{0: PackageInterface, 1: string}> $packageMap
|
||||||
*/
|
*/
|
||||||
protected function filterPackageMap(array $packageMap, RootPackageInterface $rootPackage)
|
protected function filterPackageMap(array $packageMap, RootPackageInterface $rootPackage)
|
||||||
{
|
{
|
||||||
$packages = array();
|
$packages = [];
|
||||||
$include = array();
|
$include = [];
|
||||||
$replacedBy = array();
|
$replacedBy = [];
|
||||||
|
|
||||||
foreach ($packageMap as $item) {
|
foreach ($packageMap as $item) {
|
||||||
$package = $item[0];
|
$package = $item[0];
|
||||||
|
@ -1339,11 +1306,11 @@ INITIALIZER;
|
||||||
*/
|
*/
|
||||||
protected function sortPackageMap(array $packageMap)
|
protected function sortPackageMap(array $packageMap)
|
||||||
{
|
{
|
||||||
$packages = array();
|
$packages = [];
|
||||||
$paths = array();
|
$paths = [];
|
||||||
|
|
||||||
foreach ($packageMap as $item) {
|
foreach ($packageMap as $item) {
|
||||||
list($package, $path) = $item;
|
[$package, $path] = $item;
|
||||||
$name = $package->getName();
|
$name = $package->getName();
|
||||||
$packages[$name] = $package;
|
$packages[$name] = $package;
|
||||||
$paths[$name] = $path;
|
$paths[$name] = $path;
|
||||||
|
@ -1351,11 +1318,11 @@ INITIALIZER;
|
||||||
|
|
||||||
$sortedPackages = PackageSorter::sortPackages($packages);
|
$sortedPackages = PackageSorter::sortPackages($packages);
|
||||||
|
|
||||||
$sortedPackageMap = array();
|
$sortedPackageMap = [];
|
||||||
|
|
||||||
foreach ($sortedPackages as $package) {
|
foreach ($sortedPackages as $package) {
|
||||||
$name = $package->getName();
|
$name = $package->getName();
|
||||||
$sortedPackageMap[] = array($packages[$name], $paths[$name]);
|
$sortedPackageMap[] = [$packages[$name], $paths[$name]];
|
||||||
}
|
}
|
||||||
|
|
||||||
return $sortedPackageMap;
|
return $sortedPackageMap;
|
||||||
|
|
|
@ -36,11 +36,10 @@ class ClassMapGenerator
|
||||||
*
|
*
|
||||||
* @param \Traversable<string>|array<string> $dirs Directories or a single path to search in
|
* @param \Traversable<string>|array<string> $dirs Directories or a single path to search in
|
||||||
* @param string $file The name of the class map file
|
* @param string $file The name of the class map file
|
||||||
* @return void
|
|
||||||
*/
|
*/
|
||||||
public static function dump(iterable $dirs, string $file): void
|
public static function dump(iterable $dirs, string $file): void
|
||||||
{
|
{
|
||||||
$maps = array();
|
$maps = [];
|
||||||
|
|
||||||
foreach ($dirs as $dir) {
|
foreach ($dirs as $dir) {
|
||||||
$maps = array_merge($maps, static::createMap($dir));
|
$maps = array_merge($maps, static::createMap($dir));
|
||||||
|
@ -61,7 +60,7 @@ class ClassMapGenerator
|
||||||
* @return array<class-string, non-empty-string> A class map array
|
* @return array<class-string, non-empty-string> A class map array
|
||||||
* @throws \RuntimeException When the path is neither an existing file nor directory
|
* @throws \RuntimeException When the path is neither an existing file nor directory
|
||||||
*/
|
*/
|
||||||
public static function createMap($path, string $excluded = null, IOInterface $io = null, ?string $namespace = null, ?string $autoloadType = null, array &$scannedFiles = array()): array
|
public static function createMap($path, ?string $excluded = null, ?IOInterface $io = null, ?string $namespace = null, ?string $autoloadType = null, array &$scannedFiles = []): array
|
||||||
{
|
{
|
||||||
$generator = new \Composer\ClassMapGenerator\ClassMapGenerator(['php', 'inc', 'hh']);
|
$generator = new \Composer\ClassMapGenerator\ClassMapGenerator(['php', 'inc', 'hh']);
|
||||||
$fileList = new FileList();
|
$fileList = new FileList();
|
||||||
|
|
|
@ -49,25 +49,20 @@ class PhpFileCleaner
|
||||||
|
|
||||||
/**
|
/**
|
||||||
* @param string[] $types
|
* @param string[] $types
|
||||||
* @return void
|
|
||||||
*/
|
*/
|
||||||
public static function setTypeConfig(array $types): void
|
public static function setTypeConfig(array $types): void
|
||||||
{
|
{
|
||||||
foreach ($types as $type) {
|
foreach ($types as $type) {
|
||||||
self::$typeConfig[$type[0]] = array(
|
self::$typeConfig[$type[0]] = [
|
||||||
'name' => $type,
|
'name' => $type,
|
||||||
'length' => \strlen($type),
|
'length' => \strlen($type),
|
||||||
'pattern' => '{.\b(?<![\$:>])'.$type.'\s++[a-zA-Z_\x7f-\xff:][a-zA-Z0-9_\x7f-\xff:\-]*+}Ais',
|
'pattern' => '{.\b(?<![\$:>])'.$type.'\s++[a-zA-Z_\x7f-\xff:][a-zA-Z0-9_\x7f-\xff:\-]*+}Ais',
|
||||||
);
|
];
|
||||||
}
|
}
|
||||||
|
|
||||||
self::$restPattern = '{[^?"\'</'.implode('', array_keys(self::$typeConfig)).']+}A';
|
self::$restPattern = '{[^?"\'</'.implode('', array_keys(self::$typeConfig)).']+}A';
|
||||||
}
|
}
|
||||||
|
|
||||||
/**
|
|
||||||
* @param string $contents
|
|
||||||
* @param int $maxMatches
|
|
||||||
*/
|
|
||||||
public function __construct(string $contents, int $maxMatches)
|
public function __construct(string $contents, int $maxMatches)
|
||||||
{
|
{
|
||||||
$this->contents = $contents;
|
$this->contents = $contents;
|
||||||
|
@ -75,9 +70,6 @@ class PhpFileCleaner
|
||||||
$this->maxMatches = $maxMatches;
|
$this->maxMatches = $maxMatches;
|
||||||
}
|
}
|
||||||
|
|
||||||
/**
|
|
||||||
* @return string
|
|
||||||
*/
|
|
||||||
public function clean(): string
|
public function clean(): string
|
||||||
{
|
{
|
||||||
$clean = '';
|
$clean = '';
|
||||||
|
@ -149,9 +141,6 @@ class PhpFileCleaner
|
||||||
return $clean;
|
return $clean;
|
||||||
}
|
}
|
||||||
|
|
||||||
/**
|
|
||||||
* @return void
|
|
||||||
*/
|
|
||||||
private function skipToPhp(): void
|
private function skipToPhp(): void
|
||||||
{
|
{
|
||||||
while ($this->index < $this->len) {
|
while ($this->index < $this->len) {
|
||||||
|
@ -164,10 +153,6 @@ class PhpFileCleaner
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
|
|
||||||
/**
|
|
||||||
* @param string $delimiter
|
|
||||||
* @return void
|
|
||||||
*/
|
|
||||||
private function skipString(string $delimiter): void
|
private function skipString(string $delimiter): void
|
||||||
{
|
{
|
||||||
$this->index += 1;
|
$this->index += 1;
|
||||||
|
@ -184,9 +169,6 @@ class PhpFileCleaner
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
|
|
||||||
/**
|
|
||||||
* @return void
|
|
||||||
*/
|
|
||||||
private function skipComment(): void
|
private function skipComment(): void
|
||||||
{
|
{
|
||||||
$this->index += 2;
|
$this->index += 2;
|
||||||
|
@ -200,9 +182,6 @@ class PhpFileCleaner
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
|
|
||||||
/**
|
|
||||||
* @return void
|
|
||||||
*/
|
|
||||||
private function skipToNewline(): void
|
private function skipToNewline(): void
|
||||||
{
|
{
|
||||||
while ($this->index < $this->len) {
|
while ($this->index < $this->len) {
|
||||||
|
@ -213,10 +192,6 @@ class PhpFileCleaner
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
|
|
||||||
/**
|
|
||||||
* @param string $delimiter
|
|
||||||
* @return void
|
|
||||||
*/
|
|
||||||
private function skipHeredoc(string $delimiter): void
|
private function skipHeredoc(string $delimiter): void
|
||||||
{
|
{
|
||||||
$firstDelimiterChar = $delimiter[0];
|
$firstDelimiterChar = $delimiter[0];
|
||||||
|
@ -256,10 +231,6 @@ class PhpFileCleaner
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
|
|
||||||
/**
|
|
||||||
* @param string $char
|
|
||||||
* @return bool
|
|
||||||
*/
|
|
||||||
private function peek(string $char): bool
|
private function peek(string $char): bool
|
||||||
{
|
{
|
||||||
return $this->index + 1 < $this->len && $this->contents[$this->index + 1] === $char;
|
return $this->index + 1 < $this->len && $this->contents[$this->index + 1] === $char;
|
||||||
|
@ -268,9 +239,8 @@ class PhpFileCleaner
|
||||||
/**
|
/**
|
||||||
* @param non-empty-string $regex
|
* @param non-empty-string $regex
|
||||||
* @param null|array<int, string> $match
|
* @param null|array<int, string> $match
|
||||||
* @return bool
|
|
||||||
*/
|
*/
|
||||||
private function match($regex, array &$match = null): bool
|
private function match($regex, ?array &$match = null): bool
|
||||||
{
|
{
|
||||||
return Preg::isMatch($regex, $this->contents, $match, 0, $this->index);
|
return Preg::isMatch($regex, $this->contents, $match, 0, $this->index);
|
||||||
}
|
}
|
||||||
|
|
|
@ -42,13 +42,12 @@ class Cache
|
||||||
private $readOnly;
|
private $readOnly;
|
||||||
|
|
||||||
/**
|
/**
|
||||||
* @param IOInterface $io
|
|
||||||
* @param string $cacheDir location of the cache
|
* @param string $cacheDir location of the cache
|
||||||
* @param string $allowlist List of characters that are allowed in path names (used in a regex character class)
|
* @param string $allowlist List of characters that are allowed in path names (used in a regex character class)
|
||||||
* @param Filesystem $filesystem optional filesystem instance
|
* @param Filesystem $filesystem optional filesystem instance
|
||||||
* @param bool $readOnly whether the cache is in readOnly mode
|
* @param bool $readOnly whether the cache is in readOnly mode
|
||||||
*/
|
*/
|
||||||
public function __construct(IOInterface $io, string $cacheDir, string $allowlist = 'a-z0-9.', Filesystem $filesystem = null, bool $readOnly = false)
|
public function __construct(IOInterface $io, string $cacheDir, string $allowlist = 'a-z0-9.', ?Filesystem $filesystem = null, bool $readOnly = false)
|
||||||
{
|
{
|
||||||
$this->io = $io;
|
$this->io = $io;
|
||||||
$this->root = rtrim($cacheDir, '/\\') . '/';
|
$this->root = rtrim($cacheDir, '/\\') . '/';
|
||||||
|
@ -62,8 +61,6 @@ class Cache
|
||||||
}
|
}
|
||||||
|
|
||||||
/**
|
/**
|
||||||
* @param bool $readOnly
|
|
||||||
*
|
|
||||||
* @return void
|
* @return void
|
||||||
*/
|
*/
|
||||||
public function setReadOnly(bool $readOnly)
|
public function setReadOnly(bool $readOnly)
|
||||||
|
@ -80,8 +77,6 @@ class Cache
|
||||||
}
|
}
|
||||||
|
|
||||||
/**
|
/**
|
||||||
* @param string $path
|
|
||||||
*
|
|
||||||
* @return bool
|
* @return bool
|
||||||
*/
|
*/
|
||||||
public static function isUsable(string $path)
|
public static function isUsable(string $path)
|
||||||
|
@ -121,8 +116,6 @@ class Cache
|
||||||
}
|
}
|
||||||
|
|
||||||
/**
|
/**
|
||||||
* @param string $file
|
|
||||||
*
|
|
||||||
* @return string|false
|
* @return string|false
|
||||||
*/
|
*/
|
||||||
public function read(string $file)
|
public function read(string $file)
|
||||||
|
@ -140,9 +133,6 @@ class Cache
|
||||||
}
|
}
|
||||||
|
|
||||||
/**
|
/**
|
||||||
* @param string $file
|
|
||||||
* @param string $contents
|
|
||||||
*
|
|
||||||
* @return bool
|
* @return bool
|
||||||
*/
|
*/
|
||||||
public function write(string $file, string $contents)
|
public function write(string $file, string $contents)
|
||||||
|
@ -184,8 +174,6 @@ class Cache
|
||||||
/**
|
/**
|
||||||
* Copy a file into the cache
|
* Copy a file into the cache
|
||||||
*
|
*
|
||||||
* @param string $file
|
|
||||||
* @param string $source
|
|
||||||
*
|
*
|
||||||
* @return bool
|
* @return bool
|
||||||
*/
|
*/
|
||||||
|
@ -210,8 +198,6 @@ class Cache
|
||||||
/**
|
/**
|
||||||
* Copy a file out of the cache
|
* Copy a file out of the cache
|
||||||
*
|
*
|
||||||
* @param string $file
|
|
||||||
* @param string $target
|
|
||||||
*
|
*
|
||||||
* @return bool
|
* @return bool
|
||||||
*/
|
*/
|
||||||
|
@ -259,8 +245,6 @@ class Cache
|
||||||
}
|
}
|
||||||
|
|
||||||
/**
|
/**
|
||||||
* @param string $file
|
|
||||||
*
|
|
||||||
* @return bool
|
* @return bool
|
||||||
*/
|
*/
|
||||||
public function remove(string $file)
|
public function remove(string $file)
|
||||||
|
@ -290,7 +274,6 @@ class Cache
|
||||||
}
|
}
|
||||||
|
|
||||||
/**
|
/**
|
||||||
* @param string $file
|
|
||||||
* @return int|false
|
* @return int|false
|
||||||
* @phpstan-return int<0, max>|false
|
* @phpstan-return int<0, max>|false
|
||||||
*/
|
*/
|
||||||
|
@ -307,9 +290,6 @@ class Cache
|
||||||
}
|
}
|
||||||
|
|
||||||
/**
|
/**
|
||||||
* @param int $ttl
|
|
||||||
* @param int $maxSize
|
|
||||||
*
|
|
||||||
* @return bool
|
* @return bool
|
||||||
*/
|
*/
|
||||||
public function gc(int $ttl, int $maxSize)
|
public function gc(int $ttl, int $maxSize)
|
||||||
|
@ -362,8 +342,6 @@ class Cache
|
||||||
}
|
}
|
||||||
|
|
||||||
/**
|
/**
|
||||||
* @param string $file
|
|
||||||
*
|
|
||||||
* @return string|false
|
* @return string|false
|
||||||
*/
|
*/
|
||||||
public function sha1(string $file)
|
public function sha1(string $file)
|
||||||
|
@ -379,8 +357,6 @@ class Cache
|
||||||
}
|
}
|
||||||
|
|
||||||
/**
|
/**
|
||||||
* @param string $file
|
|
||||||
*
|
|
||||||
* @return string|false
|
* @return string|false
|
||||||
*/
|
*/
|
||||||
public function sha256(string $file)
|
public function sha256(string $file)
|
||||||
|
|
|
@ -21,9 +21,6 @@ use Symfony\Component\Console\Output\OutputInterface;
|
||||||
*/
|
*/
|
||||||
class AboutCommand extends BaseCommand
|
class AboutCommand extends BaseCommand
|
||||||
{
|
{
|
||||||
/**
|
|
||||||
* @return void
|
|
||||||
*/
|
|
||||||
protected function configure(): void
|
protected function configure(): void
|
||||||
{
|
{
|
||||||
$this
|
$this
|
||||||
|
|
|
@ -43,15 +43,12 @@ class ArchiveCommand extends BaseCommand
|
||||||
|
|
||||||
private const FORMATS = ['tar', 'tar.gz', 'tar.bz2', 'zip'];
|
private const FORMATS = ['tar', 'tar.gz', 'tar.bz2', 'zip'];
|
||||||
|
|
||||||
/**
|
|
||||||
* @return void
|
|
||||||
*/
|
|
||||||
protected function configure(): void
|
protected function configure(): void
|
||||||
{
|
{
|
||||||
$this
|
$this
|
||||||
->setName('archive')
|
->setName('archive')
|
||||||
->setDescription('Creates an archive of this composer package')
|
->setDescription('Creates an archive of this composer package')
|
||||||
->setDefinition(array(
|
->setDefinition([
|
||||||
new InputArgument('package', InputArgument::OPTIONAL, 'The package to archive instead of the current project', null, $this->suggestAvailablePackage()),
|
new InputArgument('package', InputArgument::OPTIONAL, 'The package to archive instead of the current project', null, $this->suggestAvailablePackage()),
|
||||||
new InputArgument('version', InputArgument::OPTIONAL, 'A version constraint to find the package to archive'),
|
new InputArgument('version', InputArgument::OPTIONAL, 'A version constraint to find the package to archive'),
|
||||||
new InputOption('format', 'f', InputOption::VALUE_REQUIRED, 'Format of the resulting archive: tar, tar.gz, tar.bz2 or zip (default tar)', null, self::FORMATS),
|
new InputOption('format', 'f', InputOption::VALUE_REQUIRED, 'Format of the resulting archive: tar, tar.gz, tar.bz2 or zip (default tar)', null, self::FORMATS),
|
||||||
|
@ -59,7 +56,7 @@ class ArchiveCommand extends BaseCommand
|
||||||
new InputOption('file', null, InputOption::VALUE_REQUIRED, 'Write the archive with the given file name.'
|
new InputOption('file', null, InputOption::VALUE_REQUIRED, 'Write the archive with the given file name.'
|
||||||
.' Note that the format will be appended.'),
|
.' Note that the format will be appended.'),
|
||||||
new InputOption('ignore-filters', null, InputOption::VALUE_NONE, 'Ignore filters when saving package'),
|
new InputOption('ignore-filters', null, InputOption::VALUE_NONE, 'Ignore filters when saving package'),
|
||||||
))
|
])
|
||||||
->setHelp(
|
->setHelp(
|
||||||
<<<EOT
|
<<<EOT
|
||||||
The <info>archive</info> command creates an archive of the specified format
|
The <info>archive</info> command creates an archive of the specified format
|
||||||
|
@ -150,9 +147,6 @@ EOT
|
||||||
}
|
}
|
||||||
|
|
||||||
/**
|
/**
|
||||||
* @param string $packageName
|
|
||||||
* @param string|null $version
|
|
||||||
*
|
|
||||||
* @return (BasePackage&CompletePackageInterface)|false
|
* @return (BasePackage&CompletePackageInterface)|false
|
||||||
*/
|
*/
|
||||||
protected function selectPackage(IOInterface $io, string $packageName, ?string $version = null)
|
protected function selectPackage(IOInterface $io, string $packageName, ?string $version = null)
|
||||||
|
@ -161,7 +155,7 @@ EOT
|
||||||
|
|
||||||
if ($composer = $this->tryComposer()) {
|
if ($composer = $this->tryComposer()) {
|
||||||
$localRepo = $composer->getRepositoryManager()->getLocalRepository();
|
$localRepo = $composer->getRepositoryManager()->getLocalRepository();
|
||||||
$repo = new CompositeRepository(array_merge(array($localRepo), $composer->getRepositoryManager()->getRepositories()));
|
$repo = new CompositeRepository(array_merge([$localRepo], $composer->getRepositoryManager()->getRepositories()));
|
||||||
} else {
|
} else {
|
||||||
$defaultRepos = RepositoryFactory::defaultReposWithDefaultManager($io);
|
$defaultRepos = RepositoryFactory::defaultReposWithDefaultManager($io);
|
||||||
$io->writeError('No composer.json found in the current directory, searching packages from ' . implode(', ', array_keys($defaultRepos)));
|
$io->writeError('No composer.json found in the current directory, searching packages from ' . implode(', ', array_keys($defaultRepos)));
|
||||||
|
|
|
@ -1,5 +1,15 @@
|
||||||
<?php declare(strict_types=1);
|
<?php declare(strict_types=1);
|
||||||
|
|
||||||
|
/*
|
||||||
|
* This file is part of Composer.
|
||||||
|
*
|
||||||
|
* (c) Nils Adermann <naderman@naderman.de>
|
||||||
|
* Jordi Boggiano <j.boggiano@seld.be>
|
||||||
|
*
|
||||||
|
* For the full copyright and license information, please view the LICENSE
|
||||||
|
* file that was distributed with this source code.
|
||||||
|
*/
|
||||||
|
|
||||||
namespace Composer\Command;
|
namespace Composer\Command;
|
||||||
|
|
||||||
use Composer\Composer;
|
use Composer\Composer;
|
||||||
|
@ -19,11 +29,11 @@ class AuditCommand extends BaseCommand
|
||||||
$this
|
$this
|
||||||
->setName('audit')
|
->setName('audit')
|
||||||
->setDescription('Checks for security vulnerability advisories for installed packages')
|
->setDescription('Checks for security vulnerability advisories for installed packages')
|
||||||
->setDefinition(array(
|
->setDefinition([
|
||||||
new InputOption('no-dev', null, InputOption::VALUE_NONE, 'Disables auditing of require-dev packages.'),
|
new InputOption('no-dev', null, InputOption::VALUE_NONE, 'Disables auditing of require-dev packages.'),
|
||||||
new InputOption('format', 'f', InputOption::VALUE_REQUIRED, 'Output format. Must be "table", "plain", "json", or "summary".', Auditor::FORMAT_TABLE, Auditor::FORMATS),
|
new InputOption('format', 'f', InputOption::VALUE_REQUIRED, 'Output format. Must be "table", "plain", "json", or "summary".', Auditor::FORMAT_TABLE, Auditor::FORMATS),
|
||||||
new InputOption('locked', null, InputOption::VALUE_NONE, 'Audit based on the lock file instead of the installed packages.'),
|
new InputOption('locked', null, InputOption::VALUE_NONE, 'Audit based on the lock file instead of the installed packages.'),
|
||||||
))
|
])
|
||||||
->setHelp(
|
->setHelp(
|
||||||
<<<EOT
|
<<<EOT
|
||||||
The <info>audit</info> command checks for security vulnerability advisories for installed packages.
|
The <info>audit</info> command checks for security vulnerability advisories for installed packages.
|
||||||
|
@ -43,6 +53,7 @@ EOT
|
||||||
|
|
||||||
if (count($packages) === 0) {
|
if (count($packages) === 0) {
|
||||||
$this->getIO()->writeError('No packages - skipping audit.');
|
$this->getIO()->writeError('No packages - skipping audit.');
|
||||||
|
|
||||||
return 0;
|
return 0;
|
||||||
}
|
}
|
||||||
|
|
||||||
|
@ -56,7 +67,6 @@ EOT
|
||||||
}
|
}
|
||||||
|
|
||||||
/**
|
/**
|
||||||
* @param InputInterface $input
|
|
||||||
* @return PackageInterface[]
|
* @return PackageInterface[]
|
||||||
*/
|
*/
|
||||||
private function getPackages(Composer $composer, InputInterface $input): array
|
private function getPackages(Composer $composer, InputInterface $input): array
|
||||||
|
@ -66,11 +76,12 @@ EOT
|
||||||
throw new \UnexpectedValueException('Valid composer.json and composer.lock files are required to run this command with --locked');
|
throw new \UnexpectedValueException('Valid composer.json and composer.lock files are required to run this command with --locked');
|
||||||
}
|
}
|
||||||
$locker = $composer->getLocker();
|
$locker = $composer->getLocker();
|
||||||
|
|
||||||
return $locker->getLockedRepository(!$input->getOption('no-dev'))->getPackages();
|
return $locker->getLockedRepository(!$input->getOption('no-dev'))->getPackages();
|
||||||
}
|
}
|
||||||
|
|
||||||
$rootPkg = $composer->getPackage();
|
$rootPkg = $composer->getPackage();
|
||||||
$installedRepo = new InstalledRepository(array($composer->getRepositoryManager()->getLocalRepository()));
|
$installedRepo = new InstalledRepository([$composer->getRepositoryManager()->getLocalRepository()]);
|
||||||
|
|
||||||
if ($input->getOption('no-dev')) {
|
if ($input->getOption('no-dev')) {
|
||||||
return RepositoryUtils::filterRequiredPackages($installedRepo->getPackages(), $rootPkg);
|
return RepositoryUtils::filterRequiredPackages($installedRepo->getPackages(), $rootPkg);
|
||||||
|
|
|
@ -93,7 +93,7 @@ abstract class BaseCommand extends Command
|
||||||
* @param bool|null $disableScripts If null, reads --no-scripts as default
|
* @param bool|null $disableScripts If null, reads --no-scripts as default
|
||||||
* @throws \RuntimeException
|
* @throws \RuntimeException
|
||||||
*/
|
*/
|
||||||
public function requireComposer(bool $disablePlugins = null, bool $disableScripts = null): Composer
|
public function requireComposer(?bool $disablePlugins = null, ?bool $disableScripts = null): Composer
|
||||||
{
|
{
|
||||||
if (null === $this->composer) {
|
if (null === $this->composer) {
|
||||||
$application = parent::getApplication();
|
$application = parent::getApplication();
|
||||||
|
@ -119,7 +119,7 @@ abstract class BaseCommand extends Command
|
||||||
* @param bool|null $disablePlugins If null, reads --no-plugins as default
|
* @param bool|null $disablePlugins If null, reads --no-plugins as default
|
||||||
* @param bool|null $disableScripts If null, reads --no-scripts as default
|
* @param bool|null $disableScripts If null, reads --no-scripts as default
|
||||||
*/
|
*/
|
||||||
public function tryComposer(bool $disablePlugins = null, bool $disableScripts = null): ?Composer
|
public function tryComposer(?bool $disablePlugins = null, ?bool $disableScripts = null): ?Composer
|
||||||
{
|
{
|
||||||
if (null === $this->composer) {
|
if (null === $this->composer) {
|
||||||
$application = parent::getApplication();
|
$application = parent::getApplication();
|
||||||
|
@ -239,7 +239,7 @@ abstract class BaseCommand extends Command
|
||||||
$composer->getEventDispatcher()->dispatch($preCommandRunEvent->getName(), $preCommandRunEvent);
|
$composer->getEventDispatcher()->dispatch($preCommandRunEvent->getName(), $preCommandRunEvent);
|
||||||
}
|
}
|
||||||
|
|
||||||
if (true === $input->hasParameterOption(array('--no-ansi')) && $input->hasOption('no-progress')) {
|
if (true === $input->hasParameterOption(['--no-ansi']) && $input->hasOption('no-progress')) {
|
||||||
$input->setOption('no-progress', true);
|
$input->setOption('no-progress', true);
|
||||||
}
|
}
|
||||||
|
|
||||||
|
@ -282,7 +282,6 @@ abstract class BaseCommand extends Command
|
||||||
/**
|
/**
|
||||||
* Returns preferSource and preferDist values based on the configuration.
|
* Returns preferSource and preferDist values based on the configuration.
|
||||||
*
|
*
|
||||||
* @param bool $keepVcsRequiresPreferSource
|
|
||||||
*
|
*
|
||||||
* @return bool[] An array composed of the preferSource and preferDist values
|
* @return bool[] An array composed of the preferSource and preferDist values
|
||||||
*/
|
*/
|
||||||
|
@ -336,7 +335,7 @@ abstract class BaseCommand extends Command
|
||||||
$preferDist = $input->getOption('prefer-dist');
|
$preferDist = $input->getOption('prefer-dist');
|
||||||
}
|
}
|
||||||
|
|
||||||
return array($preferSource, $preferDist);
|
return [$preferSource, $preferDist];
|
||||||
}
|
}
|
||||||
|
|
||||||
protected function getPlatformRequirementFilter(InputInterface $input): PlatformRequirementFilterInterface
|
protected function getPlatformRequirementFilter(InputInterface $input): PlatformRequirementFilterInterface
|
||||||
|
@ -364,7 +363,7 @@ abstract class BaseCommand extends Command
|
||||||
*/
|
*/
|
||||||
protected function formatRequirements(array $requirements)
|
protected function formatRequirements(array $requirements)
|
||||||
{
|
{
|
||||||
$requires = array();
|
$requires = [];
|
||||||
$requirements = $this->normalizeRequirements($requirements);
|
$requirements = $this->normalizeRequirements($requirements);
|
||||||
foreach ($requirements as $requirement) {
|
foreach ($requirements as $requirement) {
|
||||||
if (!isset($requirement['version'])) {
|
if (!isset($requirement['version'])) {
|
||||||
|
|
|
@ -18,7 +18,6 @@ use Composer\Package\CompletePackageInterface;
|
||||||
use Composer\Package\RootPackage;
|
use Composer\Package\RootPackage;
|
||||||
use Composer\Repository\InstalledArrayRepository;
|
use Composer\Repository\InstalledArrayRepository;
|
||||||
use Composer\Repository\CompositeRepository;
|
use Composer\Repository\CompositeRepository;
|
||||||
use Composer\Repository\RepositoryInterface;
|
|
||||||
use Composer\Repository\RootPackageRepository;
|
use Composer\Repository\RootPackageRepository;
|
||||||
use Composer\Repository\InstalledRepository;
|
use Composer\Repository\InstalledRepository;
|
||||||
use Composer\Repository\PlatformRepository;
|
use Composer\Repository\PlatformRepository;
|
||||||
|
@ -77,19 +76,20 @@ abstract class BaseDependencyCommand extends BaseCommand
|
||||||
|
|
||||||
if (count($localRepo->getPackages()) === 0 && (count($rootPkg->getRequires()) > 0 || count($rootPkg->getDevRequires()) > 0)) {
|
if (count($localRepo->getPackages()) === 0 && (count($rootPkg->getRequires()) > 0 || count($rootPkg->getDevRequires()) > 0)) {
|
||||||
$output->writeln('<warning>No dependencies installed. Try running composer install or update, or use --locked.</warning>');
|
$output->writeln('<warning>No dependencies installed. Try running composer install or update, or use --locked.</warning>');
|
||||||
|
|
||||||
return 1;
|
return 1;
|
||||||
}
|
}
|
||||||
|
|
||||||
$repos[] = $localRepo;
|
$repos[] = $localRepo;
|
||||||
|
|
||||||
$platformOverrides = $composer->getConfig()->get('platform') ?: array();
|
$platformOverrides = $composer->getConfig()->get('platform') ?: [];
|
||||||
$repos[] = new PlatformRepository([], $platformOverrides);
|
$repos[] = new PlatformRepository([], $platformOverrides);
|
||||||
}
|
}
|
||||||
|
|
||||||
$installedRepo = new InstalledRepository($repos);
|
$installedRepo = new InstalledRepository($repos);
|
||||||
|
|
||||||
// Parse package name and constraint
|
// Parse package name and constraint
|
||||||
list($needle, $textConstraint) = array_pad(
|
[$needle, $textConstraint] = array_pad(
|
||||||
explode(':', $input->getArgument(self::ARGUMENT_PACKAGE)),
|
explode(':', $input->getArgument(self::ARGUMENT_PACKAGE)),
|
||||||
2,
|
2,
|
||||||
$input->hasArgument(self::ARGUMENT_CONSTRAINT) ? $input->getArgument(self::ARGUMENT_CONSTRAINT) : '*'
|
$input->hasArgument(self::ARGUMENT_CONSTRAINT) ? $input->getArgument(self::ARGUMENT_CONSTRAINT) : '*'
|
||||||
|
@ -106,12 +106,12 @@ abstract class BaseDependencyCommand extends BaseCommand
|
||||||
if (!$installedRepo->findPackage($needle, $textConstraint)) {
|
if (!$installedRepo->findPackage($needle, $textConstraint)) {
|
||||||
$defaultRepos = new CompositeRepository(RepositoryFactory::defaultRepos($this->getIO(), $composer->getConfig(), $composer->getRepositoryManager()));
|
$defaultRepos = new CompositeRepository(RepositoryFactory::defaultRepos($this->getIO(), $composer->getConfig(), $composer->getRepositoryManager()));
|
||||||
if ($match = $defaultRepos->findPackage($needle, $textConstraint)) {
|
if ($match = $defaultRepos->findPackage($needle, $textConstraint)) {
|
||||||
$installedRepo->addRepository(new InstalledArrayRepository(array(clone $match)));
|
$installedRepo->addRepository(new InstalledArrayRepository([clone $match]));
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
|
|
||||||
// Include replaced packages for inverted lookups as they are then the actual starting point to consider
|
// Include replaced packages for inverted lookups as they are then the actual starting point to consider
|
||||||
$needles = array($needle);
|
$needles = [$needle];
|
||||||
if ($inverted) {
|
if ($inverted) {
|
||||||
foreach ($packages as $package) {
|
foreach ($packages as $package) {
|
||||||
$needles = array_merge($needles, array_map(static function (Link $link): string {
|
$needles = array_merge($needles, array_map(static function (Link $link): string {
|
||||||
|
@ -161,29 +161,27 @@ abstract class BaseDependencyCommand extends BaseCommand
|
||||||
* Assembles and prints a bottom-up table of the dependencies.
|
* Assembles and prints a bottom-up table of the dependencies.
|
||||||
*
|
*
|
||||||
* @param array{PackageInterface, Link, mixed}[] $results
|
* @param array{PackageInterface, Link, mixed}[] $results
|
||||||
*
|
|
||||||
* @return void
|
|
||||||
*/
|
*/
|
||||||
protected function printTable(OutputInterface $output, $results): void
|
protected function printTable(OutputInterface $output, $results): void
|
||||||
{
|
{
|
||||||
$table = array();
|
$table = [];
|
||||||
$doubles = array();
|
$doubles = [];
|
||||||
do {
|
do {
|
||||||
$queue = array();
|
$queue = [];
|
||||||
$rows = array();
|
$rows = [];
|
||||||
foreach ($results as $result) {
|
foreach ($results as $result) {
|
||||||
/**
|
/**
|
||||||
* @var PackageInterface $package
|
* @var PackageInterface $package
|
||||||
* @var Link $link
|
* @var Link $link
|
||||||
*/
|
*/
|
||||||
list($package, $link, $children) = $result;
|
[$package, $link, $children] = $result;
|
||||||
$unique = (string) $link;
|
$unique = (string) $link;
|
||||||
if (isset($doubles[$unique])) {
|
if (isset($doubles[$unique])) {
|
||||||
continue;
|
continue;
|
||||||
}
|
}
|
||||||
$doubles[$unique] = true;
|
$doubles[$unique] = true;
|
||||||
$version = $package->getPrettyVersion() === RootPackage::DEFAULT_PRETTY_VERSION ? '-' : $package->getPrettyVersion();
|
$version = $package->getPrettyVersion() === RootPackage::DEFAULT_PRETTY_VERSION ? '-' : $package->getPrettyVersion();
|
||||||
$rows[] = array($package->getPrettyName(), $version, $link->getDescription(), sprintf('%s (%s)', $link->getTarget(), $link->getPrettyConstraint()));
|
$rows[] = [$package->getPrettyName(), $version, $link->getDescription(), sprintf('%s (%s)', $link->getTarget(), $link->getPrettyConstraint())];
|
||||||
if ($children) {
|
if ($children) {
|
||||||
$queue = array_merge($queue, $children);
|
$queue = array_merge($queue, $children);
|
||||||
}
|
}
|
||||||
|
@ -197,18 +195,16 @@ abstract class BaseDependencyCommand extends BaseCommand
|
||||||
|
|
||||||
/**
|
/**
|
||||||
* Init styles for tree
|
* Init styles for tree
|
||||||
*
|
|
||||||
* @return void
|
|
||||||
*/
|
*/
|
||||||
protected function initStyles(OutputInterface $output): void
|
protected function initStyles(OutputInterface $output): void
|
||||||
{
|
{
|
||||||
$this->colors = array(
|
$this->colors = [
|
||||||
'green',
|
'green',
|
||||||
'yellow',
|
'yellow',
|
||||||
'cyan',
|
'cyan',
|
||||||
'magenta',
|
'magenta',
|
||||||
'blue',
|
'blue',
|
||||||
);
|
];
|
||||||
|
|
||||||
foreach ($this->colors as $color) {
|
foreach ($this->colors as $color) {
|
||||||
$style = new OutputFormatterStyle($color);
|
$style = new OutputFormatterStyle($color);
|
||||||
|
@ -222,15 +218,13 @@ abstract class BaseDependencyCommand extends BaseCommand
|
||||||
* @param array{PackageInterface, Link, mixed[]|bool}[] $results Results to be printed at this level.
|
* @param array{PackageInterface, Link, mixed[]|bool}[] $results Results to be printed at this level.
|
||||||
* @param string $prefix Prefix of the current tree level.
|
* @param string $prefix Prefix of the current tree level.
|
||||||
* @param int $level Current level of recursion.
|
* @param int $level Current level of recursion.
|
||||||
*
|
|
||||||
* @return void
|
|
||||||
*/
|
*/
|
||||||
protected function printTree(array $results, string $prefix = '', int $level = 1): void
|
protected function printTree(array $results, string $prefix = '', int $level = 1): void
|
||||||
{
|
{
|
||||||
$count = count($results);
|
$count = count($results);
|
||||||
$idx = 0;
|
$idx = 0;
|
||||||
foreach ($results as $result) {
|
foreach ($results as $result) {
|
||||||
list($package, $link, $children) = $result;
|
[$package, $link, $children] = $result;
|
||||||
|
|
||||||
$color = $this->colors[$level % count($this->colors)];
|
$color = $this->colors[$level % count($this->colors)];
|
||||||
$prevColor = $this->colors[($level - 1) % count($this->colors)];
|
$prevColor = $this->colors[($level - 1) % count($this->colors)];
|
||||||
|
@ -246,16 +240,11 @@ abstract class BaseDependencyCommand extends BaseCommand
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
|
|
||||||
/**
|
|
||||||
* @param string $line
|
|
||||||
*
|
|
||||||
* @return void
|
|
||||||
*/
|
|
||||||
private function writeTreeLine(string $line): void
|
private function writeTreeLine(string $line): void
|
||||||
{
|
{
|
||||||
$io = $this->getIO();
|
$io = $this->getIO();
|
||||||
if (!$io->isDecorated()) {
|
if (!$io->isDecorated()) {
|
||||||
$line = str_replace(array('└', '├', '──', '│'), array('`-', '|-', '-', '|'), $line);
|
$line = str_replace(['└', '├', '──', '│'], ['`-', '|-', '-', '|'], $line);
|
||||||
}
|
}
|
||||||
|
|
||||||
$io->write($line);
|
$io->write($line);
|
||||||
|
|
|
@ -12,29 +12,18 @@
|
||||||
|
|
||||||
namespace Composer\Command;
|
namespace Composer\Command;
|
||||||
|
|
||||||
use Composer\DependencyResolver\Request;
|
|
||||||
use Composer\Package\AliasPackage;
|
use Composer\Package\AliasPackage;
|
||||||
use Composer\Package\Locker;
|
use Composer\Package\Locker;
|
||||||
use Composer\Package\Version\VersionBumper;
|
use Composer\Package\Version\VersionBumper;
|
||||||
use Composer\Package\Version\VersionSelector;
|
|
||||||
use Composer\Util\Filesystem;
|
use Composer\Util\Filesystem;
|
||||||
use Symfony\Component\Console\Input\InputInterface;
|
use Symfony\Component\Console\Input\InputInterface;
|
||||||
use Composer\Console\Input\InputArgument;
|
use Composer\Console\Input\InputArgument;
|
||||||
use Composer\Console\Input\InputOption;
|
use Composer\Console\Input\InputOption;
|
||||||
use Symfony\Component\Console\Output\OutputInterface;
|
use Symfony\Component\Console\Output\OutputInterface;
|
||||||
use Composer\Factory;
|
use Composer\Factory;
|
||||||
use Composer\Installer;
|
|
||||||
use Composer\Installer\InstallerEvents;
|
|
||||||
use Composer\Json\JsonFile;
|
use Composer\Json\JsonFile;
|
||||||
use Composer\Json\JsonManipulator;
|
use Composer\Json\JsonManipulator;
|
||||||
use Composer\Package\Version\VersionParser;
|
|
||||||
use Composer\Package\Loader\ArrayLoader;
|
|
||||||
use Composer\Package\BasePackage;
|
|
||||||
use Composer\Plugin\CommandEvent;
|
|
||||||
use Composer\Plugin\PluginEvents;
|
|
||||||
use Composer\Repository\CompositeRepository;
|
|
||||||
use Composer\Repository\PlatformRepository;
|
use Composer\Repository\PlatformRepository;
|
||||||
use Composer\IO\IOInterface;
|
|
||||||
use Composer\Util\Silencer;
|
use Composer\Util\Silencer;
|
||||||
|
|
||||||
/**
|
/**
|
||||||
|
@ -52,11 +41,11 @@ final class BumpCommand extends BaseCommand
|
||||||
$this
|
$this
|
||||||
->setName('bump')
|
->setName('bump')
|
||||||
->setDescription('Increases the lower limit of your composer.json requirements to the currently installed versions')
|
->setDescription('Increases the lower limit of your composer.json requirements to the currently installed versions')
|
||||||
->setDefinition(array(
|
->setDefinition([
|
||||||
new InputArgument('packages', InputArgument::IS_ARRAY | InputArgument::OPTIONAL, 'Optional package name(s) to restrict which packages are bumped.', null, $this->suggestRootRequirement()),
|
new InputArgument('packages', InputArgument::IS_ARRAY | InputArgument::OPTIONAL, 'Optional package name(s) to restrict which packages are bumped.', null, $this->suggestRootRequirement()),
|
||||||
new InputOption('dev-only', 'D', InputOption::VALUE_NONE, 'Only bump requirements in "require-dev".'),
|
new InputOption('dev-only', 'D', InputOption::VALUE_NONE, 'Only bump requirements in "require-dev".'),
|
||||||
new InputOption('no-dev-only', 'R', InputOption::VALUE_NONE, 'Only bump requirements in "require".'),
|
new InputOption('no-dev-only', 'R', InputOption::VALUE_NONE, 'Only bump requirements in "require".'),
|
||||||
))
|
])
|
||||||
->setHelp(
|
->setHelp(
|
||||||
<<<EOT
|
<<<EOT
|
||||||
The <info>bump</info> command increases the lower limit of your composer.json requirements
|
The <info>bump</info> command increases the lower limit of your composer.json requirements
|
||||||
|
@ -135,7 +124,7 @@ EOT
|
||||||
$tasks = [];
|
$tasks = [];
|
||||||
if (!$input->getOption('no-dev-only')) {
|
if (!$input->getOption('no-dev-only')) {
|
||||||
$tasks['require-dev'] = $composer->getPackage()->getDevRequires();
|
$tasks['require-dev'] = $composer->getPackage()->getDevRequires();
|
||||||
};
|
}
|
||||||
if (!$input->getOption('dev-only')) {
|
if (!$input->getOption('dev-only')) {
|
||||||
$tasks['require'] = $composer->getPackage()->getRequires();
|
$tasks['require'] = $composer->getPackage()->getRequires();
|
||||||
}
|
}
|
||||||
|
|
|
@ -24,18 +24,15 @@ use Composer\Json\JsonFile;
|
||||||
|
|
||||||
class CheckPlatformReqsCommand extends BaseCommand
|
class CheckPlatformReqsCommand extends BaseCommand
|
||||||
{
|
{
|
||||||
/**
|
|
||||||
* @return void
|
|
||||||
*/
|
|
||||||
protected function configure(): void
|
protected function configure(): void
|
||||||
{
|
{
|
||||||
$this->setName('check-platform-reqs')
|
$this->setName('check-platform-reqs')
|
||||||
->setDescription('Check that platform requirements are satisfied')
|
->setDescription('Check that platform requirements are satisfied')
|
||||||
->setDefinition(array(
|
->setDefinition([
|
||||||
new InputOption('no-dev', null, InputOption::VALUE_NONE, 'Disables checking of require-dev packages requirements.'),
|
new InputOption('no-dev', null, InputOption::VALUE_NONE, 'Disables checking of require-dev packages requirements.'),
|
||||||
new InputOption('lock', null, InputOption::VALUE_NONE, 'Checks requirements only from the lock file, not from installed packages.'),
|
new InputOption('lock', null, InputOption::VALUE_NONE, 'Checks requirements only from the lock file, not from installed packages.'),
|
||||||
new InputOption('format', 'f', InputOption::VALUE_REQUIRED, 'Format of the output: text or json', 'text', ['json', 'text']),
|
new InputOption('format', 'f', InputOption::VALUE_REQUIRED, 'Format of the output: text or json', 'text', ['json', 'text']),
|
||||||
))
|
])
|
||||||
->setHelp(
|
->setHelp(
|
||||||
<<<EOT
|
<<<EOT
|
||||||
Checks that your PHP and extensions versions match the platform requirements of the installed packages.
|
Checks that your PHP and extensions versions match the platform requirements of the installed packages.
|
||||||
|
@ -52,8 +49,8 @@ EOT
|
||||||
{
|
{
|
||||||
$composer = $this->requireComposer();
|
$composer = $this->requireComposer();
|
||||||
|
|
||||||
$requires = array();
|
$requires = [];
|
||||||
$removePackages = array();
|
$removePackages = [];
|
||||||
if ($input->getOption('lock')) {
|
if ($input->getOption('lock')) {
|
||||||
$this->getIO()->writeError('<info>Checking '.($input->getOption('no-dev') ? 'non-dev ' : '').'platform requirements using the lock file</info>');
|
$this->getIO()->writeError('<info>Checking '.($input->getOption('no-dev') ? 'non-dev ' : '').'platform requirements using the lock file</info>');
|
||||||
$installedRepo = $composer->getLocker()->getLockedRepository(!$input->getOption('no-dev'));
|
$installedRepo = $composer->getLocker()->getLockedRepository(!$input->getOption('no-dev'));
|
||||||
|
@ -76,10 +73,10 @@ EOT
|
||||||
}
|
}
|
||||||
|
|
||||||
foreach ($requires as $require => $link) {
|
foreach ($requires as $require => $link) {
|
||||||
$requires[$require] = array($link);
|
$requires[$require] = [$link];
|
||||||
}
|
}
|
||||||
|
|
||||||
$installedRepo = new InstalledRepository(array($installedRepo, new RootPackageRepository(clone $composer->getPackage())));
|
$installedRepo = new InstalledRepository([$installedRepo, new RootPackageRepository(clone $composer->getPackage())]);
|
||||||
foreach ($installedRepo->getPackages() as $package) {
|
foreach ($installedRepo->getPackages() as $package) {
|
||||||
if (in_array($package->getName(), $removePackages, true)) {
|
if (in_array($package->getName(), $removePackages, true)) {
|
||||||
continue;
|
continue;
|
||||||
|
@ -91,9 +88,9 @@ EOT
|
||||||
|
|
||||||
ksort($requires);
|
ksort($requires);
|
||||||
|
|
||||||
$installedRepo->addRepository(new PlatformRepository(array(), array()));
|
$installedRepo->addRepository(new PlatformRepository([], []));
|
||||||
|
|
||||||
$results = array();
|
$results = [];
|
||||||
$exitCode = 0;
|
$exitCode = 0;
|
||||||
|
|
||||||
/**
|
/**
|
||||||
|
@ -103,7 +100,7 @@ EOT
|
||||||
if (PlatformRepository::isPlatformPackage($require)) {
|
if (PlatformRepository::isPlatformPackage($require)) {
|
||||||
$candidates = $installedRepo->findPackagesWithReplacersAndProviders($require);
|
$candidates = $installedRepo->findPackagesWithReplacersAndProviders($require);
|
||||||
if ($candidates) {
|
if ($candidates) {
|
||||||
$reqResults = array();
|
$reqResults = [];
|
||||||
foreach ($candidates as $candidate) {
|
foreach ($candidates as $candidate) {
|
||||||
$candidateConstraint = null;
|
$candidateConstraint = null;
|
||||||
if ($candidate->getName() === $require) {
|
if ($candidate->getName() === $require) {
|
||||||
|
@ -125,26 +122,26 @@ EOT
|
||||||
|
|
||||||
foreach ($links as $link) {
|
foreach ($links as $link) {
|
||||||
if (!$link->getConstraint()->matches($candidateConstraint)) {
|
if (!$link->getConstraint()->matches($candidateConstraint)) {
|
||||||
$reqResults[] = array(
|
$reqResults[] = [
|
||||||
$candidate->getName() === $require ? $candidate->getPrettyName() : $require,
|
$candidate->getName() === $require ? $candidate->getPrettyName() : $require,
|
||||||
$candidateConstraint->getPrettyString(),
|
$candidateConstraint->getPrettyString(),
|
||||||
$link,
|
$link,
|
||||||
'<error>failed</error>',
|
'<error>failed</error>',
|
||||||
$candidate->getName() === $require ? '' : '<comment>provided by '.$candidate->getPrettyName().'</comment>',
|
$candidate->getName() === $require ? '' : '<comment>provided by '.$candidate->getPrettyName().'</comment>',
|
||||||
);
|
];
|
||||||
|
|
||||||
// skip to next candidate
|
// skip to next candidate
|
||||||
continue 2;
|
continue 2;
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
|
|
||||||
$results[] = array(
|
$results[] = [
|
||||||
$candidate->getName() === $require ? $candidate->getPrettyName() : $require,
|
$candidate->getName() === $require ? $candidate->getPrettyName() : $require,
|
||||||
$candidateConstraint->getPrettyString(),
|
$candidateConstraint->getPrettyString(),
|
||||||
null,
|
null,
|
||||||
'<info>success</info>',
|
'<info>success</info>',
|
||||||
$candidate->getName() === $require ? '' : '<comment>provided by '.$candidate->getPrettyName().'</comment>',
|
$candidate->getName() === $require ? '' : '<comment>provided by '.$candidate->getPrettyName().'</comment>',
|
||||||
);
|
];
|
||||||
|
|
||||||
// candidate matched, skip to next requirement
|
// candidate matched, skip to next requirement
|
||||||
continue 2;
|
continue 2;
|
||||||
|
@ -157,13 +154,13 @@ EOT
|
||||||
continue;
|
continue;
|
||||||
}
|
}
|
||||||
|
|
||||||
$results[] = array(
|
$results[] = [
|
||||||
$require,
|
$require,
|
||||||
'n/a',
|
'n/a',
|
||||||
$links[0],
|
$links[0],
|
||||||
'<error>missing</error>',
|
'<error>missing</error>',
|
||||||
'',
|
'',
|
||||||
);
|
];
|
||||||
|
|
||||||
$exitCode = max($exitCode, 2);
|
$exitCode = max($exitCode, 2);
|
||||||
}
|
}
|
||||||
|
@ -176,20 +173,18 @@ EOT
|
||||||
|
|
||||||
/**
|
/**
|
||||||
* @param mixed[] $results
|
* @param mixed[] $results
|
||||||
*
|
|
||||||
* @return void
|
|
||||||
*/
|
*/
|
||||||
protected function printTable(OutputInterface $output, array $results, string $format): void
|
protected function printTable(OutputInterface $output, array $results, string $format): void
|
||||||
{
|
{
|
||||||
$rows = array();
|
$rows = [];
|
||||||
foreach ($results as $result) {
|
foreach ($results as $result) {
|
||||||
/**
|
/**
|
||||||
* @var Link|null $link
|
* @var Link|null $link
|
||||||
*/
|
*/
|
||||||
list($platformPackage, $version, $link, $status, $provider) = $result;
|
[$platformPackage, $version, $link, $status, $provider] = $result;
|
||||||
|
|
||||||
if ('json' === $format) {
|
if ('json' === $format) {
|
||||||
$rows[] = array(
|
$rows[] = [
|
||||||
"name" => $platformPackage,
|
"name" => $platformPackage,
|
||||||
"version" => $version,
|
"version" => $version,
|
||||||
"status" => strip_tags($status),
|
"status" => strip_tags($status),
|
||||||
|
@ -200,15 +195,15 @@ EOT
|
||||||
'constraint' => $link->getPrettyConstraint(),
|
'constraint' => $link->getPrettyConstraint(),
|
||||||
] : null,
|
] : null,
|
||||||
"provider" => $provider === '' ? null : strip_tags($provider),
|
"provider" => $provider === '' ? null : strip_tags($provider),
|
||||||
);
|
];
|
||||||
} else {
|
} else {
|
||||||
$rows[] = array(
|
$rows[] = [
|
||||||
$platformPackage,
|
$platformPackage,
|
||||||
$version,
|
$version,
|
||||||
$link,
|
$link,
|
||||||
$link ? sprintf('%s %s %s (%s)', $link->getSource(), $link->getDescription(), $link->getTarget(), $link->getPrettyConstraint()) : '',
|
$link ? sprintf('%s %s %s (%s)', $link->getSource(), $link->getDescription(), $link->getTarget(), $link->getPrettyConstraint()) : '',
|
||||||
rtrim($status.' '.$provider),
|
rtrim($status.' '.$provider),
|
||||||
);
|
];
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
|
|
||||||
|
|
|
@ -23,18 +23,15 @@ use Symfony\Component\Console\Output\OutputInterface;
|
||||||
*/
|
*/
|
||||||
class ClearCacheCommand extends BaseCommand
|
class ClearCacheCommand extends BaseCommand
|
||||||
{
|
{
|
||||||
/**
|
|
||||||
* @return void
|
|
||||||
*/
|
|
||||||
protected function configure(): void
|
protected function configure(): void
|
||||||
{
|
{
|
||||||
$this
|
$this
|
||||||
->setName('clear-cache')
|
->setName('clear-cache')
|
||||||
->setAliases(array('clearcache', 'cc'))
|
->setAliases(['clearcache', 'cc'])
|
||||||
->setDescription('Clears composer\'s internal package cache')
|
->setDescription('Clears composer\'s internal package cache')
|
||||||
->setDefinition(array(
|
->setDefinition([
|
||||||
new InputOption('gc', null, InputOption::VALUE_NONE, 'Only run garbage collection, not a full cache clear'),
|
new InputOption('gc', null, InputOption::VALUE_NONE, 'Only run garbage collection, not a full cache clear'),
|
||||||
))
|
])
|
||||||
->setHelp(
|
->setHelp(
|
||||||
<<<EOT
|
<<<EOT
|
||||||
The <info>clear-cache</info> deletes all cached packages from composer's
|
The <info>clear-cache</info> deletes all cached packages from composer's
|
||||||
|
@ -51,12 +48,12 @@ EOT
|
||||||
$config = Factory::createConfig();
|
$config = Factory::createConfig();
|
||||||
$io = $this->getIO();
|
$io = $this->getIO();
|
||||||
|
|
||||||
$cachePaths = array(
|
$cachePaths = [
|
||||||
'cache-vcs-dir' => $config->get('cache-vcs-dir'),
|
'cache-vcs-dir' => $config->get('cache-vcs-dir'),
|
||||||
'cache-repo-dir' => $config->get('cache-repo-dir'),
|
'cache-repo-dir' => $config->get('cache-repo-dir'),
|
||||||
'cache-files-dir' => $config->get('cache-files-dir'),
|
'cache-files-dir' => $config->get('cache-files-dir'),
|
||||||
'cache-dir' => $config->get('cache-dir'),
|
'cache-dir' => $config->get('cache-dir'),
|
||||||
);
|
];
|
||||||
|
|
||||||
foreach ($cachePaths as $key => $cachePath) {
|
foreach ($cachePaths as $key => $cachePath) {
|
||||||
// only individual dirs get garbage collected
|
// only individual dirs get garbage collected
|
||||||
|
@ -83,7 +80,7 @@ EOT
|
||||||
if ($key === 'cache-files-dir') {
|
if ($key === 'cache-files-dir') {
|
||||||
$cache->gc($config->get('cache-files-ttl'), $config->get('cache-files-maxsize'));
|
$cache->gc($config->get('cache-files-ttl'), $config->get('cache-files-maxsize'));
|
||||||
} elseif ($key === 'cache-repo-dir') {
|
} elseif ($key === 'cache-repo-dir') {
|
||||||
$cache->gc($config->get('cache-ttl'), 1024*1024*1024 /* 1GB, this should almost never clear anything that is not outdated */);
|
$cache->gc($config->get('cache-ttl'), 1024 * 1024 * 1024 /* 1GB, this should almost never clear anything that is not outdated */);
|
||||||
} elseif ($key === 'cache-vcs-dir') {
|
} elseif ($key === 'cache-vcs-dir') {
|
||||||
$cache->gcVcsCache($config->get('cache-ttl'));
|
$cache->gcVcsCache($config->get('cache-ttl'));
|
||||||
}
|
}
|
||||||
|
|
|
@ -33,7 +33,7 @@ trait CompletionTrait
|
||||||
/**
|
/**
|
||||||
* @see BaseCommand::requireComposer()
|
* @see BaseCommand::requireComposer()
|
||||||
*/
|
*/
|
||||||
abstract public function requireComposer(bool $disablePlugins = null, bool $disableScripts = null): Composer;
|
abstract public function requireComposer(?bool $disablePlugins = null, ?bool $disableScripts = null): Composer;
|
||||||
|
|
||||||
/**
|
/**
|
||||||
* Suggestion values for "prefer-install" option
|
* Suggestion values for "prefer-install" option
|
||||||
|
@ -80,9 +80,9 @@ trait CompletionTrait
|
||||||
$platformHint = [];
|
$platformHint = [];
|
||||||
if ($includePlatformPackages) {
|
if ($includePlatformPackages) {
|
||||||
if ($locker->isLocked()) {
|
if ($locker->isLocked()) {
|
||||||
$platformRepo = new PlatformRepository(array(), $locker->getPlatformOverrides());
|
$platformRepo = new PlatformRepository([], $locker->getPlatformOverrides());
|
||||||
} else {
|
} else {
|
||||||
$platformRepo = new PlatformRepository(array(), $composer->getConfig()->get('platform'));
|
$platformRepo = new PlatformRepository([], $composer->getConfig()->get('platform'));
|
||||||
}
|
}
|
||||||
if ($input->getCompletionValue() === '') {
|
if ($input->getCompletionValue() === '') {
|
||||||
// to reduce noise, when no text is yet entered we list only two entries for ext- and lib- prefixes
|
// to reduce noise, when no text is yet entered we list only two entries for ext- and lib- prefixes
|
||||||
|
@ -203,6 +203,7 @@ trait CompletionTrait
|
||||||
$repos = new PlatformRepository([], $this->requireComposer()->getConfig()->get('platform'));
|
$repos = new PlatformRepository([], $this->requireComposer()->getConfig()->get('platform'));
|
||||||
|
|
||||||
$pattern = BasePackage::packageNameToRegexp($input->getCompletionValue().'*');
|
$pattern = BasePackage::packageNameToRegexp($input->getCompletionValue().'*');
|
||||||
|
|
||||||
return array_filter(array_map(static function (PackageInterface $package) {
|
return array_filter(array_map(static function (PackageInterface $package) {
|
||||||
return $package->getName();
|
return $package->getName();
|
||||||
}, $repos->getPackages()), static function (string $name) use ($pattern): bool {
|
}, $repos->getPackages()), static function (string $name) use ($pattern): bool {
|
||||||
|
|
|
@ -59,15 +59,12 @@ class ConfigCommand extends BaseCommand
|
||||||
*/
|
*/
|
||||||
protected $authConfigSource;
|
protected $authConfigSource;
|
||||||
|
|
||||||
/**
|
|
||||||
* @return void
|
|
||||||
*/
|
|
||||||
protected function configure(): void
|
protected function configure(): void
|
||||||
{
|
{
|
||||||
$this
|
$this
|
||||||
->setName('config')
|
->setName('config')
|
||||||
->setDescription('Sets config options')
|
->setDescription('Sets config options')
|
||||||
->setDefinition(array(
|
->setDefinition([
|
||||||
new InputOption('global', 'g', InputOption::VALUE_NONE, 'Apply command to the global config file'),
|
new InputOption('global', 'g', InputOption::VALUE_NONE, 'Apply command to the global config file'),
|
||||||
new InputOption('editor', 'e', InputOption::VALUE_NONE, 'Open editor'),
|
new InputOption('editor', 'e', InputOption::VALUE_NONE, 'Open editor'),
|
||||||
new InputOption('auth', 'a', InputOption::VALUE_NONE, 'Affect auth config file (only used for --editor)'),
|
new InputOption('auth', 'a', InputOption::VALUE_NONE, 'Affect auth config file (only used for --editor)'),
|
||||||
|
@ -81,7 +78,7 @@ class ConfigCommand extends BaseCommand
|
||||||
new InputOption('source', null, InputOption::VALUE_NONE, 'Display where the config value is loaded from'),
|
new InputOption('source', null, InputOption::VALUE_NONE, 'Display where the config value is loaded from'),
|
||||||
new InputArgument('setting-key', null, 'Setting key'),
|
new InputArgument('setting-key', null, 'Setting key'),
|
||||||
new InputArgument('setting-value', InputArgument::IS_ARRAY, 'Setting value'),
|
new InputArgument('setting-value', InputArgument::IS_ARRAY, 'Setting value'),
|
||||||
))
|
])
|
||||||
->setHelp(
|
->setHelp(
|
||||||
<<<EOT
|
<<<EOT
|
||||||
This command allows you to edit composer config settings and repositories
|
This command allows you to edit composer config settings and repositories
|
||||||
|
@ -151,7 +148,6 @@ EOT
|
||||||
}
|
}
|
||||||
|
|
||||||
/**
|
/**
|
||||||
* @return void
|
|
||||||
* @throws \Exception
|
* @throws \Exception
|
||||||
*/
|
*/
|
||||||
protected function initialize(InputInterface $input, OutputInterface $output): void
|
protected function initialize(InputInterface $input, OutputInterface $output): void
|
||||||
|
@ -193,12 +189,12 @@ EOT
|
||||||
// Initialize the global file if it's not there, ignoring any warnings or notices
|
// Initialize the global file if it's not there, ignoring any warnings or notices
|
||||||
if ($input->getOption('global') && !$this->configFile->exists()) {
|
if ($input->getOption('global') && !$this->configFile->exists()) {
|
||||||
touch($this->configFile->getPath());
|
touch($this->configFile->getPath());
|
||||||
$this->configFile->write(array('config' => new \ArrayObject));
|
$this->configFile->write(['config' => new \ArrayObject]);
|
||||||
Silencer::call('chmod', $this->configFile->getPath(), 0600);
|
Silencer::call('chmod', $this->configFile->getPath(), 0600);
|
||||||
}
|
}
|
||||||
if ($input->getOption('global') && !$this->authConfigFile->exists()) {
|
if ($input->getOption('global') && !$this->authConfigFile->exists()) {
|
||||||
touch($this->authConfigFile->getPath());
|
touch($this->authConfigFile->getPath());
|
||||||
$this->authConfigFile->write(array('bitbucket-oauth' => new \ArrayObject, 'github-oauth' => new \ArrayObject, 'gitlab-oauth' => new \ArrayObject, 'gitlab-token' => new \ArrayObject, 'http-basic' => new \ArrayObject, 'bearer' => new \ArrayObject));
|
$this->authConfigFile->write(['bitbucket-oauth' => new \ArrayObject, 'github-oauth' => new \ArrayObject, 'gitlab-oauth' => new \ArrayObject, 'gitlab-token' => new \ArrayObject, 'http-basic' => new \ArrayObject, 'bearer' => new \ArrayObject]);
|
||||||
Silencer::call('chmod', $this->authConfigFile->getPath(), 0600);
|
Silencer::call('chmod', $this->authConfigFile->getPath(), 0600);
|
||||||
}
|
}
|
||||||
|
|
||||||
|
@ -219,7 +215,7 @@ EOT
|
||||||
if (Platform::isWindows()) {
|
if (Platform::isWindows()) {
|
||||||
$editor = 'notepad';
|
$editor = 'notepad';
|
||||||
} else {
|
} else {
|
||||||
foreach (array('editor', 'vim', 'vi', 'nano', 'pico', 'ed') as $candidate) {
|
foreach (['editor', 'vim', 'vi', 'nano', 'pico', 'ed'] as $candidate) {
|
||||||
if (exec('which '.$candidate)) {
|
if (exec('which '.$candidate)) {
|
||||||
$editor = $candidate;
|
$editor = $candidate;
|
||||||
break;
|
break;
|
||||||
|
@ -238,7 +234,7 @@ EOT
|
||||||
|
|
||||||
if (false === $input->getOption('global')) {
|
if (false === $input->getOption('global')) {
|
||||||
$this->config->merge($this->configFile->read(), $this->configFile->getPath());
|
$this->config->merge($this->configFile->read(), $this->configFile->getPath());
|
||||||
$this->config->merge(array('config' => $this->authConfigFile->exists() ? $this->authConfigFile->read() : array()), $this->authConfigFile->getPath());
|
$this->config->merge(['config' => $this->authConfigFile->exists() ? $this->authConfigFile->read() : []], $this->authConfigFile->getPath());
|
||||||
}
|
}
|
||||||
|
|
||||||
// List the configuration of the file settings
|
// List the configuration of the file settings
|
||||||
|
@ -254,18 +250,18 @@ EOT
|
||||||
}
|
}
|
||||||
|
|
||||||
// If the user enters in a config variable, parse it and save to file
|
// If the user enters in a config variable, parse it and save to file
|
||||||
if (array() !== $input->getArgument('setting-value') && $input->getOption('unset')) {
|
if ([] !== $input->getArgument('setting-value') && $input->getOption('unset')) {
|
||||||
throw new \RuntimeException('You can not combine a setting value with --unset');
|
throw new \RuntimeException('You can not combine a setting value with --unset');
|
||||||
}
|
}
|
||||||
|
|
||||||
// show the value if no value is provided
|
// show the value if no value is provided
|
||||||
if (array() === $input->getArgument('setting-value') && !$input->getOption('unset')) {
|
if ([] === $input->getArgument('setting-value') && !$input->getOption('unset')) {
|
||||||
$properties = array('name', 'type', 'description', 'homepage', 'version', 'minimum-stability', 'prefer-stable', 'keywords', 'license', 'extra');
|
$properties = ['name', 'type', 'description', 'homepage', 'version', 'minimum-stability', 'prefer-stable', 'keywords', 'license', 'extra'];
|
||||||
$rawData = $this->configFile->read();
|
$rawData = $this->configFile->read();
|
||||||
$data = $this->config->all();
|
$data = $this->config->all();
|
||||||
if (Preg::isMatch('/^repos?(?:itories)?(?:\.(.+))?/', $settingKey, $matches)) {
|
if (Preg::isMatch('/^repos?(?:itories)?(?:\.(.+))?/', $settingKey, $matches)) {
|
||||||
if (!isset($matches[1]) || $matches[1] === '') {
|
if (!isset($matches[1]) || $matches[1] === '') {
|
||||||
$value = $data['repositories'] ?? array();
|
$value = $data['repositories'] ?? [];
|
||||||
} else {
|
} else {
|
||||||
if (!isset($data['repositories'][$matches[1]])) {
|
if (!isset($data['repositories'][$matches[1]])) {
|
||||||
throw new \InvalidArgumentException('There is no '.$matches[1].' repository defined');
|
throw new \InvalidArgumentException('There is no '.$matches[1].' repository defined');
|
||||||
|
@ -321,36 +317,36 @@ EOT
|
||||||
$values = $input->getArgument('setting-value'); // what the user is trying to add/change
|
$values = $input->getArgument('setting-value'); // what the user is trying to add/change
|
||||||
|
|
||||||
$booleanValidator = static function ($val): bool {
|
$booleanValidator = static function ($val): bool {
|
||||||
return in_array($val, array('true', 'false', '1', '0'), true);
|
return in_array($val, ['true', 'false', '1', '0'], true);
|
||||||
};
|
};
|
||||||
$booleanNormalizer = static function ($val): bool {
|
$booleanNormalizer = static function ($val): bool {
|
||||||
return $val !== 'false' && (bool) $val;
|
return $val !== 'false' && (bool) $val;
|
||||||
};
|
};
|
||||||
|
|
||||||
// handle config values
|
// handle config values
|
||||||
$uniqueConfigValues = array(
|
$uniqueConfigValues = [
|
||||||
'process-timeout' => array('is_numeric', 'intval'),
|
'process-timeout' => ['is_numeric', 'intval'],
|
||||||
'use-include-path' => array($booleanValidator, $booleanNormalizer),
|
'use-include-path' => [$booleanValidator, $booleanNormalizer],
|
||||||
'use-github-api' => array($booleanValidator, $booleanNormalizer),
|
'use-github-api' => [$booleanValidator, $booleanNormalizer],
|
||||||
'preferred-install' => array(
|
'preferred-install' => [
|
||||||
static function ($val): bool {
|
static function ($val): bool {
|
||||||
return in_array($val, array('auto', 'source', 'dist'), true);
|
return in_array($val, ['auto', 'source', 'dist'], true);
|
||||||
},
|
},
|
||||||
static function ($val) {
|
static function ($val) {
|
||||||
return $val;
|
return $val;
|
||||||
},
|
},
|
||||||
),
|
],
|
||||||
'gitlab-protocol' => array(
|
'gitlab-protocol' => [
|
||||||
static function ($val): bool {
|
static function ($val): bool {
|
||||||
return in_array($val, array('git', 'http', 'https'), true);
|
return in_array($val, ['git', 'http', 'https'], true);
|
||||||
},
|
},
|
||||||
static function ($val) {
|
static function ($val) {
|
||||||
return $val;
|
return $val;
|
||||||
},
|
},
|
||||||
),
|
],
|
||||||
'store-auths' => array(
|
'store-auths' => [
|
||||||
static function ($val): bool {
|
static function ($val): bool {
|
||||||
return in_array($val, array('true', 'false', 'prompt'), true);
|
return in_array($val, ['true', 'false', 'prompt'], true);
|
||||||
},
|
},
|
||||||
static function ($val) {
|
static function ($val) {
|
||||||
if ('prompt' === $val) {
|
if ('prompt' === $val) {
|
||||||
|
@ -359,56 +355,56 @@ EOT
|
||||||
|
|
||||||
return $val !== 'false' && (bool) $val;
|
return $val !== 'false' && (bool) $val;
|
||||||
},
|
},
|
||||||
),
|
],
|
||||||
'notify-on-install' => array($booleanValidator, $booleanNormalizer),
|
'notify-on-install' => [$booleanValidator, $booleanNormalizer],
|
||||||
'vendor-dir' => array('is_string', static function ($val) {
|
'vendor-dir' => ['is_string', static function ($val) {
|
||||||
return $val;
|
return $val;
|
||||||
}),
|
}],
|
||||||
'bin-dir' => array('is_string', static function ($val) {
|
'bin-dir' => ['is_string', static function ($val) {
|
||||||
return $val;
|
return $val;
|
||||||
}),
|
}],
|
||||||
'archive-dir' => array('is_string', static function ($val) {
|
'archive-dir' => ['is_string', static function ($val) {
|
||||||
return $val;
|
return $val;
|
||||||
}),
|
}],
|
||||||
'archive-format' => array('is_string', static function ($val) {
|
'archive-format' => ['is_string', static function ($val) {
|
||||||
return $val;
|
return $val;
|
||||||
}),
|
}],
|
||||||
'data-dir' => array('is_string', static function ($val) {
|
'data-dir' => ['is_string', static function ($val) {
|
||||||
return $val;
|
return $val;
|
||||||
}),
|
}],
|
||||||
'cache-dir' => array('is_string', static function ($val) {
|
'cache-dir' => ['is_string', static function ($val) {
|
||||||
return $val;
|
return $val;
|
||||||
}),
|
}],
|
||||||
'cache-files-dir' => array('is_string', static function ($val) {
|
'cache-files-dir' => ['is_string', static function ($val) {
|
||||||
return $val;
|
return $val;
|
||||||
}),
|
}],
|
||||||
'cache-repo-dir' => array('is_string', static function ($val) {
|
'cache-repo-dir' => ['is_string', static function ($val) {
|
||||||
return $val;
|
return $val;
|
||||||
}),
|
}],
|
||||||
'cache-vcs-dir' => array('is_string', static function ($val) {
|
'cache-vcs-dir' => ['is_string', static function ($val) {
|
||||||
return $val;
|
return $val;
|
||||||
}),
|
}],
|
||||||
'cache-ttl' => array('is_numeric', 'intval'),
|
'cache-ttl' => ['is_numeric', 'intval'],
|
||||||
'cache-files-ttl' => array('is_numeric', 'intval'),
|
'cache-files-ttl' => ['is_numeric', 'intval'],
|
||||||
'cache-files-maxsize' => array(
|
'cache-files-maxsize' => [
|
||||||
static function ($val): bool {
|
static function ($val): bool {
|
||||||
return Preg::isMatch('/^\s*([0-9.]+)\s*(?:([kmg])(?:i?b)?)?\s*$/i', $val);
|
return Preg::isMatch('/^\s*([0-9.]+)\s*(?:([kmg])(?:i?b)?)?\s*$/i', $val);
|
||||||
},
|
},
|
||||||
static function ($val) {
|
static function ($val) {
|
||||||
return $val;
|
return $val;
|
||||||
},
|
},
|
||||||
),
|
],
|
||||||
'bin-compat' => array(
|
'bin-compat' => [
|
||||||
static function ($val): bool {
|
static function ($val): bool {
|
||||||
return in_array($val, array('auto', 'full', 'symlink'));
|
return in_array($val, ['auto', 'full', 'symlink']);
|
||||||
},
|
},
|
||||||
static function ($val) {
|
static function ($val) {
|
||||||
return $val;
|
return $val;
|
||||||
},
|
},
|
||||||
),
|
],
|
||||||
'discard-changes' => array(
|
'discard-changes' => [
|
||||||
static function ($val): bool {
|
static function ($val): bool {
|
||||||
return in_array($val, array('stash', 'true', 'false', '1', '0'), true);
|
return in_array($val, ['stash', 'true', 'false', '1', '0'], true);
|
||||||
},
|
},
|
||||||
static function ($val) {
|
static function ($val) {
|
||||||
if ('stash' === $val) {
|
if ('stash' === $val) {
|
||||||
|
@ -417,40 +413,40 @@ EOT
|
||||||
|
|
||||||
return $val !== 'false' && (bool) $val;
|
return $val !== 'false' && (bool) $val;
|
||||||
},
|
},
|
||||||
),
|
],
|
||||||
'autoloader-suffix' => array('is_string', static function ($val) {
|
'autoloader-suffix' => ['is_string', static function ($val) {
|
||||||
return $val === 'null' ? null : $val;
|
return $val === 'null' ? null : $val;
|
||||||
}),
|
}],
|
||||||
'sort-packages' => array($booleanValidator, $booleanNormalizer),
|
'sort-packages' => [$booleanValidator, $booleanNormalizer],
|
||||||
'optimize-autoloader' => array($booleanValidator, $booleanNormalizer),
|
'optimize-autoloader' => [$booleanValidator, $booleanNormalizer],
|
||||||
'classmap-authoritative' => array($booleanValidator, $booleanNormalizer),
|
'classmap-authoritative' => [$booleanValidator, $booleanNormalizer],
|
||||||
'apcu-autoloader' => array($booleanValidator, $booleanNormalizer),
|
'apcu-autoloader' => [$booleanValidator, $booleanNormalizer],
|
||||||
'prepend-autoloader' => array($booleanValidator, $booleanNormalizer),
|
'prepend-autoloader' => [$booleanValidator, $booleanNormalizer],
|
||||||
'disable-tls' => array($booleanValidator, $booleanNormalizer),
|
'disable-tls' => [$booleanValidator, $booleanNormalizer],
|
||||||
'secure-http' => array($booleanValidator, $booleanNormalizer),
|
'secure-http' => [$booleanValidator, $booleanNormalizer],
|
||||||
'cafile' => array(
|
'cafile' => [
|
||||||
static function ($val): bool {
|
static function ($val): bool {
|
||||||
return file_exists($val) && Filesystem::isReadable($val);
|
return file_exists($val) && Filesystem::isReadable($val);
|
||||||
},
|
},
|
||||||
static function ($val) {
|
static function ($val) {
|
||||||
return $val === 'null' ? null : $val;
|
return $val === 'null' ? null : $val;
|
||||||
},
|
},
|
||||||
),
|
],
|
||||||
'capath' => array(
|
'capath' => [
|
||||||
static function ($val): bool {
|
static function ($val): bool {
|
||||||
return is_dir($val) && Filesystem::isReadable($val);
|
return is_dir($val) && Filesystem::isReadable($val);
|
||||||
},
|
},
|
||||||
static function ($val) {
|
static function ($val) {
|
||||||
return $val === 'null' ? null : $val;
|
return $val === 'null' ? null : $val;
|
||||||
},
|
},
|
||||||
),
|
],
|
||||||
'github-expose-hostname' => array($booleanValidator, $booleanNormalizer),
|
'github-expose-hostname' => [$booleanValidator, $booleanNormalizer],
|
||||||
'htaccess-protect' => array($booleanValidator, $booleanNormalizer),
|
'htaccess-protect' => [$booleanValidator, $booleanNormalizer],
|
||||||
'lock' => array($booleanValidator, $booleanNormalizer),
|
'lock' => [$booleanValidator, $booleanNormalizer],
|
||||||
'allow-plugins' => array($booleanValidator, $booleanNormalizer),
|
'allow-plugins' => [$booleanValidator, $booleanNormalizer],
|
||||||
'platform-check' => array(
|
'platform-check' => [
|
||||||
static function ($val): bool {
|
static function ($val): bool {
|
||||||
return in_array($val, array('php-only', 'true', 'false', '1', '0'), true);
|
return in_array($val, ['php-only', 'true', 'false', '1', '0'], true);
|
||||||
},
|
},
|
||||||
static function ($val) {
|
static function ($val) {
|
||||||
if ('php-only' === $val) {
|
if ('php-only' === $val) {
|
||||||
|
@ -459,10 +455,10 @@ EOT
|
||||||
|
|
||||||
return $val !== 'false' && (bool) $val;
|
return $val !== 'false' && (bool) $val;
|
||||||
},
|
},
|
||||||
),
|
],
|
||||||
'use-parent-dir' => array(
|
'use-parent-dir' => [
|
||||||
static function ($val): bool {
|
static function ($val): bool {
|
||||||
return in_array($val, array('true', 'false', 'prompt'), true);
|
return in_array($val, ['true', 'false', 'prompt'], true);
|
||||||
},
|
},
|
||||||
static function ($val) {
|
static function ($val) {
|
||||||
if ('prompt' === $val) {
|
if ('prompt' === $val) {
|
||||||
|
@ -471,17 +467,17 @@ EOT
|
||||||
|
|
||||||
return $val !== 'false' && (bool) $val;
|
return $val !== 'false' && (bool) $val;
|
||||||
},
|
},
|
||||||
),
|
],
|
||||||
);
|
];
|
||||||
$multiConfigValues = array(
|
$multiConfigValues = [
|
||||||
'github-protocols' => array(
|
'github-protocols' => [
|
||||||
static function ($vals) {
|
static function ($vals) {
|
||||||
if (!is_array($vals)) {
|
if (!is_array($vals)) {
|
||||||
return 'array expected';
|
return 'array expected';
|
||||||
}
|
}
|
||||||
|
|
||||||
foreach ($vals as $val) {
|
foreach ($vals as $val) {
|
||||||
if (!in_array($val, array('git', 'https', 'ssh'))) {
|
if (!in_array($val, ['git', 'https', 'ssh'])) {
|
||||||
return 'valid protocols include: git, https, ssh';
|
return 'valid protocols include: git, https, ssh';
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
|
@ -491,8 +487,8 @@ EOT
|
||||||
static function ($vals) {
|
static function ($vals) {
|
||||||
return $vals;
|
return $vals;
|
||||||
},
|
},
|
||||||
),
|
],
|
||||||
'github-domains' => array(
|
'github-domains' => [
|
||||||
static function ($vals) {
|
static function ($vals) {
|
||||||
if (!is_array($vals)) {
|
if (!is_array($vals)) {
|
||||||
return 'array expected';
|
return 'array expected';
|
||||||
|
@ -503,8 +499,8 @@ EOT
|
||||||
static function ($vals) {
|
static function ($vals) {
|
||||||
return $vals;
|
return $vals;
|
||||||
},
|
},
|
||||||
),
|
],
|
||||||
'gitlab-domains' => array(
|
'gitlab-domains' => [
|
||||||
static function ($vals) {
|
static function ($vals) {
|
||||||
if (!is_array($vals)) {
|
if (!is_array($vals)) {
|
||||||
return 'array expected';
|
return 'array expected';
|
||||||
|
@ -515,8 +511,8 @@ EOT
|
||||||
static function ($vals) {
|
static function ($vals) {
|
||||||
return $vals;
|
return $vals;
|
||||||
},
|
},
|
||||||
),
|
],
|
||||||
);
|
];
|
||||||
|
|
||||||
if ($input->getOption('unset') && (isset($uniqueConfigValues[$settingKey]) || isset($multiConfigValues[$settingKey]))) {
|
if ($input->getOption('unset') && (isset($uniqueConfigValues[$settingKey]) || isset($multiConfigValues[$settingKey]))) {
|
||||||
if ($settingKey === 'disable-tls' && $this->config->get('disable-tls')) {
|
if ($settingKey === 'disable-tls' && $this->config->get('disable-tls')) {
|
||||||
|
@ -545,7 +541,7 @@ EOT
|
||||||
return 0;
|
return 0;
|
||||||
}
|
}
|
||||||
|
|
||||||
list($validator) = $uniqueConfigValues['preferred-install'];
|
[$validator] = $uniqueConfigValues['preferred-install'];
|
||||||
if (!$validator($values[0])) {
|
if (!$validator($values[0])) {
|
||||||
throw new \RuntimeException('Invalid value for '.$settingKey.'. Should be one of: auto, source, or dist');
|
throw new \RuntimeException('Invalid value for '.$settingKey.'. Should be one of: auto, source, or dist');
|
||||||
}
|
}
|
||||||
|
@ -578,34 +574,34 @@ EOT
|
||||||
}
|
}
|
||||||
|
|
||||||
// handle properties
|
// handle properties
|
||||||
$uniqueProps = array(
|
$uniqueProps = [
|
||||||
'name' => array('is_string', static function ($val) {
|
'name' => ['is_string', static function ($val) {
|
||||||
return $val;
|
return $val;
|
||||||
}),
|
}],
|
||||||
'type' => array('is_string', static function ($val) {
|
'type' => ['is_string', static function ($val) {
|
||||||
return $val;
|
return $val;
|
||||||
}),
|
}],
|
||||||
'description' => array('is_string', static function ($val) {
|
'description' => ['is_string', static function ($val) {
|
||||||
return $val;
|
return $val;
|
||||||
}),
|
}],
|
||||||
'homepage' => array('is_string', static function ($val) {
|
'homepage' => ['is_string', static function ($val) {
|
||||||
return $val;
|
return $val;
|
||||||
}),
|
}],
|
||||||
'version' => array('is_string', static function ($val) {
|
'version' => ['is_string', static function ($val) {
|
||||||
return $val;
|
return $val;
|
||||||
}),
|
}],
|
||||||
'minimum-stability' => array(
|
'minimum-stability' => [
|
||||||
static function ($val): bool {
|
static function ($val): bool {
|
||||||
return isset(BasePackage::$stabilities[VersionParser::normalizeStability($val)]);
|
return isset(BasePackage::$stabilities[VersionParser::normalizeStability($val)]);
|
||||||
},
|
},
|
||||||
static function ($val): string {
|
static function ($val): string {
|
||||||
return VersionParser::normalizeStability($val);
|
return VersionParser::normalizeStability($val);
|
||||||
},
|
},
|
||||||
),
|
],
|
||||||
'prefer-stable' => array($booleanValidator, $booleanNormalizer),
|
'prefer-stable' => [$booleanValidator, $booleanNormalizer],
|
||||||
);
|
];
|
||||||
$multiProps = array(
|
$multiProps = [
|
||||||
'keywords' => array(
|
'keywords' => [
|
||||||
static function ($vals) {
|
static function ($vals) {
|
||||||
if (!is_array($vals)) {
|
if (!is_array($vals)) {
|
||||||
return 'array expected';
|
return 'array expected';
|
||||||
|
@ -616,8 +612,8 @@ EOT
|
||||||
static function ($vals) {
|
static function ($vals) {
|
||||||
return $vals;
|
return $vals;
|
||||||
},
|
},
|
||||||
),
|
],
|
||||||
'license' => array(
|
'license' => [
|
||||||
static function ($vals) {
|
static function ($vals) {
|
||||||
if (!is_array($vals)) {
|
if (!is_array($vals)) {
|
||||||
return 'array expected';
|
return 'array expected';
|
||||||
|
@ -628,8 +624,8 @@ EOT
|
||||||
static function ($vals) {
|
static function ($vals) {
|
||||||
return $vals;
|
return $vals;
|
||||||
},
|
},
|
||||||
),
|
],
|
||||||
);
|
];
|
||||||
|
|
||||||
if ($input->getOption('global') && (isset($uniqueProps[$settingKey]) || isset($multiProps[$settingKey]) || strpos($settingKey, 'extra.') === 0)) {
|
if ($input->getOption('global') && (isset($uniqueProps[$settingKey]) || isset($multiProps[$settingKey]) || strpos($settingKey, 'extra.') === 0)) {
|
||||||
throw new \InvalidArgumentException('The ' . $settingKey . ' property can not be set in the global config.json file. Use `composer global config` to apply changes to the global composer.json');
|
throw new \InvalidArgumentException('The ' . $settingKey . ' property can not be set in the global config.json file. Use `composer global config` to apply changes to the global composer.json');
|
||||||
|
@ -659,10 +655,10 @@ EOT
|
||||||
}
|
}
|
||||||
|
|
||||||
if (2 === count($values)) {
|
if (2 === count($values)) {
|
||||||
$this->configSource->addRepository($matches[1], array(
|
$this->configSource->addRepository($matches[1], [
|
||||||
'type' => $values[0],
|
'type' => $values[0],
|
||||||
'url' => $values[1],
|
'url' => $values[1],
|
||||||
), $input->getOption('append'));
|
], $input->getOption('append'));
|
||||||
|
|
||||||
return 0;
|
return 0;
|
||||||
}
|
}
|
||||||
|
@ -727,7 +723,7 @@ EOT
|
||||||
}
|
}
|
||||||
|
|
||||||
// handle unsetting extra/suggest
|
// handle unsetting extra/suggest
|
||||||
if (in_array($settingKey, array('suggest', 'extra'), true) && $input->getOption('unset')) {
|
if (in_array($settingKey, ['suggest', 'extra'], true) && $input->getOption('unset')) {
|
||||||
$this->configSource->removeProperty($settingKey);
|
$this->configSource->removeProperty($settingKey);
|
||||||
|
|
||||||
return 0;
|
return 0;
|
||||||
|
@ -767,11 +763,11 @@ EOT
|
||||||
throw new \RuntimeException('Expected two arguments (consumer-key, consumer-secret), got '.count($values));
|
throw new \RuntimeException('Expected two arguments (consumer-key, consumer-secret), got '.count($values));
|
||||||
}
|
}
|
||||||
$this->configSource->removeConfigSetting($matches[1].'.'.$matches[2]);
|
$this->configSource->removeConfigSetting($matches[1].'.'.$matches[2]);
|
||||||
$this->authConfigSource->addConfigSetting($matches[1].'.'.$matches[2], array('consumer-key' => $values[0], 'consumer-secret' => $values[1]));
|
$this->authConfigSource->addConfigSetting($matches[1].'.'.$matches[2], ['consumer-key' => $values[0], 'consumer-secret' => $values[1]]);
|
||||||
} elseif ($matches[1] === 'gitlab-token' && 2 === count($values)) {
|
} elseif ($matches[1] === 'gitlab-token' && 2 === count($values)) {
|
||||||
$this->configSource->removeConfigSetting($matches[1].'.'.$matches[2]);
|
$this->configSource->removeConfigSetting($matches[1].'.'.$matches[2]);
|
||||||
$this->authConfigSource->addConfigSetting($matches[1].'.'.$matches[2], array('username' => $values[0], 'token' => $values[1]));
|
$this->authConfigSource->addConfigSetting($matches[1].'.'.$matches[2], ['username' => $values[0], 'token' => $values[1]]);
|
||||||
} elseif (in_array($matches[1], array('github-oauth', 'gitlab-oauth', 'gitlab-token', 'bearer'), true)) {
|
} elseif (in_array($matches[1], ['github-oauth', 'gitlab-oauth', 'gitlab-token', 'bearer'], true)) {
|
||||||
if (1 !== count($values)) {
|
if (1 !== count($values)) {
|
||||||
throw new \RuntimeException('Too many arguments, expected only one token');
|
throw new \RuntimeException('Too many arguments, expected only one token');
|
||||||
}
|
}
|
||||||
|
@ -782,7 +778,7 @@ EOT
|
||||||
throw new \RuntimeException('Expected two arguments (username, password), got '.count($values));
|
throw new \RuntimeException('Expected two arguments (username, password), got '.count($values));
|
||||||
}
|
}
|
||||||
$this->configSource->removeConfigSetting($matches[1].'.'.$matches[2]);
|
$this->configSource->removeConfigSetting($matches[1].'.'.$matches[2]);
|
||||||
$this->authConfigSource->addConfigSetting($matches[1].'.'.$matches[2], array('username' => $values[0], 'password' => $values[1]));
|
$this->authConfigSource->addConfigSetting($matches[1].'.'.$matches[2], ['username' => $values[0], 'password' => $values[1]]);
|
||||||
}
|
}
|
||||||
|
|
||||||
return 0;
|
return 0;
|
||||||
|
@ -812,16 +808,12 @@ EOT
|
||||||
}
|
}
|
||||||
|
|
||||||
/**
|
/**
|
||||||
* @param string $key
|
|
||||||
* @param array{callable, callable} $callbacks Validator and normalizer callbacks
|
* @param array{callable, callable} $callbacks Validator and normalizer callbacks
|
||||||
* @param array<string> $values
|
* @param array<string> $values
|
||||||
* @param string $method
|
|
||||||
*
|
|
||||||
* @return void
|
|
||||||
*/
|
*/
|
||||||
protected function handleSingleValue(string $key, array $callbacks, array $values, string $method): void
|
protected function handleSingleValue(string $key, array $callbacks, array $values, string $method): void
|
||||||
{
|
{
|
||||||
list($validator, $normalizer) = $callbacks;
|
[$validator, $normalizer] = $callbacks;
|
||||||
if (1 !== count($values)) {
|
if (1 !== count($values)) {
|
||||||
throw new \RuntimeException('You can only pass one value. Example: php composer.phar config process-timeout 300');
|
throw new \RuntimeException('You can only pass one value. Example: php composer.phar config process-timeout 300');
|
||||||
}
|
}
|
||||||
|
@ -843,20 +835,16 @@ EOT
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
|
|
||||||
call_user_func(array($this->configSource, $method), $key, $normalizedValue);
|
call_user_func([$this->configSource, $method], $key, $normalizedValue);
|
||||||
}
|
}
|
||||||
|
|
||||||
/**
|
/**
|
||||||
* @param string $key
|
|
||||||
* @param array{callable, callable} $callbacks Validator and normalizer callbacks
|
* @param array{callable, callable} $callbacks Validator and normalizer callbacks
|
||||||
* @param array<string> $values
|
* @param array<string> $values
|
||||||
* @param string $method
|
|
||||||
*
|
|
||||||
* @return void
|
|
||||||
*/
|
*/
|
||||||
protected function handleMultiValue(string $key, array $callbacks, array $values, string $method): void
|
protected function handleMultiValue(string $key, array $callbacks, array $values, string $method): void
|
||||||
{
|
{
|
||||||
list($validator, $normalizer) = $callbacks;
|
[$validator, $normalizer] = $callbacks;
|
||||||
if (true !== $validation = $validator($values)) {
|
if (true !== $validation = $validator($values)) {
|
||||||
throw new \RuntimeException(sprintf(
|
throw new \RuntimeException(sprintf(
|
||||||
'%s is an invalid value'.($validation ? ' ('.$validation.')' : ''),
|
'%s is an invalid value'.($validation ? ' ('.$validation.')' : ''),
|
||||||
|
@ -864,7 +852,7 @@ EOT
|
||||||
));
|
));
|
||||||
}
|
}
|
||||||
|
|
||||||
call_user_func(array($this->configSource, $method), $key, $normalizer($values));
|
call_user_func([$this->configSource, $method], $key, $normalizer($values));
|
||||||
}
|
}
|
||||||
|
|
||||||
/**
|
/**
|
||||||
|
@ -872,17 +860,13 @@ EOT
|
||||||
*
|
*
|
||||||
* @param array<mixed[]|bool|string> $contents
|
* @param array<mixed[]|bool|string> $contents
|
||||||
* @param array<mixed[]|string> $rawContents
|
* @param array<mixed[]|string> $rawContents
|
||||||
* @param string|null $k
|
|
||||||
* @param bool $showSource
|
|
||||||
*
|
|
||||||
* @return void
|
|
||||||
*/
|
*/
|
||||||
protected function listConfiguration(array $contents, array $rawContents, OutputInterface $output, ?string $k = null, bool $showSource = false): void
|
protected function listConfiguration(array $contents, array $rawContents, OutputInterface $output, ?string $k = null, bool $showSource = false): void
|
||||||
{
|
{
|
||||||
$origK = $k;
|
$origK = $k;
|
||||||
$io = $this->getIO();
|
$io = $this->getIO();
|
||||||
foreach ($contents as $key => $value) {
|
foreach ($contents as $key => $value) {
|
||||||
if ($k === null && !in_array($key, array('config', 'repositories'))) {
|
if ($k === null && !in_array($key, ['config', 'repositories'])) {
|
||||||
continue;
|
continue;
|
||||||
}
|
}
|
||||||
|
|
||||||
|
|
|
@ -65,15 +65,12 @@ class CreateProjectCommand extends BaseCommand
|
||||||
*/
|
*/
|
||||||
protected $suggestedPackagesReporter;
|
protected $suggestedPackagesReporter;
|
||||||
|
|
||||||
/**
|
|
||||||
* @return void
|
|
||||||
*/
|
|
||||||
protected function configure(): void
|
protected function configure(): void
|
||||||
{
|
{
|
||||||
$this
|
$this
|
||||||
->setName('create-project')
|
->setName('create-project')
|
||||||
->setDescription('Creates new project from a package into given directory')
|
->setDescription('Creates new project from a package into given directory')
|
||||||
->setDefinition(array(
|
->setDefinition([
|
||||||
new InputArgument('package', InputArgument::OPTIONAL, 'Package name to be installed', null, $this->suggestAvailablePackage()),
|
new InputArgument('package', InputArgument::OPTIONAL, 'Package name to be installed', null, $this->suggestAvailablePackage()),
|
||||||
new InputArgument('directory', InputArgument::OPTIONAL, 'Directory where the files should be created'),
|
new InputArgument('directory', InputArgument::OPTIONAL, 'Directory where the files should be created'),
|
||||||
new InputArgument('version', InputArgument::OPTIONAL, 'Version, will default to latest'),
|
new InputArgument('version', InputArgument::OPTIONAL, 'Version, will default to latest'),
|
||||||
|
@ -98,7 +95,7 @@ class CreateProjectCommand extends BaseCommand
|
||||||
new InputOption('ignore-platform-req', null, InputOption::VALUE_REQUIRED | InputOption::VALUE_IS_ARRAY, 'Ignore a specific platform requirement (php & ext- packages).'),
|
new InputOption('ignore-platform-req', null, InputOption::VALUE_REQUIRED | InputOption::VALUE_IS_ARRAY, 'Ignore a specific platform requirement (php & ext- packages).'),
|
||||||
new InputOption('ignore-platform-reqs', null, InputOption::VALUE_NONE, 'Ignore all platform requirements (php & ext- packages).'),
|
new InputOption('ignore-platform-reqs', null, InputOption::VALUE_NONE, 'Ignore all platform requirements (php & ext- packages).'),
|
||||||
new InputOption('ask', null, InputOption::VALUE_NONE, 'Whether to ask for project directory.'),
|
new InputOption('ask', null, InputOption::VALUE_NONE, 'Whether to ask for project directory.'),
|
||||||
))
|
])
|
||||||
->setHelp(
|
->setHelp(
|
||||||
<<<EOT
|
<<<EOT
|
||||||
The <info>create-project</info> command creates a new project from a given
|
The <info>create-project</info> command creates a new project from a given
|
||||||
|
@ -134,7 +131,7 @@ EOT
|
||||||
$config = Factory::createConfig();
|
$config = Factory::createConfig();
|
||||||
$io = $this->getIO();
|
$io = $this->getIO();
|
||||||
|
|
||||||
list($preferSource, $preferDist) = $this->getPreferredInstallOptions($config, $input, true);
|
[$preferSource, $preferDist] = $this->getPreferredInstallOptions($config, $input, true);
|
||||||
|
|
||||||
if ($input->getOption('dev')) {
|
if ($input->getOption('dev')) {
|
||||||
$io->writeError('<warning>You are using the deprecated option "dev". Dev packages are installed by default now.</warning>');
|
$io->writeError('<warning>You are using the deprecated option "dev". Dev packages are installed by default now.</warning>');
|
||||||
|
@ -176,25 +173,11 @@ EOT
|
||||||
}
|
}
|
||||||
|
|
||||||
/**
|
/**
|
||||||
* @param string|null $packageName
|
|
||||||
* @param string|null $directory
|
|
||||||
* @param string|null $packageVersion
|
|
||||||
* @param string|null $stability
|
|
||||||
* @param bool $preferSource
|
|
||||||
* @param bool $preferDist
|
|
||||||
* @param bool $installDevPackages
|
|
||||||
* @param string|array<string>|null $repositories
|
* @param string|array<string>|null $repositories
|
||||||
* @param bool $disablePlugins
|
|
||||||
* @param bool $disableScripts
|
|
||||||
* @param bool $noProgress
|
|
||||||
* @param bool $noInstall
|
|
||||||
* @param bool $secureHttp
|
|
||||||
* @param bool $addRepository
|
|
||||||
*
|
*
|
||||||
* @return int
|
|
||||||
* @throws \Exception
|
* @throws \Exception
|
||||||
*/
|
*/
|
||||||
public function installProject(IOInterface $io, Config $config, InputInterface $input, ?string $packageName = null, ?string $directory = null, ?string $packageVersion = null, ?string $stability = 'stable', bool $preferSource = false, bool $preferDist = false, bool $installDevPackages = false, $repositories = null, bool $disablePlugins = false, bool $disableScripts = false, bool $noProgress = false, bool $noInstall = false, PlatformRequirementFilterInterface $platformRequirementFilter = null, bool $secureHttp = true, bool $addRepository = false): int
|
public function installProject(IOInterface $io, Config $config, InputInterface $input, ?string $packageName = null, ?string $directory = null, ?string $packageVersion = null, ?string $stability = 'stable', bool $preferSource = false, bool $preferDist = false, bool $installDevPackages = false, $repositories = null, bool $disablePlugins = false, bool $disableScripts = false, bool $noProgress = false, bool $noInstall = false, ?PlatformRequirementFilterInterface $platformRequirementFilter = null, bool $secureHttp = true, bool $addRepository = false): int
|
||||||
{
|
{
|
||||||
$oldCwd = Platform::getCwd();
|
$oldCwd = Platform::getCwd();
|
||||||
|
|
||||||
|
@ -230,8 +213,8 @@ EOT
|
||||||
$configSource = new JsonConfigSource(new JsonFile('composer.json'));
|
$configSource = new JsonConfigSource(new JsonFile('composer.json'));
|
||||||
|
|
||||||
if (
|
if (
|
||||||
(isset($repoConfig['packagist']) && $repoConfig === array('packagist' => false))
|
(isset($repoConfig['packagist']) && $repoConfig === ['packagist' => false])
|
||||||
|| (isset($repoConfig['packagist.org']) && $repoConfig === array('packagist.org' => false))
|
|| (isset($repoConfig['packagist.org']) && $repoConfig === ['packagist.org' => false])
|
||||||
) {
|
) {
|
||||||
$configSource->addRepository('packagist.org', false);
|
$configSource->addRepository('packagist.org', false);
|
||||||
} else {
|
} else {
|
||||||
|
@ -250,7 +233,7 @@ EOT
|
||||||
|
|
||||||
// use the new config including the newly installed project
|
// use the new config including the newly installed project
|
||||||
$config = $composer->getConfig();
|
$config = $composer->getConfig();
|
||||||
list($preferSource, $preferDist) = $this->getPreferredInstallOptions($config, $input);
|
[$preferSource, $preferDist] = $this->getPreferredInstallOptions($config, $input);
|
||||||
|
|
||||||
// install dependencies of the created project
|
// install dependencies of the created project
|
||||||
if ($noInstall === false) {
|
if ($noInstall === false) {
|
||||||
|
@ -300,7 +283,7 @@ EOT
|
||||||
) {
|
) {
|
||||||
$finder = new Finder();
|
$finder = new Finder();
|
||||||
$finder->depth(0)->directories()->in(Platform::getCwd())->ignoreVCS(false)->ignoreDotFiles(false);
|
$finder->depth(0)->directories()->in(Platform::getCwd())->ignoreVCS(false)->ignoreDotFiles(false);
|
||||||
foreach (array('.svn', '_svn', 'CVS', '_darcs', '.arch-params', '.monotone', '.bzr', '.git', '.hg', '.fslckout', '_FOSSIL_') as $vcsName) {
|
foreach (['.svn', '_svn', 'CVS', '_darcs', '.arch-params', '.monotone', '.bzr', '.git', '.hg', '.fslckout', '_FOSSIL_'] as $vcsName) {
|
||||||
$finder->name($vcsName);
|
$finder->name($vcsName);
|
||||||
}
|
}
|
||||||
|
|
||||||
|
@ -349,30 +332,18 @@ EOT
|
||||||
}
|
}
|
||||||
|
|
||||||
/**
|
/**
|
||||||
* @param string $packageName
|
|
||||||
* @param string|null $directory
|
|
||||||
* @param string|null $packageVersion
|
|
||||||
* @param string|null $stability
|
|
||||||
* @param bool $preferSource
|
|
||||||
* @param bool $preferDist
|
|
||||||
* @param bool $installDevPackages
|
|
||||||
* @param array<string>|null $repositories
|
* @param array<string>|null $repositories
|
||||||
* @param bool $disablePlugins
|
|
||||||
* @param bool $disableScripts
|
|
||||||
* @param bool $noProgress
|
|
||||||
* @param bool $secureHttp
|
|
||||||
*
|
*
|
||||||
* @return bool
|
|
||||||
* @throws \Exception
|
* @throws \Exception
|
||||||
*/
|
*/
|
||||||
protected function installRootPackage(IOInterface $io, Config $config, string $packageName, PlatformRequirementFilterInterface $platformRequirementFilter, ?string $directory = null, ?string $packageVersion = null, ?string $stability = 'stable', bool $preferSource = false, bool $preferDist = false, bool $installDevPackages = false, array $repositories = null, bool $disablePlugins = false, bool $disableScripts = false, bool $noProgress = false, bool $secureHttp = true): bool
|
protected function installRootPackage(IOInterface $io, Config $config, string $packageName, PlatformRequirementFilterInterface $platformRequirementFilter, ?string $directory = null, ?string $packageVersion = null, ?string $stability = 'stable', bool $preferSource = false, bool $preferDist = false, bool $installDevPackages = false, ?array $repositories = null, bool $disablePlugins = false, bool $disableScripts = false, bool $noProgress = false, bool $secureHttp = true): bool
|
||||||
{
|
{
|
||||||
if (!$secureHttp) {
|
if (!$secureHttp) {
|
||||||
$config->merge(array('config' => array('secure-http' => false)), Config::SOURCE_COMMAND);
|
$config->merge(['config' => ['secure-http' => false]], Config::SOURCE_COMMAND);
|
||||||
}
|
}
|
||||||
|
|
||||||
$parser = new VersionParser();
|
$parser = new VersionParser();
|
||||||
$requirements = $parser->parseNameVersionPairs(array($packageName));
|
$requirements = $parser->parseNameVersionPairs([$packageName]);
|
||||||
$name = strtolower($requirements[0]['name']);
|
$name = strtolower($requirements[0]['name']);
|
||||||
if (!$packageVersion && isset($requirements[0]['version'])) {
|
if (!$packageVersion && isset($requirements[0]['version'])) {
|
||||||
$packageVersion = $requirements[0]['version'];
|
$packageVersion = $requirements[0]['version'];
|
||||||
|
@ -428,8 +399,8 @@ EOT
|
||||||
foreach ($repositories as $repo) {
|
foreach ($repositories as $repo) {
|
||||||
$repoConfig = RepositoryFactory::configFromString($io, $config, $repo, true);
|
$repoConfig = RepositoryFactory::configFromString($io, $config, $repo, true);
|
||||||
if (
|
if (
|
||||||
(isset($repoConfig['packagist']) && $repoConfig === array('packagist' => false))
|
(isset($repoConfig['packagist']) && $repoConfig === ['packagist' => false])
|
||||||
|| (isset($repoConfig['packagist.org']) && $repoConfig === array('packagist.org' => false))
|
|| (isset($repoConfig['packagist.org']) && $repoConfig === ['packagist.org' => false])
|
||||||
) {
|
) {
|
||||||
continue;
|
continue;
|
||||||
}
|
}
|
||||||
|
@ -438,7 +409,7 @@ EOT
|
||||||
}
|
}
|
||||||
|
|
||||||
$platformOverrides = $config->get('platform');
|
$platformOverrides = $config->get('platform');
|
||||||
$platformRepo = new PlatformRepository(array(), $platformOverrides);
|
$platformRepo = new PlatformRepository([], $platformOverrides);
|
||||||
|
|
||||||
// find the latest version if there are multiple
|
// find the latest version if there are multiple
|
||||||
$versionSelector = new VersionSelector($repositorySet, $platformRepo);
|
$versionSelector = new VersionSelector($repositorySet, $platformRepo);
|
||||||
|
@ -487,7 +458,7 @@ EOT
|
||||||
$im = $composer->getInstallationManager();
|
$im = $composer->getInstallationManager();
|
||||||
$im->setOutputProgress(!$noProgress);
|
$im->setOutputProgress(!$noProgress);
|
||||||
$im->addInstaller($projectInstaller);
|
$im->addInstaller($projectInstaller);
|
||||||
$im->execute(new InstalledArrayRepository(), array(new InstallOperation($package)));
|
$im->execute(new InstalledArrayRepository(), [new InstallOperation($package)]);
|
||||||
$im->notifyInstalls($io);
|
$im->notifyInstalls($io);
|
||||||
|
|
||||||
// collect suggestions
|
// collect suggestions
|
||||||
|
|
|
@ -26,21 +26,19 @@ class DependsCommand extends BaseDependencyCommand
|
||||||
|
|
||||||
/**
|
/**
|
||||||
* Configure command metadata.
|
* Configure command metadata.
|
||||||
*
|
|
||||||
* @return void
|
|
||||||
*/
|
*/
|
||||||
protected function configure(): void
|
protected function configure(): void
|
||||||
{
|
{
|
||||||
$this
|
$this
|
||||||
->setName('depends')
|
->setName('depends')
|
||||||
->setAliases(array('why'))
|
->setAliases(['why'])
|
||||||
->setDescription('Shows which packages cause the given package to be installed')
|
->setDescription('Shows which packages cause the given package to be installed')
|
||||||
->setDefinition(array(
|
->setDefinition([
|
||||||
new InputArgument(self::ARGUMENT_PACKAGE, InputArgument::REQUIRED, 'Package to inspect', null, $this->suggestInstalledPackage(true, true)),
|
new InputArgument(self::ARGUMENT_PACKAGE, InputArgument::REQUIRED, 'Package to inspect', null, $this->suggestInstalledPackage(true, true)),
|
||||||
new InputOption(self::OPTION_RECURSIVE, 'r', InputOption::VALUE_NONE, 'Recursively resolves up to the root package'),
|
new InputOption(self::OPTION_RECURSIVE, 'r', InputOption::VALUE_NONE, 'Recursively resolves up to the root package'),
|
||||||
new InputOption(self::OPTION_TREE, 't', InputOption::VALUE_NONE, 'Prints the results as a nested tree'),
|
new InputOption(self::OPTION_TREE, 't', InputOption::VALUE_NONE, 'Prints the results as a nested tree'),
|
||||||
new InputOption('locked', null, InputOption::VALUE_NONE, 'Read dependency information from composer.lock'),
|
new InputOption('locked', null, InputOption::VALUE_NONE, 'Read dependency information from composer.lock'),
|
||||||
))
|
])
|
||||||
->setHelp(
|
->setHelp(
|
||||||
<<<EOT
|
<<<EOT
|
||||||
Displays detailed information about where a package is referenced.
|
Displays detailed information about where a package is referenced.
|
||||||
|
|
|
@ -50,9 +50,6 @@ class DiagnoseCommand extends BaseCommand
|
||||||
/** @var int */
|
/** @var int */
|
||||||
protected $exitCode = 0;
|
protected $exitCode = 0;
|
||||||
|
|
||||||
/**
|
|
||||||
* @return void
|
|
||||||
*/
|
|
||||||
protected function configure(): void
|
protected function configure(): void
|
||||||
{
|
{
|
||||||
$this
|
$this
|
||||||
|
@ -92,7 +89,7 @@ EOT
|
||||||
$config = Factory::createConfig();
|
$config = Factory::createConfig();
|
||||||
}
|
}
|
||||||
|
|
||||||
$config->merge(array('config' => array('secure-http' => false)), Config::SOURCE_COMMAND);
|
$config->merge(['config' => ['secure-http' => false]], Config::SOURCE_COMMAND);
|
||||||
$config->prohibitUrlByConfig('http://repo.packagist.org', new NullIO);
|
$config->prohibitUrlByConfig('http://repo.packagist.org', new NullIO);
|
||||||
|
|
||||||
$this->httpDownloader = Factory::createHttpDownloader($io, $config);
|
$this->httpDownloader = Factory::createHttpDownloader($io, $config);
|
||||||
|
@ -162,8 +159,8 @@ EOT
|
||||||
|
|
||||||
$io->write(sprintf('Composer version: <comment>%s</comment>', Composer::getVersion()));
|
$io->write(sprintf('Composer version: <comment>%s</comment>', Composer::getVersion()));
|
||||||
|
|
||||||
$platformOverrides = $config->get('platform') ?: array();
|
$platformOverrides = $config->get('platform') ?: [];
|
||||||
$platformRepo = new PlatformRepository(array(), $platformOverrides);
|
$platformRepo = new PlatformRepository([], $platformOverrides);
|
||||||
$phpPkg = $platformRepo->findPackage('php', '*');
|
$phpPkg = $platformRepo->findPackage('php', '*');
|
||||||
$phpVersion = $phpPkg->getPrettyVersion();
|
$phpVersion = $phpPkg->getPrettyVersion();
|
||||||
if ($phpPkg instanceof CompletePackageInterface && false !== strpos($phpPkg->getDescription(), 'overridden')) {
|
if ($phpPkg instanceof CompletePackageInterface && false !== strpos($phpPkg->getDescription(), 'overridden')) {
|
||||||
|
@ -182,7 +179,7 @@ EOT
|
||||||
$finder = new ExecutableFinder;
|
$finder = new ExecutableFinder;
|
||||||
$hasSystemUnzip = (bool) $finder->find('unzip');
|
$hasSystemUnzip = (bool) $finder->find('unzip');
|
||||||
$bin7zip = '';
|
$bin7zip = '';
|
||||||
if ($hasSystem7zip = (bool) $finder->find('7z', null, array('C:\Program Files\7-Zip'))) {
|
if ($hasSystem7zip = (bool) $finder->find('7z', null, ['C:\Program Files\7-Zip'])) {
|
||||||
$bin7zip = '7z';
|
$bin7zip = '7z';
|
||||||
}
|
}
|
||||||
if (!Platform::isWindows() && !$hasSystem7zip && $hasSystem7zip = (bool) $finder->find('7zz')) {
|
if (!Platform::isWindows() && !$hasSystem7zip && $hasSystem7zip = (bool) $finder->find('7zz')) {
|
||||||
|
@ -205,13 +202,13 @@ EOT
|
||||||
private function checkComposerSchema()
|
private function checkComposerSchema()
|
||||||
{
|
{
|
||||||
$validator = new ConfigValidator($this->getIO());
|
$validator = new ConfigValidator($this->getIO());
|
||||||
list($errors, , $warnings) = $validator->validate(Factory::getComposerFile());
|
[$errors, , $warnings] = $validator->validate(Factory::getComposerFile());
|
||||||
|
|
||||||
if ($errors || $warnings) {
|
if ($errors || $warnings) {
|
||||||
$messages = array(
|
$messages = [
|
||||||
'error' => $errors,
|
'error' => $errors,
|
||||||
'warning' => $warnings,
|
'warning' => $warnings,
|
||||||
);
|
];
|
||||||
|
|
||||||
$output = '';
|
$output = '';
|
||||||
foreach ($messages as $style => $msgs) {
|
foreach ($messages as $style => $msgs) {
|
||||||
|
@ -250,8 +247,6 @@ EOT
|
||||||
}
|
}
|
||||||
|
|
||||||
/**
|
/**
|
||||||
* @param string $proto
|
|
||||||
*
|
|
||||||
* @return string|string[]|true
|
* @return string|string[]|true
|
||||||
*/
|
*/
|
||||||
private function checkHttp(string $proto, Config $config)
|
private function checkHttp(string $proto, Config $config)
|
||||||
|
@ -261,7 +256,7 @@ EOT
|
||||||
return $result;
|
return $result;
|
||||||
}
|
}
|
||||||
|
|
||||||
$result = array();
|
$result = [];
|
||||||
if ($proto === 'https' && $config->get('disable-tls') === true) {
|
if ($proto === 'https' && $config->get('disable-tls') === true) {
|
||||||
$tlsWarning = '<warning>Composer is configured to disable SSL/TLS protection. This will leave remote HTTPS requests vulnerable to Man-In-The-Middle attacks.</warning>';
|
$tlsWarning = '<warning>Composer is configured to disable SSL/TLS protection. This will leave remote HTTPS requests vulnerable to Man-In-The-Middle attacks.</warning>';
|
||||||
}
|
}
|
||||||
|
@ -319,9 +314,6 @@ EOT
|
||||||
}
|
}
|
||||||
|
|
||||||
/**
|
/**
|
||||||
* @param string $domain
|
|
||||||
* @param string $token
|
|
||||||
*
|
|
||||||
* @return string|true|\Exception
|
* @return string|true|\Exception
|
||||||
*/
|
*/
|
||||||
private function checkGithubOauth(string $domain, string $token)
|
private function checkGithubOauth(string $domain, string $token)
|
||||||
|
@ -335,9 +327,9 @@ EOT
|
||||||
try {
|
try {
|
||||||
$url = $domain === 'github.com' ? 'https://api.'.$domain.'/' : 'https://'.$domain.'/api/v3/';
|
$url = $domain === 'github.com' ? 'https://api.'.$domain.'/' : 'https://'.$domain.'/api/v3/';
|
||||||
|
|
||||||
$this->httpDownloader->get($url, array(
|
$this->httpDownloader->get($url, [
|
||||||
'retry-auth-failure' => false,
|
'retry-auth-failure' => false,
|
||||||
));
|
]);
|
||||||
|
|
||||||
return true;
|
return true;
|
||||||
} catch (\Exception $e) {
|
} catch (\Exception $e) {
|
||||||
|
@ -350,12 +342,11 @@ EOT
|
||||||
}
|
}
|
||||||
|
|
||||||
/**
|
/**
|
||||||
* @param string $domain
|
|
||||||
* @param string $token
|
* @param string $token
|
||||||
* @throws TransportException
|
* @throws TransportException
|
||||||
* @return mixed|string
|
* @return mixed|string
|
||||||
*/
|
*/
|
||||||
private function getGithubRateLimit(string $domain, string $token = null)
|
private function getGithubRateLimit(string $domain, ?string $token = null)
|
||||||
{
|
{
|
||||||
$result = $this->checkConnectivity();
|
$result = $this->checkConnectivity();
|
||||||
if ($result !== true) {
|
if ($result !== true) {
|
||||||
|
@ -367,7 +358,7 @@ EOT
|
||||||
}
|
}
|
||||||
|
|
||||||
$url = $domain === 'github.com' ? 'https://api.'.$domain.'/rate_limit' : 'https://'.$domain.'/api/rate_limit';
|
$url = $domain === 'github.com' ? 'https://api.'.$domain.'/rate_limit' : 'https://'.$domain.'/api/rate_limit';
|
||||||
$data = $this->httpDownloader->get($url, array('retry-auth-failure' => false))->decodeJson();
|
$data = $this->httpDownloader->get($url, ['retry-auth-failure' => false])->decodeJson();
|
||||||
|
|
||||||
return $data['resources']['core'];
|
return $data['resources']['core'];
|
||||||
}
|
}
|
||||||
|
@ -397,7 +388,7 @@ EOT
|
||||||
private function checkPubKeys(Config $config)
|
private function checkPubKeys(Config $config)
|
||||||
{
|
{
|
||||||
$home = $config->get('home');
|
$home = $config->get('home');
|
||||||
$errors = array();
|
$errors = [];
|
||||||
$io = $this->getIO();
|
$io = $this->getIO();
|
||||||
|
|
||||||
if (file_exists($home.'/keys.tags.pub') && file_exists($home.'/keys.dev.pub')) {
|
if (file_exists($home.'/keys.tags.pub') && file_exists($home.'/keys.dev.pub')) {
|
||||||
|
@ -447,9 +438,6 @@ EOT
|
||||||
return true;
|
return true;
|
||||||
}
|
}
|
||||||
|
|
||||||
/**
|
|
||||||
* @return string
|
|
||||||
*/
|
|
||||||
private function getCurlVersion(): string
|
private function getCurlVersion(): string
|
||||||
{
|
{
|
||||||
if (extension_loaded('curl')) {
|
if (extension_loaded('curl')) {
|
||||||
|
@ -469,8 +457,6 @@ EOT
|
||||||
|
|
||||||
/**
|
/**
|
||||||
* @param bool|string|string[]|\Exception $result
|
* @param bool|string|string[]|\Exception $result
|
||||||
*
|
|
||||||
* @return void
|
|
||||||
*/
|
*/
|
||||||
private function outputResult($result): void
|
private function outputResult($result): void
|
||||||
{
|
{
|
||||||
|
@ -492,7 +478,7 @@ EOT
|
||||||
$hadError = true;
|
$hadError = true;
|
||||||
} else {
|
} else {
|
||||||
if (!is_array($result)) {
|
if (!is_array($result)) {
|
||||||
$result = array($result);
|
$result = [$result];
|
||||||
}
|
}
|
||||||
foreach ($result as $message) {
|
foreach ($result as $message) {
|
||||||
if (false !== strpos($message, '<error>')) {
|
if (false !== strpos($message, '<error>')) {
|
||||||
|
@ -529,8 +515,8 @@ EOT
|
||||||
};
|
};
|
||||||
|
|
||||||
// code below taken from getcomposer.org/installer, any changes should be made there and replicated here
|
// code below taken from getcomposer.org/installer, any changes should be made there and replicated here
|
||||||
$errors = array();
|
$errors = [];
|
||||||
$warnings = array();
|
$warnings = [];
|
||||||
$displayIniMessage = false;
|
$displayIniMessage = false;
|
||||||
|
|
||||||
$iniMessage = PHP_EOL.PHP_EOL.IniHelper::getMessage();
|
$iniMessage = PHP_EOL.PHP_EOL.IniHelper::getMessage();
|
||||||
|
|
|
@ -30,9 +30,9 @@ class DumpAutoloadCommand extends BaseCommand
|
||||||
{
|
{
|
||||||
$this
|
$this
|
||||||
->setName('dump-autoload')
|
->setName('dump-autoload')
|
||||||
->setAliases(array('dumpautoload'))
|
->setAliases(['dumpautoload'])
|
||||||
->setDescription('Dumps the autoloader')
|
->setDescription('Dumps the autoloader')
|
||||||
->setDefinition(array(
|
->setDefinition([
|
||||||
new InputOption('optimize', 'o', InputOption::VALUE_NONE, 'Optimizes PSR0 and PSR4 packages to be loaded with classmaps too, good for production.'),
|
new InputOption('optimize', 'o', InputOption::VALUE_NONE, 'Optimizes PSR0 and PSR4 packages to be loaded with classmaps too, good for production.'),
|
||||||
new InputOption('classmap-authoritative', 'a', InputOption::VALUE_NONE, 'Autoload classes from the classmap only. Implicitly enables `--optimize`.'),
|
new InputOption('classmap-authoritative', 'a', InputOption::VALUE_NONE, 'Autoload classes from the classmap only. Implicitly enables `--optimize`.'),
|
||||||
new InputOption('apcu', null, InputOption::VALUE_NONE, 'Use APCu to cache found/not-found classes.'),
|
new InputOption('apcu', null, InputOption::VALUE_NONE, 'Use APCu to cache found/not-found classes.'),
|
||||||
|
@ -42,7 +42,7 @@ class DumpAutoloadCommand extends BaseCommand
|
||||||
new InputOption('ignore-platform-req', null, InputOption::VALUE_REQUIRED | InputOption::VALUE_IS_ARRAY, 'Ignore a specific platform requirement (php & ext- packages).'),
|
new InputOption('ignore-platform-req', null, InputOption::VALUE_REQUIRED | InputOption::VALUE_IS_ARRAY, 'Ignore a specific platform requirement (php & ext- packages).'),
|
||||||
new InputOption('ignore-platform-reqs', null, InputOption::VALUE_NONE, 'Ignore all platform requirements (php & ext- packages).'),
|
new InputOption('ignore-platform-reqs', null, InputOption::VALUE_NONE, 'Ignore all platform requirements (php & ext- packages).'),
|
||||||
new InputOption('strict-psr', null, InputOption::VALUE_NONE, 'Return a failed status code (1) if PSR-4 or PSR-0 mapping errors are present. Requires --optimize to work.'),
|
new InputOption('strict-psr', null, InputOption::VALUE_NONE, 'Return a failed status code (1) if PSR-4 or PSR-0 mapping errors are present. Requires --optimize to work.'),
|
||||||
))
|
])
|
||||||
->setHelp(
|
->setHelp(
|
||||||
<<<EOT
|
<<<EOT
|
||||||
<info>php composer.phar dump-autoload</info>
|
<info>php composer.phar dump-autoload</info>
|
||||||
|
|
|
@ -30,7 +30,7 @@ class ExecCommand extends BaseCommand
|
||||||
$this
|
$this
|
||||||
->setName('exec')
|
->setName('exec')
|
||||||
->setDescription('Executes a vendored binary/script')
|
->setDescription('Executes a vendored binary/script')
|
||||||
->setDefinition(array(
|
->setDefinition([
|
||||||
new InputOption('list', 'l', InputOption::VALUE_NONE),
|
new InputOption('list', 'l', InputOption::VALUE_NONE),
|
||||||
new InputArgument('binary', InputArgument::OPTIONAL, 'The binary to run, e.g. phpunit', null, function () {
|
new InputArgument('binary', InputArgument::OPTIONAL, 'The binary to run, e.g. phpunit', null, function () {
|
||||||
return $this->getBinaries(false);
|
return $this->getBinaries(false);
|
||||||
|
@ -40,7 +40,7 @@ class ExecCommand extends BaseCommand
|
||||||
InputArgument::IS_ARRAY | InputArgument::OPTIONAL,
|
InputArgument::IS_ARRAY | InputArgument::OPTIONAL,
|
||||||
'Arguments to pass to the binary. Use <info>--</info> to separate from composer arguments'
|
'Arguments to pass to the binary. Use <info>--</info> to separate from composer arguments'
|
||||||
),
|
),
|
||||||
))
|
])
|
||||||
->setHelp(
|
->setHelp(
|
||||||
<<<EOT
|
<<<EOT
|
||||||
Executes a vendored binary/script.
|
Executes a vendored binary/script.
|
||||||
|
@ -99,7 +99,6 @@ EOT
|
||||||
}
|
}
|
||||||
|
|
||||||
/**
|
/**
|
||||||
* @param bool $forDisplay
|
|
||||||
* @return string[]
|
* @return string[]
|
||||||
*/
|
*/
|
||||||
private function getBinaries(bool $forDisplay): array
|
private function getBinaries(bool $forDisplay): array
|
||||||
|
|
|
@ -30,16 +30,13 @@ use Symfony\Component\Console\Output\OutputInterface;
|
||||||
*/
|
*/
|
||||||
class FundCommand extends BaseCommand
|
class FundCommand extends BaseCommand
|
||||||
{
|
{
|
||||||
/**
|
|
||||||
* @return void
|
|
||||||
*/
|
|
||||||
protected function configure(): void
|
protected function configure(): void
|
||||||
{
|
{
|
||||||
$this->setName('fund')
|
$this->setName('fund')
|
||||||
->setDescription('Discover how to help fund the maintenance of your dependencies')
|
->setDescription('Discover how to help fund the maintenance of your dependencies')
|
||||||
->setDefinition(array(
|
->setDefinition([
|
||||||
new InputOption('format', 'f', InputOption::VALUE_REQUIRED, 'Format of the output: text or json', 'text', ['text', 'json']),
|
new InputOption('format', 'f', InputOption::VALUE_REQUIRED, 'Format of the output: text or json', 'text', ['text', 'json']),
|
||||||
))
|
])
|
||||||
;
|
;
|
||||||
}
|
}
|
||||||
|
|
||||||
|
@ -49,9 +46,9 @@ class FundCommand extends BaseCommand
|
||||||
|
|
||||||
$repo = $composer->getRepositoryManager()->getLocalRepository();
|
$repo = $composer->getRepositoryManager()->getLocalRepository();
|
||||||
$remoteRepos = new CompositeRepository($composer->getRepositoryManager()->getRepositories());
|
$remoteRepos = new CompositeRepository($composer->getRepositoryManager()->getRepositories());
|
||||||
$fundings = array();
|
$fundings = [];
|
||||||
|
|
||||||
$packagesToLoad = array();
|
$packagesToLoad = [];
|
||||||
foreach ($repo->getPackages() as $package) {
|
foreach ($repo->getPackages() as $package) {
|
||||||
if ($package instanceof AliasPackage) {
|
if ($package instanceof AliasPackage) {
|
||||||
continue;
|
continue;
|
||||||
|
@ -60,7 +57,7 @@ class FundCommand extends BaseCommand
|
||||||
}
|
}
|
||||||
|
|
||||||
// load all packages dev versions in parallel
|
// load all packages dev versions in parallel
|
||||||
$result = $remoteRepos->loadPackages($packagesToLoad, array('dev' => BasePackage::STABILITY_DEV), array());
|
$result = $remoteRepos->loadPackages($packagesToLoad, ['dev' => BasePackage::STABILITY_DEV], []);
|
||||||
|
|
||||||
// collect funding data from default branches
|
// collect funding data from default branches
|
||||||
foreach ($result['packages'] as $package) {
|
foreach ($result['packages'] as $package) {
|
||||||
|
@ -92,7 +89,7 @@ class FundCommand extends BaseCommand
|
||||||
$io = $this->getIO();
|
$io = $this->getIO();
|
||||||
|
|
||||||
$format = $input->getOption('format');
|
$format = $input->getOption('format');
|
||||||
if (!in_array($format, array('text', 'json'))) {
|
if (!in_array($format, ['text', 'json'])) {
|
||||||
$io->writeError(sprintf('Unsupported format "%s". See help for supported formats.', $format));
|
$io->writeError(sprintf('Unsupported format "%s". See help for supported formats.', $format));
|
||||||
|
|
||||||
return 1;
|
return 1;
|
||||||
|
@ -137,7 +134,7 @@ class FundCommand extends BaseCommand
|
||||||
private function insertFundingData(array $fundings, CompletePackageInterface $package): array
|
private function insertFundingData(array $fundings, CompletePackageInterface $package): array
|
||||||
{
|
{
|
||||||
foreach ($package->getFunding() as $fundingOption) {
|
foreach ($package->getFunding() as $fundingOption) {
|
||||||
list($vendor, $packageName) = explode('/', $package->getPrettyName());
|
[$vendor, $packageName] = explode('/', $package->getPrettyName());
|
||||||
// ignore malformed funding entries
|
// ignore malformed funding entries
|
||||||
if (empty($fundingOption['url'])) {
|
if (empty($fundingOption['url'])) {
|
||||||
continue;
|
continue;
|
||||||
|
|
|
@ -51,18 +51,15 @@ class GlobalCommand extends BaseCommand
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
|
|
||||||
/**
|
|
||||||
* @return void
|
|
||||||
*/
|
|
||||||
protected function configure(): void
|
protected function configure(): void
|
||||||
{
|
{
|
||||||
$this
|
$this
|
||||||
->setName('global')
|
->setName('global')
|
||||||
->setDescription('Allows running commands in the global composer dir ($COMPOSER_HOME)')
|
->setDescription('Allows running commands in the global composer dir ($COMPOSER_HOME)')
|
||||||
->setDefinition(array(
|
->setDefinition([
|
||||||
new InputArgument('command-name', InputArgument::REQUIRED, ''),
|
new InputArgument('command-name', InputArgument::REQUIRED, ''),
|
||||||
new InputArgument('args', InputArgument::IS_ARRAY | InputArgument::OPTIONAL, ''),
|
new InputArgument('args', InputArgument::IS_ARRAY | InputArgument::OPTIONAL, ''),
|
||||||
))
|
])
|
||||||
->setHelp(
|
->setHelp(
|
||||||
<<<EOT
|
<<<EOT
|
||||||
Use this command as a wrapper to run other Composer commands
|
Use this command as a wrapper to run other Composer commands
|
||||||
|
@ -98,7 +95,7 @@ EOT
|
||||||
|
|
||||||
// extract real command name
|
// extract real command name
|
||||||
$tokens = Preg::split('{\s+}', $input->__toString());
|
$tokens = Preg::split('{\s+}', $input->__toString());
|
||||||
$args = array();
|
$args = [];
|
||||||
foreach ($tokens as $token) {
|
foreach ($tokens as $token) {
|
||||||
if ($token && $token[0] !== '-') {
|
if ($token && $token[0] !== '-') {
|
||||||
$args[] = $token;
|
$args[] = $token;
|
||||||
|
|
|
@ -32,20 +32,18 @@ class HomeCommand extends BaseCommand
|
||||||
|
|
||||||
/**
|
/**
|
||||||
* @inheritDoc
|
* @inheritDoc
|
||||||
*
|
|
||||||
* @return void
|
|
||||||
*/
|
*/
|
||||||
protected function configure(): void
|
protected function configure(): void
|
||||||
{
|
{
|
||||||
$this
|
$this
|
||||||
->setName('browse')
|
->setName('browse')
|
||||||
->setAliases(array('home'))
|
->setAliases(['home'])
|
||||||
->setDescription('Opens the package\'s repository URL or homepage in your browser')
|
->setDescription('Opens the package\'s repository URL or homepage in your browser')
|
||||||
->setDefinition(array(
|
->setDefinition([
|
||||||
new InputArgument('packages', InputArgument::IS_ARRAY, 'Package(s) to browse to.', null, $this->suggestInstalledPackage()),
|
new InputArgument('packages', InputArgument::IS_ARRAY, 'Package(s) to browse to.', null, $this->suggestInstalledPackage()),
|
||||||
new InputOption('homepage', 'H', InputOption::VALUE_NONE, 'Open the homepage instead of the repository URL.'),
|
new InputOption('homepage', 'H', InputOption::VALUE_NONE, 'Open the homepage instead of the repository URL.'),
|
||||||
new InputOption('show', 's', InputOption::VALUE_NONE, 'Only show the homepage or repository URL.'),
|
new InputOption('show', 's', InputOption::VALUE_NONE, 'Only show the homepage or repository URL.'),
|
||||||
))
|
])
|
||||||
->setHelp(
|
->setHelp(
|
||||||
<<<EOT
|
<<<EOT
|
||||||
The home command opens or shows a package's repository URL or
|
The home command opens or shows a package's repository URL or
|
||||||
|
@ -68,7 +66,7 @@ EOT
|
||||||
$packages = $input->getArgument('packages');
|
$packages = $input->getArgument('packages');
|
||||||
if (count($packages) === 0) {
|
if (count($packages) === 0) {
|
||||||
$io->writeError('No package specified, opening homepage for the root package');
|
$io->writeError('No package specified, opening homepage for the root package');
|
||||||
$packages = array($this->requireComposer()->getPackage()->getName());
|
$packages = [$this->requireComposer()->getPackage()->getName()];
|
||||||
}
|
}
|
||||||
|
|
||||||
foreach ($packages as $packageName) {
|
foreach ($packages as $packageName) {
|
||||||
|
@ -98,11 +96,6 @@ EOT
|
||||||
return $return;
|
return $return;
|
||||||
}
|
}
|
||||||
|
|
||||||
/**
|
|
||||||
* @param bool $showHomepage
|
|
||||||
* @param bool $showOnly
|
|
||||||
* @return bool
|
|
||||||
*/
|
|
||||||
private function handlePackage(CompletePackageInterface $package, bool $showHomepage, bool $showOnly): bool
|
private function handlePackage(CompletePackageInterface $package, bool $showHomepage, bool $showOnly): bool
|
||||||
{
|
{
|
||||||
$support = $package->getSupport();
|
$support = $package->getSupport();
|
||||||
|
@ -126,9 +119,6 @@ EOT
|
||||||
|
|
||||||
/**
|
/**
|
||||||
* opens a url in your system default browser
|
* opens a url in your system default browser
|
||||||
*
|
|
||||||
* @param string $url
|
|
||||||
* @return void
|
|
||||||
*/
|
*/
|
||||||
private function openBrowser(string $url): void
|
private function openBrowser(string $url): void
|
||||||
{
|
{
|
||||||
|
@ -166,8 +156,8 @@ EOT
|
||||||
|
|
||||||
if ($composer) {
|
if ($composer) {
|
||||||
return array_merge(
|
return array_merge(
|
||||||
array(new RootPackageRepository(clone $composer->getPackage())), // root package
|
[new RootPackageRepository(clone $composer->getPackage())], // root package
|
||||||
array($composer->getRepositoryManager()->getLocalRepository()), // installed packages
|
[$composer->getRepositoryManager()->getLocalRepository()], // installed packages
|
||||||
$composer->getRepositoryManager()->getRepositories() // remotes
|
$composer->getRepositoryManager()->getRepositories() // remotes
|
||||||
);
|
);
|
||||||
}
|
}
|
||||||
|
|
|
@ -53,7 +53,7 @@ class InitCommand extends BaseCommand
|
||||||
$this
|
$this
|
||||||
->setName('init')
|
->setName('init')
|
||||||
->setDescription('Creates a basic composer.json file in current directory')
|
->setDescription('Creates a basic composer.json file in current directory')
|
||||||
->setDefinition(array(
|
->setDefinition([
|
||||||
new InputOption('name', null, InputOption::VALUE_REQUIRED, 'Name of the package'),
|
new InputOption('name', null, InputOption::VALUE_REQUIRED, 'Name of the package'),
|
||||||
new InputOption('description', null, InputOption::VALUE_REQUIRED, 'Description of package'),
|
new InputOption('description', null, InputOption::VALUE_REQUIRED, 'Description of package'),
|
||||||
new InputOption('author', null, InputOption::VALUE_REQUIRED, 'Author name of package'),
|
new InputOption('author', null, InputOption::VALUE_REQUIRED, 'Author name of package'),
|
||||||
|
@ -65,7 +65,7 @@ class InitCommand extends BaseCommand
|
||||||
new InputOption('license', 'l', InputOption::VALUE_REQUIRED, 'License of package'),
|
new InputOption('license', 'l', InputOption::VALUE_REQUIRED, 'License of package'),
|
||||||
new InputOption('repository', null, InputOption::VALUE_REQUIRED | InputOption::VALUE_IS_ARRAY, 'Add custom repositories, either by URL or using JSON arrays'),
|
new InputOption('repository', null, InputOption::VALUE_REQUIRED | InputOption::VALUE_IS_ARRAY, 'Add custom repositories, either by URL or using JSON arrays'),
|
||||||
new InputOption('autoload', 'a', InputOption::VALUE_REQUIRED, 'Add PSR-4 autoload mapping. Maps your package\'s namespace to the provided directory. (Expects a relative path, e.g. src/)'),
|
new InputOption('autoload', 'a', InputOption::VALUE_REQUIRED, 'Add PSR-4 autoload mapping. Maps your package\'s namespace to the provided directory. (Expects a relative path, e.g. src/)'),
|
||||||
))
|
])
|
||||||
->setHelp(
|
->setHelp(
|
||||||
<<<EOT
|
<<<EOT
|
||||||
The <info>init</info> command creates a basic composer.json file
|
The <info>init</info> command creates a basic composer.json file
|
||||||
|
@ -86,7 +86,7 @@ EOT
|
||||||
{
|
{
|
||||||
$io = $this->getIO();
|
$io = $this->getIO();
|
||||||
|
|
||||||
$allowlist = array('name', 'description', 'author', 'type', 'homepage', 'require', 'require-dev', 'stability', 'license', 'autoload');
|
$allowlist = ['name', 'description', 'author', 'type', 'homepage', 'require', 'require-dev', 'stability', 'license', 'autoload'];
|
||||||
$options = array_filter(array_intersect_key($input->getOptions(), array_flip($allowlist)));
|
$options = array_filter(array_intersect_key($input->getOptions(), array_flip($allowlist)));
|
||||||
|
|
||||||
if (isset($options['name']) && !Preg::isMatch('{^[a-z0-9_.-]+/[a-z0-9_.-]+$}D', $options['name'])) {
|
if (isset($options['name']) && !Preg::isMatch('{^[a-z0-9_.-]+/[a-z0-9_.-]+$}D', $options['name'])) {
|
||||||
|
@ -114,13 +114,13 @@ EOT
|
||||||
}
|
}
|
||||||
|
|
||||||
$options['require'] = isset($options['require']) ? $this->formatRequirements($options['require']) : new \stdClass;
|
$options['require'] = isset($options['require']) ? $this->formatRequirements($options['require']) : new \stdClass;
|
||||||
if (array() === $options['require']) {
|
if ([] === $options['require']) {
|
||||||
$options['require'] = new \stdClass;
|
$options['require'] = new \stdClass;
|
||||||
}
|
}
|
||||||
|
|
||||||
if (isset($options['require-dev'])) {
|
if (isset($options['require-dev'])) {
|
||||||
$options['require-dev'] = $this->formatRequirements($options['require-dev']);
|
$options['require-dev'] = $this->formatRequirements($options['require-dev']);
|
||||||
if (array() === $options['require-dev']) {
|
if ([] === $options['require-dev']) {
|
||||||
$options['require-dev'] = new \stdClass;
|
$options['require-dev'] = new \stdClass;
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
|
@ -130,18 +130,18 @@ EOT
|
||||||
if (isset($options['autoload'])) {
|
if (isset($options['autoload'])) {
|
||||||
$autoloadPath = $options['autoload'];
|
$autoloadPath = $options['autoload'];
|
||||||
$namespace = $this->namespaceFromPackageName((string) $input->getOption('name'));
|
$namespace = $this->namespaceFromPackageName((string) $input->getOption('name'));
|
||||||
$options['autoload'] = (object) array(
|
$options['autoload'] = (object) [
|
||||||
'psr-4' => array(
|
'psr-4' => [
|
||||||
$namespace . '\\' => $autoloadPath,
|
$namespace . '\\' => $autoloadPath,
|
||||||
),
|
],
|
||||||
);
|
];
|
||||||
}
|
}
|
||||||
|
|
||||||
$file = new JsonFile(Factory::getComposerFile());
|
$file = new JsonFile(Factory::getComposerFile());
|
||||||
$json = JsonFile::encode($options);
|
$json = JsonFile::encode($options);
|
||||||
|
|
||||||
if ($input->isInteractive()) {
|
if ($input->isInteractive()) {
|
||||||
$io->writeError(array('', $json, ''));
|
$io->writeError(['', $json, '']);
|
||||||
if (!$io->askConfirmation('Do you confirm generation [<comment>yes</comment>]? ')) {
|
if (!$io->askConfirmation('Do you confirm generation [<comment>yes</comment>]? ')) {
|
||||||
$io->writeError('<error>Command aborted</error>');
|
$io->writeError('<error>Command aborted</error>');
|
||||||
|
|
||||||
|
@ -229,13 +229,13 @@ EOT
|
||||||
$io->loadConfiguration($config);
|
$io->loadConfiguration($config);
|
||||||
$repoManager = RepositoryFactory::manager($io, $config);
|
$repoManager = RepositoryFactory::manager($io, $config);
|
||||||
|
|
||||||
$repos = array(new PlatformRepository);
|
$repos = [new PlatformRepository];
|
||||||
$createDefaultPackagistRepo = true;
|
$createDefaultPackagistRepo = true;
|
||||||
foreach ($repositories as $repo) {
|
foreach ($repositories as $repo) {
|
||||||
$repoConfig = RepositoryFactory::configFromString($io, $config, $repo, true);
|
$repoConfig = RepositoryFactory::configFromString($io, $config, $repo, true);
|
||||||
if (
|
if (
|
||||||
(isset($repoConfig['packagist']) && $repoConfig === array('packagist' => false))
|
(isset($repoConfig['packagist']) && $repoConfig === ['packagist' => false])
|
||||||
|| (isset($repoConfig['packagist.org']) && $repoConfig === array('packagist.org' => false))
|
|| (isset($repoConfig['packagist.org']) && $repoConfig === ['packagist.org' => false])
|
||||||
) {
|
) {
|
||||||
$createDefaultPackagistRepo = false;
|
$createDefaultPackagistRepo = false;
|
||||||
continue;
|
continue;
|
||||||
|
@ -244,28 +244,28 @@ EOT
|
||||||
}
|
}
|
||||||
|
|
||||||
if ($createDefaultPackagistRepo) {
|
if ($createDefaultPackagistRepo) {
|
||||||
$repos[] = RepositoryFactory::createRepo($io, $config, array(
|
$repos[] = RepositoryFactory::createRepo($io, $config, [
|
||||||
'type' => 'composer',
|
'type' => 'composer',
|
||||||
'url' => 'https://repo.packagist.org',
|
'url' => 'https://repo.packagist.org',
|
||||||
), $repoManager);
|
], $repoManager);
|
||||||
}
|
}
|
||||||
|
|
||||||
$this->repos = new CompositeRepository($repos);
|
$this->repos = new CompositeRepository($repos);
|
||||||
unset($repos, $config, $repositories);
|
unset($repos, $config, $repositories);
|
||||||
}
|
}
|
||||||
|
|
||||||
$io->writeError(array(
|
$io->writeError([
|
||||||
'',
|
'',
|
||||||
$formatter->formatBlock('Welcome to the Composer config generator', 'bg=blue;fg=white', true),
|
$formatter->formatBlock('Welcome to the Composer config generator', 'bg=blue;fg=white', true),
|
||||||
'',
|
'',
|
||||||
));
|
]);
|
||||||
|
|
||||||
// namespace
|
// namespace
|
||||||
$io->writeError(array(
|
$io->writeError([
|
||||||
'',
|
'',
|
||||||
'This command will guide you through creating your composer.json config.',
|
'This command will guide you through creating your composer.json config.',
|
||||||
'',
|
'',
|
||||||
));
|
]);
|
||||||
|
|
||||||
$cwd = realpath(".");
|
$cwd = realpath(".");
|
||||||
|
|
||||||
|
@ -397,7 +397,7 @@ EOT
|
||||||
);
|
);
|
||||||
$input->setOption('license', $license);
|
$input->setOption('license', $license);
|
||||||
|
|
||||||
$io->writeError(array('', 'Define your dependencies.', ''));
|
$io->writeError(['', 'Define your dependencies.', '']);
|
||||||
|
|
||||||
// prepare to resolve dependencies
|
// prepare to resolve dependencies
|
||||||
$repos = $this->getRepos();
|
$repos = $this->getRepos();
|
||||||
|
@ -414,7 +414,7 @@ EOT
|
||||||
|
|
||||||
$question = 'Would you like to define your dependencies (require) interactively [<comment>yes</comment>]? ';
|
$question = 'Would you like to define your dependencies (require) interactively [<comment>yes</comment>]? ';
|
||||||
$require = $input->getOption('require');
|
$require = $input->getOption('require');
|
||||||
$requirements = array();
|
$requirements = [];
|
||||||
if (count($require) > 0 || $io->askConfirmation($question)) {
|
if (count($require) > 0 || $io->askConfirmation($question)) {
|
||||||
$requirements = $this->determineRequirements($input, $output, $require, $platformRepo, $preferredStability);
|
$requirements = $this->determineRequirements($input, $output, $require, $platformRepo, $preferredStability);
|
||||||
}
|
}
|
||||||
|
@ -422,7 +422,7 @@ EOT
|
||||||
|
|
||||||
$question = 'Would you like to define your dev dependencies (require-dev) interactively [<comment>yes</comment>]? ';
|
$question = 'Would you like to define your dev dependencies (require-dev) interactively [<comment>yes</comment>]? ';
|
||||||
$requireDev = $input->getOption('require-dev');
|
$requireDev = $input->getOption('require-dev');
|
||||||
$devRequirements = array();
|
$devRequirements = [];
|
||||||
if (count($requireDev) > 0 || $io->askConfirmation($question)) {
|
if (count($requireDev) > 0 || $io->askConfirmation($question)) {
|
||||||
$devRequirements = $this->determineRequirements($input, $output, $requireDev, $platformRepo, $preferredStability);
|
$devRequirements = $this->determineRequirements($input, $output, $requireDev, $platformRepo, $preferredStability);
|
||||||
}
|
}
|
||||||
|
@ -460,7 +460,6 @@ EOT
|
||||||
}
|
}
|
||||||
|
|
||||||
/**
|
/**
|
||||||
* @param string $author
|
|
||||||
* @return array{name: string, email: string|null}
|
* @return array{name: string, email: string|null}
|
||||||
*/
|
*/
|
||||||
private function parseAuthorString(string $author): array
|
private function parseAuthorString(string $author): array
|
||||||
|
@ -471,10 +470,10 @@ EOT
|
||||||
throw new \InvalidArgumentException('Invalid email "'.$match['email'].'"');
|
throw new \InvalidArgumentException('Invalid email "'.$match['email'].'"');
|
||||||
}
|
}
|
||||||
|
|
||||||
return array(
|
return [
|
||||||
'name' => trim($match['name']),
|
'name' => trim($match['name']),
|
||||||
'email' => $hasEmail ? $match['email'] : null,
|
'email' => $hasEmail ? $match['email'] : null,
|
||||||
);
|
];
|
||||||
}
|
}
|
||||||
|
|
||||||
throw new \InvalidArgumentException(
|
throw new \InvalidArgumentException(
|
||||||
|
@ -484,8 +483,6 @@ EOT
|
||||||
}
|
}
|
||||||
|
|
||||||
/**
|
/**
|
||||||
* @param string $author
|
|
||||||
*
|
|
||||||
* @return array<int, array{name: string, email?: string}>
|
* @return array<int, array{name: string, email?: string}>
|
||||||
*/
|
*/
|
||||||
protected function formatAuthors(string $author): array
|
protected function formatAuthors(string $author): array
|
||||||
|
@ -495,17 +492,13 @@ EOT
|
||||||
unset($author['email']);
|
unset($author['email']);
|
||||||
}
|
}
|
||||||
|
|
||||||
return array($author);
|
return [$author];
|
||||||
}
|
}
|
||||||
|
|
||||||
/**
|
/**
|
||||||
* Extract namespace from package's vendor name.
|
* Extract namespace from package's vendor name.
|
||||||
*
|
*
|
||||||
* new_projects.acme-extra/package-name becomes "NewProjectsAcmeExtra\PackageName"
|
* new_projects.acme-extra/package-name becomes "NewProjectsAcmeExtra\PackageName"
|
||||||
*
|
|
||||||
* @param string $packageName
|
|
||||||
*
|
|
||||||
* @return string|null
|
|
||||||
*/
|
*/
|
||||||
public function namespaceFromPackageName(string $packageName): ?string
|
public function namespaceFromPackageName(string $packageName): ?string
|
||||||
{
|
{
|
||||||
|
@ -538,11 +531,11 @@ EOT
|
||||||
$finder = new ExecutableFinder();
|
$finder = new ExecutableFinder();
|
||||||
$gitBin = $finder->find('git');
|
$gitBin = $finder->find('git');
|
||||||
|
|
||||||
$cmd = new Process(array($gitBin, 'config', '-l'));
|
$cmd = new Process([$gitBin, 'config', '-l']);
|
||||||
$cmd->run();
|
$cmd->run();
|
||||||
|
|
||||||
if ($cmd->isSuccessful()) {
|
if ($cmd->isSuccessful()) {
|
||||||
$this->gitConfig = array();
|
$this->gitConfig = [];
|
||||||
Preg::matchAll('{^([^=]+)=(.*)$}m', $cmd->getOutput(), $matches);
|
Preg::matchAll('{^([^=]+)=(.*)$}m', $cmd->getOutput(), $matches);
|
||||||
foreach ($matches[1] as $key => $match) {
|
foreach ($matches[1] as $key => $match) {
|
||||||
$this->gitConfig[$match] = $matches[2][$key];
|
$this->gitConfig[$match] = $matches[2][$key];
|
||||||
|
@ -551,7 +544,7 @@ EOT
|
||||||
return $this->gitConfig;
|
return $this->gitConfig;
|
||||||
}
|
}
|
||||||
|
|
||||||
return $this->gitConfig = array();
|
return $this->gitConfig = [];
|
||||||
}
|
}
|
||||||
|
|
||||||
/**
|
/**
|
||||||
|
@ -564,11 +557,6 @@ EOT
|
||||||
* "/$vendor/"
|
* "/$vendor/"
|
||||||
* "/$vendor/*"
|
* "/$vendor/*"
|
||||||
* "$vendor/*"
|
* "$vendor/*"
|
||||||
*
|
|
||||||
* @param string $ignoreFile
|
|
||||||
* @param string $vendor
|
|
||||||
*
|
|
||||||
* @return bool
|
|
||||||
*/
|
*/
|
||||||
protected function hasVendorIgnore(string $ignoreFile, string $vendor = 'vendor'): bool
|
protected function hasVendorIgnore(string $ignoreFile, string $vendor = 'vendor'): bool
|
||||||
{
|
{
|
||||||
|
@ -588,12 +576,6 @@ EOT
|
||||||
return false;
|
return false;
|
||||||
}
|
}
|
||||||
|
|
||||||
/**
|
|
||||||
* @param string $ignoreFile
|
|
||||||
* @param string $vendor
|
|
||||||
*
|
|
||||||
* @return void
|
|
||||||
*/
|
|
||||||
protected function addVendorIgnore(string $ignoreFile, string $vendor = '/vendor/'): void
|
protected function addVendorIgnore(string $ignoreFile, string $vendor = '/vendor/'): void
|
||||||
{
|
{
|
||||||
$contents = "";
|
$contents = "";
|
||||||
|
@ -608,11 +590,6 @@ EOT
|
||||||
file_put_contents($ignoreFile, $contents . $vendor. "\n");
|
file_put_contents($ignoreFile, $contents . $vendor. "\n");
|
||||||
}
|
}
|
||||||
|
|
||||||
/**
|
|
||||||
* @param string $email
|
|
||||||
*
|
|
||||||
* @return bool
|
|
||||||
*/
|
|
||||||
protected function isValidEmail(string $email): bool
|
protected function isValidEmail(string $email): bool
|
||||||
{
|
{
|
||||||
// assume it's valid if we can't validate it
|
// assume it's valid if we can't validate it
|
||||||
|
@ -623,29 +600,23 @@ EOT
|
||||||
return false !== filter_var($email, FILTER_VALIDATE_EMAIL);
|
return false !== filter_var($email, FILTER_VALIDATE_EMAIL);
|
||||||
}
|
}
|
||||||
|
|
||||||
/**
|
|
||||||
* @return void
|
|
||||||
*/
|
|
||||||
private function updateDependencies(OutputInterface $output): void
|
private function updateDependencies(OutputInterface $output): void
|
||||||
{
|
{
|
||||||
try {
|
try {
|
||||||
$updateCommand = $this->getApplication()->find('update');
|
$updateCommand = $this->getApplication()->find('update');
|
||||||
$this->getApplication()->resetComposer();
|
$this->getApplication()->resetComposer();
|
||||||
$updateCommand->run(new ArrayInput(array()), $output);
|
$updateCommand->run(new ArrayInput([]), $output);
|
||||||
} catch (\Exception $e) {
|
} catch (\Exception $e) {
|
||||||
$this->getIO()->writeError('Could not update dependencies. Run `composer update` to see more information.');
|
$this->getIO()->writeError('Could not update dependencies. Run `composer update` to see more information.');
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
|
|
||||||
/**
|
|
||||||
* @return void
|
|
||||||
*/
|
|
||||||
private function runDumpAutoloadCommand(OutputInterface $output): void
|
private function runDumpAutoloadCommand(OutputInterface $output): void
|
||||||
{
|
{
|
||||||
try {
|
try {
|
||||||
$command = $this->getApplication()->find('dump-autoload');
|
$command = $this->getApplication()->find('dump-autoload');
|
||||||
$this->getApplication()->resetComposer();
|
$this->getApplication()->resetComposer();
|
||||||
$command->run(new ArrayInput(array()), $output);
|
$command->run(new ArrayInput([]), $output);
|
||||||
} catch (\Exception $e) {
|
} catch (\Exception $e) {
|
||||||
$this->getIO()->writeError('Could not run dump-autoload.');
|
$this->getIO()->writeError('Could not run dump-autoload.');
|
||||||
}
|
}
|
||||||
|
@ -653,12 +624,11 @@ EOT
|
||||||
|
|
||||||
/**
|
/**
|
||||||
* @param array<string, string|array<string>> $options
|
* @param array<string, string|array<string>> $options
|
||||||
* @return bool
|
|
||||||
*/
|
*/
|
||||||
private function hasDependencies(array $options): bool
|
private function hasDependencies(array $options): bool
|
||||||
{
|
{
|
||||||
$requires = (array) $options['require'];
|
$requires = (array) $options['require'];
|
||||||
$devRequires = isset($options['require-dev']) ? (array) $options['require-dev'] : array();
|
$devRequires = isset($options['require-dev']) ? (array) $options['require-dev'] : [];
|
||||||
|
|
||||||
return !empty($requires) || !empty($devRequires);
|
return !empty($requires) || !empty($devRequires);
|
||||||
}
|
}
|
||||||
|
|
|
@ -39,9 +39,9 @@ class InstallCommand extends BaseCommand
|
||||||
{
|
{
|
||||||
$this
|
$this
|
||||||
->setName('install')
|
->setName('install')
|
||||||
->setAliases(array('i'))
|
->setAliases(['i'])
|
||||||
->setDescription('Installs the project dependencies from the composer.lock file if present, or falls back on the composer.json')
|
->setDescription('Installs the project dependencies from the composer.lock file if present, or falls back on the composer.json')
|
||||||
->setDefinition(array(
|
->setDefinition([
|
||||||
new InputOption('prefer-source', null, InputOption::VALUE_NONE, 'Forces installation from package sources when possible, including VCS information.'),
|
new InputOption('prefer-source', null, InputOption::VALUE_NONE, 'Forces installation from package sources when possible, including VCS information.'),
|
||||||
new InputOption('prefer-dist', null, InputOption::VALUE_NONE, 'Forces installation from package dist (default behavior).'),
|
new InputOption('prefer-dist', null, InputOption::VALUE_NONE, 'Forces installation from package dist (default behavior).'),
|
||||||
new InputOption('prefer-install', null, InputOption::VALUE_REQUIRED, 'Forces installation from package dist|source|auto (auto chooses source for dev versions, dist for the rest).', null, $this->suggestPreferInstall()),
|
new InputOption('prefer-install', null, InputOption::VALUE_REQUIRED, 'Forces installation from package dist|source|auto (auto chooses source for dev versions, dist for the rest).', null, $this->suggestPreferInstall()),
|
||||||
|
@ -62,7 +62,7 @@ class InstallCommand extends BaseCommand
|
||||||
new InputOption('ignore-platform-req', null, InputOption::VALUE_REQUIRED | InputOption::VALUE_IS_ARRAY, 'Ignore a specific platform requirement (php & ext- packages).'),
|
new InputOption('ignore-platform-req', null, InputOption::VALUE_REQUIRED | InputOption::VALUE_IS_ARRAY, 'Ignore a specific platform requirement (php & ext- packages).'),
|
||||||
new InputOption('ignore-platform-reqs', null, InputOption::VALUE_NONE, 'Ignore all platform requirements (php & ext- packages).'),
|
new InputOption('ignore-platform-reqs', null, InputOption::VALUE_NONE, 'Ignore all platform requirements (php & ext- packages).'),
|
||||||
new InputArgument('packages', InputArgument::IS_ARRAY | InputArgument::OPTIONAL, 'Should not be provided, use composer require instead to add a given package to composer.json.'),
|
new InputArgument('packages', InputArgument::IS_ARRAY | InputArgument::OPTIONAL, 'Should not be provided, use composer require instead to add a given package to composer.json.'),
|
||||||
))
|
])
|
||||||
->setHelp(
|
->setHelp(
|
||||||
<<<EOT
|
<<<EOT
|
||||||
The <info>install</info> command reads the composer.lock file from
|
The <info>install</info> command reads the composer.lock file from
|
||||||
|
@ -113,7 +113,7 @@ EOT
|
||||||
$install = Installer::create($io, $composer);
|
$install = Installer::create($io, $composer);
|
||||||
|
|
||||||
$config = $composer->getConfig();
|
$config = $composer->getConfig();
|
||||||
list($preferSource, $preferDist) = $this->getPreferredInstallOptions($config, $input);
|
[$preferSource, $preferDist] = $this->getPreferredInstallOptions($config, $input);
|
||||||
|
|
||||||
$optimize = $input->getOption('optimize-autoloader') || $config->get('optimize-autoloader');
|
$optimize = $input->getOption('optimize-autoloader') || $config->get('optimize-autoloader');
|
||||||
$authoritative = $input->getOption('classmap-authoritative') || $config->get('classmap-authoritative');
|
$authoritative = $input->getOption('classmap-authoritative') || $config->get('classmap-authoritative');
|
||||||
|
|
|
@ -17,8 +17,6 @@ use Composer\Json\JsonFile;
|
||||||
use Composer\Package\CompletePackageInterface;
|
use Composer\Package\CompletePackageInterface;
|
||||||
use Composer\Plugin\CommandEvent;
|
use Composer\Plugin\CommandEvent;
|
||||||
use Composer\Plugin\PluginEvents;
|
use Composer\Plugin\PluginEvents;
|
||||||
use Composer\Package\PackageInterface;
|
|
||||||
use Composer\Repository\RepositoryInterface;
|
|
||||||
use Composer\Repository\RepositoryUtils;
|
use Composer\Repository\RepositoryUtils;
|
||||||
use Composer\Util\PackageInfo;
|
use Composer\Util\PackageInfo;
|
||||||
use Composer\Util\PackageSorter;
|
use Composer\Util\PackageSorter;
|
||||||
|
@ -33,18 +31,15 @@ use Symfony\Component\Console\Style\SymfonyStyle;
|
||||||
*/
|
*/
|
||||||
class LicensesCommand extends BaseCommand
|
class LicensesCommand extends BaseCommand
|
||||||
{
|
{
|
||||||
/**
|
|
||||||
* @return void
|
|
||||||
*/
|
|
||||||
protected function configure(): void
|
protected function configure(): void
|
||||||
{
|
{
|
||||||
$this
|
$this
|
||||||
->setName('licenses')
|
->setName('licenses')
|
||||||
->setDescription('Shows information about licenses of dependencies')
|
->setDescription('Shows information about licenses of dependencies')
|
||||||
->setDefinition(array(
|
->setDefinition([
|
||||||
new InputOption('format', 'f', InputOption::VALUE_REQUIRED, 'Format of the output: text, json or summary', 'text', ['text', 'json', 'summary']),
|
new InputOption('format', 'f', InputOption::VALUE_REQUIRED, 'Format of the output: text, json or summary', 'text', ['text', 'json', 'summary']),
|
||||||
new InputOption('no-dev', null, InputOption::VALUE_NONE, 'Disables search in require-dev packages.'),
|
new InputOption('no-dev', null, InputOption::VALUE_NONE, 'Disables search in require-dev packages.'),
|
||||||
))
|
])
|
||||||
->setHelp(
|
->setHelp(
|
||||||
<<<EOT
|
<<<EOT
|
||||||
The license command displays detailed information about the licenses of
|
The license command displays detailed information about the licenses of
|
||||||
|
@ -85,7 +80,7 @@ EOT
|
||||||
|
|
||||||
$table = new Table($output);
|
$table = new Table($output);
|
||||||
$table->setStyle('compact');
|
$table->setStyle('compact');
|
||||||
$table->setHeaders(array('Name', 'Version', 'Licenses'));
|
$table->setHeaders(['Name', 'Version', 'Licenses']);
|
||||||
foreach ($packages as $package) {
|
foreach ($packages as $package) {
|
||||||
$link = PackageInfo::getViewSourceOrHomepageUrl($package);
|
$link = PackageInfo::getViewSourceOrHomepageUrl($package);
|
||||||
if ($link !== null) {
|
if ($link !== null) {
|
||||||
|
@ -94,36 +89,36 @@ EOT
|
||||||
$name = $package->getPrettyName();
|
$name = $package->getPrettyName();
|
||||||
}
|
}
|
||||||
|
|
||||||
$table->addRow(array(
|
$table->addRow([
|
||||||
$name,
|
$name,
|
||||||
$package->getFullPrettyVersion(),
|
$package->getFullPrettyVersion(),
|
||||||
implode(', ', $package instanceof CompletePackageInterface ? $package->getLicense() : array()) ?: 'none',
|
implode(', ', $package instanceof CompletePackageInterface ? $package->getLicense() : []) ?: 'none',
|
||||||
));
|
]);
|
||||||
}
|
}
|
||||||
$table->render();
|
$table->render();
|
||||||
break;
|
break;
|
||||||
|
|
||||||
case 'json':
|
case 'json':
|
||||||
$dependencies = array();
|
$dependencies = [];
|
||||||
foreach ($packages as $package) {
|
foreach ($packages as $package) {
|
||||||
$dependencies[$package->getPrettyName()] = array(
|
$dependencies[$package->getPrettyName()] = [
|
||||||
'version' => $package->getFullPrettyVersion(),
|
'version' => $package->getFullPrettyVersion(),
|
||||||
'license' => $package instanceof CompletePackageInterface ? $package->getLicense() : array(),
|
'license' => $package instanceof CompletePackageInterface ? $package->getLicense() : [],
|
||||||
);
|
];
|
||||||
}
|
}
|
||||||
|
|
||||||
$io->write(JsonFile::encode(array(
|
$io->write(JsonFile::encode([
|
||||||
'name' => $root->getPrettyName(),
|
'name' => $root->getPrettyName(),
|
||||||
'version' => $root->getFullPrettyVersion(),
|
'version' => $root->getFullPrettyVersion(),
|
||||||
'license' => $root->getLicense(),
|
'license' => $root->getLicense(),
|
||||||
'dependencies' => $dependencies,
|
'dependencies' => $dependencies,
|
||||||
)));
|
]));
|
||||||
break;
|
break;
|
||||||
|
|
||||||
case 'summary':
|
case 'summary':
|
||||||
$usedLicenses = array();
|
$usedLicenses = [];
|
||||||
foreach ($packages as $package) {
|
foreach ($packages as $package) {
|
||||||
$licenses = $package instanceof CompletePackageInterface ? $package->getLicense() : array();
|
$licenses = $package instanceof CompletePackageInterface ? $package->getLicense() : [];
|
||||||
if (count($licenses) === 0) {
|
if (count($licenses) === 0) {
|
||||||
$licenses[] = 'none';
|
$licenses[] = 'none';
|
||||||
}
|
}
|
||||||
|
@ -138,14 +133,14 @@ EOT
|
||||||
// Sort licenses so that the most used license will appear first
|
// Sort licenses so that the most used license will appear first
|
||||||
arsort($usedLicenses, SORT_NUMERIC);
|
arsort($usedLicenses, SORT_NUMERIC);
|
||||||
|
|
||||||
$rows = array();
|
$rows = [];
|
||||||
foreach ($usedLicenses as $usedLicense => $numberOfDependencies) {
|
foreach ($usedLicenses as $usedLicense => $numberOfDependencies) {
|
||||||
$rows[] = array($usedLicense, $numberOfDependencies);
|
$rows[] = [$usedLicense, $numberOfDependencies];
|
||||||
}
|
}
|
||||||
|
|
||||||
$symfonyIo = new SymfonyStyle($input, $output);
|
$symfonyIo = new SymfonyStyle($input, $output);
|
||||||
$symfonyIo->table(
|
$symfonyIo->table(
|
||||||
array('License', 'Number of dependencies'),
|
['License', 'Number of dependencies'],
|
||||||
$rows
|
$rows
|
||||||
);
|
);
|
||||||
break;
|
break;
|
||||||
|
|
|
@ -25,15 +25,12 @@ class OutdatedCommand extends BaseCommand
|
||||||
{
|
{
|
||||||
use CompletionTrait;
|
use CompletionTrait;
|
||||||
|
|
||||||
/**
|
|
||||||
* @return void
|
|
||||||
*/
|
|
||||||
protected function configure(): void
|
protected function configure(): void
|
||||||
{
|
{
|
||||||
$this
|
$this
|
||||||
->setName('outdated')
|
->setName('outdated')
|
||||||
->setDescription('Shows a list of installed packages that have updates available, including their latest version')
|
->setDescription('Shows a list of installed packages that have updates available, including their latest version')
|
||||||
->setDefinition(array(
|
->setDefinition([
|
||||||
new InputArgument('package', InputArgument::OPTIONAL, 'Package to inspect. Or a name including a wildcard (*) to filter lists of packages instead.', null, $this->suggestInstalledPackage(false)),
|
new InputArgument('package', InputArgument::OPTIONAL, 'Package to inspect. Or a name including a wildcard (*) to filter lists of packages instead.', null, $this->suggestInstalledPackage(false)),
|
||||||
new InputOption('outdated', 'o', InputOption::VALUE_NONE, 'Show only packages that are outdated (this is the default, but present here for compat with `show`'),
|
new InputOption('outdated', 'o', InputOption::VALUE_NONE, 'Show only packages that are outdated (this is the default, but present here for compat with `show`'),
|
||||||
new InputOption('all', 'a', InputOption::VALUE_NONE, 'Show all installed packages with their latest versions'),
|
new InputOption('all', 'a', InputOption::VALUE_NONE, 'Show all installed packages with their latest versions'),
|
||||||
|
@ -48,7 +45,7 @@ class OutdatedCommand extends BaseCommand
|
||||||
new InputOption('no-dev', null, InputOption::VALUE_NONE, 'Disables search in require-dev packages.'),
|
new InputOption('no-dev', null, InputOption::VALUE_NONE, 'Disables search in require-dev packages.'),
|
||||||
new InputOption('ignore-platform-req', null, InputOption::VALUE_REQUIRED | InputOption::VALUE_IS_ARRAY, 'Ignore a specific platform requirement (php & ext- packages). Use with the --outdated option'),
|
new InputOption('ignore-platform-req', null, InputOption::VALUE_REQUIRED | InputOption::VALUE_IS_ARRAY, 'Ignore a specific platform requirement (php & ext- packages). Use with the --outdated option'),
|
||||||
new InputOption('ignore-platform-reqs', null, InputOption::VALUE_NONE, 'Ignore all platform requirements (php & ext- packages). Use with the --outdated option'),
|
new InputOption('ignore-platform-reqs', null, InputOption::VALUE_NONE, 'Ignore all platform requirements (php & ext- packages). Use with the --outdated option'),
|
||||||
))
|
])
|
||||||
->setHelp(
|
->setHelp(
|
||||||
<<<EOT
|
<<<EOT
|
||||||
The outdated command is just a proxy for `composer show -l`
|
The outdated command is just a proxy for `composer show -l`
|
||||||
|
@ -69,10 +66,10 @@ EOT
|
||||||
|
|
||||||
protected function execute(InputInterface $input, OutputInterface $output): int
|
protected function execute(InputInterface $input, OutputInterface $output): int
|
||||||
{
|
{
|
||||||
$args = array(
|
$args = [
|
||||||
'command' => 'show',
|
'command' => 'show',
|
||||||
'--latest' => true,
|
'--latest' => true,
|
||||||
);
|
];
|
||||||
if (!$input->getOption('all')) {
|
if (!$input->getOption('all')) {
|
||||||
$args['--outdated'] = true;
|
$args['--outdated'] = true;
|
||||||
}
|
}
|
||||||
|
|
|
@ -39,14 +39,11 @@ trait PackageDiscoveryTrait
|
||||||
/** @var RepositorySet[] */
|
/** @var RepositorySet[] */
|
||||||
private $repositorySets;
|
private $repositorySets;
|
||||||
|
|
||||||
/**
|
|
||||||
* @return CompositeRepository
|
|
||||||
*/
|
|
||||||
protected function getRepos(): CompositeRepository
|
protected function getRepos(): CompositeRepository
|
||||||
{
|
{
|
||||||
if (null === $this->repos) {
|
if (null === $this->repos) {
|
||||||
$this->repos = new CompositeRepository(array_merge(
|
$this->repos = new CompositeRepository(array_merge(
|
||||||
array(new PlatformRepository),
|
[new PlatformRepository],
|
||||||
RepositoryFactory::defaultReposWithDefaultManager($this->getIO())
|
RepositoryFactory::defaultReposWithDefaultManager($this->getIO())
|
||||||
));
|
));
|
||||||
}
|
}
|
||||||
|
@ -89,11 +86,11 @@ trait PackageDiscoveryTrait
|
||||||
* @return array<string>
|
* @return array<string>
|
||||||
* @throws \Exception
|
* @throws \Exception
|
||||||
*/
|
*/
|
||||||
final protected function determineRequirements(InputInterface $input, OutputInterface $output, array $requires = array(), ?PlatformRepository $platformRepo = null, string $preferredStability = 'stable', bool $checkProvidedVersions = true, bool $fixed = false): array
|
final protected function determineRequirements(InputInterface $input, OutputInterface $output, array $requires = [], ?PlatformRepository $platformRepo = null, string $preferredStability = 'stable', bool $checkProvidedVersions = true, bool $fixed = false): array
|
||||||
{
|
{
|
||||||
if (count($requires) > 0) {
|
if (count($requires) > 0) {
|
||||||
$requires = $this->normalizeRequirements($requires);
|
$requires = $this->normalizeRequirements($requires);
|
||||||
$result = array();
|
$result = [];
|
||||||
$io = $this->getIO();
|
$io = $this->getIO();
|
||||||
|
|
||||||
foreach ($requires as $requirement) {
|
foreach ($requires as $requirement) {
|
||||||
|
@ -103,7 +100,7 @@ trait PackageDiscoveryTrait
|
||||||
|
|
||||||
if (!isset($requirement['version'])) {
|
if (!isset($requirement['version'])) {
|
||||||
// determine the best version automatically
|
// determine the best version automatically
|
||||||
list($name, $version) = $this->findBestVersionAndNameForPackage($input, $requirement['name'], $platformRepo, $preferredStability, $fixed);
|
[$name, $version] = $this->findBestVersionAndNameForPackage($input, $requirement['name'], $platformRepo, $preferredStability, $fixed);
|
||||||
$requirement['version'] = $version;
|
$requirement['version'] = $version;
|
||||||
|
|
||||||
// replace package name from packagist.org
|
// replace package name from packagist.org
|
||||||
|
@ -130,7 +127,7 @@ trait PackageDiscoveryTrait
|
||||||
if (null !== $composer) {
|
if (null !== $composer) {
|
||||||
$installedRepo = $composer->getRepositoryManager()->getLocalRepository();
|
$installedRepo = $composer->getRepositoryManager()->getLocalRepository();
|
||||||
}
|
}
|
||||||
$existingPackages = array();
|
$existingPackages = [];
|
||||||
if (null !== $installedRepo) {
|
if (null !== $installedRepo) {
|
||||||
foreach ($installedRepo->getPackages() as $package) {
|
foreach ($installedRepo->getPackages() as $package) {
|
||||||
$existingPackages[] = $package->getName();
|
$existingPackages[] = $package->getName();
|
||||||
|
@ -163,10 +160,10 @@ trait PackageDiscoveryTrait
|
||||||
if (!$exactMatch) {
|
if (!$exactMatch) {
|
||||||
$providers = $this->getRepos()->getProviders($package);
|
$providers = $this->getRepos()->getProviders($package);
|
||||||
if (count($providers) > 0) {
|
if (count($providers) > 0) {
|
||||||
array_unshift($matches, array('name' => $package, 'description' => ''));
|
array_unshift($matches, ['name' => $package, 'description' => '']);
|
||||||
}
|
}
|
||||||
|
|
||||||
$choices = array();
|
$choices = [];
|
||||||
foreach ($matches as $position => $foundPackage) {
|
foreach ($matches as $position => $foundPackage) {
|
||||||
$abandoned = '';
|
$abandoned = '';
|
||||||
if (isset($foundPackage['abandoned'])) {
|
if (isset($foundPackage['abandoned'])) {
|
||||||
|
@ -181,11 +178,11 @@ trait PackageDiscoveryTrait
|
||||||
$choices[] = sprintf(' <info>%5s</info> %s %s', "[$position]", $foundPackage['name'], $abandoned);
|
$choices[] = sprintf(' <info>%5s</info> %s %s', "[$position]", $foundPackage['name'], $abandoned);
|
||||||
}
|
}
|
||||||
|
|
||||||
$io->writeError(array(
|
$io->writeError([
|
||||||
'',
|
'',
|
||||||
sprintf('Found <info>%s</info> packages matching <info>%s</info>', count($matches), $package),
|
sprintf('Found <info>%s</info> packages matching <info>%s</info>', count($matches), $package),
|
||||||
'',
|
'',
|
||||||
));
|
]);
|
||||||
|
|
||||||
$io->writeError($choices);
|
$io->writeError($choices);
|
||||||
$io->writeError('');
|
$io->writeError('');
|
||||||
|
@ -242,7 +239,7 @@ trait PackageDiscoveryTrait
|
||||||
);
|
);
|
||||||
|
|
||||||
if (false === $constraint) {
|
if (false === $constraint) {
|
||||||
list(, $constraint) = $this->findBestVersionAndNameForPackage($input, $package, $platformRepo, $preferredStability);
|
[, $constraint] = $this->findBestVersionAndNameForPackage($input, $package, $platformRepo, $preferredStability);
|
||||||
|
|
||||||
$io->writeError(sprintf(
|
$io->writeError(sprintf(
|
||||||
'Using version <info>%s</info> for <info>%s</info>',
|
'Using version <info>%s</info> for <info>%s</info>',
|
||||||
|
@ -292,7 +289,7 @@ trait PackageDiscoveryTrait
|
||||||
// platform packages can not be found in the pool in versions other than the local platform's has
|
// platform packages can not be found in the pool in versions other than the local platform's has
|
||||||
// so if platform reqs are ignored we just take the user's word for it
|
// so if platform reqs are ignored we just take the user's word for it
|
||||||
if ($platformRequirementFilter->isIgnored($name)) {
|
if ($platformRequirementFilter->isIgnored($name)) {
|
||||||
return array($name, '*');
|
return [$name, '*'];
|
||||||
}
|
}
|
||||||
|
|
||||||
// Check if it is a virtual package provided by others
|
// Check if it is a virtual package provided by others
|
||||||
|
@ -308,7 +305,7 @@ trait PackageDiscoveryTrait
|
||||||
}, 3, '*');
|
}, 3, '*');
|
||||||
}
|
}
|
||||||
|
|
||||||
return array($name, $constraint);
|
return [$name, $constraint];
|
||||||
}
|
}
|
||||||
|
|
||||||
// Check whether the package requirements were the problem
|
// Check whether the package requirements were the problem
|
||||||
|
@ -371,10 +368,10 @@ trait PackageDiscoveryTrait
|
||||||
));
|
));
|
||||||
}
|
}
|
||||||
|
|
||||||
return array(
|
return [
|
||||||
$package->getPrettyName(),
|
$package->getPrettyName(),
|
||||||
$fixed ? $package->getPrettyVersion() : $versionSelector->findRecommendedRequireVersion($package),
|
$fixed ? $package->getPrettyVersion() : $versionSelector->findRecommendedRequireVersion($package),
|
||||||
);
|
];
|
||||||
}
|
}
|
||||||
|
|
||||||
/**
|
/**
|
||||||
|
@ -393,9 +390,9 @@ trait PackageDiscoveryTrait
|
||||||
}
|
}
|
||||||
|
|
||||||
// ignore search errors
|
// ignore search errors
|
||||||
return array();
|
return [];
|
||||||
}
|
}
|
||||||
$similarPackages = array();
|
$similarPackages = [];
|
||||||
|
|
||||||
$installedRepo = $this->requireComposer()->getRepositoryManager()->getLocalRepository();
|
$installedRepo = $this->requireComposer()->getRepositoryManager()->getLocalRepository();
|
||||||
|
|
||||||
|
@ -413,7 +410,7 @@ trait PackageDiscoveryTrait
|
||||||
|
|
||||||
private function getPlatformExceptionDetails(PackageInterface $candidate, ?PlatformRepository $platformRepo = null): string
|
private function getPlatformExceptionDetails(PackageInterface $candidate, ?PlatformRepository $platformRepo = null): string
|
||||||
{
|
{
|
||||||
$details = array();
|
$details = [];
|
||||||
if (null === $platformRepo) {
|
if (null === $platformRepo) {
|
||||||
return '';
|
return '';
|
||||||
}
|
}
|
||||||
|
|
|
@ -26,22 +26,20 @@ class ProhibitsCommand extends BaseDependencyCommand
|
||||||
|
|
||||||
/**
|
/**
|
||||||
* Configure command metadata.
|
* Configure command metadata.
|
||||||
*
|
|
||||||
* @return void
|
|
||||||
*/
|
*/
|
||||||
protected function configure(): void
|
protected function configure(): void
|
||||||
{
|
{
|
||||||
$this
|
$this
|
||||||
->setName('prohibits')
|
->setName('prohibits')
|
||||||
->setAliases(array('why-not'))
|
->setAliases(['why-not'])
|
||||||
->setDescription('Shows which packages prevent the given package from being installed')
|
->setDescription('Shows which packages prevent the given package from being installed')
|
||||||
->setDefinition(array(
|
->setDefinition([
|
||||||
new InputArgument(self::ARGUMENT_PACKAGE, InputArgument::REQUIRED, 'Package to inspect', null, $this->suggestAvailablePackage()),
|
new InputArgument(self::ARGUMENT_PACKAGE, InputArgument::REQUIRED, 'Package to inspect', null, $this->suggestAvailablePackage()),
|
||||||
new InputArgument(self::ARGUMENT_CONSTRAINT, InputArgument::REQUIRED, 'Version constraint, which version you expected to be installed'),
|
new InputArgument(self::ARGUMENT_CONSTRAINT, InputArgument::REQUIRED, 'Version constraint, which version you expected to be installed'),
|
||||||
new InputOption(self::OPTION_RECURSIVE, 'r', InputOption::VALUE_NONE, 'Recursively resolves up to the root package'),
|
new InputOption(self::OPTION_RECURSIVE, 'r', InputOption::VALUE_NONE, 'Recursively resolves up to the root package'),
|
||||||
new InputOption(self::OPTION_TREE, 't', InputOption::VALUE_NONE, 'Prints the results as a nested tree'),
|
new InputOption(self::OPTION_TREE, 't', InputOption::VALUE_NONE, 'Prints the results as a nested tree'),
|
||||||
new InputOption('locked', null, InputOption::VALUE_NONE, 'Read dependency information from composer.lock'),
|
new InputOption('locked', null, InputOption::VALUE_NONE, 'Read dependency information from composer.lock'),
|
||||||
))
|
])
|
||||||
->setHelp(
|
->setHelp(
|
||||||
<<<EOT
|
<<<EOT
|
||||||
Displays detailed information about why a package cannot be installed.
|
Displays detailed information about why a package cannot be installed.
|
||||||
|
|
|
@ -34,15 +34,12 @@ class ReinstallCommand extends BaseCommand
|
||||||
{
|
{
|
||||||
use CompletionTrait;
|
use CompletionTrait;
|
||||||
|
|
||||||
/**
|
|
||||||
* @return void
|
|
||||||
*/
|
|
||||||
protected function configure(): void
|
protected function configure(): void
|
||||||
{
|
{
|
||||||
$this
|
$this
|
||||||
->setName('reinstall')
|
->setName('reinstall')
|
||||||
->setDescription('Uninstalls and reinstalls the given package names')
|
->setDescription('Uninstalls and reinstalls the given package names')
|
||||||
->setDefinition(array(
|
->setDefinition([
|
||||||
new InputOption('prefer-source', null, InputOption::VALUE_NONE, 'Forces installation from package sources when possible, including VCS information.'),
|
new InputOption('prefer-source', null, InputOption::VALUE_NONE, 'Forces installation from package sources when possible, including VCS information.'),
|
||||||
new InputOption('prefer-dist', null, InputOption::VALUE_NONE, 'Forces installation from package dist (default behavior).'),
|
new InputOption('prefer-dist', null, InputOption::VALUE_NONE, 'Forces installation from package dist (default behavior).'),
|
||||||
new InputOption('prefer-install', null, InputOption::VALUE_REQUIRED, 'Forces installation from package dist|source|auto (auto chooses source for dev versions, dist for the rest).', null, $this->suggestPreferInstall()),
|
new InputOption('prefer-install', null, InputOption::VALUE_REQUIRED, 'Forces installation from package dist|source|auto (auto chooses source for dev versions, dist for the rest).', null, $this->suggestPreferInstall()),
|
||||||
|
@ -55,7 +52,7 @@ class ReinstallCommand extends BaseCommand
|
||||||
new InputOption('ignore-platform-req', null, InputOption::VALUE_REQUIRED | InputOption::VALUE_IS_ARRAY, 'Ignore a specific platform requirement (php & ext- packages).'),
|
new InputOption('ignore-platform-req', null, InputOption::VALUE_REQUIRED | InputOption::VALUE_IS_ARRAY, 'Ignore a specific platform requirement (php & ext- packages).'),
|
||||||
new InputOption('ignore-platform-reqs', null, InputOption::VALUE_NONE, 'Ignore all platform requirements (php & ext- packages).'),
|
new InputOption('ignore-platform-reqs', null, InputOption::VALUE_NONE, 'Ignore all platform requirements (php & ext- packages).'),
|
||||||
new InputArgument('packages', InputArgument::IS_ARRAY | InputArgument::REQUIRED, 'List of package names to reinstall, can include a wildcard (*) to match any substring.', null, $this->suggestInstalledPackage(false)),
|
new InputArgument('packages', InputArgument::IS_ARRAY | InputArgument::REQUIRED, 'List of package names to reinstall, can include a wildcard (*) to match any substring.', null, $this->suggestInstalledPackage(false)),
|
||||||
))
|
])
|
||||||
->setHelp(
|
->setHelp(
|
||||||
<<<EOT
|
<<<EOT
|
||||||
The <info>reinstall</info> command looks up installed packages by name,
|
The <info>reinstall</info> command looks up installed packages by name,
|
||||||
|
@ -78,8 +75,8 @@ EOT
|
||||||
$composer = $this->requireComposer();
|
$composer = $this->requireComposer();
|
||||||
|
|
||||||
$localRepo = $composer->getRepositoryManager()->getLocalRepository();
|
$localRepo = $composer->getRepositoryManager()->getLocalRepository();
|
||||||
$packagesToReinstall = array();
|
$packagesToReinstall = [];
|
||||||
$packageNamesToReinstall = array();
|
$packageNamesToReinstall = [];
|
||||||
foreach ($input->getArgument('packages') as $pattern) {
|
foreach ($input->getArgument('packages') as $pattern) {
|
||||||
$patternRegexp = BasePackage::packageNameToRegexp($pattern);
|
$patternRegexp = BasePackage::packageNameToRegexp($pattern);
|
||||||
$matched = false;
|
$matched = false;
|
||||||
|
@ -102,7 +99,7 @@ EOT
|
||||||
return 1;
|
return 1;
|
||||||
}
|
}
|
||||||
|
|
||||||
$uninstallOperations = array();
|
$uninstallOperations = [];
|
||||||
foreach ($packagesToReinstall as $package) {
|
foreach ($packagesToReinstall as $package) {
|
||||||
$uninstallOperations[] = new UninstallOperation($package);
|
$uninstallOperations[] = new UninstallOperation($package);
|
||||||
}
|
}
|
||||||
|
@ -119,7 +116,7 @@ EOT
|
||||||
$installOperations = $transaction->getOperations();
|
$installOperations = $transaction->getOperations();
|
||||||
|
|
||||||
// reverse-sort the uninstalls based on the install order
|
// reverse-sort the uninstalls based on the install order
|
||||||
$installOrder = array();
|
$installOrder = [];
|
||||||
foreach ($installOperations as $index => $op) {
|
foreach ($installOperations as $index => $op) {
|
||||||
if ($op instanceof InstallOperation && !$op->getPackage() instanceof AliasPackage) {
|
if ($op instanceof InstallOperation && !$op->getPackage() instanceof AliasPackage) {
|
||||||
$installOrder[$op->getPackage()->getName()] = $index;
|
$installOrder[$op->getPackage()->getName()] = $index;
|
||||||
|
@ -134,7 +131,7 @@ EOT
|
||||||
$eventDispatcher->dispatch($commandEvent->getName(), $commandEvent);
|
$eventDispatcher->dispatch($commandEvent->getName(), $commandEvent);
|
||||||
|
|
||||||
$config = $composer->getConfig();
|
$config = $composer->getConfig();
|
||||||
list($preferSource, $preferDist) = $this->getPreferredInstallOptions($config, $input);
|
[$preferSource, $preferDist] = $this->getPreferredInstallOptions($config, $input);
|
||||||
|
|
||||||
$installationManager = $composer->getInstallationManager();
|
$installationManager = $composer->getInstallationManager();
|
||||||
$downloadManager = $composer->getDownloadManager();
|
$downloadManager = $composer->getDownloadManager();
|
||||||
|
|
|
@ -43,7 +43,7 @@ class RemoveCommand extends BaseCommand
|
||||||
$this
|
$this
|
||||||
->setName('remove')
|
->setName('remove')
|
||||||
->setDescription('Removes a package from the require or require-dev')
|
->setDescription('Removes a package from the require or require-dev')
|
||||||
->setDefinition(array(
|
->setDefinition([
|
||||||
new InputArgument('packages', InputArgument::IS_ARRAY | InputArgument::REQUIRED, 'Packages that should be removed.', null, $this->suggestRootRequirement()),
|
new InputArgument('packages', InputArgument::IS_ARRAY | InputArgument::REQUIRED, 'Packages that should be removed.', null, $this->suggestRootRequirement()),
|
||||||
new InputOption('dev', null, InputOption::VALUE_NONE, 'Removes a package from the require-dev section.'),
|
new InputOption('dev', null, InputOption::VALUE_NONE, 'Removes a package from the require-dev section.'),
|
||||||
new InputOption('dry-run', null, InputOption::VALUE_NONE, 'Outputs the operations but will not execute anything (implicitly enables --verbose).'),
|
new InputOption('dry-run', null, InputOption::VALUE_NONE, 'Outputs the operations but will not execute anything (implicitly enables --verbose).'),
|
||||||
|
@ -64,7 +64,7 @@ class RemoveCommand extends BaseCommand
|
||||||
new InputOption('classmap-authoritative', 'a', InputOption::VALUE_NONE, 'Autoload classes from the classmap only. Implicitly enables `--optimize-autoloader`.'),
|
new InputOption('classmap-authoritative', 'a', InputOption::VALUE_NONE, 'Autoload classes from the classmap only. Implicitly enables `--optimize-autoloader`.'),
|
||||||
new InputOption('apcu-autoloader', null, InputOption::VALUE_NONE, 'Use APCu to cache found/not-found classes.'),
|
new InputOption('apcu-autoloader', null, InputOption::VALUE_NONE, 'Use APCu to cache found/not-found classes.'),
|
||||||
new InputOption('apcu-autoloader-prefix', null, InputOption::VALUE_REQUIRED, 'Use a custom prefix for the APCu autoloader cache. Implicitly enables --apcu-autoloader'),
|
new InputOption('apcu-autoloader-prefix', null, InputOption::VALUE_REQUIRED, 'Use a custom prefix for the APCu autoloader cache. Implicitly enables --apcu-autoloader'),
|
||||||
))
|
])
|
||||||
->setHelp(
|
->setHelp(
|
||||||
<<<EOT
|
<<<EOT
|
||||||
The <info>remove</info> command removes a package from the current
|
The <info>remove</info> command removes a package from the current
|
||||||
|
@ -92,7 +92,7 @@ EOT
|
||||||
|
|
||||||
$lockedPackages = $locker->getLockedRepository()->getPackages();
|
$lockedPackages = $locker->getLockedRepository()->getPackages();
|
||||||
|
|
||||||
$required = array();
|
$required = [];
|
||||||
foreach (array_merge($composer->getPackage()->getRequires(), $composer->getPackage()->getDevRequires()) as $link) {
|
foreach (array_merge($composer->getPackage()->getRequires(), $composer->getPackage()->getDevRequires()) as $link) {
|
||||||
$required[$link->getTarget()] = true;
|
$required[$link->getTarget()] = true;
|
||||||
}
|
}
|
||||||
|
@ -113,7 +113,7 @@ EOT
|
||||||
}
|
}
|
||||||
} while ($found);
|
} while ($found);
|
||||||
|
|
||||||
$unused = array();
|
$unused = [];
|
||||||
foreach ($lockedPackages as $package) {
|
foreach ($lockedPackages as $package) {
|
||||||
$unused[] = $package->getName();
|
$unused[] = $package->getName();
|
||||||
}
|
}
|
||||||
|
@ -154,7 +154,7 @@ EOT
|
||||||
}
|
}
|
||||||
|
|
||||||
// make sure name checks are done case insensitively
|
// make sure name checks are done case insensitively
|
||||||
foreach (array('require', 'require-dev') as $linkType) {
|
foreach (['require', 'require-dev'] as $linkType) {
|
||||||
if (isset($composer[$linkType])) {
|
if (isset($composer[$linkType])) {
|
||||||
foreach ($composer[$linkType] as $name => $version) {
|
foreach ($composer[$linkType] as $name => $version) {
|
||||||
$composer[$linkType][strtolower($name)] = $name;
|
$composer[$linkType][strtolower($name)] = $name;
|
||||||
|
@ -163,7 +163,7 @@ EOT
|
||||||
}
|
}
|
||||||
|
|
||||||
$dryRun = $input->getOption('dry-run');
|
$dryRun = $input->getOption('dry-run');
|
||||||
$toRemove = array();
|
$toRemove = [];
|
||||||
foreach ($packages as $package) {
|
foreach ($packages as $package) {
|
||||||
if (isset($composer[$type][$package])) {
|
if (isset($composer[$type][$package])) {
|
||||||
if ($dryRun) {
|
if ($dryRun) {
|
||||||
|
@ -224,10 +224,10 @@ EOT
|
||||||
|
|
||||||
if ($dryRun) {
|
if ($dryRun) {
|
||||||
$rootPackage = $composer->getPackage();
|
$rootPackage = $composer->getPackage();
|
||||||
$links = array(
|
$links = [
|
||||||
'require' => $rootPackage->getRequires(),
|
'require' => $rootPackage->getRequires(),
|
||||||
'require-dev' => $rootPackage->getDevRequires(),
|
'require-dev' => $rootPackage->getDevRequires(),
|
||||||
);
|
];
|
||||||
foreach ($toRemove as $type => $names) {
|
foreach ($toRemove as $type => $names) {
|
||||||
foreach ($names as $name) {
|
foreach ($names as $name) {
|
||||||
unset($links[$type][$name]);
|
unset($links[$type][$name]);
|
||||||
|
|
|
@ -14,7 +14,6 @@ namespace Composer\Command;
|
||||||
|
|
||||||
use Composer\DependencyResolver\Request;
|
use Composer\DependencyResolver\Request;
|
||||||
use Composer\Package\CompletePackageInterface;
|
use Composer\Package\CompletePackageInterface;
|
||||||
use Composer\Package\PackageInterface;
|
|
||||||
use Composer\Util\Filesystem;
|
use Composer\Util\Filesystem;
|
||||||
use Composer\Util\PackageSorter;
|
use Composer\Util\PackageSorter;
|
||||||
use Seld\Signal\SignalHandler;
|
use Seld\Signal\SignalHandler;
|
||||||
|
@ -71,9 +70,9 @@ class RequireCommand extends BaseCommand
|
||||||
{
|
{
|
||||||
$this
|
$this
|
||||||
->setName('require')
|
->setName('require')
|
||||||
->setAliases(array('r'))
|
->setAliases(['r'])
|
||||||
->setDescription('Adds required packages to your composer.json and installs them')
|
->setDescription('Adds required packages to your composer.json and installs them')
|
||||||
->setDefinition(array(
|
->setDefinition([
|
||||||
new InputArgument('packages', InputArgument::IS_ARRAY | InputArgument::OPTIONAL, 'Optional package name can also include a version constraint, e.g. foo/bar or foo/bar:1.0.0 or foo/bar=1.0.0 or "foo/bar 1.0.0"', null, $this->suggestAvailablePackageInclPlatform()),
|
new InputArgument('packages', InputArgument::IS_ARRAY | InputArgument::OPTIONAL, 'Optional package name can also include a version constraint, e.g. foo/bar or foo/bar:1.0.0 or foo/bar=1.0.0 or "foo/bar 1.0.0"', null, $this->suggestAvailablePackageInclPlatform()),
|
||||||
new InputOption('dev', null, InputOption::VALUE_NONE, 'Add requirement to require-dev.'),
|
new InputOption('dev', null, InputOption::VALUE_NONE, 'Add requirement to require-dev.'),
|
||||||
new InputOption('dry-run', null, InputOption::VALUE_NONE, 'Outputs the operations but will not execute anything (implicitly enables --verbose).'),
|
new InputOption('dry-run', null, InputOption::VALUE_NONE, 'Outputs the operations but will not execute anything (implicitly enables --verbose).'),
|
||||||
|
@ -101,7 +100,7 @@ class RequireCommand extends BaseCommand
|
||||||
new InputOption('classmap-authoritative', 'a', InputOption::VALUE_NONE, 'Autoload classes from the classmap only. Implicitly enables `--optimize-autoloader`.'),
|
new InputOption('classmap-authoritative', 'a', InputOption::VALUE_NONE, 'Autoload classes from the classmap only. Implicitly enables `--optimize-autoloader`.'),
|
||||||
new InputOption('apcu-autoloader', null, InputOption::VALUE_NONE, 'Use APCu to cache found/not-found classes.'),
|
new InputOption('apcu-autoloader', null, InputOption::VALUE_NONE, 'Use APCu to cache found/not-found classes.'),
|
||||||
new InputOption('apcu-autoloader-prefix', null, InputOption::VALUE_REQUIRED, 'Use a custom prefix for the APCu autoloader cache. Implicitly enables --apcu-autoloader'),
|
new InputOption('apcu-autoloader-prefix', null, InputOption::VALUE_REQUIRED, 'Use a custom prefix for the APCu autoloader cache. Implicitly enables --apcu-autoloader'),
|
||||||
))
|
])
|
||||||
->setHelp(
|
->setHelp(
|
||||||
<<<EOT
|
<<<EOT
|
||||||
The require command adds required packages to your composer.json and installs them.
|
The require command adds required packages to your composer.json and installs them.
|
||||||
|
@ -191,7 +190,7 @@ EOT
|
||||||
$platformOverrides = $composer->getConfig()->get('platform');
|
$platformOverrides = $composer->getConfig()->get('platform');
|
||||||
// initialize $this->repos as it is used by the PackageDiscoveryTrait
|
// initialize $this->repos as it is used by the PackageDiscoveryTrait
|
||||||
$this->repos = new CompositeRepository(array_merge(
|
$this->repos = new CompositeRepository(array_merge(
|
||||||
array($platformRepo = new PlatformRepository(array(), $platformOverrides)),
|
[$platformRepo = new PlatformRepository([], $platformOverrides)],
|
||||||
$repos
|
$repos
|
||||||
));
|
));
|
||||||
|
|
||||||
|
@ -285,7 +284,7 @@ EOT
|
||||||
}
|
}
|
||||||
|
|
||||||
$input->setOption('dev', true);
|
$input->setOption('dev', true);
|
||||||
list($requireKey, $removeKey) = array($removeKey, $requireKey);
|
[$requireKey, $removeKey] = [$removeKey, $requireKey];
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
|
@ -334,13 +333,12 @@ EOT
|
||||||
|
|
||||||
/**
|
/**
|
||||||
* @param array<string, string> $newRequirements
|
* @param array<string, string> $newRequirements
|
||||||
* @param string $requireKey
|
|
||||||
* @return string[]
|
* @return string[]
|
||||||
*/
|
*/
|
||||||
private function getInconsistentRequireKeys(array $newRequirements, string $requireKey): array
|
private function getInconsistentRequireKeys(array $newRequirements, string $requireKey): array
|
||||||
{
|
{
|
||||||
$requireKeys = $this->getPackagesByRequireKey();
|
$requireKeys = $this->getPackagesByRequireKey();
|
||||||
$inconsistentRequirements = array();
|
$inconsistentRequirements = [];
|
||||||
foreach ($requireKeys as $package => $packageRequireKey) {
|
foreach ($requireKeys as $package => $packageRequireKey) {
|
||||||
if (!isset($newRequirements[$package])) {
|
if (!isset($newRequirements[$package])) {
|
||||||
continue;
|
continue;
|
||||||
|
@ -359,8 +357,8 @@ EOT
|
||||||
private function getPackagesByRequireKey(): array
|
private function getPackagesByRequireKey(): array
|
||||||
{
|
{
|
||||||
$composerDefinition = $this->json->read();
|
$composerDefinition = $this->json->read();
|
||||||
$require = array();
|
$require = [];
|
||||||
$requireDev = array();
|
$requireDev = [];
|
||||||
|
|
||||||
if (isset($composerDefinition['require'])) {
|
if (isset($composerDefinition['require'])) {
|
||||||
$require = $composerDefinition['require'];
|
$require = $composerDefinition['require'];
|
||||||
|
@ -378,9 +376,6 @@ EOT
|
||||||
|
|
||||||
/**
|
/**
|
||||||
* @param array<string, string> $requirements
|
* @param array<string, string> $requirements
|
||||||
* @param string $requireKey
|
|
||||||
* @param string $removeKey
|
|
||||||
* @return int
|
|
||||||
* @throws \Exception
|
* @throws \Exception
|
||||||
*/
|
*/
|
||||||
private function doUpdate(InputInterface $input, OutputInterface $output, IOInterface $io, array $requirements, string $requireKey, string $removeKey): int
|
private function doUpdate(InputInterface $input, OutputInterface $output, IOInterface $io, array $requirements, string $requireKey, string $removeKey): int
|
||||||
|
@ -396,10 +391,10 @@ EOT
|
||||||
|
|
||||||
if ($input->getOption('dry-run')) {
|
if ($input->getOption('dry-run')) {
|
||||||
$rootPackage = $composer->getPackage();
|
$rootPackage = $composer->getPackage();
|
||||||
$links = array(
|
$links = [
|
||||||
'require' => $rootPackage->getRequires(),
|
'require' => $rootPackage->getRequires(),
|
||||||
'require-dev' => $rootPackage->getDevRequires(),
|
'require-dev' => $rootPackage->getDevRequires(),
|
||||||
);
|
];
|
||||||
$loader = new ArrayLoader();
|
$loader = new ArrayLoader();
|
||||||
$newLinks = $loader->parseLinks($rootPackage->getName(), $rootPackage->getPrettyVersion(), BasePackage::$supportedLinkTypes[$requireKey]['method'], $requirements);
|
$newLinks = $loader->parseLinks($rootPackage->getName(), $rootPackage->getPrettyVersion(), BasePackage::$supportedLinkTypes[$requireKey]['method'], $requirements);
|
||||||
$links[$requireKey] = array_merge($links[$requireKey], $newLinks);
|
$links[$requireKey] = array_merge($links[$requireKey], $newLinks);
|
||||||
|
@ -435,7 +430,7 @@ EOT
|
||||||
|
|
||||||
$install = Installer::create($io, $composer);
|
$install = Installer::create($io, $composer);
|
||||||
|
|
||||||
list($preferSource, $preferDist) = $this->getPreferredInstallOptions($composer->getConfig(), $input);
|
[$preferSource, $preferDist] = $this->getPreferredInstallOptions($composer->getConfig(), $input);
|
||||||
|
|
||||||
$install
|
$install
|
||||||
->setDryRun($input->getOption('dry-run'))
|
->setDryRun($input->getOption('dry-run'))
|
||||||
|
@ -480,10 +475,6 @@ EOT
|
||||||
|
|
||||||
/**
|
/**
|
||||||
* @param array<string, string> $new
|
* @param array<string, string> $new
|
||||||
* @param string $requireKey
|
|
||||||
* @param string $removeKey
|
|
||||||
* @param bool $sortPackages
|
|
||||||
* @return bool
|
|
||||||
*/
|
*/
|
||||||
private function updateFileCleanly(JsonFile $json, array $new, string $requireKey, string $removeKey, bool $sortPackages): bool
|
private function updateFileCleanly(JsonFile $json, array $new, string $requireKey, string $removeKey, bool $sortPackages): bool
|
||||||
{
|
{
|
||||||
|
@ -509,7 +500,6 @@ EOT
|
||||||
|
|
||||||
protected function interact(InputInterface $input, OutputInterface $output): void
|
protected function interact(InputInterface $input, OutputInterface $output): void
|
||||||
{
|
{
|
||||||
|
|
||||||
}
|
}
|
||||||
|
|
||||||
private function revertComposerFile(): void
|
private function revertComposerFile(): void
|
||||||
|
|
|
@ -29,7 +29,7 @@ class RunScriptCommand extends BaseCommand
|
||||||
/**
|
/**
|
||||||
* @var string[] Array with command events
|
* @var string[] Array with command events
|
||||||
*/
|
*/
|
||||||
protected $scriptEvents = array(
|
protected $scriptEvents = [
|
||||||
ScriptEvents::PRE_INSTALL_CMD,
|
ScriptEvents::PRE_INSTALL_CMD,
|
||||||
ScriptEvents::POST_INSTALL_CMD,
|
ScriptEvents::POST_INSTALL_CMD,
|
||||||
ScriptEvents::PRE_UPDATE_CMD,
|
ScriptEvents::PRE_UPDATE_CMD,
|
||||||
|
@ -42,18 +42,15 @@ class RunScriptCommand extends BaseCommand
|
||||||
ScriptEvents::POST_ARCHIVE_CMD,
|
ScriptEvents::POST_ARCHIVE_CMD,
|
||||||
ScriptEvents::PRE_AUTOLOAD_DUMP,
|
ScriptEvents::PRE_AUTOLOAD_DUMP,
|
||||||
ScriptEvents::POST_AUTOLOAD_DUMP,
|
ScriptEvents::POST_AUTOLOAD_DUMP,
|
||||||
);
|
];
|
||||||
|
|
||||||
/**
|
|
||||||
* @return void
|
|
||||||
*/
|
|
||||||
protected function configure(): void
|
protected function configure(): void
|
||||||
{
|
{
|
||||||
$this
|
$this
|
||||||
->setName('run-script')
|
->setName('run-script')
|
||||||
->setAliases(array('run'))
|
->setAliases(['run'])
|
||||||
->setDescription('Runs the scripts defined in composer.json')
|
->setDescription('Runs the scripts defined in composer.json')
|
||||||
->setDefinition(array(
|
->setDefinition([
|
||||||
new InputArgument('script', InputArgument::OPTIONAL, 'Script name to run.', null, function () {
|
new InputArgument('script', InputArgument::OPTIONAL, 'Script name to run.', null, function () {
|
||||||
return array_keys($this->requireComposer()->getPackage()->getScripts());
|
return array_keys($this->requireComposer()->getPackage()->getScripts());
|
||||||
}),
|
}),
|
||||||
|
@ -62,7 +59,7 @@ class RunScriptCommand extends BaseCommand
|
||||||
new InputOption('dev', null, InputOption::VALUE_NONE, 'Sets the dev mode.'),
|
new InputOption('dev', null, InputOption::VALUE_NONE, 'Sets the dev mode.'),
|
||||||
new InputOption('no-dev', null, InputOption::VALUE_NONE, 'Disables the dev mode.'),
|
new InputOption('no-dev', null, InputOption::VALUE_NONE, 'Disables the dev mode.'),
|
||||||
new InputOption('list', 'l', InputOption::VALUE_NONE, 'List scripts.'),
|
new InputOption('list', 'l', InputOption::VALUE_NONE, 'List scripts.'),
|
||||||
))
|
])
|
||||||
->setHelp(
|
->setHelp(
|
||||||
<<<EOT
|
<<<EOT
|
||||||
The <info>run-script</info> command runs scripts defined in composer.json:
|
The <info>run-script</info> command runs scripts defined in composer.json:
|
||||||
|
@ -115,9 +112,6 @@ EOT
|
||||||
return $composer->getEventDispatcher()->dispatchScript($script, $devMode, $args);
|
return $composer->getEventDispatcher()->dispatchScript($script, $devMode, $args);
|
||||||
}
|
}
|
||||||
|
|
||||||
/**
|
|
||||||
* @return int
|
|
||||||
*/
|
|
||||||
protected function listScripts(OutputInterface $output): int
|
protected function listScripts(OutputInterface $output): int
|
||||||
{
|
{
|
||||||
$scripts = $this->requireComposer()->getPackage()->getScripts();
|
$scripts = $this->requireComposer()->getPackage()->getScripts();
|
||||||
|
@ -128,7 +122,7 @@ EOT
|
||||||
|
|
||||||
$io = $this->getIO();
|
$io = $this->getIO();
|
||||||
$io->writeError('<info>scripts:</info>');
|
$io->writeError('<info>scripts:</info>');
|
||||||
$table = array();
|
$table = [];
|
||||||
foreach ($scripts as $name => $script) {
|
foreach ($scripts as $name => $script) {
|
||||||
$description = '';
|
$description = '';
|
||||||
try {
|
try {
|
||||||
|
@ -139,7 +133,7 @@ EOT
|
||||||
} catch (\Symfony\Component\Console\Exception\CommandNotFoundException $e) {
|
} catch (\Symfony\Component\Console\Exception\CommandNotFoundException $e) {
|
||||||
// ignore scripts that have no command associated, like native Composer script listeners
|
// ignore scripts that have no command associated, like native Composer script listeners
|
||||||
}
|
}
|
||||||
$table[] = array(' '.$name, $description);
|
$table[] = [' '.$name, $description];
|
||||||
}
|
}
|
||||||
|
|
||||||
$this->renderTable($table, $output);
|
$this->renderTable($table, $output);
|
||||||
|
|
|
@ -35,19 +35,16 @@ class ScriptAliasCommand extends BaseCommand
|
||||||
parent::__construct();
|
parent::__construct();
|
||||||
}
|
}
|
||||||
|
|
||||||
/**
|
|
||||||
* @return void
|
|
||||||
*/
|
|
||||||
protected function configure(): void
|
protected function configure(): void
|
||||||
{
|
{
|
||||||
$this
|
$this
|
||||||
->setName($this->script)
|
->setName($this->script)
|
||||||
->setDescription($this->description)
|
->setDescription($this->description)
|
||||||
->setDefinition(array(
|
->setDefinition([
|
||||||
new InputOption('dev', null, InputOption::VALUE_NONE, 'Sets the dev mode.'),
|
new InputOption('dev', null, InputOption::VALUE_NONE, 'Sets the dev mode.'),
|
||||||
new InputOption('no-dev', null, InputOption::VALUE_NONE, 'Disables the dev mode.'),
|
new InputOption('no-dev', null, InputOption::VALUE_NONE, 'Disables the dev mode.'),
|
||||||
new InputArgument('args', InputArgument::IS_ARRAY | InputArgument::OPTIONAL, ''),
|
new InputArgument('args', InputArgument::IS_ARRAY | InputArgument::OPTIONAL, ''),
|
||||||
))
|
])
|
||||||
->setHelp(
|
->setHelp(
|
||||||
<<<EOT
|
<<<EOT
|
||||||
The <info>run-script</info> command runs scripts defined in composer.json:
|
The <info>run-script</info> command runs scripts defined in composer.json:
|
||||||
|
|
|
@ -30,21 +30,18 @@ use Composer\Plugin\PluginEvents;
|
||||||
*/
|
*/
|
||||||
class SearchCommand extends BaseCommand
|
class SearchCommand extends BaseCommand
|
||||||
{
|
{
|
||||||
/**
|
|
||||||
* @return void
|
|
||||||
*/
|
|
||||||
protected function configure(): void
|
protected function configure(): void
|
||||||
{
|
{
|
||||||
$this
|
$this
|
||||||
->setName('search')
|
->setName('search')
|
||||||
->setDescription('Searches for packages')
|
->setDescription('Searches for packages')
|
||||||
->setDefinition(array(
|
->setDefinition([
|
||||||
new InputOption('only-name', 'N', InputOption::VALUE_NONE, 'Search only in package names'),
|
new InputOption('only-name', 'N', InputOption::VALUE_NONE, 'Search only in package names'),
|
||||||
new InputOption('only-vendor', 'O', InputOption::VALUE_NONE, 'Search only for vendor / organization names, returns only "vendor" as result'),
|
new InputOption('only-vendor', 'O', InputOption::VALUE_NONE, 'Search only for vendor / organization names, returns only "vendor" as result'),
|
||||||
new InputOption('type', 't', InputOption::VALUE_REQUIRED, 'Search for a specific package type'),
|
new InputOption('type', 't', InputOption::VALUE_REQUIRED, 'Search for a specific package type'),
|
||||||
new InputOption('format', 'f', InputOption::VALUE_REQUIRED, 'Format of the output: text or json', 'text', ['json', 'text']),
|
new InputOption('format', 'f', InputOption::VALUE_REQUIRED, 'Format of the output: text or json', 'text', ['json', 'text']),
|
||||||
new InputArgument('tokens', InputArgument::IS_ARRAY | InputArgument::REQUIRED, 'tokens to search for'),
|
new InputArgument('tokens', InputArgument::IS_ARRAY | InputArgument::REQUIRED, 'tokens to search for'),
|
||||||
))
|
])
|
||||||
->setHelp(
|
->setHelp(
|
||||||
<<<EOT
|
<<<EOT
|
||||||
The search command searches for packages by its name
|
The search command searches for packages by its name
|
||||||
|
@ -63,18 +60,18 @@ EOT
|
||||||
$io = $this->getIO();
|
$io = $this->getIO();
|
||||||
|
|
||||||
$format = $input->getOption('format');
|
$format = $input->getOption('format');
|
||||||
if (!in_array($format, array('text', 'json'))) {
|
if (!in_array($format, ['text', 'json'])) {
|
||||||
$io->writeError(sprintf('Unsupported format "%s". See help for supported formats.', $format));
|
$io->writeError(sprintf('Unsupported format "%s". See help for supported formats.', $format));
|
||||||
|
|
||||||
return 1;
|
return 1;
|
||||||
}
|
}
|
||||||
|
|
||||||
if (!($composer = $this->tryComposer())) {
|
if (!($composer = $this->tryComposer())) {
|
||||||
$composer = Factory::create($this->getIO(), array(), $input->hasParameterOption('--no-plugins'));
|
$composer = Factory::create($this->getIO(), [], $input->hasParameterOption('--no-plugins'));
|
||||||
}
|
}
|
||||||
$localRepo = $composer->getRepositoryManager()->getLocalRepository();
|
$localRepo = $composer->getRepositoryManager()->getLocalRepository();
|
||||||
$installedRepo = new CompositeRepository(array($localRepo, $platformRepo));
|
$installedRepo = new CompositeRepository([$localRepo, $platformRepo]);
|
||||||
$repos = new CompositeRepository(array_merge(array($installedRepo), $composer->getRepositoryManager()->getRepositories()));
|
$repos = new CompositeRepository(array_merge([$installedRepo], $composer->getRepositoryManager()->getRepositories()));
|
||||||
|
|
||||||
$commandEvent = new CommandEvent(PluginEvents::COMMAND, 'search', $input, $output);
|
$commandEvent = new CommandEvent(PluginEvents::COMMAND, 'search', $input, $output);
|
||||||
$composer->getEventDispatcher()->dispatch($commandEvent->getName(), $commandEvent);
|
$composer->getEventDispatcher()->dispatch($commandEvent->getName(), $commandEvent);
|
||||||
|
|
|
@ -39,16 +39,13 @@ class SelfUpdateCommand extends BaseCommand
|
||||||
private const HOMEPAGE = 'getcomposer.org';
|
private const HOMEPAGE = 'getcomposer.org';
|
||||||
private const OLD_INSTALL_EXT = '-old.phar';
|
private const OLD_INSTALL_EXT = '-old.phar';
|
||||||
|
|
||||||
/**
|
|
||||||
* @return void
|
|
||||||
*/
|
|
||||||
protected function configure(): void
|
protected function configure(): void
|
||||||
{
|
{
|
||||||
$this
|
$this
|
||||||
->setName('self-update')
|
->setName('self-update')
|
||||||
->setAliases(array('selfupdate'))
|
->setAliases(['selfupdate'])
|
||||||
->setDescription('Updates composer.phar to the latest version')
|
->setDescription('Updates composer.phar to the latest version')
|
||||||
->setDefinition(array(
|
->setDefinition([
|
||||||
new InputOption('rollback', 'r', InputOption::VALUE_NONE, 'Revert to an older installation of composer'),
|
new InputOption('rollback', 'r', InputOption::VALUE_NONE, 'Revert to an older installation of composer'),
|
||||||
new InputOption('clean-backups', null, InputOption::VALUE_NONE, 'Delete old backups during an update. This makes the current version of composer the only backup available after the update'),
|
new InputOption('clean-backups', null, InputOption::VALUE_NONE, 'Delete old backups during an update. This makes the current version of composer the only backup available after the update'),
|
||||||
new InputArgument('version', InputArgument::OPTIONAL, 'The version to update to'),
|
new InputArgument('version', InputArgument::OPTIONAL, 'The version to update to'),
|
||||||
|
@ -61,7 +58,7 @@ class SelfUpdateCommand extends BaseCommand
|
||||||
new InputOption('2', null, InputOption::VALUE_NONE, 'Force an update to the stable channel, but only use 2.x versions'),
|
new InputOption('2', null, InputOption::VALUE_NONE, 'Force an update to the stable channel, but only use 2.x versions'),
|
||||||
new InputOption('2.2', null, InputOption::VALUE_NONE, 'Force an update to the stable channel, but only use 2.2.x LTS versions'),
|
new InputOption('2.2', null, InputOption::VALUE_NONE, 'Force an update to the stable channel, but only use 2.2.x LTS versions'),
|
||||||
new InputOption('set-channel-only', null, InputOption::VALUE_NONE, 'Only store the channel as the default one and then exit'),
|
new InputOption('set-channel-only', null, InputOption::VALUE_NONE, 'Only store the channel as the default one and then exit'),
|
||||||
))
|
])
|
||||||
->setHelp(
|
->setHelp(
|
||||||
<<<EOT
|
<<<EOT
|
||||||
The <info>self-update</info> command checks getcomposer.org for newer
|
The <info>self-update</info> command checks getcomposer.org for newer
|
||||||
|
@ -361,7 +358,6 @@ TAGSPUBKEY
|
||||||
}
|
}
|
||||||
|
|
||||||
/**
|
/**
|
||||||
* @return void
|
|
||||||
* @throws \Exception
|
* @throws \Exception
|
||||||
*/
|
*/
|
||||||
protected function fetchKeys(IOInterface $io, Config $config): void
|
protected function fetchKeys(IOInterface $io, Config $config): void
|
||||||
|
@ -410,9 +406,6 @@ TAGSPUBKEY
|
||||||
}
|
}
|
||||||
|
|
||||||
/**
|
/**
|
||||||
* @param string $rollbackDir
|
|
||||||
* @param string $localFilename
|
|
||||||
* @return int
|
|
||||||
* @throws FilesystemException
|
* @throws FilesystemException
|
||||||
*/
|
*/
|
||||||
protected function rollback(OutputInterface $output, string $rollbackDir, string $localFilename): int
|
protected function rollback(OutputInterface $output, string $rollbackDir, string $localFilename): int
|
||||||
|
@ -449,7 +442,7 @@ TAGSPUBKEY
|
||||||
* @throws FilesystemException If the file cannot be moved
|
* @throws FilesystemException If the file cannot be moved
|
||||||
* @return bool Whether the phar is valid and has been moved
|
* @return bool Whether the phar is valid and has been moved
|
||||||
*/
|
*/
|
||||||
protected function setLocalPhar(string $localFilename, string $newFilename, string $backupTarget = null): bool
|
protected function setLocalPhar(string $localFilename, string $newFilename, ?string $backupTarget = null): bool
|
||||||
{
|
{
|
||||||
$io = $this->getIO();
|
$io = $this->getIO();
|
||||||
$perms = @fileperms($localFilename);
|
$perms = @fileperms($localFilename);
|
||||||
|
@ -498,12 +491,6 @@ TAGSPUBKEY
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
|
|
||||||
/**
|
|
||||||
* @param string $rollbackDir
|
|
||||||
* @param string|null $except
|
|
||||||
*
|
|
||||||
* @return void
|
|
||||||
*/
|
|
||||||
protected function cleanBackups(string $rollbackDir, ?string $except = null): void
|
protected function cleanBackups(string $rollbackDir, ?string $except = null): void
|
||||||
{
|
{
|
||||||
$finder = $this->getOldInstallationFinder($rollbackDir);
|
$finder = $this->getOldInstallationFinder($rollbackDir);
|
||||||
|
@ -533,10 +520,6 @@ TAGSPUBKEY
|
||||||
return null;
|
return null;
|
||||||
}
|
}
|
||||||
|
|
||||||
/**
|
|
||||||
* @param string $rollbackDir
|
|
||||||
* @return Finder
|
|
||||||
*/
|
|
||||||
protected function getOldInstallationFinder(string $rollbackDir): Finder
|
protected function getOldInstallationFinder(string $rollbackDir): Finder
|
||||||
{
|
{
|
||||||
return Finder::create()
|
return Finder::create()
|
||||||
|
@ -583,8 +566,6 @@ TAGSPUBKEY
|
||||||
|
|
||||||
/**
|
/**
|
||||||
* Returns true if this is a non-admin Windows user account
|
* Returns true if this is a non-admin Windows user account
|
||||||
*
|
|
||||||
* @return bool
|
|
||||||
*/
|
*/
|
||||||
protected function isWindowsNonAdminUser(): bool
|
protected function isWindowsNonAdminUser(): bool
|
||||||
{
|
{
|
||||||
|
|
|
@ -75,9 +75,9 @@ class ShowCommand extends BaseCommand
|
||||||
{
|
{
|
||||||
$this
|
$this
|
||||||
->setName('show')
|
->setName('show')
|
||||||
->setAliases(array('info'))
|
->setAliases(['info'])
|
||||||
->setDescription('Shows information about packages')
|
->setDescription('Shows information about packages')
|
||||||
->setDefinition(array(
|
->setDefinition([
|
||||||
new InputArgument('package', InputArgument::OPTIONAL, 'Package to inspect. Or a name including a wildcard (*) to filter lists of packages instead.', null, $this->suggestPackageBasedOnMode()),
|
new InputArgument('package', InputArgument::OPTIONAL, 'Package to inspect. Or a name including a wildcard (*) to filter lists of packages instead.', null, $this->suggestPackageBasedOnMode()),
|
||||||
new InputArgument('version', InputArgument::OPTIONAL, 'Version or version constraint to inspect'),
|
new InputArgument('version', InputArgument::OPTIONAL, 'Version or version constraint to inspect'),
|
||||||
new InputOption('all', null, InputOption::VALUE_NONE, 'List all packages'),
|
new InputOption('all', null, InputOption::VALUE_NONE, 'List all packages'),
|
||||||
|
@ -101,7 +101,7 @@ class ShowCommand extends BaseCommand
|
||||||
new InputOption('no-dev', null, InputOption::VALUE_NONE, 'Disables search in require-dev packages.'),
|
new InputOption('no-dev', null, InputOption::VALUE_NONE, 'Disables search in require-dev packages.'),
|
||||||
new InputOption('ignore-platform-req', null, InputOption::VALUE_REQUIRED | InputOption::VALUE_IS_ARRAY, 'Ignore a specific platform requirement (php & ext- packages). Use with the --outdated option'),
|
new InputOption('ignore-platform-req', null, InputOption::VALUE_REQUIRED | InputOption::VALUE_IS_ARRAY, 'Ignore a specific platform requirement (php & ext- packages). Use with the --outdated option'),
|
||||||
new InputOption('ignore-platform-reqs', null, InputOption::VALUE_NONE, 'Ignore all platform requirements (php & ext- packages). Use with the --outdated option'),
|
new InputOption('ignore-platform-reqs', null, InputOption::VALUE_NONE, 'Ignore all platform requirements (php & ext- packages). Use with the --outdated option'),
|
||||||
))
|
])
|
||||||
->setHelp(
|
->setHelp(
|
||||||
<<<EOT
|
<<<EOT
|
||||||
The show command displays detailed information about a package, or
|
The show command displays detailed information about a package, or
|
||||||
|
@ -179,7 +179,7 @@ EOT
|
||||||
}
|
}
|
||||||
|
|
||||||
$format = $input->getOption('format');
|
$format = $input->getOption('format');
|
||||||
if (!in_array($format, array('text', 'json'))) {
|
if (!in_array($format, ['text', 'json'])) {
|
||||||
$io->writeError(sprintf('Unsupported format "%s". See help for supported formats.', $format));
|
$io->writeError(sprintf('Unsupported format "%s". See help for supported formats.', $format));
|
||||||
|
|
||||||
return 1;
|
return 1;
|
||||||
|
@ -188,11 +188,11 @@ EOT
|
||||||
$platformReqFilter = $this->getPlatformRequirementFilter($input);
|
$platformReqFilter = $this->getPlatformRequirementFilter($input);
|
||||||
|
|
||||||
// init repos
|
// init repos
|
||||||
$platformOverrides = array();
|
$platformOverrides = [];
|
||||||
if ($composer) {
|
if ($composer) {
|
||||||
$platformOverrides = $composer->getConfig()->get('platform');
|
$platformOverrides = $composer->getConfig()->get('platform');
|
||||||
}
|
}
|
||||||
$platformRepo = new PlatformRepository(array(), $platformOverrides);
|
$platformRepo = new PlatformRepository([], $platformOverrides);
|
||||||
$lockedRepo = null;
|
$lockedRepo = null;
|
||||||
|
|
||||||
if ($input->getOption('self')) {
|
if ($input->getOption('self')) {
|
||||||
|
@ -205,11 +205,11 @@ EOT
|
||||||
if ($input->getArgument('package')) {
|
if ($input->getArgument('package')) {
|
||||||
throw new \InvalidArgumentException('You cannot use --self together with a package name');
|
throw new \InvalidArgumentException('You cannot use --self together with a package name');
|
||||||
}
|
}
|
||||||
$repos = $installedRepo = new InstalledRepository(array(new RootPackageRepository($package)));
|
$repos = $installedRepo = new InstalledRepository([new RootPackageRepository($package)]);
|
||||||
} elseif ($input->getOption('platform')) {
|
} elseif ($input->getOption('platform')) {
|
||||||
$repos = $installedRepo = new InstalledRepository(array($platformRepo));
|
$repos = $installedRepo = new InstalledRepository([$platformRepo]);
|
||||||
} elseif ($input->getOption('available')) {
|
} elseif ($input->getOption('available')) {
|
||||||
$installedRepo = new InstalledRepository(array($platformRepo));
|
$installedRepo = new InstalledRepository([$platformRepo]);
|
||||||
if ($composer) {
|
if ($composer) {
|
||||||
$repos = new CompositeRepository($composer->getRepositoryManager()->getRepositories());
|
$repos = new CompositeRepository($composer->getRepositoryManager()->getRepositories());
|
||||||
$installedRepo->addRepository($composer->getRepositoryManager()->getLocalRepository());
|
$installedRepo->addRepository($composer->getRepositoryManager()->getLocalRepository());
|
||||||
|
@ -223,36 +223,36 @@ EOT
|
||||||
$locker = $composer->getLocker();
|
$locker = $composer->getLocker();
|
||||||
if ($locker->isLocked()) {
|
if ($locker->isLocked()) {
|
||||||
$lockedRepo = $locker->getLockedRepository(true);
|
$lockedRepo = $locker->getLockedRepository(true);
|
||||||
$installedRepo = new InstalledRepository(array($lockedRepo, $localRepo, $platformRepo));
|
$installedRepo = new InstalledRepository([$lockedRepo, $localRepo, $platformRepo]);
|
||||||
} else {
|
} else {
|
||||||
$installedRepo = new InstalledRepository(array($localRepo, $platformRepo));
|
$installedRepo = new InstalledRepository([$localRepo, $platformRepo]);
|
||||||
}
|
}
|
||||||
$repos = new CompositeRepository(array_merge(array(new FilterRepository($installedRepo, array('canonical' => false))), $composer->getRepositoryManager()->getRepositories()));
|
$repos = new CompositeRepository(array_merge([new FilterRepository($installedRepo, ['canonical' => false])], $composer->getRepositoryManager()->getRepositories()));
|
||||||
} elseif ($input->getOption('all')) {
|
} elseif ($input->getOption('all')) {
|
||||||
$defaultRepos = RepositoryFactory::defaultReposWithDefaultManager($io);
|
$defaultRepos = RepositoryFactory::defaultReposWithDefaultManager($io);
|
||||||
$io->writeError('No composer.json found in the current directory, showing available packages from ' . implode(', ', array_keys($defaultRepos)));
|
$io->writeError('No composer.json found in the current directory, showing available packages from ' . implode(', ', array_keys($defaultRepos)));
|
||||||
$installedRepo = new InstalledRepository(array($platformRepo));
|
$installedRepo = new InstalledRepository([$platformRepo]);
|
||||||
$repos = new CompositeRepository(array_merge(array($installedRepo), $defaultRepos));
|
$repos = new CompositeRepository(array_merge([$installedRepo], $defaultRepos));
|
||||||
} elseif ($input->getOption('locked')) {
|
} elseif ($input->getOption('locked')) {
|
||||||
if (!$composer || !$composer->getLocker()->isLocked()) {
|
if (!$composer || !$composer->getLocker()->isLocked()) {
|
||||||
throw new \UnexpectedValueException('A valid composer.json and composer.lock files is required to run this command with --locked');
|
throw new \UnexpectedValueException('A valid composer.json and composer.lock files is required to run this command with --locked');
|
||||||
}
|
}
|
||||||
$locker = $composer->getLocker();
|
$locker = $composer->getLocker();
|
||||||
$lockedRepo = $locker->getLockedRepository(!$input->getOption('no-dev'));
|
$lockedRepo = $locker->getLockedRepository(!$input->getOption('no-dev'));
|
||||||
$repos = $installedRepo = new InstalledRepository(array($lockedRepo));
|
$repos = $installedRepo = new InstalledRepository([$lockedRepo]);
|
||||||
} else {
|
} else {
|
||||||
// --installed / default case
|
// --installed / default case
|
||||||
if (!$composer) {
|
if (!$composer) {
|
||||||
$composer = $this->requireComposer();
|
$composer = $this->requireComposer();
|
||||||
}
|
}
|
||||||
$rootPkg = $composer->getPackage();
|
$rootPkg = $composer->getPackage();
|
||||||
$repos = $installedRepo = new InstalledRepository(array($composer->getRepositoryManager()->getLocalRepository()));
|
$repos = $installedRepo = new InstalledRepository([$composer->getRepositoryManager()->getLocalRepository()]);
|
||||||
|
|
||||||
if ($input->getOption('no-dev')) {
|
if ($input->getOption('no-dev')) {
|
||||||
$packages = RepositoryUtils::filterRequiredPackages($installedRepo->getPackages(), $rootPkg);
|
$packages = RepositoryUtils::filterRequiredPackages($installedRepo->getPackages(), $rootPkg);
|
||||||
$repos = $installedRepo = new InstalledRepository(array(new InstalledArrayRepository(array_map(static function ($pkg): PackageInterface {
|
$repos = $installedRepo = new InstalledRepository([new InstalledArrayRepository(array_map(static function ($pkg): PackageInterface {
|
||||||
return clone $pkg;
|
return clone $pkg;
|
||||||
}, $packages))));
|
}, $packages))]);
|
||||||
}
|
}
|
||||||
|
|
||||||
if (!$installedRepo->getPackages() && ($rootPkg->getRequires() || $rootPkg->getDevRequires())) {
|
if (!$installedRepo->getPackages() && ($rootPkg->getRequires() || $rootPkg->getDevRequires())) {
|
||||||
|
@ -274,9 +274,9 @@ EOT
|
||||||
|
|
||||||
// show single package or single version
|
// show single package or single version
|
||||||
if (isset($package)) {
|
if (isset($package)) {
|
||||||
$versions = array($package->getPrettyVersion() => $package->getVersion());
|
$versions = [$package->getPrettyVersion() => $package->getVersion()];
|
||||||
} elseif (null !== $packageFilter && !str_contains($packageFilter, '*')) {
|
} elseif (null !== $packageFilter && !str_contains($packageFilter, '*')) {
|
||||||
list($package, $versions) = $this->getPackage($installedRepo, $repos, $packageFilter, $input->getArgument('version'));
|
[$package, $versions] = $this->getPackage($installedRepo, $repos, $packageFilter, $input->getArgument('version'));
|
||||||
|
|
||||||
if (!isset($package)) {
|
if (!isset($package)) {
|
||||||
$options = $input->getOptions();
|
$options = $input->getOptions();
|
||||||
|
@ -306,9 +306,9 @@ EOT
|
||||||
$arrayTree = $this->generatePackageTree($package, $installedRepo, $repos);
|
$arrayTree = $this->generatePackageTree($package, $installedRepo, $repos);
|
||||||
|
|
||||||
if ('json' === $format) {
|
if ('json' === $format) {
|
||||||
$io->write(JsonFile::encode(array('installed' => array($arrayTree))));
|
$io->write(JsonFile::encode(['installed' => [$arrayTree]]));
|
||||||
} else {
|
} else {
|
||||||
$this->displayPackageTree(array($arrayTree));
|
$this->displayPackageTree([$arrayTree]);
|
||||||
}
|
}
|
||||||
|
|
||||||
return $exitCode;
|
return $exitCode;
|
||||||
|
@ -350,7 +350,7 @@ EOT
|
||||||
usort($packages, static function (BasePackage $a, BasePackage $b): int {
|
usort($packages, static function (BasePackage $a, BasePackage $b): int {
|
||||||
return strcmp((string) $a, (string) $b);
|
return strcmp((string) $a, (string) $b);
|
||||||
});
|
});
|
||||||
$arrayTree = array();
|
$arrayTree = [];
|
||||||
foreach ($packages as $package) {
|
foreach ($packages as $package) {
|
||||||
if (in_array($package->getName(), $rootRequires, true)) {
|
if (in_array($package->getName(), $rootRequires, true)) {
|
||||||
$arrayTree[] = $this->generatePackageTree($package, $installedRepo, $repos);
|
$arrayTree[] = $this->generatePackageTree($package, $installedRepo, $repos);
|
||||||
|
@ -358,7 +358,7 @@ EOT
|
||||||
}
|
}
|
||||||
|
|
||||||
if ('json' === $format) {
|
if ('json' === $format) {
|
||||||
$io->write(JsonFile::encode(array('installed' => $arrayTree)));
|
$io->write(JsonFile::encode(['installed' => $arrayTree]));
|
||||||
} else {
|
} else {
|
||||||
$this->displayPackageTree($arrayTree);
|
$this->displayPackageTree($arrayTree);
|
||||||
}
|
}
|
||||||
|
@ -368,7 +368,7 @@ EOT
|
||||||
|
|
||||||
// list packages
|
// list packages
|
||||||
/** @var array<string, array<string, string|CompletePackageInterface>> $packages */
|
/** @var array<string, array<string, string|CompletePackageInterface>> $packages */
|
||||||
$packages = array();
|
$packages = [];
|
||||||
$packageFilterRegex = null;
|
$packageFilterRegex = null;
|
||||||
if (null !== $packageFilter) {
|
if (null !== $packageFilter) {
|
||||||
$packageFilterRegex = '{^'.str_replace('\\*', '.*?', preg_quote($packageFilter)).'$}i';
|
$packageFilterRegex = '{^'.str_replace('\\*', '.*?', preg_quote($packageFilter)).'$}i';
|
||||||
|
@ -430,11 +430,11 @@ EOT
|
||||||
$ignoredPackages = array_map('strtolower', $input->getOption('ignore'));
|
$ignoredPackages = array_map('strtolower', $input->getOption('ignore'));
|
||||||
$indent = $showAllTypes ? ' ' : '';
|
$indent = $showAllTypes ? ' ' : '';
|
||||||
/** @var PackageInterface[] $latestPackages */
|
/** @var PackageInterface[] $latestPackages */
|
||||||
$latestPackages = array();
|
$latestPackages = [];
|
||||||
$exitCode = 0;
|
$exitCode = 0;
|
||||||
$viewData = array();
|
$viewData = [];
|
||||||
$viewMetaData = array();
|
$viewMetaData = [];
|
||||||
foreach (array('platform' => true, 'locked' => true, 'available' => false, 'installed' => true) as $type => $showVersion) {
|
foreach (['platform' => true, 'locked' => true, 'available' => false, 'installed' => true] as $type => $showVersion) {
|
||||||
if (isset($packages[$type])) {
|
if (isset($packages[$type])) {
|
||||||
ksort($packages[$type]);
|
ksort($packages[$type]);
|
||||||
|
|
||||||
|
@ -460,9 +460,9 @@ EOT
|
||||||
|
|
||||||
$hasOutdatedPackages = false;
|
$hasOutdatedPackages = false;
|
||||||
|
|
||||||
$viewData[$type] = array();
|
$viewData[$type] = [];
|
||||||
foreach ($packages[$type] as $package) {
|
foreach ($packages[$type] as $package) {
|
||||||
$packageViewData = array();
|
$packageViewData = [];
|
||||||
if (is_object($package)) {
|
if (is_object($package)) {
|
||||||
$latestPackage = null;
|
$latestPackage = null;
|
||||||
if ($showLatest && isset($latestPackages[$package->getPrettyName()])) {
|
if ($showLatest && isset($latestPackages[$package->getPrettyName()])) {
|
||||||
|
@ -531,12 +531,12 @@ EOT
|
||||||
}
|
}
|
||||||
$viewData[$type][] = $packageViewData;
|
$viewData[$type][] = $packageViewData;
|
||||||
}
|
}
|
||||||
$viewMetaData[$type] = array(
|
$viewMetaData[$type] = [
|
||||||
'nameLength' => $nameLength,
|
'nameLength' => $nameLength,
|
||||||
'versionLength' => $versionLength,
|
'versionLength' => $versionLength,
|
||||||
'latestLength' => $latestLength,
|
'latestLength' => $latestLength,
|
||||||
'writeLatest' => $writeLatest,
|
'writeLatest' => $writeLatest,
|
||||||
);
|
];
|
||||||
if ($input->getOption('strict') && $hasOutdatedPackages) {
|
if ($input->getOption('strict') && $hasOutdatedPackages) {
|
||||||
$exitCode = 1;
|
$exitCode = 1;
|
||||||
break;
|
break;
|
||||||
|
@ -647,7 +647,7 @@ EOT
|
||||||
$updateStatus = $package['latest-status'];
|
$updateStatus = $package['latest-status'];
|
||||||
$style = $this->updateStatusToVersionStyle($updateStatus);
|
$style = $this->updateStatusToVersionStyle($updateStatus);
|
||||||
if (!$io->isDecorated()) {
|
if (!$io->isDecorated()) {
|
||||||
$latestVersion = str_replace(array('up-to-date', 'semver-safe-update', 'update-possible'), array('=', '!', '~'), $updateStatus) . ' ' . $latestVersion;
|
$latestVersion = str_replace(['up-to-date', 'semver-safe-update', 'update-possible'], ['=', '!', '~'], $updateStatus) . ' ' . $latestVersion;
|
||||||
}
|
}
|
||||||
$io->write(' <' . $style . '>' . str_pad($latestVersion, $latestLength, ' ') . '</' . $style . '>', false);
|
$io->write(' <' . $style . '>' . str_pad($latestVersion, $latestLength, ' ') . '</' . $style . '>', false);
|
||||||
}
|
}
|
||||||
|
@ -696,7 +696,6 @@ EOT
|
||||||
/**
|
/**
|
||||||
* finds a package by name and version if provided
|
* finds a package by name and version if provided
|
||||||
*
|
*
|
||||||
* @param string $name
|
|
||||||
* @param ConstraintInterface|string $version
|
* @param ConstraintInterface|string $version
|
||||||
* @throws \InvalidArgumentException
|
* @throws \InvalidArgumentException
|
||||||
* @return array{CompletePackageInterface|null, array<string, string>}
|
* @return array{CompletePackageInterface|null, array<string, string>}
|
||||||
|
@ -712,7 +711,7 @@ EOT
|
||||||
$repositorySet->addRepository($repos);
|
$repositorySet->addRepository($repos);
|
||||||
|
|
||||||
$matchedPackage = null;
|
$matchedPackage = null;
|
||||||
$versions = array();
|
$versions = [];
|
||||||
if (PlatformRepository::isPlatformPackage($name)) {
|
if (PlatformRepository::isPlatformPackage($name)) {
|
||||||
$pool = $repositorySet->createPoolWithAllPackages();
|
$pool = $repositorySet->createPoolWithAllPackages();
|
||||||
} else {
|
} else {
|
||||||
|
@ -739,18 +738,15 @@ EOT
|
||||||
$matchedPackage = $pool->literalToPackage($preferred[0]);
|
$matchedPackage = $pool->literalToPackage($preferred[0]);
|
||||||
}
|
}
|
||||||
|
|
||||||
return array($matchedPackage, $versions);
|
return [$matchedPackage, $versions];
|
||||||
}
|
}
|
||||||
|
|
||||||
/**
|
/**
|
||||||
* Prints package info.
|
* Prints package info.
|
||||||
*
|
*
|
||||||
* @param array<string, string> $versions
|
* @param array<string, string> $versions
|
||||||
* @param PackageInterface|null $latestPackage
|
|
||||||
*
|
|
||||||
* @return void
|
|
||||||
*/
|
*/
|
||||||
protected function printPackageInfo(CompletePackageInterface $package, array $versions, InstalledRepository $installedRepo, PackageInterface $latestPackage = null): void
|
protected function printPackageInfo(CompletePackageInterface $package, array $versions, InstalledRepository $installedRepo, ?PackageInterface $latestPackage = null): void
|
||||||
{
|
{
|
||||||
$io = $this->getIO();
|
$io = $this->getIO();
|
||||||
|
|
||||||
|
@ -774,16 +770,13 @@ EOT
|
||||||
* Prints package metadata.
|
* Prints package metadata.
|
||||||
*
|
*
|
||||||
* @param array<string, string> $versions
|
* @param array<string, string> $versions
|
||||||
* @param PackageInterface|null $latestPackage
|
|
||||||
*
|
|
||||||
* @return void
|
|
||||||
*/
|
*/
|
||||||
protected function printMeta(CompletePackageInterface $package, array $versions, InstalledRepository $installedRepo, PackageInterface $latestPackage = null): void
|
protected function printMeta(CompletePackageInterface $package, array $versions, InstalledRepository $installedRepo, ?PackageInterface $latestPackage = null): void
|
||||||
{
|
{
|
||||||
$io = $this->getIO();
|
$io = $this->getIO();
|
||||||
$io->write('<info>name</info> : ' . $package->getPrettyName());
|
$io->write('<info>name</info> : ' . $package->getPrettyName());
|
||||||
$io->write('<info>descrip.</info> : ' . $package->getDescription());
|
$io->write('<info>descrip.</info> : ' . $package->getDescription());
|
||||||
$io->write('<info>keywords</info> : ' . implode(', ', $package->getKeywords() ?: array()));
|
$io->write('<info>keywords</info> : ' . implode(', ', $package->getKeywords() ?: []));
|
||||||
$this->printVersions($package, $versions, $installedRepo);
|
$this->printVersions($package, $versions, $installedRepo);
|
||||||
if ($latestPackage) {
|
if ($latestPackage) {
|
||||||
$style = $this->getVersionStyle($latestPackage, $package);
|
$style = $this->getVersionStyle($latestPackage, $package);
|
||||||
|
@ -843,8 +836,6 @@ EOT
|
||||||
* Prints all available versions of this package and highlights the installed one if any.
|
* Prints all available versions of this package and highlights the installed one if any.
|
||||||
*
|
*
|
||||||
* @param array<string, string> $versions
|
* @param array<string, string> $versions
|
||||||
*
|
|
||||||
* @return void
|
|
||||||
*/
|
*/
|
||||||
protected function printVersions(CompletePackageInterface $package, array $versions, InstalledRepository $installedRepo): void
|
protected function printVersions(CompletePackageInterface $package, array $versions, InstalledRepository $installedRepo): void
|
||||||
{
|
{
|
||||||
|
@ -870,12 +861,9 @@ EOT
|
||||||
/**
|
/**
|
||||||
* print link objects
|
* print link objects
|
||||||
*
|
*
|
||||||
* @param string $linkType
|
|
||||||
* @param string $title
|
* @param string $title
|
||||||
*
|
|
||||||
* @return void
|
|
||||||
*/
|
*/
|
||||||
protected function printLinks(CompletePackageInterface $package, string $linkType, string $title = null): void
|
protected function printLinks(CompletePackageInterface $package, string $linkType, ?string $title = null): void
|
||||||
{
|
{
|
||||||
$title = $title ?: $linkType;
|
$title = $title ?: $linkType;
|
||||||
$io = $this->getIO();
|
$io = $this->getIO();
|
||||||
|
@ -890,8 +878,6 @@ EOT
|
||||||
|
|
||||||
/**
|
/**
|
||||||
* Prints the licenses of a package with metadata
|
* Prints the licenses of a package with metadata
|
||||||
*
|
|
||||||
* @return void
|
|
||||||
*/
|
*/
|
||||||
protected function printLicenses(CompletePackageInterface $package): void
|
protected function printLicenses(CompletePackageInterface $package): void
|
||||||
{
|
{
|
||||||
|
@ -922,19 +908,17 @@ EOT
|
||||||
* Prints package info in JSON format.
|
* Prints package info in JSON format.
|
||||||
*
|
*
|
||||||
* @param array<string, string> $versions
|
* @param array<string, string> $versions
|
||||||
*
|
|
||||||
* @return void
|
|
||||||
*/
|
*/
|
||||||
protected function printPackageInfoAsJson(CompletePackageInterface $package, array $versions, InstalledRepository $installedRepo, PackageInterface $latestPackage = null): void
|
protected function printPackageInfoAsJson(CompletePackageInterface $package, array $versions, InstalledRepository $installedRepo, ?PackageInterface $latestPackage = null): void
|
||||||
{
|
{
|
||||||
$json = array(
|
$json = [
|
||||||
'name' => $package->getPrettyName(),
|
'name' => $package->getPrettyName(),
|
||||||
'description' => $package->getDescription(),
|
'description' => $package->getDescription(),
|
||||||
'keywords' => $package->getKeywords() ?: array(),
|
'keywords' => $package->getKeywords() ?: [],
|
||||||
'type' => $package->getType(),
|
'type' => $package->getType(),
|
||||||
'homepage' => $package->getHomepage(),
|
'homepage' => $package->getHomepage(),
|
||||||
'names' => $package->getNames(),
|
'names' => $package->getNames(),
|
||||||
);
|
];
|
||||||
|
|
||||||
$json = $this->appendVersions($json, $versions);
|
$json = $this->appendVersions($json, $versions);
|
||||||
$json = $this->appendLicenses($json, $package);
|
$json = $this->appendLicenses($json, $package);
|
||||||
|
@ -946,19 +930,19 @@ EOT
|
||||||
}
|
}
|
||||||
|
|
||||||
if (null !== $package->getSourceType()) {
|
if (null !== $package->getSourceType()) {
|
||||||
$json['source'] = array(
|
$json['source'] = [
|
||||||
'type' => $package->getSourceType(),
|
'type' => $package->getSourceType(),
|
||||||
'url' => $package->getSourceUrl(),
|
'url' => $package->getSourceUrl(),
|
||||||
'reference' => $package->getSourceReference(),
|
'reference' => $package->getSourceReference(),
|
||||||
);
|
];
|
||||||
}
|
}
|
||||||
|
|
||||||
if (null !== $package->getDistType()) {
|
if (null !== $package->getDistType()) {
|
||||||
$json['dist'] = array(
|
$json['dist'] = [
|
||||||
'type' => $package->getDistType(),
|
'type' => $package->getDistType(),
|
||||||
'url' => $package->getDistUrl(),
|
'url' => $package->getDistUrl(),
|
||||||
'reference' => $package->getDistReference(),
|
'reference' => $package->getDistReference(),
|
||||||
);
|
];
|
||||||
}
|
}
|
||||||
|
|
||||||
if ($installedRepo->hasPackage($package)) {
|
if ($installedRepo->hasPackage($package)) {
|
||||||
|
@ -1021,11 +1005,11 @@ EOT
|
||||||
return $licenseId;
|
return $licenseId;
|
||||||
}
|
}
|
||||||
|
|
||||||
return array(
|
return [
|
||||||
'name' => $license[0],
|
'name' => $license[0],
|
||||||
'osi' => $licenseId,
|
'osi' => $licenseId,
|
||||||
'url' => $license[2],
|
'url' => $license[2],
|
||||||
);
|
];
|
||||||
}, $licenses);
|
}, $licenses);
|
||||||
}
|
}
|
||||||
|
|
||||||
|
@ -1039,11 +1023,11 @@ EOT
|
||||||
private function appendAutoload(array $json, CompletePackageInterface $package): array
|
private function appendAutoload(array $json, CompletePackageInterface $package): array
|
||||||
{
|
{
|
||||||
if ($package->getAutoload()) {
|
if ($package->getAutoload()) {
|
||||||
$autoload = array();
|
$autoload = [];
|
||||||
|
|
||||||
foreach ($package->getAutoload() as $type => $autoloads) {
|
foreach ($package->getAutoload() as $type => $autoloads) {
|
||||||
if ($type === 'psr-0' || $type === 'psr-4') {
|
if ($type === 'psr-0' || $type === 'psr-4') {
|
||||||
$psr = array();
|
$psr = [];
|
||||||
|
|
||||||
foreach ($autoloads as $name => $path) {
|
foreach ($autoloads as $name => $path) {
|
||||||
if (!$path) {
|
if (!$path) {
|
||||||
|
@ -1080,7 +1064,6 @@ EOT
|
||||||
|
|
||||||
/**
|
/**
|
||||||
* @param array<string, string|string[]|null> $json
|
* @param array<string, string|string[]|null> $json
|
||||||
* @param string $linkType
|
|
||||||
* @return array<string, string|string[]|null>
|
* @return array<string, string|string[]|null>
|
||||||
*/
|
*/
|
||||||
private function appendLink(array $json, CompletePackageInterface $package, string $linkType): array
|
private function appendLink(array $json, CompletePackageInterface $package, string $linkType): array
|
||||||
|
@ -1088,7 +1071,7 @@ EOT
|
||||||
$links = $package->{'get' . ucfirst($linkType)}();
|
$links = $package->{'get' . ucfirst($linkType)}();
|
||||||
|
|
||||||
if ($links) {
|
if ($links) {
|
||||||
$json[$linkType] = array();
|
$json[$linkType] = [];
|
||||||
|
|
||||||
foreach ($links as $link) {
|
foreach ($links as $link) {
|
||||||
$json[$linkType][$link->getTarget()] = $link->getPrettyConstraint();
|
$json[$linkType][$link->getTarget()] = $link->getPrettyConstraint();
|
||||||
|
@ -1100,18 +1083,16 @@ EOT
|
||||||
|
|
||||||
/**
|
/**
|
||||||
* Init styles for tree
|
* Init styles for tree
|
||||||
*
|
|
||||||
* @return void
|
|
||||||
*/
|
*/
|
||||||
protected function initStyles(OutputInterface $output): void
|
protected function initStyles(OutputInterface $output): void
|
||||||
{
|
{
|
||||||
$this->colors = array(
|
$this->colors = [
|
||||||
'green',
|
'green',
|
||||||
'yellow',
|
'yellow',
|
||||||
'cyan',
|
'cyan',
|
||||||
'magenta',
|
'magenta',
|
||||||
'blue',
|
'blue',
|
||||||
);
|
];
|
||||||
|
|
||||||
foreach ($this->colors as $color) {
|
foreach ($this->colors as $color) {
|
||||||
$style = new OutputFormatterStyle($color);
|
$style = new OutputFormatterStyle($color);
|
||||||
|
@ -1123,7 +1104,6 @@ EOT
|
||||||
* Display the tree
|
* Display the tree
|
||||||
*
|
*
|
||||||
* @param array<int, array<string, string|mixed[]>> $arrayTree
|
* @param array<int, array<string, string|mixed[]>> $arrayTree
|
||||||
* @return void
|
|
||||||
*/
|
*/
|
||||||
protected function displayPackageTree(array $arrayTree): void
|
protected function displayPackageTree(array $arrayTree): void
|
||||||
{
|
{
|
||||||
|
@ -1162,7 +1142,7 @@ EOT
|
||||||
$this->writeTreeLine($info);
|
$this->writeTreeLine($info);
|
||||||
|
|
||||||
$treeBar = str_replace('└', ' ', $treeBar);
|
$treeBar = str_replace('└', ' ', $treeBar);
|
||||||
$packagesInTree = array($package['name'], $requireName);
|
$packagesInTree = [$package['name'], $requireName];
|
||||||
|
|
||||||
$this->displayTree($require, $packagesInTree, $treeBar, $level + 1);
|
$this->displayTree($require, $packagesInTree, $treeBar, $level + 1);
|
||||||
}
|
}
|
||||||
|
@ -1182,14 +1162,14 @@ EOT
|
||||||
): array {
|
): array {
|
||||||
$requires = $package->getRequires();
|
$requires = $package->getRequires();
|
||||||
ksort($requires);
|
ksort($requires);
|
||||||
$children = array();
|
$children = [];
|
||||||
foreach ($requires as $requireName => $require) {
|
foreach ($requires as $requireName => $require) {
|
||||||
$packagesInTree = array($package->getName(), $requireName);
|
$packagesInTree = [$package->getName(), $requireName];
|
||||||
|
|
||||||
$treeChildDesc = array(
|
$treeChildDesc = [
|
||||||
'name' => $requireName,
|
'name' => $requireName,
|
||||||
'version' => $require->getPrettyConstraint(),
|
'version' => $require->getPrettyConstraint(),
|
||||||
);
|
];
|
||||||
|
|
||||||
$deepChildren = $this->addTree($requireName, $require, $installedRepo, $remoteRepos, $packagesInTree);
|
$deepChildren = $this->addTree($requireName, $require, $installedRepo, $remoteRepos, $packagesInTree);
|
||||||
|
|
||||||
|
@ -1199,11 +1179,11 @@ EOT
|
||||||
|
|
||||||
$children[] = $treeChildDesc;
|
$children[] = $treeChildDesc;
|
||||||
}
|
}
|
||||||
$tree = array(
|
$tree = [
|
||||||
'name' => $package->getPrettyName(),
|
'name' => $package->getPrettyName(),
|
||||||
'version' => $package->getPrettyVersion(),
|
'version' => $package->getPrettyVersion(),
|
||||||
'description' => $package instanceof CompletePackageInterface ? $package->getDescription() : '',
|
'description' => $package instanceof CompletePackageInterface ? $package->getDescription() : '',
|
||||||
);
|
];
|
||||||
|
|
||||||
if ($children) {
|
if ($children) {
|
||||||
$tree['requires'] = $children;
|
$tree['requires'] = $children;
|
||||||
|
@ -1217,10 +1197,6 @@ EOT
|
||||||
*
|
*
|
||||||
* @param array<string, array<int, array<string, mixed[]|string>>|string|null>|string $package
|
* @param array<string, array<int, array<string, mixed[]|string>>|string|null>|string $package
|
||||||
* @param array<int, string|mixed[]> $packagesInTree
|
* @param array<int, string|mixed[]> $packagesInTree
|
||||||
* @param string $previousTreeBar
|
|
||||||
* @param int $level
|
|
||||||
*
|
|
||||||
* @return void
|
|
||||||
*/
|
*/
|
||||||
protected function displayTree(
|
protected function displayTree(
|
||||||
$package,
|
$package,
|
||||||
|
@ -1270,7 +1246,6 @@ EOT
|
||||||
/**
|
/**
|
||||||
* Display a package tree
|
* Display a package tree
|
||||||
*
|
*
|
||||||
* @param string $name
|
|
||||||
* @param string[] $packagesInTree
|
* @param string[] $packagesInTree
|
||||||
* @return array<int, array<string, array<int, array<string, string>>|string>>
|
* @return array<int, array<string, array<int, array<string, string>>|string>>
|
||||||
*/
|
*/
|
||||||
|
@ -1281,8 +1256,8 @@ EOT
|
||||||
RepositoryInterface $remoteRepos,
|
RepositoryInterface $remoteRepos,
|
||||||
array $packagesInTree
|
array $packagesInTree
|
||||||
): array {
|
): array {
|
||||||
$children = array();
|
$children = [];
|
||||||
list($package) = $this->getPackage(
|
[$package] = $this->getPackage(
|
||||||
$installedRepo,
|
$installedRepo,
|
||||||
$remoteRepos,
|
$remoteRepos,
|
||||||
$name,
|
$name,
|
||||||
|
@ -1294,10 +1269,10 @@ EOT
|
||||||
foreach ($requires as $requireName => $require) {
|
foreach ($requires as $requireName => $require) {
|
||||||
$currentTree = $packagesInTree;
|
$currentTree = $packagesInTree;
|
||||||
|
|
||||||
$treeChildDesc = array(
|
$treeChildDesc = [
|
||||||
'name' => $requireName,
|
'name' => $requireName,
|
||||||
'version' => $require->getPrettyConstraint(),
|
'version' => $require->getPrettyConstraint(),
|
||||||
);
|
];
|
||||||
|
|
||||||
if (!in_array($requireName, $currentTree, true)) {
|
if (!in_array($requireName, $currentTree, true)) {
|
||||||
$currentTree[] = $requireName;
|
$currentTree[] = $requireName;
|
||||||
|
@ -1314,21 +1289,14 @@ EOT
|
||||||
return $children;
|
return $children;
|
||||||
}
|
}
|
||||||
|
|
||||||
/**
|
|
||||||
* @param string $updateStatus
|
|
||||||
* @return string
|
|
||||||
*/
|
|
||||||
private function updateStatusToVersionStyle(string $updateStatus): string
|
private function updateStatusToVersionStyle(string $updateStatus): string
|
||||||
{
|
{
|
||||||
// 'up-to-date' is printed green
|
// 'up-to-date' is printed green
|
||||||
// 'semver-safe-update' is printed red
|
// 'semver-safe-update' is printed red
|
||||||
// 'update-possible' is printed yellow
|
// 'update-possible' is printed yellow
|
||||||
return str_replace(array('up-to-date', 'semver-safe-update', 'update-possible'), array('info', 'highlight', 'comment'), $updateStatus);
|
return str_replace(['up-to-date', 'semver-safe-update', 'update-possible'], ['info', 'highlight', 'comment'], $updateStatus);
|
||||||
}
|
}
|
||||||
|
|
||||||
/**
|
|
||||||
* @return string
|
|
||||||
*/
|
|
||||||
private function getUpdateStatus(PackageInterface $latestPackage, PackageInterface $package): string
|
private function getUpdateStatus(PackageInterface $latestPackage, PackageInterface $package): string
|
||||||
{
|
{
|
||||||
if ($latestPackage->getFullPrettyVersion() === $package->getFullPrettyVersion()) {
|
if ($latestPackage->getFullPrettyVersion() === $package->getFullPrettyVersion()) {
|
||||||
|
@ -1348,16 +1316,11 @@ EOT
|
||||||
return 'update-possible';
|
return 'update-possible';
|
||||||
}
|
}
|
||||||
|
|
||||||
/**
|
|
||||||
* @param string $line
|
|
||||||
*
|
|
||||||
* @return void
|
|
||||||
*/
|
|
||||||
private function writeTreeLine(string $line): void
|
private function writeTreeLine(string $line): void
|
||||||
{
|
{
|
||||||
$io = $this->getIO();
|
$io = $this->getIO();
|
||||||
if (!$io->isDecorated()) {
|
if (!$io->isDecorated()) {
|
||||||
$line = str_replace(array('└', '├', '──', '│'), array('`-', '|-', '-', '|'), $line);
|
$line = str_replace(['└', '├', '──', '│'], ['`-', '|-', '-', '|'], $line);
|
||||||
}
|
}
|
||||||
|
|
||||||
$io->write($line);
|
$io->write($line);
|
||||||
|
@ -1419,9 +1382,6 @@ EOT
|
||||||
return $candidate !== false ? $candidate : null;
|
return $candidate !== false ? $candidate : null;
|
||||||
}
|
}
|
||||||
|
|
||||||
/**
|
|
||||||
* @return RepositorySet
|
|
||||||
*/
|
|
||||||
private function getRepositorySet(Composer $composer): RepositorySet
|
private function getRepositorySet(Composer $composer): RepositorySet
|
||||||
{
|
{
|
||||||
if (!$this->repositorySet) {
|
if (!$this->repositorySet) {
|
||||||
|
|
|
@ -37,7 +37,6 @@ class StatusCommand extends BaseCommand
|
||||||
private const EXIT_CODE_VERSION_CHANGES = 4;
|
private const EXIT_CODE_VERSION_CHANGES = 4;
|
||||||
|
|
||||||
/**
|
/**
|
||||||
* @return void
|
|
||||||
* @throws \Symfony\Component\Console\Exception\InvalidArgumentException
|
* @throws \Symfony\Component\Console\Exception\InvalidArgumentException
|
||||||
*/
|
*/
|
||||||
protected function configure(): void
|
protected function configure(): void
|
||||||
|
@ -45,9 +44,9 @@ class StatusCommand extends BaseCommand
|
||||||
$this
|
$this
|
||||||
->setName('status')
|
->setName('status')
|
||||||
->setDescription('Shows a list of locally modified packages')
|
->setDescription('Shows a list of locally modified packages')
|
||||||
->setDefinition(array(
|
->setDefinition([
|
||||||
new InputOption('verbose', 'v|vv|vvv', InputOption::VALUE_NONE, 'Show modified files for each directory that contains changes.'),
|
new InputOption('verbose', 'v|vv|vvv', InputOption::VALUE_NONE, 'Show modified files for each directory that contains changes.'),
|
||||||
))
|
])
|
||||||
->setHelp(
|
->setHelp(
|
||||||
<<<EOT
|
<<<EOT
|
||||||
The status command displays a list of dependencies that have
|
The status command displays a list of dependencies that have
|
||||||
|
@ -77,9 +76,6 @@ EOT
|
||||||
return $exitCode;
|
return $exitCode;
|
||||||
}
|
}
|
||||||
|
|
||||||
/**
|
|
||||||
* @return int
|
|
||||||
*/
|
|
||||||
private function doExecute(InputInterface $input): int
|
private function doExecute(InputInterface $input): int
|
||||||
{
|
{
|
||||||
// init repos
|
// init repos
|
||||||
|
@ -90,10 +86,10 @@ EOT
|
||||||
$dm = $composer->getDownloadManager();
|
$dm = $composer->getDownloadManager();
|
||||||
$im = $composer->getInstallationManager();
|
$im = $composer->getInstallationManager();
|
||||||
|
|
||||||
$errors = array();
|
$errors = [];
|
||||||
$io = $this->getIO();
|
$io = $this->getIO();
|
||||||
$unpushedChanges = array();
|
$unpushedChanges = [];
|
||||||
$vcsVersionChanges = array();
|
$vcsVersionChanges = [];
|
||||||
|
|
||||||
$parser = new VersionParser;
|
$parser = new VersionParser;
|
||||||
$guesser = new VersionGuesser($composer->getConfig(), $composer->getLoop()->getProcessExecutor() ?? new ProcessExecutor($io), $parser);
|
$guesser = new VersionGuesser($composer->getConfig(), $composer->getLoop()->getProcessExecutor() ?? new ProcessExecutor($io), $parser);
|
||||||
|
@ -130,16 +126,16 @@ EOT
|
||||||
$currentVersion = $guesser->guessVersion($dumper->dump($package), $targetDir);
|
$currentVersion = $guesser->guessVersion($dumper->dump($package), $targetDir);
|
||||||
|
|
||||||
if ($previousRef && $currentVersion && $currentVersion['commit'] !== $previousRef) {
|
if ($previousRef && $currentVersion && $currentVersion['commit'] !== $previousRef) {
|
||||||
$vcsVersionChanges[$targetDir] = array(
|
$vcsVersionChanges[$targetDir] = [
|
||||||
'previous' => array(
|
'previous' => [
|
||||||
'version' => $package->getPrettyVersion(),
|
'version' => $package->getPrettyVersion(),
|
||||||
'ref' => $previousRef,
|
'ref' => $previousRef,
|
||||||
),
|
],
|
||||||
'current' => array(
|
'current' => [
|
||||||
'version' => $currentVersion['pretty_version'],
|
'version' => $currentVersion['pretty_version'],
|
||||||
'ref' => $currentVersion['commit'],
|
'ref' => $currentVersion['commit'],
|
||||||
),
|
],
|
||||||
);
|
];
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
|
|
|
@ -25,22 +25,19 @@ class SuggestsCommand extends BaseCommand
|
||||||
{
|
{
|
||||||
use CompletionTrait;
|
use CompletionTrait;
|
||||||
|
|
||||||
/**
|
|
||||||
* @return void
|
|
||||||
*/
|
|
||||||
protected function configure(): void
|
protected function configure(): void
|
||||||
{
|
{
|
||||||
$this
|
$this
|
||||||
->setName('suggests')
|
->setName('suggests')
|
||||||
->setDescription('Shows package suggestions')
|
->setDescription('Shows package suggestions')
|
||||||
->setDefinition(array(
|
->setDefinition([
|
||||||
new InputOption('by-package', null, InputOption::VALUE_NONE, 'Groups output by suggesting package (default)'),
|
new InputOption('by-package', null, InputOption::VALUE_NONE, 'Groups output by suggesting package (default)'),
|
||||||
new InputOption('by-suggestion', null, InputOption::VALUE_NONE, 'Groups output by suggested package'),
|
new InputOption('by-suggestion', null, InputOption::VALUE_NONE, 'Groups output by suggested package'),
|
||||||
new InputOption('all', 'a', InputOption::VALUE_NONE, 'Show suggestions from all dependencies, including transitive ones'),
|
new InputOption('all', 'a', InputOption::VALUE_NONE, 'Show suggestions from all dependencies, including transitive ones'),
|
||||||
new InputOption('list', null, InputOption::VALUE_NONE, 'Show only list of suggested package names'),
|
new InputOption('list', null, InputOption::VALUE_NONE, 'Show only list of suggested package names'),
|
||||||
new InputOption('no-dev', null, InputOption::VALUE_NONE, 'Exclude suggestions from require-dev packages'),
|
new InputOption('no-dev', null, InputOption::VALUE_NONE, 'Exclude suggestions from require-dev packages'),
|
||||||
new InputArgument('packages', InputArgument::IS_ARRAY | InputArgument::OPTIONAL, 'Packages that you want to list suggestions from.', null, $this->suggestInstalledPackage()),
|
new InputArgument('packages', InputArgument::IS_ARRAY | InputArgument::OPTIONAL, 'Packages that you want to list suggestions from.', null, $this->suggestInstalledPackage()),
|
||||||
))
|
])
|
||||||
->setHelp(
|
->setHelp(
|
||||||
<<<EOT
|
<<<EOT
|
||||||
|
|
||||||
|
@ -56,16 +53,16 @@ EOT
|
||||||
{
|
{
|
||||||
$composer = $this->requireComposer();
|
$composer = $this->requireComposer();
|
||||||
|
|
||||||
$installedRepos = array(
|
$installedRepos = [
|
||||||
new RootPackageRepository(clone $composer->getPackage()),
|
new RootPackageRepository(clone $composer->getPackage()),
|
||||||
);
|
];
|
||||||
|
|
||||||
$locker = $composer->getLocker();
|
$locker = $composer->getLocker();
|
||||||
if ($locker->isLocked()) {
|
if ($locker->isLocked()) {
|
||||||
$installedRepos[] = new PlatformRepository(array(), $locker->getPlatformOverrides());
|
$installedRepos[] = new PlatformRepository([], $locker->getPlatformOverrides());
|
||||||
$installedRepos[] = $locker->getLockedRepository(!$input->getOption('no-dev'));
|
$installedRepos[] = $locker->getLockedRepository(!$input->getOption('no-dev'));
|
||||||
} else {
|
} else {
|
||||||
$installedRepos[] = new PlatformRepository(array(), $composer->getConfig()->get('platform'));
|
$installedRepos[] = new PlatformRepository([], $composer->getConfig()->get('platform'));
|
||||||
$installedRepos[] = $composer->getRepositoryManager()->getLocalRepository();
|
$installedRepos[] = $composer->getRepositoryManager()->getLocalRepository();
|
||||||
}
|
}
|
||||||
|
|
||||||
|
|
|
@ -21,10 +21,7 @@ use Composer\Pcre\Preg;
|
||||||
use Composer\Plugin\CommandEvent;
|
use Composer\Plugin\CommandEvent;
|
||||||
use Composer\Plugin\PluginEvents;
|
use Composer\Plugin\PluginEvents;
|
||||||
use Composer\Package\Version\VersionParser;
|
use Composer\Package\Version\VersionParser;
|
||||||
use Composer\Semver\Constraint\ConstraintInterface;
|
|
||||||
use Composer\Util\HttpDownloader;
|
use Composer\Util\HttpDownloader;
|
||||||
use Composer\Semver\Constraint\MultiConstraint;
|
|
||||||
use Composer\Package\Link;
|
|
||||||
use Composer\Advisory\Auditor;
|
use Composer\Advisory\Auditor;
|
||||||
use Symfony\Component\Console\Helper\Table;
|
use Symfony\Component\Console\Helper\Table;
|
||||||
use Symfony\Component\Console\Input\InputInterface;
|
use Symfony\Component\Console\Input\InputInterface;
|
||||||
|
@ -48,9 +45,9 @@ class UpdateCommand extends BaseCommand
|
||||||
{
|
{
|
||||||
$this
|
$this
|
||||||
->setName('update')
|
->setName('update')
|
||||||
->setAliases(array('u', 'upgrade'))
|
->setAliases(['u', 'upgrade'])
|
||||||
->setDescription('Updates your dependencies to the latest version according to composer.json, and updates the composer.lock file')
|
->setDescription('Updates your dependencies to the latest version according to composer.json, and updates the composer.lock file')
|
||||||
->setDefinition(array(
|
->setDefinition([
|
||||||
new InputArgument('packages', InputArgument::IS_ARRAY | InputArgument::OPTIONAL, 'Packages that should be updated, if not provided all packages are.', null, $this->suggestInstalledPackage(false)),
|
new InputArgument('packages', InputArgument::IS_ARRAY | InputArgument::OPTIONAL, 'Packages that should be updated, if not provided all packages are.', null, $this->suggestInstalledPackage(false)),
|
||||||
new InputOption('with', null, InputOption::VALUE_IS_ARRAY | InputOption::VALUE_REQUIRED, 'Temporary version constraint to add, e.g. foo/bar:1.0.0 or foo/bar=1.0.0'),
|
new InputOption('with', null, InputOption::VALUE_IS_ARRAY | InputOption::VALUE_REQUIRED, 'Temporary version constraint to add, e.g. foo/bar:1.0.0 or foo/bar=1.0.0'),
|
||||||
new InputOption('prefer-source', null, InputOption::VALUE_NONE, 'Forces installation from package sources when possible, including VCS information.'),
|
new InputOption('prefer-source', null, InputOption::VALUE_NONE, 'Forces installation from package sources when possible, including VCS information.'),
|
||||||
|
@ -79,7 +76,7 @@ class UpdateCommand extends BaseCommand
|
||||||
new InputOption('prefer-lowest', null, InputOption::VALUE_NONE, 'Prefer lowest versions of dependencies (can also be set via the COMPOSER_PREFER_LOWEST=1 env var).'),
|
new InputOption('prefer-lowest', null, InputOption::VALUE_NONE, 'Prefer lowest versions of dependencies (can also be set via the COMPOSER_PREFER_LOWEST=1 env var).'),
|
||||||
new InputOption('interactive', 'i', InputOption::VALUE_NONE, 'Interactive interface with autocompletion to select the packages to update.'),
|
new InputOption('interactive', 'i', InputOption::VALUE_NONE, 'Interactive interface with autocompletion to select the packages to update.'),
|
||||||
new InputOption('root-reqs', null, InputOption::VALUE_NONE, 'Restricts the update to your first degree dependencies.'),
|
new InputOption('root-reqs', null, InputOption::VALUE_NONE, 'Restricts the update to your first degree dependencies.'),
|
||||||
))
|
])
|
||||||
->setHelp(
|
->setHelp(
|
||||||
<<<EOT
|
<<<EOT
|
||||||
The <info>update</info> command reads the composer.json file from the
|
The <info>update</info> command reads the composer.json file from the
|
||||||
|
@ -180,7 +177,7 @@ EOT
|
||||||
// the arguments lock/nothing/mirrors are not package names but trigger a mirror update instead
|
// 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
|
// they are further mutually exclusive with listing actual package names
|
||||||
$filteredPackages = array_filter($packages, static function ($package): bool {
|
$filteredPackages = array_filter($packages, static function ($package): bool {
|
||||||
return !in_array($package, array('lock', 'nothing', 'mirrors'), true);
|
return !in_array($package, ['lock', 'nothing', 'mirrors'], true);
|
||||||
});
|
});
|
||||||
$updateMirrors = $input->getOption('lock') || count($filteredPackages) !== count($packages);
|
$updateMirrors = $input->getOption('lock') || count($filteredPackages) !== count($packages);
|
||||||
$packages = $filteredPackages;
|
$packages = $filteredPackages;
|
||||||
|
@ -199,7 +196,7 @@ EOT
|
||||||
$install = Installer::create($io, $composer);
|
$install = Installer::create($io, $composer);
|
||||||
|
|
||||||
$config = $composer->getConfig();
|
$config = $composer->getConfig();
|
||||||
list($preferSource, $preferDist) = $this->getPreferredInstallOptions($config, $input);
|
[$preferSource, $preferDist] = $this->getPreferredInstallOptions($config, $input);
|
||||||
|
|
||||||
$optimize = $input->getOption('optimize-autoloader') || $config->get('optimize-autoloader');
|
$optimize = $input->getOption('optimize-autoloader') || $config->get('optimize-autoloader');
|
||||||
$authoritative = $input->getOption('classmap-authoritative') || $config->get('classmap-authoritative');
|
$authoritative = $input->getOption('classmap-authoritative') || $config->get('classmap-authoritative');
|
||||||
|
@ -257,7 +254,7 @@ EOT
|
||||||
$composer->getPackage()->getRequires(),
|
$composer->getPackage()->getRequires(),
|
||||||
$composer->getPackage()->getDevRequires()
|
$composer->getPackage()->getDevRequires()
|
||||||
);
|
);
|
||||||
$autocompleterValues = array();
|
$autocompleterValues = [];
|
||||||
foreach ($requires as $require) {
|
foreach ($requires as $require) {
|
||||||
$target = $require->getTarget();
|
$target = $require->getTarget();
|
||||||
$autocompleterValues[strtolower($target)] = $target;
|
$autocompleterValues[strtolower($target)] = $target;
|
||||||
|
@ -294,9 +291,9 @@ EOT
|
||||||
}
|
}
|
||||||
|
|
||||||
$table = new Table($output);
|
$table = new Table($output);
|
||||||
$table->setHeaders(array('Selected packages'));
|
$table->setHeaders(['Selected packages']);
|
||||||
foreach ($packages as $package) {
|
foreach ($packages as $package) {
|
||||||
$table->addRow(array($package));
|
$table->addRow([$package]);
|
||||||
}
|
}
|
||||||
$table->render();
|
$table->render();
|
||||||
|
|
||||||
|
|
|
@ -36,14 +36,13 @@ class ValidateCommand extends BaseCommand
|
||||||
{
|
{
|
||||||
/**
|
/**
|
||||||
* configure
|
* configure
|
||||||
* @return void
|
|
||||||
*/
|
*/
|
||||||
protected function configure(): void
|
protected function configure(): void
|
||||||
{
|
{
|
||||||
$this
|
$this
|
||||||
->setName('validate')
|
->setName('validate')
|
||||||
->setDescription('Validates a composer.json and composer.lock')
|
->setDescription('Validates a composer.json and composer.lock')
|
||||||
->setDefinition(array(
|
->setDefinition([
|
||||||
new InputOption('no-check-all', null, InputOption::VALUE_NONE, 'Do not validate requires for overly strict/loose constraints'),
|
new InputOption('no-check-all', null, InputOption::VALUE_NONE, 'Do not validate requires for overly strict/loose constraints'),
|
||||||
new InputOption('check-lock', null, InputOption::VALUE_NONE, 'Check if lock file is up to date (even when config.lock is false)'),
|
new InputOption('check-lock', null, InputOption::VALUE_NONE, 'Check if lock file is up to date (even when config.lock is false)'),
|
||||||
new InputOption('no-check-lock', null, InputOption::VALUE_NONE, 'Do not check if lock file is up to date'),
|
new InputOption('no-check-lock', null, InputOption::VALUE_NONE, 'Do not check if lock file is up to date'),
|
||||||
|
@ -52,7 +51,7 @@ class ValidateCommand extends BaseCommand
|
||||||
new InputOption('with-dependencies', 'A', InputOption::VALUE_NONE, 'Also validate the composer.json of all installed dependencies'),
|
new InputOption('with-dependencies', 'A', InputOption::VALUE_NONE, 'Also validate the composer.json of all installed dependencies'),
|
||||||
new InputOption('strict', null, InputOption::VALUE_NONE, 'Return a non-zero exit code for warnings as well as errors'),
|
new InputOption('strict', null, InputOption::VALUE_NONE, 'Return a non-zero exit code for warnings as well as errors'),
|
||||||
new InputArgument('file', InputArgument::OPTIONAL, 'path to composer.json file'),
|
new InputArgument('file', InputArgument::OPTIONAL, 'path to composer.json file'),
|
||||||
))
|
])
|
||||||
->setHelp(
|
->setHelp(
|
||||||
<<<EOT
|
<<<EOT
|
||||||
The validate command validates a given composer.json and composer.lock
|
The validate command validates a given composer.json and composer.lock
|
||||||
|
@ -89,9 +88,9 @@ EOT
|
||||||
$checkLock = !$input->getOption('no-check-lock');
|
$checkLock = !$input->getOption('no-check-lock');
|
||||||
$checkVersion = $input->getOption('no-check-version') ? 0 : ConfigValidator::CHECK_VERSION;
|
$checkVersion = $input->getOption('no-check-version') ? 0 : ConfigValidator::CHECK_VERSION;
|
||||||
$isStrict = $input->getOption('strict');
|
$isStrict = $input->getOption('strict');
|
||||||
list($errors, $publishErrors, $warnings) = $validator->validate($file, $checkAll, $checkVersion);
|
[$errors, $publishErrors, $warnings] = $validator->validate($file, $checkAll, $checkVersion);
|
||||||
|
|
||||||
$lockErrors = array();
|
$lockErrors = [];
|
||||||
$composer = Factory::create($io, $file, $input->hasParameterOption('--no-plugins'));
|
$composer = Factory::create($io, $file, $input->hasParameterOption('--no-plugins'));
|
||||||
// config.lock = false ~= implicit --no-check-lock; --check-lock overrides
|
// config.lock = false ~= implicit --no-check-lock; --check-lock overrides
|
||||||
$checkLock = ($checkLock && $composer->getConfig()->get('lock')) || $input->getOption('check-lock');
|
$checkLock = ($checkLock && $composer->getConfig()->get('lock')) || $input->getOption('check-lock');
|
||||||
|
@ -102,14 +101,14 @@ EOT
|
||||||
|
|
||||||
if ($locker->isLocked()) {
|
if ($locker->isLocked()) {
|
||||||
$missingRequirements = false;
|
$missingRequirements = false;
|
||||||
$sets = array(
|
$sets = [
|
||||||
array('repo' => $locker->getLockedRepository(false), 'method' => 'getRequires', 'description' => 'Required'),
|
['repo' => $locker->getLockedRepository(false), 'method' => 'getRequires', 'description' => 'Required'],
|
||||||
array('repo' => $locker->getLockedRepository(true), 'method' => 'getDevRequires', 'description' => 'Required (in require-dev)'),
|
['repo' => $locker->getLockedRepository(true), 'method' => 'getDevRequires', 'description' => 'Required (in require-dev)'],
|
||||||
);
|
];
|
||||||
foreach ($sets as $set) {
|
foreach ($sets as $set) {
|
||||||
$installedRepo = new InstalledRepository(array($set['repo']));
|
$installedRepo = new InstalledRepository([$set['repo']]);
|
||||||
|
|
||||||
foreach (call_user_func(array($composer->getPackage(), $set['method'])) as $link) {
|
foreach (call_user_func([$composer->getPackage(), $set['method']]) as $link) {
|
||||||
if (PlatformRepository::isPlatformPackage($link->getTarget())) {
|
if (PlatformRepository::isPlatformPackage($link->getTarget())) {
|
||||||
continue;
|
continue;
|
||||||
}
|
}
|
||||||
|
@ -143,7 +142,7 @@ EOT
|
||||||
$path = $composer->getInstallationManager()->getInstallPath($package);
|
$path = $composer->getInstallationManager()->getInstallPath($package);
|
||||||
$file = $path . '/composer.json';
|
$file = $path . '/composer.json';
|
||||||
if (is_dir($path) && file_exists($file)) {
|
if (is_dir($path) && file_exists($file)) {
|
||||||
list($errors, $publishErrors, $warnings) = $validator->validate($file, $checkAll, $checkVersion);
|
[$errors, $publishErrors, $warnings] = $validator->validate($file, $checkAll, $checkVersion);
|
||||||
|
|
||||||
$this->outputResult($io, $package->getPrettyName(), $errors, $warnings, $checkPublish, $publishErrors);
|
$this->outputResult($io, $package->getPrettyName(), $errors, $warnings, $checkPublish, $publishErrors);
|
||||||
|
|
||||||
|
@ -161,18 +160,12 @@ EOT
|
||||||
}
|
}
|
||||||
|
|
||||||
/**
|
/**
|
||||||
* @param string $name
|
|
||||||
* @param string[] $errors
|
* @param string[] $errors
|
||||||
* @param string[] $warnings
|
* @param string[] $warnings
|
||||||
* @param bool $checkPublish
|
|
||||||
* @param string[] $publishErrors
|
* @param string[] $publishErrors
|
||||||
* @param bool $checkLock
|
|
||||||
* @param string[] $lockErrors
|
* @param string[] $lockErrors
|
||||||
* @param bool $printSchemaUrl
|
|
||||||
*
|
|
||||||
* @return void
|
|
||||||
*/
|
*/
|
||||||
private function outputResult(IOInterface $io, string $name, array &$errors, array &$warnings, bool $checkPublish = false, array $publishErrors = array(), bool $checkLock = false, array $lockErrors = array(), bool $printSchemaUrl = false): void
|
private function outputResult(IOInterface $io, string $name, array &$errors, array &$warnings, bool $checkPublish = false, array $publishErrors = [], bool $checkLock = false, array $lockErrors = [], bool $printSchemaUrl = false): void
|
||||||
{
|
{
|
||||||
$doPrintSchemaUrl = false;
|
$doPrintSchemaUrl = false;
|
||||||
|
|
||||||
|
@ -209,7 +202,7 @@ EOT
|
||||||
}
|
}
|
||||||
|
|
||||||
// Avoid setting the exit code to 1 in case --strict and --no-check-publish/--no-check-lock are combined
|
// Avoid setting the exit code to 1 in case --strict and --no-check-publish/--no-check-lock are combined
|
||||||
$extraWarnings = array();
|
$extraWarnings = [];
|
||||||
|
|
||||||
// If checking publish errors, display them as errors, otherwise just show them as warnings
|
// If checking publish errors, display them as errors, otherwise just show them as warnings
|
||||||
if ($publishErrors) {
|
if ($publishErrors) {
|
||||||
|
@ -237,10 +230,10 @@ EOT
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
|
|
||||||
$messages = array(
|
$messages = [
|
||||||
'error' => $errors,
|
'error' => $errors,
|
||||||
'warning' => array_merge($warnings, $extraWarnings),
|
'warning' => array_merge($warnings, $extraWarnings),
|
||||||
);
|
];
|
||||||
|
|
||||||
foreach ($messages as $style => $msgs) {
|
foreach ($messages as $style => $msgs) {
|
||||||
foreach ($msgs as $msg) {
|
foreach ($msgs as $msg) {
|
||||||
|
|
|
@ -40,7 +40,6 @@ class Compiler
|
||||||
*
|
*
|
||||||
* @param string $pharFile The full path to the file to create
|
* @param string $pharFile The full path to the file to create
|
||||||
*
|
*
|
||||||
* @return void
|
|
||||||
*
|
*
|
||||||
* @throws \RuntimeException
|
* @throws \RuntimeException
|
||||||
*/
|
*/
|
||||||
|
@ -50,13 +49,13 @@ class Compiler
|
||||||
unlink($pharFile);
|
unlink($pharFile);
|
||||||
}
|
}
|
||||||
|
|
||||||
$process = new Process(array('git', 'log', '--pretty=%H', '-n1', 'HEAD'), __DIR__);
|
$process = new Process(['git', 'log', '--pretty=%H', '-n1', 'HEAD'], __DIR__);
|
||||||
if ($process->run() !== 0) {
|
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.');
|
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());
|
$this->version = trim($process->getOutput());
|
||||||
|
|
||||||
$process = new Process(array('git', 'log', '-n1', '--pretty=%ci', 'HEAD'), __DIR__);
|
$process = new Process(['git', 'log', '-n1', '--pretty=%ci', 'HEAD'], __DIR__);
|
||||||
if ($process->run() !== 0) {
|
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.');
|
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.');
|
||||||
}
|
}
|
||||||
|
@ -64,7 +63,7 @@ class Compiler
|
||||||
$this->versionDate = new \DateTime(trim($process->getOutput()));
|
$this->versionDate = new \DateTime(trim($process->getOutput()));
|
||||||
$this->versionDate->setTimezone(new \DateTimeZone('UTC'));
|
$this->versionDate->setTimezone(new \DateTimeZone('UTC'));
|
||||||
|
|
||||||
$process = new Process(array('git', 'describe', '--tags', '--exact-match', 'HEAD'), __DIR__);
|
$process = new Process(['git', 'describe', '--tags', '--exact-match', 'HEAD'], __DIR__);
|
||||||
if ($process->run() === 0) {
|
if ($process->run() === 0) {
|
||||||
$this->version = trim($process->getOutput());
|
$this->version = trim($process->getOutput());
|
||||||
} else {
|
} else {
|
||||||
|
@ -132,19 +131,19 @@ class Compiler
|
||||||
;
|
;
|
||||||
|
|
||||||
$extraFiles = [];
|
$extraFiles = [];
|
||||||
foreach (array(
|
foreach ([
|
||||||
__DIR__ . '/../../vendor/composer/spdx-licenses/res/spdx-exceptions.json',
|
__DIR__ . '/../../vendor/composer/spdx-licenses/res/spdx-exceptions.json',
|
||||||
__DIR__ . '/../../vendor/composer/spdx-licenses/res/spdx-licenses.json',
|
__DIR__ . '/../../vendor/composer/spdx-licenses/res/spdx-licenses.json',
|
||||||
CaBundle::getBundledCaBundlePath(),
|
CaBundle::getBundledCaBundlePath(),
|
||||||
__DIR__ . '/../../vendor/symfony/console/Resources/bin/hiddeninput.exe',
|
__DIR__ . '/../../vendor/symfony/console/Resources/bin/hiddeninput.exe',
|
||||||
__DIR__ . '/../../vendor/symfony/console/Resources/completion.bash',
|
__DIR__ . '/../../vendor/symfony/console/Resources/completion.bash',
|
||||||
) as $file) {
|
] as $file) {
|
||||||
$extraFiles[$file] = realpath($file);
|
$extraFiles[$file] = realpath($file);
|
||||||
if (!file_exists($file)) {
|
if (!file_exists($file)) {
|
||||||
throw new \RuntimeException('Extra file listed is missing from the filesystem: '.$file);
|
throw new \RuntimeException('Extra file listed is missing from the filesystem: '.$file);
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
$unexpectedFiles = array();
|
$unexpectedFiles = [];
|
||||||
|
|
||||||
foreach ($finder as $file) {
|
foreach ($finder as $file) {
|
||||||
if (false !== ($index = array_search($file->getRealPath(), $extraFiles, true))) {
|
if (false !== ($index = array_search($file->getRealPath(), $extraFiles, true))) {
|
||||||
|
@ -197,10 +196,6 @@ class Compiler
|
||||||
]);
|
]);
|
||||||
}
|
}
|
||||||
|
|
||||||
/**
|
|
||||||
* @param \SplFileInfo $file
|
|
||||||
* @return string
|
|
||||||
*/
|
|
||||||
private function getRelativeFilePath(\SplFileInfo $file): string
|
private function getRelativeFilePath(\SplFileInfo $file): string
|
||||||
{
|
{
|
||||||
$realPath = $file->getRealPath();
|
$realPath = $file->getRealPath();
|
||||||
|
@ -212,11 +207,6 @@ class Compiler
|
||||||
return strtr($relativePath, '\\', '/');
|
return strtr($relativePath, '\\', '/');
|
||||||
}
|
}
|
||||||
|
|
||||||
/**
|
|
||||||
* @param bool $strip
|
|
||||||
*
|
|
||||||
* @return void
|
|
||||||
*/
|
|
||||||
private function addFile(\Phar $phar, \SplFileInfo $file, bool $strip = true): void
|
private function addFile(\Phar $phar, \SplFileInfo $file, bool $strip = true): void
|
||||||
{
|
{
|
||||||
$path = $this->getRelativeFilePath($file);
|
$path = $this->getRelativeFilePath($file);
|
||||||
|
@ -230,11 +220,11 @@ class Compiler
|
||||||
if ($path === 'src/Composer/Composer.php') {
|
if ($path === 'src/Composer/Composer.php') {
|
||||||
$content = strtr(
|
$content = strtr(
|
||||||
$content,
|
$content,
|
||||||
array(
|
[
|
||||||
'@package_version@' => $this->version,
|
'@package_version@' => $this->version,
|
||||||
'@package_branch_alias_version@' => $this->branchAliasVersion,
|
'@package_branch_alias_version@' => $this->branchAliasVersion,
|
||||||
'@release_date@' => $this->versionDate->format('Y-m-d H:i:s'),
|
'@release_date@' => $this->versionDate->format('Y-m-d H:i:s'),
|
||||||
)
|
]
|
||||||
);
|
);
|
||||||
$content = Preg::replace('{SOURCE_VERSION = \'[^\']+\';}', 'SOURCE_VERSION = \'\';', $content);
|
$content = Preg::replace('{SOURCE_VERSION = \'[^\']+\';}', 'SOURCE_VERSION = \'\';', $content);
|
||||||
}
|
}
|
||||||
|
@ -242,9 +232,6 @@ class Compiler
|
||||||
$phar->addFromString($path, $content);
|
$phar->addFromString($path, $content);
|
||||||
}
|
}
|
||||||
|
|
||||||
/**
|
|
||||||
* @return void
|
|
||||||
*/
|
|
||||||
private function addComposerBin(\Phar $phar): void
|
private function addComposerBin(\Phar $phar): void
|
||||||
{
|
{
|
||||||
$content = file_get_contents(__DIR__.'/../../bin/composer');
|
$content = file_get_contents(__DIR__.'/../../bin/composer');
|
||||||
|
@ -268,7 +255,7 @@ class Compiler
|
||||||
foreach (token_get_all($source) as $token) {
|
foreach (token_get_all($source) as $token) {
|
||||||
if (is_string($token)) {
|
if (is_string($token)) {
|
||||||
$output .= $token;
|
$output .= $token;
|
||||||
} elseif (in_array($token[0], array(T_COMMENT, T_DOC_COMMENT))) {
|
} elseif (in_array($token[0], [T_COMMENT, T_DOC_COMMENT])) {
|
||||||
$output .= str_repeat("\n", substr_count($token[1], "\n"));
|
$output .= str_repeat("\n", substr_count($token[1], "\n"));
|
||||||
} elseif (T_WHITESPACE === $token[0]) {
|
} elseif (T_WHITESPACE === $token[0]) {
|
||||||
// reduce wide spaces
|
// reduce wide spaces
|
||||||
|
@ -286,9 +273,6 @@ class Compiler
|
||||||
return $output;
|
return $output;
|
||||||
}
|
}
|
||||||
|
|
||||||
/**
|
|
||||||
* @return string
|
|
||||||
*/
|
|
||||||
private function getStub(): string
|
private function getStub(): string
|
||||||
{
|
{
|
||||||
$stub = <<<'EOF'
|
$stub = <<<'EOF'
|
||||||
|
|
|
@ -67,9 +67,6 @@ class Composer extends PartialComposer
|
||||||
*/
|
*/
|
||||||
public const RUNTIME_API_VERSION = '2.2.2';
|
public const RUNTIME_API_VERSION = '2.2.2';
|
||||||
|
|
||||||
/**
|
|
||||||
* @return string
|
|
||||||
*/
|
|
||||||
public static function getVersion(): string
|
public static function getVersion(): string
|
||||||
{
|
{
|
||||||
// no replacement done, this must be a source checkout
|
// no replacement done, this must be a source checkout
|
||||||
|
|
|
@ -31,14 +31,14 @@ class Config
|
||||||
public const RELATIVE_PATHS = 1;
|
public const RELATIVE_PATHS = 1;
|
||||||
|
|
||||||
/** @var array<string, mixed> */
|
/** @var array<string, mixed> */
|
||||||
public static $defaultConfig = array(
|
public static $defaultConfig = [
|
||||||
'process-timeout' => 300,
|
'process-timeout' => 300,
|
||||||
'use-include-path' => false,
|
'use-include-path' => false,
|
||||||
'allow-plugins' => array(),
|
'allow-plugins' => [],
|
||||||
'use-parent-dir' => 'prompt',
|
'use-parent-dir' => 'prompt',
|
||||||
'preferred-install' => 'dist',
|
'preferred-install' => 'dist',
|
||||||
'notify-on-install' => true,
|
'notify-on-install' => true,
|
||||||
'github-protocols' => array('https', 'ssh', 'git'),
|
'github-protocols' => ['https', 'ssh', 'git'],
|
||||||
'gitlab-protocol' => null,
|
'gitlab-protocol' => null,
|
||||||
'vendor-dir' => 'vendor',
|
'vendor-dir' => 'vendor',
|
||||||
'bin-dir' => '{$vendor-dir}/bin',
|
'bin-dir' => '{$vendor-dir}/bin',
|
||||||
|
@ -59,38 +59,38 @@ class Config
|
||||||
'classmap-authoritative' => false,
|
'classmap-authoritative' => false,
|
||||||
'apcu-autoloader' => false,
|
'apcu-autoloader' => false,
|
||||||
'prepend-autoloader' => true,
|
'prepend-autoloader' => true,
|
||||||
'github-domains' => array('github.com'),
|
'github-domains' => ['github.com'],
|
||||||
'bitbucket-expose-hostname' => true,
|
'bitbucket-expose-hostname' => true,
|
||||||
'disable-tls' => false,
|
'disable-tls' => false,
|
||||||
'secure-http' => true,
|
'secure-http' => true,
|
||||||
'secure-svn-domains' => array(),
|
'secure-svn-domains' => [],
|
||||||
'cafile' => null,
|
'cafile' => null,
|
||||||
'capath' => null,
|
'capath' => null,
|
||||||
'github-expose-hostname' => true,
|
'github-expose-hostname' => true,
|
||||||
'gitlab-domains' => array('gitlab.com'),
|
'gitlab-domains' => ['gitlab.com'],
|
||||||
'store-auths' => 'prompt',
|
'store-auths' => 'prompt',
|
||||||
'platform' => array(),
|
'platform' => [],
|
||||||
'archive-format' => 'tar',
|
'archive-format' => 'tar',
|
||||||
'archive-dir' => '.',
|
'archive-dir' => '.',
|
||||||
'htaccess-protect' => true,
|
'htaccess-protect' => true,
|
||||||
'use-github-api' => true,
|
'use-github-api' => true,
|
||||||
'lock' => true,
|
'lock' => true,
|
||||||
'platform-check' => 'php-only',
|
'platform-check' => 'php-only',
|
||||||
'bitbucket-oauth' => array(),
|
'bitbucket-oauth' => [],
|
||||||
'github-oauth' => array(),
|
'github-oauth' => [],
|
||||||
'gitlab-oauth' => array(),
|
'gitlab-oauth' => [],
|
||||||
'gitlab-token' => array(),
|
'gitlab-token' => [],
|
||||||
'http-basic' => array(),
|
'http-basic' => [],
|
||||||
'bearer' => array(),
|
'bearer' => [],
|
||||||
);
|
];
|
||||||
|
|
||||||
/** @var array<string, mixed> */
|
/** @var array<string, mixed> */
|
||||||
public static $defaultRepositories = array(
|
public static $defaultRepositories = [
|
||||||
'packagist.org' => array(
|
'packagist.org' => [
|
||||||
'type' => 'composer',
|
'type' => 'composer',
|
||||||
'url' => 'https://repo.packagist.org',
|
'url' => 'https://repo.packagist.org',
|
||||||
),
|
],
|
||||||
);
|
];
|
||||||
|
|
||||||
/** @var array<string, mixed> */
|
/** @var array<string, mixed> */
|
||||||
private $config;
|
private $config;
|
||||||
|
@ -105,11 +105,11 @@ class Config
|
||||||
/** @var bool */
|
/** @var bool */
|
||||||
private $useEnvironment;
|
private $useEnvironment;
|
||||||
/** @var array<string, true> */
|
/** @var array<string, true> */
|
||||||
private $warnedHosts = array();
|
private $warnedHosts = [];
|
||||||
/** @var array<string, true> */
|
/** @var array<string, true> */
|
||||||
private $sslVerifyWarnedHosts = array();
|
private $sslVerifyWarnedHosts = [];
|
||||||
/** @var array<string, string> */
|
/** @var array<string, string> */
|
||||||
private $sourceOfConfigValue = array();
|
private $sourceOfConfigValue = [];
|
||||||
|
|
||||||
/**
|
/**
|
||||||
* @param bool $useEnvironment Use COMPOSER_ environment variables to replace config settings
|
* @param bool $useEnvironment Use COMPOSER_ environment variables to replace config settings
|
||||||
|
@ -133,33 +133,21 @@ class Config
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
|
|
||||||
/**
|
|
||||||
* @return void
|
|
||||||
*/
|
|
||||||
public function setConfigSource(ConfigSourceInterface $source): void
|
public function setConfigSource(ConfigSourceInterface $source): void
|
||||||
{
|
{
|
||||||
$this->configSource = $source;
|
$this->configSource = $source;
|
||||||
}
|
}
|
||||||
|
|
||||||
/**
|
|
||||||
* @return ConfigSourceInterface
|
|
||||||
*/
|
|
||||||
public function getConfigSource(): ConfigSourceInterface
|
public function getConfigSource(): ConfigSourceInterface
|
||||||
{
|
{
|
||||||
return $this->configSource;
|
return $this->configSource;
|
||||||
}
|
}
|
||||||
|
|
||||||
/**
|
|
||||||
* @return void
|
|
||||||
*/
|
|
||||||
public function setAuthConfigSource(ConfigSourceInterface $source): void
|
public function setAuthConfigSource(ConfigSourceInterface $source): void
|
||||||
{
|
{
|
||||||
$this->authConfigSource = $source;
|
$this->authConfigSource = $source;
|
||||||
}
|
}
|
||||||
|
|
||||||
/**
|
|
||||||
* @return ConfigSourceInterface
|
|
||||||
*/
|
|
||||||
public function getAuthConfigSource(): ConfigSourceInterface
|
public function getAuthConfigSource(): ConfigSourceInterface
|
||||||
{
|
{
|
||||||
return $this->authConfigSource;
|
return $this->authConfigSource;
|
||||||
|
@ -169,33 +157,30 @@ class Config
|
||||||
* Merges new config values with the existing ones (overriding)
|
* Merges new config values with the existing ones (overriding)
|
||||||
*
|
*
|
||||||
* @param array{config?: array<string, mixed>, repositories?: array<mixed>} $config
|
* @param array{config?: array<string, mixed>, repositories?: array<mixed>} $config
|
||||||
* @param string $source
|
|
||||||
*
|
|
||||||
* @return void
|
|
||||||
*/
|
*/
|
||||||
public function merge(array $config, string $source = self::SOURCE_UNKNOWN): void
|
public function merge(array $config, string $source = self::SOURCE_UNKNOWN): void
|
||||||
{
|
{
|
||||||
// override defaults with given config
|
// override defaults with given config
|
||||||
if (!empty($config['config']) && is_array($config['config'])) {
|
if (!empty($config['config']) && is_array($config['config'])) {
|
||||||
foreach ($config['config'] as $key => $val) {
|
foreach ($config['config'] as $key => $val) {
|
||||||
if (in_array($key, array('bitbucket-oauth', 'github-oauth', 'gitlab-oauth', 'gitlab-token', 'http-basic', 'bearer'), true) && isset($this->config[$key])) {
|
if (in_array($key, ['bitbucket-oauth', 'github-oauth', 'gitlab-oauth', 'gitlab-token', 'http-basic', 'bearer'], true) && isset($this->config[$key])) {
|
||||||
$this->config[$key] = array_merge($this->config[$key], $val);
|
$this->config[$key] = array_merge($this->config[$key], $val);
|
||||||
$this->setSourceOfConfigValue($val, $key, $source);
|
$this->setSourceOfConfigValue($val, $key, $source);
|
||||||
} elseif (in_array($key, array('allow-plugins'), true) && isset($this->config[$key]) && is_array($this->config[$key]) && is_array($val)) {
|
} elseif (in_array($key, ['allow-plugins'], true) && isset($this->config[$key]) && is_array($this->config[$key]) && is_array($val)) {
|
||||||
// merging $val first to get the local config on top of the global one, then appending the global config,
|
// merging $val first to get the local config on top of the global one, then appending the global config,
|
||||||
// then merging local one again to make sure the values from local win over global ones for keys present in both
|
// then merging local one again to make sure the values from local win over global ones for keys present in both
|
||||||
$this->config[$key] = array_merge($val, $this->config[$key], $val);
|
$this->config[$key] = array_merge($val, $this->config[$key], $val);
|
||||||
$this->setSourceOfConfigValue($val, $key, $source);
|
$this->setSourceOfConfigValue($val, $key, $source);
|
||||||
} elseif (in_array($key, array('gitlab-domains', 'github-domains'), true) && isset($this->config[$key])) {
|
} elseif (in_array($key, ['gitlab-domains', 'github-domains'], true) && isset($this->config[$key])) {
|
||||||
$this->config[$key] = array_unique(array_merge($this->config[$key], $val));
|
$this->config[$key] = array_unique(array_merge($this->config[$key], $val));
|
||||||
$this->setSourceOfConfigValue($val, $key, $source);
|
$this->setSourceOfConfigValue($val, $key, $source);
|
||||||
} elseif ('preferred-install' === $key && isset($this->config[$key])) {
|
} elseif ('preferred-install' === $key && isset($this->config[$key])) {
|
||||||
if (is_array($val) || is_array($this->config[$key])) {
|
if (is_array($val) || is_array($this->config[$key])) {
|
||||||
if (is_string($val)) {
|
if (is_string($val)) {
|
||||||
$val = array('*' => $val);
|
$val = ['*' => $val];
|
||||||
}
|
}
|
||||||
if (is_string($this->config[$key])) {
|
if (is_string($this->config[$key])) {
|
||||||
$this->config[$key] = array('*' => $this->config[$key]);
|
$this->config[$key] = ['*' => $this->config[$key]];
|
||||||
$this->sourceOfConfigValue[$key . '*'] = $source;
|
$this->sourceOfConfigValue[$key . '*'] = $source;
|
||||||
}
|
}
|
||||||
$this->config[$key] = array_merge($this->config[$key], $val);
|
$this->config[$key] = array_merge($this->config[$key], $val);
|
||||||
|
@ -267,7 +252,6 @@ class Config
|
||||||
/**
|
/**
|
||||||
* Returns a setting
|
* Returns a setting
|
||||||
*
|
*
|
||||||
* @param string $key
|
|
||||||
* @param int $flags Options (see class constants)
|
* @param int $flags Options (see class constants)
|
||||||
* @throws \RuntimeException
|
* @throws \RuntimeException
|
||||||
*
|
*
|
||||||
|
@ -379,7 +363,7 @@ class Config
|
||||||
case 'bin-compat':
|
case 'bin-compat':
|
||||||
$value = $this->getComposerEnv('COMPOSER_BIN_COMPAT') ?: $this->config[$key];
|
$value = $this->getComposerEnv('COMPOSER_BIN_COMPAT') ?: $this->config[$key];
|
||||||
|
|
||||||
if (!in_array($value, array('auto', 'full', 'proxy', 'symlink'))) {
|
if (!in_array($value, ['auto', 'full', 'proxy', 'symlink'])) {
|
||||||
throw new \RuntimeException(
|
throw new \RuntimeException(
|
||||||
"Invalid value for 'bin-compat': {$value}. Expected auto, full or proxy"
|
"Invalid value for 'bin-compat': {$value}. Expected auto, full or proxy"
|
||||||
);
|
);
|
||||||
|
@ -393,7 +377,7 @@ class Config
|
||||||
|
|
||||||
case 'discard-changes':
|
case 'discard-changes':
|
||||||
if ($env = $this->getComposerEnv('COMPOSER_DISCARD_CHANGES')) {
|
if ($env = $this->getComposerEnv('COMPOSER_DISCARD_CHANGES')) {
|
||||||
if (!in_array($env, array('stash', 'true', 'false', '1', '0'), true)) {
|
if (!in_array($env, ['stash', 'true', 'false', '1', '0'], true)) {
|
||||||
throw new \RuntimeException(
|
throw new \RuntimeException(
|
||||||
"Invalid value for COMPOSER_DISCARD_CHANGES: {$env}. Expected 1, 0, true, false or stash"
|
"Invalid value for COMPOSER_DISCARD_CHANGES: {$env}. Expected 1, 0, true, false or stash"
|
||||||
);
|
);
|
||||||
|
@ -406,7 +390,7 @@ class Config
|
||||||
return $env !== 'false' && (bool) $env;
|
return $env !== 'false' && (bool) $env;
|
||||||
}
|
}
|
||||||
|
|
||||||
if (!in_array($this->config[$key], array(true, false, 'stash'), true)) {
|
if (!in_array($this->config[$key], [true, false, 'stash'], true)) {
|
||||||
throw new \RuntimeException(
|
throw new \RuntimeException(
|
||||||
"Invalid value for 'discard-changes': {$this->config[$key]}. Expected true, false or stash"
|
"Invalid value for 'discard-changes': {$this->config[$key]}. Expected true, false or stash"
|
||||||
);
|
);
|
||||||
|
@ -442,15 +426,13 @@ class Config
|
||||||
}
|
}
|
||||||
|
|
||||||
/**
|
/**
|
||||||
* @param int $flags
|
|
||||||
*
|
|
||||||
* @return array<string, mixed[]>
|
* @return array<string, mixed[]>
|
||||||
*/
|
*/
|
||||||
public function all(int $flags = 0): array
|
public function all(int $flags = 0): array
|
||||||
{
|
{
|
||||||
$all = array(
|
$all = [
|
||||||
'repositories' => $this->getRepositories(),
|
'repositories' => $this->getRepositories(),
|
||||||
);
|
];
|
||||||
foreach (array_keys($this->config) as $key) {
|
foreach (array_keys($this->config) as $key) {
|
||||||
$all['config'][$key] = $this->get($key, $flags);
|
$all['config'][$key] = $this->get($key, $flags);
|
||||||
}
|
}
|
||||||
|
@ -458,10 +440,6 @@ class Config
|
||||||
return $all;
|
return $all;
|
||||||
}
|
}
|
||||||
|
|
||||||
/**
|
|
||||||
* @param string $key
|
|
||||||
* @return string
|
|
||||||
*/
|
|
||||||
public function getSourceOfValue(string $key): string
|
public function getSourceOfValue(string $key): string
|
||||||
{
|
{
|
||||||
$this->get($key);
|
$this->get($key);
|
||||||
|
@ -471,10 +449,6 @@ class Config
|
||||||
|
|
||||||
/**
|
/**
|
||||||
* @param mixed $configValue
|
* @param mixed $configValue
|
||||||
* @param string $path
|
|
||||||
* @param string $source
|
|
||||||
*
|
|
||||||
* @return void
|
|
||||||
*/
|
*/
|
||||||
private function setSourceOfConfigValue($configValue, string $path, string $source): void
|
private function setSourceOfConfigValue($configValue, string $path, string $source): void
|
||||||
{
|
{
|
||||||
|
@ -492,17 +466,14 @@ class Config
|
||||||
*/
|
*/
|
||||||
public function raw(): array
|
public function raw(): array
|
||||||
{
|
{
|
||||||
return array(
|
return [
|
||||||
'repositories' => $this->getRepositories(),
|
'repositories' => $this->getRepositories(),
|
||||||
'config' => $this->config,
|
'config' => $this->config,
|
||||||
);
|
];
|
||||||
}
|
}
|
||||||
|
|
||||||
/**
|
/**
|
||||||
* Checks whether a setting exists
|
* Checks whether a setting exists
|
||||||
*
|
|
||||||
* @param string $key
|
|
||||||
* @return bool
|
|
||||||
*/
|
*/
|
||||||
public function has(string $key): bool
|
public function has(string $key): bool
|
||||||
{
|
{
|
||||||
|
@ -532,9 +503,6 @@ class Config
|
||||||
* Turns relative paths in absolute paths without realpath()
|
* Turns relative paths in absolute paths without realpath()
|
||||||
*
|
*
|
||||||
* Since the dirs might not exist yet we can not call realpath or it will fail.
|
* Since the dirs might not exist yet we can not call realpath or it will fail.
|
||||||
*
|
|
||||||
* @param string $path
|
|
||||||
* @return string
|
|
||||||
*/
|
*/
|
||||||
private function realpath(string $path): string
|
private function realpath(string $path): string
|
||||||
{
|
{
|
||||||
|
@ -551,7 +519,6 @@ class Config
|
||||||
* This should be used to read COMPOSER_ environment variables
|
* This should be used to read COMPOSER_ environment variables
|
||||||
* that overload config values.
|
* that overload config values.
|
||||||
*
|
*
|
||||||
* @param string $var
|
|
||||||
* @return string|bool
|
* @return string|bool
|
||||||
*/
|
*/
|
||||||
private function getComposerEnv(string $var)
|
private function getComposerEnv(string $var)
|
||||||
|
@ -563,11 +530,6 @@ class Config
|
||||||
return false;
|
return false;
|
||||||
}
|
}
|
||||||
|
|
||||||
/**
|
|
||||||
* @param string $name
|
|
||||||
*
|
|
||||||
* @return void
|
|
||||||
*/
|
|
||||||
private function disableRepoByName(string $name): void
|
private function disableRepoByName(string $name): void
|
||||||
{
|
{
|
||||||
if (isset($this->repositories[$name])) {
|
if (isset($this->repositories[$name])) {
|
||||||
|
@ -580,13 +542,10 @@ class Config
|
||||||
/**
|
/**
|
||||||
* Validates that the passed URL is allowed to be used by current config, or throws an exception.
|
* Validates that the passed URL is allowed to be used by current config, or throws an exception.
|
||||||
*
|
*
|
||||||
* @param string $url
|
|
||||||
* @param IOInterface $io
|
* @param IOInterface $io
|
||||||
* @param mixed[] $repoOptions
|
* @param mixed[] $repoOptions
|
||||||
*
|
|
||||||
* @return void
|
|
||||||
*/
|
*/
|
||||||
public function prohibitUrlByConfig(string $url, IOInterface $io = null, array $repoOptions = []): void
|
public function prohibitUrlByConfig(string $url, ?IOInterface $io = null, array $repoOptions = []): void
|
||||||
{
|
{
|
||||||
// Return right away if the URL is malformed or custom (see issue #5173)
|
// Return right away if the URL is malformed or custom (see issue #5173)
|
||||||
if (false === filter_var($url, FILTER_VALIDATE_URL)) {
|
if (false === filter_var($url, FILTER_VALIDATE_URL)) {
|
||||||
|
@ -596,7 +555,7 @@ class Config
|
||||||
// Extract scheme and throw exception on known insecure protocols
|
// Extract scheme and throw exception on known insecure protocols
|
||||||
$scheme = parse_url($url, PHP_URL_SCHEME);
|
$scheme = parse_url($url, PHP_URL_SCHEME);
|
||||||
$hostname = parse_url($url, PHP_URL_HOST);
|
$hostname = parse_url($url, PHP_URL_HOST);
|
||||||
if (in_array($scheme, array('http', 'git', 'ftp', 'svn'))) {
|
if (in_array($scheme, ['http', 'git', 'ftp', 'svn'])) {
|
||||||
if ($this->get('secure-http')) {
|
if ($this->get('secure-http')) {
|
||||||
if ($scheme === 'svn') {
|
if ($scheme === 'svn') {
|
||||||
if (in_array($hostname, $this->get('secure-svn-domains'), true)) {
|
if (in_array($hostname, $this->get('secure-svn-domains'), true)) {
|
||||||
|
@ -608,7 +567,7 @@ class Config
|
||||||
|
|
||||||
throw new TransportException("Your configuration does not allow connections to $url. See https://getcomposer.org/doc/06-config.md#secure-http for details.");
|
throw new TransportException("Your configuration does not allow connections to $url. See https://getcomposer.org/doc/06-config.md#secure-http for details.");
|
||||||
}
|
}
|
||||||
if ($io !== null) {
|
if ($io !== null) {
|
||||||
if (is_string($hostname)) {
|
if (is_string($hostname)) {
|
||||||
if (!isset($this->warnedHosts[$hostname])) {
|
if (!isset($this->warnedHosts[$hostname])) {
|
||||||
$io->writeError("<warning>Warning: Accessing $hostname over $scheme which is an insecure protocol.</warning>");
|
$io->writeError("<warning>Warning: Accessing $hostname over $scheme which is an insecure protocol.</warning>");
|
||||||
|
@ -644,8 +603,6 @@ class Config
|
||||||
* "vendor/bin/long-running-script --watch"
|
* "vendor/bin/long-running-script --watch"
|
||||||
* ]
|
* ]
|
||||||
* }
|
* }
|
||||||
*
|
|
||||||
* @return void
|
|
||||||
*/
|
*/
|
||||||
public static function disableProcessTimeout(): void
|
public static function disableProcessTimeout(): void
|
||||||
{
|
{
|
||||||
|
|
|
@ -26,17 +26,11 @@ interface ConfigSourceInterface
|
||||||
* @param string $name Name
|
* @param string $name Name
|
||||||
* @param mixed[]|false $config Configuration
|
* @param mixed[]|false $config Configuration
|
||||||
* @param bool $append Whether the repo should be appended (true) or prepended (false)
|
* @param bool $append Whether the repo should be appended (true) or prepended (false)
|
||||||
*
|
|
||||||
* @return void
|
|
||||||
*/
|
*/
|
||||||
public function addRepository(string $name, $config, bool $append = true): void;
|
public function addRepository(string $name, $config, bool $append = true): void;
|
||||||
|
|
||||||
/**
|
/**
|
||||||
* Remove a repository
|
* Remove a repository
|
||||||
*
|
|
||||||
* @param string $name
|
|
||||||
*
|
|
||||||
* @return void
|
|
||||||
*/
|
*/
|
||||||
public function removeRepository(string $name): void;
|
public function removeRepository(string $name): void;
|
||||||
|
|
||||||
|
@ -45,17 +39,11 @@ interface ConfigSourceInterface
|
||||||
*
|
*
|
||||||
* @param string $name Name
|
* @param string $name Name
|
||||||
* @param mixed $value Value
|
* @param mixed $value Value
|
||||||
*
|
|
||||||
* @return void
|
|
||||||
*/
|
*/
|
||||||
public function addConfigSetting(string $name, $value): void;
|
public function addConfigSetting(string $name, $value): void;
|
||||||
|
|
||||||
/**
|
/**
|
||||||
* Remove a config setting
|
* Remove a config setting
|
||||||
*
|
|
||||||
* @param string $name
|
|
||||||
*
|
|
||||||
* @return void
|
|
||||||
*/
|
*/
|
||||||
public function removeConfigSetting(string $name): void;
|
public function removeConfigSetting(string $name): void;
|
||||||
|
|
||||||
|
@ -64,17 +52,11 @@ interface ConfigSourceInterface
|
||||||
*
|
*
|
||||||
* @param string $name Name
|
* @param string $name Name
|
||||||
* @param string|string[] $value Value
|
* @param string|string[] $value Value
|
||||||
*
|
|
||||||
* @return void
|
|
||||||
*/
|
*/
|
||||||
public function addProperty(string $name, $value): void;
|
public function addProperty(string $name, $value): void;
|
||||||
|
|
||||||
/**
|
/**
|
||||||
* Remove a property
|
* Remove a property
|
||||||
*
|
|
||||||
* @param string $name
|
|
||||||
*
|
|
||||||
* @return void
|
|
||||||
*/
|
*/
|
||||||
public function removeProperty(string $name): void;
|
public function removeProperty(string $name): void;
|
||||||
|
|
||||||
|
@ -84,8 +66,6 @@ interface ConfigSourceInterface
|
||||||
* @param string $type Type (require, require-dev, provide, suggest, replace, conflict)
|
* @param string $type Type (require, require-dev, provide, suggest, replace, conflict)
|
||||||
* @param string $name Name
|
* @param string $name Name
|
||||||
* @param string $value Value
|
* @param string $value Value
|
||||||
*
|
|
||||||
* @return void
|
|
||||||
*/
|
*/
|
||||||
public function addLink(string $type, string $name, string $value): void;
|
public function addLink(string $type, string $name, string $value): void;
|
||||||
|
|
||||||
|
@ -94,15 +74,11 @@ interface ConfigSourceInterface
|
||||||
*
|
*
|
||||||
* @param string $type Type (require, require-dev, provide, suggest, replace, conflict)
|
* @param string $type Type (require, require-dev, provide, suggest, replace, conflict)
|
||||||
* @param string $name Name
|
* @param string $name Name
|
||||||
*
|
|
||||||
* @return void
|
|
||||||
*/
|
*/
|
||||||
public function removeLink(string $type, string $name): void;
|
public function removeLink(string $type, string $name): void;
|
||||||
|
|
||||||
/**
|
/**
|
||||||
* Gives a user-friendly name to this source (file path or so)
|
* Gives a user-friendly name to this source (file path or so)
|
||||||
*
|
|
||||||
* @return string
|
|
||||||
*/
|
*/
|
||||||
public function getName(): string;
|
public function getName(): string;
|
||||||
}
|
}
|
||||||
|
|
|
@ -39,9 +39,6 @@ class JsonConfigSource implements ConfigSourceInterface
|
||||||
|
|
||||||
/**
|
/**
|
||||||
* Constructor
|
* Constructor
|
||||||
*
|
|
||||||
* @param JsonFile $file
|
|
||||||
* @param bool $authConfig
|
|
||||||
*/
|
*/
|
||||||
public function __construct(JsonFile $file, bool $authConfig = false)
|
public function __construct(JsonFile $file, bool $authConfig = false)
|
||||||
{
|
{
|
||||||
|
@ -70,7 +67,7 @@ class JsonConfigSource implements ConfigSourceInterface
|
||||||
if ($index === $repo) {
|
if ($index === $repo) {
|
||||||
continue;
|
continue;
|
||||||
}
|
}
|
||||||
if (is_numeric($index) && ($val === array('packagist' => false) || $val === array('packagist.org' => false))) {
|
if (is_numeric($index) && ($val === ['packagist' => false] || $val === ['packagist.org' => false])) {
|
||||||
unset($config['repositories'][$index]);
|
unset($config['repositories'][$index]);
|
||||||
$config['repositories']['packagist.org'] = false;
|
$config['repositories']['packagist.org'] = false;
|
||||||
break;
|
break;
|
||||||
|
@ -81,7 +78,7 @@ class JsonConfigSource implements ConfigSourceInterface
|
||||||
if ($append) {
|
if ($append) {
|
||||||
$config['repositories'][$repo] = $repoConfig;
|
$config['repositories'][$repo] = $repoConfig;
|
||||||
} else {
|
} else {
|
||||||
$config['repositories'] = array($repo => $repoConfig) + $config['repositories'];
|
$config['repositories'] = [$repo => $repoConfig] + $config['repositories'];
|
||||||
}
|
}
|
||||||
}, $name, $config, $append);
|
}, $name, $config, $append);
|
||||||
}
|
}
|
||||||
|
@ -104,7 +101,7 @@ class JsonConfigSource implements ConfigSourceInterface
|
||||||
$authConfig = $this->authConfig;
|
$authConfig = $this->authConfig;
|
||||||
$this->manipulateJson('addConfigSetting', static function (&$config, $key, $val) use ($authConfig): void {
|
$this->manipulateJson('addConfigSetting', static function (&$config, $key, $val) use ($authConfig): void {
|
||||||
if (Preg::isMatch('{^(bitbucket-oauth|github-oauth|gitlab-oauth|gitlab-token|bearer|http-basic|platform)\.}', $key)) {
|
if (Preg::isMatch('{^(bitbucket-oauth|github-oauth|gitlab-oauth|gitlab-token|bearer|http-basic|platform)\.}', $key)) {
|
||||||
list($key, $host) = explode('.', $key, 2);
|
[$key, $host] = explode('.', $key, 2);
|
||||||
if ($authConfig) {
|
if ($authConfig) {
|
||||||
$config[$key][$host] = $val;
|
$config[$key][$host] = $val;
|
||||||
} else {
|
} else {
|
||||||
|
@ -124,7 +121,7 @@ class JsonConfigSource implements ConfigSourceInterface
|
||||||
$authConfig = $this->authConfig;
|
$authConfig = $this->authConfig;
|
||||||
$this->manipulateJson('removeConfigSetting', static function (&$config, $key) use ($authConfig): void {
|
$this->manipulateJson('removeConfigSetting', static function (&$config, $key) use ($authConfig): void {
|
||||||
if (Preg::isMatch('{^(bitbucket-oauth|github-oauth|gitlab-oauth|gitlab-token|bearer|http-basic|platform)\.}', $key)) {
|
if (Preg::isMatch('{^(bitbucket-oauth|github-oauth|gitlab-oauth|gitlab-token|bearer|http-basic|platform)\.}', $key)) {
|
||||||
list($key, $host) = explode('.', $key, 2);
|
[$key, $host] = explode('.', $key, 2);
|
||||||
if ($authConfig) {
|
if ($authConfig) {
|
||||||
unset($config[$key][$host]);
|
unset($config[$key][$host]);
|
||||||
} else {
|
} else {
|
||||||
|
@ -148,7 +145,7 @@ class JsonConfigSource implements ConfigSourceInterface
|
||||||
$arr = &$config[reset($bits)];
|
$arr = &$config[reset($bits)];
|
||||||
foreach ($bits as $bit) {
|
foreach ($bits as $bit) {
|
||||||
if (!isset($arr[$bit])) {
|
if (!isset($arr[$bit])) {
|
||||||
$arr[$bit] = array();
|
$arr[$bit] = [];
|
||||||
}
|
}
|
||||||
$arr = &$arr[$bit];
|
$arr = &$arr[$bit];
|
||||||
}
|
}
|
||||||
|
@ -208,11 +205,7 @@ class JsonConfigSource implements ConfigSourceInterface
|
||||||
}
|
}
|
||||||
|
|
||||||
/**
|
/**
|
||||||
* @param string $method
|
|
||||||
* @param callable $fallback
|
|
||||||
* @param mixed ...$args
|
* @param mixed ...$args
|
||||||
*
|
|
||||||
* @return void
|
|
||||||
*/
|
*/
|
||||||
private function manipulateJson(string $method, callable $fallback, ...$args): void
|
private function manipulateJson(string $method, callable $fallback, ...$args): void
|
||||||
{
|
{
|
||||||
|
@ -239,38 +232,38 @@ class JsonConfigSource implements ConfigSourceInterface
|
||||||
// override manipulator method for auth config files
|
// override manipulator method for auth config files
|
||||||
if ($this->authConfig && $method === 'addConfigSetting') {
|
if ($this->authConfig && $method === 'addConfigSetting') {
|
||||||
$method = 'addSubNode';
|
$method = 'addSubNode';
|
||||||
list($mainNode, $name) = explode('.', $args[0], 2);
|
[$mainNode, $name] = explode('.', $args[0], 2);
|
||||||
$args = array($mainNode, $name, $args[1]);
|
$args = [$mainNode, $name, $args[1]];
|
||||||
} elseif ($this->authConfig && $method === 'removeConfigSetting') {
|
} elseif ($this->authConfig && $method === 'removeConfigSetting') {
|
||||||
$method = 'removeSubNode';
|
$method = 'removeSubNode';
|
||||||
list($mainNode, $name) = explode('.', $args[0], 2);
|
[$mainNode, $name] = explode('.', $args[0], 2);
|
||||||
$args = array($mainNode, $name);
|
$args = [$mainNode, $name];
|
||||||
}
|
}
|
||||||
|
|
||||||
// try to update cleanly
|
// try to update cleanly
|
||||||
if (call_user_func_array(array($manipulator, $method), $args)) {
|
if (call_user_func_array([$manipulator, $method], $args)) {
|
||||||
file_put_contents($this->file->getPath(), $manipulator->getContents());
|
file_put_contents($this->file->getPath(), $manipulator->getContents());
|
||||||
} else {
|
} else {
|
||||||
// on failed clean update, call the fallback and rewrite the whole file
|
// on failed clean update, call the fallback and rewrite the whole file
|
||||||
$config = $this->file->read();
|
$config = $this->file->read();
|
||||||
$this->arrayUnshiftRef($args, $config);
|
$this->arrayUnshiftRef($args, $config);
|
||||||
call_user_func_array($fallback, $args);
|
$fallback(...$args);
|
||||||
// avoid ending up with arrays for keys that should be objects
|
// avoid ending up with arrays for keys that should be objects
|
||||||
foreach (array('require', 'require-dev', 'conflict', 'provide', 'replace', 'suggest', 'config', 'autoload', 'autoload-dev', 'scripts', 'scripts-descriptions', 'support') as $prop) {
|
foreach (['require', 'require-dev', 'conflict', 'provide', 'replace', 'suggest', 'config', 'autoload', 'autoload-dev', 'scripts', 'scripts-descriptions', 'support'] as $prop) {
|
||||||
if (isset($config[$prop]) && $config[$prop] === array()) {
|
if (isset($config[$prop]) && $config[$prop] === []) {
|
||||||
$config[$prop] = new \stdClass;
|
$config[$prop] = new \stdClass;
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
foreach (array('psr-0', 'psr-4') as $prop) {
|
foreach (['psr-0', 'psr-4'] as $prop) {
|
||||||
if (isset($config['autoload'][$prop]) && $config['autoload'][$prop] === array()) {
|
if (isset($config['autoload'][$prop]) && $config['autoload'][$prop] === []) {
|
||||||
$config['autoload'][$prop] = new \stdClass;
|
$config['autoload'][$prop] = new \stdClass;
|
||||||
}
|
}
|
||||||
if (isset($config['autoload-dev'][$prop]) && $config['autoload-dev'][$prop] === array()) {
|
if (isset($config['autoload-dev'][$prop]) && $config['autoload-dev'][$prop] === []) {
|
||||||
$config['autoload-dev'][$prop] = new \stdClass;
|
$config['autoload-dev'][$prop] = new \stdClass;
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
foreach (array('platform', 'http-basic', 'bearer', 'gitlab-token', 'gitlab-oauth', 'github-oauth', 'preferred-install') as $prop) {
|
foreach (['platform', 'http-basic', 'bearer', 'gitlab-token', 'gitlab-oauth', 'github-oauth', 'preferred-install'] as $prop) {
|
||||||
if (isset($config['config'][$prop]) && $config['config'][$prop] === array()) {
|
if (isset($config['config'][$prop]) && $config['config'][$prop] === []) {
|
||||||
$config['config'][$prop] = new \stdClass;
|
$config['config'][$prop] = new \stdClass;
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
|
@ -295,7 +288,6 @@ class JsonConfigSource implements ConfigSourceInterface
|
||||||
*
|
*
|
||||||
* @param mixed[] $array
|
* @param mixed[] $array
|
||||||
* @param mixed $value
|
* @param mixed $value
|
||||||
* @return int
|
|
||||||
*/
|
*/
|
||||||
private function arrayUnshiftRef(array &$array, &$value): int
|
private function arrayUnshiftRef(array &$array, &$value): int
|
||||||
{
|
{
|
||||||
|
|
|
@ -129,7 +129,7 @@ class Application extends BaseApplication
|
||||||
$this->signalHandler->unregister();
|
$this->signalHandler->unregister();
|
||||||
}
|
}
|
||||||
|
|
||||||
public function run(InputInterface $input = null, OutputInterface $output = null): int
|
public function run(?InputInterface $input = null, ?OutputInterface $output = null): int
|
||||||
{
|
{
|
||||||
if (null === $output) {
|
if (null === $output) {
|
||||||
$output = Factory::createOutput();
|
$output = Factory::createOutput();
|
||||||
|
@ -148,9 +148,9 @@ class Application extends BaseApplication
|
||||||
$input->setInteractive(false);
|
$input->setInteractive(false);
|
||||||
}
|
}
|
||||||
|
|
||||||
$io = $this->io = new ConsoleIO($input, $output, new HelperSet(array(
|
$io = $this->io = new ConsoleIO($input, $output, new HelperSet([
|
||||||
new QuestionHelper(),
|
new QuestionHelper(),
|
||||||
)));
|
]));
|
||||||
|
|
||||||
// Register error handler again to pass it the IO instance
|
// Register error handler again to pass it the IO instance
|
||||||
ErrorHandler::register($io);
|
ErrorHandler::register($io);
|
||||||
|
@ -183,7 +183,7 @@ class Application extends BaseApplication
|
||||||
}
|
}
|
||||||
|
|
||||||
// prompt user for dir change if no composer.json is present in current dir
|
// prompt user for dir change if no composer.json is present in current dir
|
||||||
if ($io->isInteractive() && null === $newWorkDir && !in_array($commandName, array('', 'list', 'init', 'about', 'help', 'diagnose', 'self-update', 'global', 'create-project', 'outdated'), true) && !file_exists(Factory::getComposerFile()) && ($useParentDirIfNoJsonAvailable = $this->getUseParentDirConfigValue()) !== false) {
|
if ($io->isInteractive() && null === $newWorkDir && !in_array($commandName, ['', 'list', 'init', 'about', 'help', 'diagnose', 'self-update', 'global', 'create-project', 'outdated'], true) && !file_exists(Factory::getComposerFile()) && ($useParentDirIfNoJsonAvailable = $this->getUseParentDirConfigValue()) !== false) {
|
||||||
$dir = dirname(Platform::getCwd(true));
|
$dir = dirname(Platform::getCwd(true));
|
||||||
$home = realpath(Platform::getEnv('HOME') ?: Platform::getEnv('USERPROFILE') ?: '/');
|
$home = realpath(Platform::getEnv('HOME') ?: Platform::getEnv('USERPROFILE') ?: '/');
|
||||||
|
|
||||||
|
@ -207,12 +207,12 @@ class Application extends BaseApplication
|
||||||
|
|
||||||
// avoid loading plugins/initializing the Composer instance earlier than necessary if no plugin command is needed
|
// avoid loading plugins/initializing the Composer instance earlier than necessary if no plugin command is needed
|
||||||
// if showing the version, we never need plugin commands
|
// if showing the version, we never need plugin commands
|
||||||
$mayNeedPluginCommand = false === $input->hasParameterOption(array('--version', '-V'))
|
$mayNeedPluginCommand = false === $input->hasParameterOption(['--version', '-V'])
|
||||||
&& (
|
&& (
|
||||||
// not a composer command, so try loading plugin ones
|
// not a composer command, so try loading plugin ones
|
||||||
false === $commandName
|
false === $commandName
|
||||||
// list command requires plugin commands to show them
|
// list command requires plugin commands to show them
|
||||||
|| in_array($commandName, array('', 'list', 'help'), true)
|
|| in_array($commandName, ['', 'list', 'help'], true)
|
||||||
);
|
);
|
||||||
|
|
||||||
if ($mayNeedPluginCommand && !$this->disablePluginsByDefault && !$this->hasPluginCommands) {
|
if ($mayNeedPluginCommand && !$this->disablePluginsByDefault && !$this->hasPluginCommands) {
|
||||||
|
@ -389,14 +389,13 @@ class Application extends BaseApplication
|
||||||
}
|
}
|
||||||
|
|
||||||
/**
|
/**
|
||||||
* @param InputInterface $input
|
|
||||||
* @throws \RuntimeException
|
* @throws \RuntimeException
|
||||||
* @return ?string
|
* @return ?string
|
||||||
*/
|
*/
|
||||||
private function getNewWorkingDir(InputInterface $input): ?string
|
private function getNewWorkingDir(InputInterface $input): ?string
|
||||||
{
|
{
|
||||||
/** @var string|null $workingDir */
|
/** @var string|null $workingDir */
|
||||||
$workingDir = $input->getParameterOption(array('--working-dir', '-d'), null, true);
|
$workingDir = $input->getParameterOption(['--working-dir', '-d'], null, true);
|
||||||
if (null !== $workingDir && !is_dir($workingDir)) {
|
if (null !== $workingDir && !is_dir($workingDir)) {
|
||||||
throw new \RuntimeException('Invalid working directory specified, '.$workingDir.' does not exist.');
|
throw new \RuntimeException('Invalid working directory specified, '.$workingDir.' does not exist.');
|
||||||
}
|
}
|
||||||
|
@ -404,9 +403,6 @@ class Application extends BaseApplication
|
||||||
return $workingDir;
|
return $workingDir;
|
||||||
}
|
}
|
||||||
|
|
||||||
/**
|
|
||||||
* @return void
|
|
||||||
*/
|
|
||||||
private function hintCommonErrors(\Throwable $exception, OutputInterface $output): void
|
private function hintCommonErrors(\Throwable $exception, OutputInterface $output): void
|
||||||
{
|
{
|
||||||
$io = $this->getIO();
|
$io = $this->getIO();
|
||||||
|
@ -457,9 +453,6 @@ class Application extends BaseApplication
|
||||||
}
|
}
|
||||||
|
|
||||||
/**
|
/**
|
||||||
* @param bool $required
|
|
||||||
* @param bool|null $disablePlugins
|
|
||||||
* @param bool|null $disableScripts
|
|
||||||
* @throws JsonValidationException
|
* @throws JsonValidationException
|
||||||
* @throws \InvalidArgumentException
|
* @throws \InvalidArgumentException
|
||||||
* @return ?Composer If $required is true then the return value is guaranteed
|
* @return ?Composer If $required is true then the return value is guaranteed
|
||||||
|
@ -496,8 +489,6 @@ class Application extends BaseApplication
|
||||||
|
|
||||||
/**
|
/**
|
||||||
* Removes the cached composer instance
|
* Removes the cached composer instance
|
||||||
*
|
|
||||||
* @return void
|
|
||||||
*/
|
*/
|
||||||
public function resetComposer(): void
|
public function resetComposer(): void
|
||||||
{
|
{
|
||||||
|
@ -507,9 +498,6 @@ class Application extends BaseApplication
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
|
|
||||||
/**
|
|
||||||
* @return IOInterface
|
|
||||||
*/
|
|
||||||
public function getIO(): IOInterface
|
public function getIO(): IOInterface
|
||||||
{
|
{
|
||||||
return $this->io;
|
return $this->io;
|
||||||
|
@ -526,7 +514,7 @@ class Application extends BaseApplication
|
||||||
*/
|
*/
|
||||||
protected function getDefaultCommands(): array
|
protected function getDefaultCommands(): array
|
||||||
{
|
{
|
||||||
$commands = array_merge(parent::getDefaultCommands(), array(
|
$commands = array_merge(parent::getDefaultCommands(), [
|
||||||
new Command\AboutCommand(),
|
new Command\AboutCommand(),
|
||||||
new Command\ConfigCommand(),
|
new Command\ConfigCommand(),
|
||||||
new Command\DependsCommand(),
|
new Command\DependsCommand(),
|
||||||
|
@ -557,7 +545,7 @@ class Application extends BaseApplication
|
||||||
new Command\FundCommand(),
|
new Command\FundCommand(),
|
||||||
new Command\ReinstallCommand(),
|
new Command\ReinstallCommand(),
|
||||||
new Command\BumpCommand(),
|
new Command\BumpCommand(),
|
||||||
));
|
]);
|
||||||
|
|
||||||
if (strpos(__FILE__, 'phar:') === 0 || '1' === Platform::getEnv('COMPOSER_TESTS_ARE_RUNNING')) {
|
if (strpos(__FILE__, 'phar:') === 0 || '1' === Platform::getEnv('COMPOSER_TESTS_ARE_RUNNING')) {
|
||||||
$commands[] = new Command\SelfUpdateCommand();
|
$commands[] = new Command\SelfUpdateCommand();
|
||||||
|
@ -599,7 +587,7 @@ class Application extends BaseApplication
|
||||||
*/
|
*/
|
||||||
private function getPluginCommands(): array
|
private function getPluginCommands(): array
|
||||||
{
|
{
|
||||||
$commands = array();
|
$commands = [];
|
||||||
|
|
||||||
$composer = $this->getComposer(false, false);
|
$composer = $this->getComposer(false, false);
|
||||||
if (null === $composer) {
|
if (null === $composer) {
|
||||||
|
@ -608,7 +596,7 @@ class Application extends BaseApplication
|
||||||
|
|
||||||
if (null !== $composer) {
|
if (null !== $composer) {
|
||||||
$pm = $composer->getPluginManager();
|
$pm = $composer->getPluginManager();
|
||||||
foreach ($pm->getPluginCapabilities('Composer\Plugin\Capability\CommandProvider', array('composer' => $composer, 'io' => $this->io)) as $capability) {
|
foreach ($pm->getPluginCapabilities('Composer\Plugin\Capability\CommandProvider', ['composer' => $composer, 'io' => $this->io]) as $capability) {
|
||||||
$newCommands = $capability->getCommands();
|
$newCommands = $capability->getCommands();
|
||||||
if (!is_array($newCommands)) {
|
if (!is_array($newCommands)) {
|
||||||
throw new \UnexpectedValueException('Plugin capability '.get_class($capability).' failed to return an array from getCommands');
|
throw new \UnexpectedValueException('Plugin capability '.get_class($capability).' failed to return an array from getCommands');
|
||||||
|
|
|
@ -27,13 +27,6 @@ final class GithubActionError
|
||||||
$this->io = $io;
|
$this->io = $io;
|
||||||
}
|
}
|
||||||
|
|
||||||
/**
|
|
||||||
* @param string $message
|
|
||||||
* @param null|string $file
|
|
||||||
* @param null|int $line
|
|
||||||
*
|
|
||||||
* @return void
|
|
||||||
*/
|
|
||||||
public function emit(string $message, ?string $file = null, ?int $line = null): void
|
public function emit(string $message, ?string $file = null, ?int $line = null): void
|
||||||
{
|
{
|
||||||
if (Platform::getEnv('GITHUB_ACTIONS') && !Platform::getEnv('COMPOSER_TESTS_ARE_RUNNING')) {
|
if (Platform::getEnv('GITHUB_ACTIONS') && !Platform::getEnv('COMPOSER_TESTS_ARE_RUNNING')) {
|
||||||
|
@ -51,10 +44,6 @@ final class GithubActionError
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
|
|
||||||
/**
|
|
||||||
* @param string $data
|
|
||||||
* @return string
|
|
||||||
*/
|
|
||||||
private function escapeData(string $data): string
|
private function escapeData(string $data): string
|
||||||
{
|
{
|
||||||
// see https://github.com/actions/toolkit/blob/4f7fb6513a355689f69f0849edeb369a4dc81729/packages/core/src/command.ts#L80-L85
|
// see https://github.com/actions/toolkit/blob/4f7fb6513a355689f69f0849edeb369a4dc81729/packages/core/src/command.ts#L80-L85
|
||||||
|
@ -65,10 +54,6 @@ final class GithubActionError
|
||||||
return $data;
|
return $data;
|
||||||
}
|
}
|
||||||
|
|
||||||
/**
|
|
||||||
* @param string $property
|
|
||||||
* @return string
|
|
||||||
*/
|
|
||||||
private function escapeProperty(string $property): string
|
private function escapeProperty(string $property): string
|
||||||
{
|
{
|
||||||
// see https://github.com/actions/toolkit/blob/4f7fb6513a355689f69f0849edeb369a4dc81729/packages/core/src/command.ts#L87-L94
|
// see https://github.com/actions/toolkit/blob/4f7fb6513a355689f69f0849edeb369a4dc81729/packages/core/src/command.ts#L87-L94
|
||||||
|
|
|
@ -23,7 +23,7 @@ use Symfony\Component\Console\Formatter\OutputFormatterStyle;
|
||||||
class HtmlOutputFormatter extends OutputFormatter
|
class HtmlOutputFormatter extends OutputFormatter
|
||||||
{
|
{
|
||||||
/** @var array<int, string> */
|
/** @var array<int, string> */
|
||||||
private static $availableForegroundColors = array(
|
private static $availableForegroundColors = [
|
||||||
30 => 'black',
|
30 => 'black',
|
||||||
31 => 'red',
|
31 => 'red',
|
||||||
32 => 'green',
|
32 => 'green',
|
||||||
|
@ -32,9 +32,9 @@ class HtmlOutputFormatter extends OutputFormatter
|
||||||
35 => 'magenta',
|
35 => 'magenta',
|
||||||
36 => 'cyan',
|
36 => 'cyan',
|
||||||
37 => 'white',
|
37 => 'white',
|
||||||
);
|
];
|
||||||
/** @var array<int, string> */
|
/** @var array<int, string> */
|
||||||
private static $availableBackgroundColors = array(
|
private static $availableBackgroundColors = [
|
||||||
40 => 'black',
|
40 => 'black',
|
||||||
41 => 'red',
|
41 => 'red',
|
||||||
42 => 'green',
|
42 => 'green',
|
||||||
|
@ -43,20 +43,20 @@ class HtmlOutputFormatter extends OutputFormatter
|
||||||
45 => 'magenta',
|
45 => 'magenta',
|
||||||
46 => 'cyan',
|
46 => 'cyan',
|
||||||
47 => 'white',
|
47 => 'white',
|
||||||
);
|
];
|
||||||
/** @var array<int, string> */
|
/** @var array<int, string> */
|
||||||
private static $availableOptions = array(
|
private static $availableOptions = [
|
||||||
1 => 'bold',
|
1 => 'bold',
|
||||||
4 => 'underscore',
|
4 => 'underscore',
|
||||||
//5 => 'blink',
|
//5 => 'blink',
|
||||||
//7 => 'reverse',
|
//7 => 'reverse',
|
||||||
//8 => 'conceal'
|
//8 => 'conceal'
|
||||||
);
|
];
|
||||||
|
|
||||||
/**
|
/**
|
||||||
* @param array<string, OutputFormatterStyle> $styles Array of "name => FormatterStyle" instances
|
* @param array<string, OutputFormatterStyle> $styles Array of "name => FormatterStyle" instances
|
||||||
*/
|
*/
|
||||||
public function __construct(array $styles = array())
|
public function __construct(array $styles = [])
|
||||||
{
|
{
|
||||||
parent::__construct(true, $styles);
|
parent::__construct(true, $styles);
|
||||||
}
|
}
|
||||||
|
|
|
@ -44,7 +44,7 @@ class InputArgument extends BaseInputArgument
|
||||||
*
|
*
|
||||||
* @throws InvalidArgumentException When argument mode is not valid
|
* @throws InvalidArgumentException When argument mode is not valid
|
||||||
*/
|
*/
|
||||||
public function __construct(string $name, int $mode = null, string $description = '', $default = null, $suggestedValues = [])
|
public function __construct(string $name, ?int $mode = null, string $description = '', $default = null, $suggestedValues = [])
|
||||||
{
|
{
|
||||||
parent::__construct($name, $mode, $description, $default);
|
parent::__construct($name, $mode, $description, $default);
|
||||||
|
|
||||||
|
|
|
@ -43,7 +43,7 @@ class InputOption extends BaseInputOption
|
||||||
*
|
*
|
||||||
* @throws InvalidArgumentException If option mode is invalid or incompatible
|
* @throws InvalidArgumentException If option mode is invalid or incompatible
|
||||||
*/
|
*/
|
||||||
public function __construct(string $name, $shortcut = null, int $mode = null, string $description = '', $default = null, $suggestedValues = [])
|
public function __construct(string $name, $shortcut = null, ?int $mode = null, string $description = '', $default = null, $suggestedValues = [])
|
||||||
{
|
{
|
||||||
parent::__construct($name, $shortcut, $mode, $description, $default);
|
parent::__construct($name, $shortcut, $mode, $description, $default);
|
||||||
|
|
||||||
|
|
|
@ -30,32 +30,23 @@ class Decisions implements \Iterator, \Countable
|
||||||
/**
|
/**
|
||||||
* @var array<array{0: int, 1: Rule}>
|
* @var array<array{0: int, 1: Rule}>
|
||||||
*/
|
*/
|
||||||
protected $decisionQueue = array();
|
protected $decisionQueue = [];
|
||||||
|
|
||||||
public function __construct(Pool $pool)
|
public function __construct(Pool $pool)
|
||||||
{
|
{
|
||||||
$this->pool = $pool;
|
$this->pool = $pool;
|
||||||
$this->decisionMap = array();
|
$this->decisionMap = [];
|
||||||
}
|
}
|
||||||
|
|
||||||
/**
|
|
||||||
* @param int $literal
|
|
||||||
* @param int $level
|
|
||||||
* @return void
|
|
||||||
*/
|
|
||||||
public function decide(int $literal, int $level, Rule $why): void
|
public function decide(int $literal, int $level, Rule $why): void
|
||||||
{
|
{
|
||||||
$this->addDecision($literal, $level);
|
$this->addDecision($literal, $level);
|
||||||
$this->decisionQueue[] = array(
|
$this->decisionQueue[] = [
|
||||||
self::DECISION_LITERAL => $literal,
|
self::DECISION_LITERAL => $literal,
|
||||||
self::DECISION_REASON => $why,
|
self::DECISION_REASON => $why,
|
||||||
);
|
];
|
||||||
}
|
}
|
||||||
|
|
||||||
/**
|
|
||||||
* @param int $literal
|
|
||||||
* @return bool
|
|
||||||
*/
|
|
||||||
public function satisfy(int $literal): bool
|
public function satisfy(int $literal): bool
|
||||||
{
|
{
|
||||||
$packageId = abs($literal);
|
$packageId = abs($literal);
|
||||||
|
@ -66,10 +57,6 @@ class Decisions implements \Iterator, \Countable
|
||||||
);
|
);
|
||||||
}
|
}
|
||||||
|
|
||||||
/**
|
|
||||||
* @param int $literal
|
|
||||||
* @return bool
|
|
||||||
*/
|
|
||||||
public function conflict(int $literal): bool
|
public function conflict(int $literal): bool
|
||||||
{
|
{
|
||||||
$packageId = abs($literal);
|
$packageId = abs($literal);
|
||||||
|
@ -80,28 +67,16 @@ class Decisions implements \Iterator, \Countable
|
||||||
);
|
);
|
||||||
}
|
}
|
||||||
|
|
||||||
/**
|
|
||||||
* @param int $literalOrPackageId
|
|
||||||
* @return bool
|
|
||||||
*/
|
|
||||||
public function decided(int $literalOrPackageId): bool
|
public function decided(int $literalOrPackageId): bool
|
||||||
{
|
{
|
||||||
return !empty($this->decisionMap[abs($literalOrPackageId)]);
|
return !empty($this->decisionMap[abs($literalOrPackageId)]);
|
||||||
}
|
}
|
||||||
|
|
||||||
/**
|
|
||||||
* @param int $literalOrPackageId
|
|
||||||
* @return bool
|
|
||||||
*/
|
|
||||||
public function undecided(int $literalOrPackageId): bool
|
public function undecided(int $literalOrPackageId): bool
|
||||||
{
|
{
|
||||||
return empty($this->decisionMap[abs($literalOrPackageId)]);
|
return empty($this->decisionMap[abs($literalOrPackageId)]);
|
||||||
}
|
}
|
||||||
|
|
||||||
/**
|
|
||||||
* @param int $literalOrPackageId
|
|
||||||
* @return bool
|
|
||||||
*/
|
|
||||||
public function decidedInstall(int $literalOrPackageId): bool
|
public function decidedInstall(int $literalOrPackageId): bool
|
||||||
{
|
{
|
||||||
$packageId = abs($literalOrPackageId);
|
$packageId = abs($literalOrPackageId);
|
||||||
|
@ -109,10 +84,6 @@ class Decisions implements \Iterator, \Countable
|
||||||
return isset($this->decisionMap[$packageId]) && $this->decisionMap[$packageId] > 0;
|
return isset($this->decisionMap[$packageId]) && $this->decisionMap[$packageId] > 0;
|
||||||
}
|
}
|
||||||
|
|
||||||
/**
|
|
||||||
* @param int $literalOrPackageId
|
|
||||||
* @return int
|
|
||||||
*/
|
|
||||||
public function decisionLevel(int $literalOrPackageId): int
|
public function decisionLevel(int $literalOrPackageId): int
|
||||||
{
|
{
|
||||||
$packageId = abs($literalOrPackageId);
|
$packageId = abs($literalOrPackageId);
|
||||||
|
@ -123,10 +94,6 @@ class Decisions implements \Iterator, \Countable
|
||||||
return 0;
|
return 0;
|
||||||
}
|
}
|
||||||
|
|
||||||
/**
|
|
||||||
* @param int $literalOrPackageId
|
|
||||||
* @return Rule|null
|
|
||||||
*/
|
|
||||||
public function decisionRule(int $literalOrPackageId): ?Rule
|
public function decisionRule(int $literalOrPackageId): ?Rule
|
||||||
{
|
{
|
||||||
$packageId = abs($literalOrPackageId);
|
$packageId = abs($literalOrPackageId);
|
||||||
|
@ -141,7 +108,6 @@ class Decisions implements \Iterator, \Countable
|
||||||
}
|
}
|
||||||
|
|
||||||
/**
|
/**
|
||||||
* @param int $queueOffset
|
|
||||||
* @return array{0: int, 1: Rule} a literal and decision reason
|
* @return array{0: int, 1: Rule} a literal and decision reason
|
||||||
*/
|
*/
|
||||||
public function atOffset(int $queueOffset): array
|
public function atOffset(int $queueOffset): array
|
||||||
|
@ -149,34 +115,21 @@ class Decisions implements \Iterator, \Countable
|
||||||
return $this->decisionQueue[$queueOffset];
|
return $this->decisionQueue[$queueOffset];
|
||||||
}
|
}
|
||||||
|
|
||||||
/**
|
|
||||||
* @param int $queueOffset
|
|
||||||
* @return bool
|
|
||||||
*/
|
|
||||||
public function validOffset(int $queueOffset): bool
|
public function validOffset(int $queueOffset): bool
|
||||||
{
|
{
|
||||||
return $queueOffset >= 0 && $queueOffset < \count($this->decisionQueue);
|
return $queueOffset >= 0 && $queueOffset < \count($this->decisionQueue);
|
||||||
}
|
}
|
||||||
|
|
||||||
/**
|
|
||||||
* @return Rule
|
|
||||||
*/
|
|
||||||
public function lastReason(): Rule
|
public function lastReason(): Rule
|
||||||
{
|
{
|
||||||
return $this->decisionQueue[\count($this->decisionQueue) - 1][self::DECISION_REASON];
|
return $this->decisionQueue[\count($this->decisionQueue) - 1][self::DECISION_REASON];
|
||||||
}
|
}
|
||||||
|
|
||||||
/**
|
|
||||||
* @return int
|
|
||||||
*/
|
|
||||||
public function lastLiteral(): int
|
public function lastLiteral(): int
|
||||||
{
|
{
|
||||||
return $this->decisionQueue[\count($this->decisionQueue) - 1][self::DECISION_LITERAL];
|
return $this->decisionQueue[\count($this->decisionQueue) - 1][self::DECISION_LITERAL];
|
||||||
}
|
}
|
||||||
|
|
||||||
/**
|
|
||||||
* @return void
|
|
||||||
*/
|
|
||||||
public function reset(): void
|
public function reset(): void
|
||||||
{
|
{
|
||||||
while ($decision = array_pop($this->decisionQueue)) {
|
while ($decision = array_pop($this->decisionQueue)) {
|
||||||
|
@ -184,10 +137,6 @@ class Decisions implements \Iterator, \Countable
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
|
|
||||||
/**
|
|
||||||
* @param int $offset
|
|
||||||
* @return void
|
|
||||||
*/
|
|
||||||
public function resetToOffset(int $offset): void
|
public function resetToOffset(int $offset): void
|
||||||
{
|
{
|
||||||
while (\count($this->decisionQueue) > $offset + 1) {
|
while (\count($this->decisionQueue) > $offset + 1) {
|
||||||
|
@ -196,9 +145,6 @@ class Decisions implements \Iterator, \Countable
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
|
|
||||||
/**
|
|
||||||
* @return void
|
|
||||||
*/
|
|
||||||
public function revertLast(): void
|
public function revertLast(): void
|
||||||
{
|
{
|
||||||
$this->decisionMap[abs($this->lastLiteral())] = 0;
|
$this->decisionMap[abs($this->lastLiteral())] = 0;
|
||||||
|
@ -239,26 +185,18 @@ class Decisions implements \Iterator, \Countable
|
||||||
return false !== current($this->decisionQueue);
|
return false !== current($this->decisionQueue);
|
||||||
}
|
}
|
||||||
|
|
||||||
/**
|
|
||||||
* @return bool
|
|
||||||
*/
|
|
||||||
public function isEmpty(): bool
|
public function isEmpty(): bool
|
||||||
{
|
{
|
||||||
return \count($this->decisionQueue) === 0;
|
return \count($this->decisionQueue) === 0;
|
||||||
}
|
}
|
||||||
|
|
||||||
/**
|
|
||||||
* @param int $literal
|
|
||||||
* @param int $level
|
|
||||||
* @return void
|
|
||||||
*/
|
|
||||||
protected function addDecision(int $literal, int $level): void
|
protected function addDecision(int $literal, int $level): void
|
||||||
{
|
{
|
||||||
$packageId = abs($literal);
|
$packageId = abs($literal);
|
||||||
|
|
||||||
$previousDecision = $this->decisionMap[$packageId] ?? 0;
|
$previousDecision = $this->decisionMap[$packageId] ?? 0;
|
||||||
if ($previousDecision !== 0) {
|
if ($previousDecision !== 0) {
|
||||||
$literalString = $this->pool->literalToPrettyString($literal, array());
|
$literalString = $this->pool->literalToPrettyString($literal, []);
|
||||||
$package = $this->pool->literalToPackage($literal);
|
$package = $this->pool->literalToPackage($literal);
|
||||||
throw new SolverBugException(
|
throw new SolverBugException(
|
||||||
"Trying to decide $literalString on level $level, even though $package was previously decided as ".$previousDecision."."
|
"Trying to decide $literalString on level $level, even though $package was previously decided as ".$previousDecision."."
|
||||||
|
@ -272,10 +210,7 @@ class Decisions implements \Iterator, \Countable
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
|
|
||||||
/**
|
public function toString(?Pool $pool = null): string
|
||||||
* @return string
|
|
||||||
*/
|
|
||||||
public function toString(Pool $pool = null): string
|
|
||||||
{
|
{
|
||||||
$decisionMap = $this->decisionMap;
|
$decisionMap = $this->decisionMap;
|
||||||
ksort($decisionMap);
|
ksort($decisionMap);
|
||||||
|
|
|
@ -32,10 +32,6 @@ class DefaultPolicy implements PolicyInterface
|
||||||
/** @var array<int, array<string, int>> */
|
/** @var array<int, array<string, int>> */
|
||||||
private $sortingCachePerPool;
|
private $sortingCachePerPool;
|
||||||
|
|
||||||
/**
|
|
||||||
* @param bool $preferStable
|
|
||||||
* @param bool $preferLowest
|
|
||||||
*/
|
|
||||||
public function __construct(bool $preferStable = false, bool $preferLowest = false)
|
public function __construct(bool $preferStable = false, bool $preferLowest = false)
|
||||||
{
|
{
|
||||||
$this->preferStable = $preferStable;
|
$this->preferStable = $preferStable;
|
||||||
|
@ -44,7 +40,6 @@ class DefaultPolicy implements PolicyInterface
|
||||||
|
|
||||||
/**
|
/**
|
||||||
* @param string $operator One of Constraint::STR_OP_*
|
* @param string $operator One of Constraint::STR_OP_*
|
||||||
* @return bool
|
|
||||||
*
|
*
|
||||||
* @phpstan-param Constraint::STR_OP_* $operator
|
* @phpstan-param Constraint::STR_OP_* $operator
|
||||||
*/
|
*/
|
||||||
|
@ -65,7 +60,7 @@ class DefaultPolicy implements PolicyInterface
|
||||||
* @param string $requiredPackage
|
* @param string $requiredPackage
|
||||||
* @return int[]
|
* @return int[]
|
||||||
*/
|
*/
|
||||||
public function selectPreferredPackages(Pool $pool, array $literals, string $requiredPackage = null): array
|
public function selectPreferredPackages(Pool $pool, array $literals, ?string $requiredPackage = null): array
|
||||||
{
|
{
|
||||||
sort($literals);
|
sort($literals);
|
||||||
$resultCacheKey = implode(',', $literals).$requiredPackage;
|
$resultCacheKey = implode(',', $literals).$requiredPackage;
|
||||||
|
@ -94,7 +89,7 @@ class DefaultPolicy implements PolicyInterface
|
||||||
$sortedLiterals = $this->pruneRemoteAliases($pool, $sortedLiterals);
|
$sortedLiterals = $this->pruneRemoteAliases($pool, $sortedLiterals);
|
||||||
}
|
}
|
||||||
|
|
||||||
$selected = \call_user_func_array('array_merge', array_values($packages));
|
$selected = array_merge(...array_values($packages));
|
||||||
|
|
||||||
// now sort the result across all packages to respect replaces across packages
|
// now sort the result across all packages to respect replaces across packages
|
||||||
usort($selected, function ($a, $b) use ($pool, $requiredPackage, $poolId): int {
|
usort($selected, function ($a, $b) use ($pool, $requiredPackage, $poolId): int {
|
||||||
|
@ -116,12 +111,12 @@ class DefaultPolicy implements PolicyInterface
|
||||||
*/
|
*/
|
||||||
protected function groupLiteralsByName(Pool $pool, array $literals): array
|
protected function groupLiteralsByName(Pool $pool, array $literals): array
|
||||||
{
|
{
|
||||||
$packages = array();
|
$packages = [];
|
||||||
foreach ($literals as $literal) {
|
foreach ($literals as $literal) {
|
||||||
$packageName = $pool->literalToPackage($literal)->getName();
|
$packageName = $pool->literalToPackage($literal)->getName();
|
||||||
|
|
||||||
if (!isset($packages[$packageName])) {
|
if (!isset($packages[$packageName])) {
|
||||||
$packages[$packageName] = array();
|
$packages[$packageName] = [];
|
||||||
}
|
}
|
||||||
$packages[$packageName][] = $literal;
|
$packages[$packageName][] = $literal;
|
||||||
}
|
}
|
||||||
|
@ -131,9 +126,6 @@ class DefaultPolicy implements PolicyInterface
|
||||||
|
|
||||||
/**
|
/**
|
||||||
* @protected
|
* @protected
|
||||||
* @param null|string $requiredPackage
|
|
||||||
* @param bool $ignoreReplace
|
|
||||||
* @return int
|
|
||||||
*/
|
*/
|
||||||
public function compareByPriority(Pool $pool, BasePackage $a, BasePackage $b, ?string $requiredPackage = null, bool $ignoreReplace = false): int
|
public function compareByPriority(Pool $pool, BasePackage $a, BasePackage $b, ?string $requiredPackage = null, bool $ignoreReplace = false): int
|
||||||
{
|
{
|
||||||
|
@ -185,8 +177,6 @@ class DefaultPolicy implements PolicyInterface
|
||||||
*
|
*
|
||||||
* Replace constraints are ignored. This method should only be used for
|
* Replace constraints are ignored. This method should only be used for
|
||||||
* prioritisation, not for actual constraint verification.
|
* prioritisation, not for actual constraint verification.
|
||||||
*
|
|
||||||
* @return bool
|
|
||||||
*/
|
*/
|
||||||
protected function replaces(BasePackage $source, BasePackage $target): bool
|
protected function replaces(BasePackage $source, BasePackage $target): bool
|
||||||
{
|
{
|
||||||
|
@ -194,7 +184,7 @@ class DefaultPolicy implements PolicyInterface
|
||||||
if ($link->getTarget() === $target->getName()
|
if ($link->getTarget() === $target->getName()
|
||||||
// && (null === $link->getConstraint() ||
|
// && (null === $link->getConstraint() ||
|
||||||
// $link->getConstraint()->matches(new Constraint('==', $target->getVersion())))) {
|
// $link->getConstraint()->matches(new Constraint('==', $target->getVersion())))) {
|
||||||
) {
|
) {
|
||||||
return true;
|
return true;
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
|
@ -209,7 +199,7 @@ class DefaultPolicy implements PolicyInterface
|
||||||
protected function pruneToBestVersion(Pool $pool, array $literals): array
|
protected function pruneToBestVersion(Pool $pool, array $literals): array
|
||||||
{
|
{
|
||||||
$operator = $this->preferLowest ? '<' : '>';
|
$operator = $this->preferLowest ? '<' : '>';
|
||||||
$bestLiterals = array($literals[0]);
|
$bestLiterals = [$literals[0]];
|
||||||
$bestPackage = $pool->literalToPackage($literals[0]);
|
$bestPackage = $pool->literalToPackage($literals[0]);
|
||||||
foreach ($literals as $i => $literal) {
|
foreach ($literals as $i => $literal) {
|
||||||
if (0 === $i) {
|
if (0 === $i) {
|
||||||
|
@ -220,7 +210,7 @@ class DefaultPolicy implements PolicyInterface
|
||||||
|
|
||||||
if ($this->versionCompare($package, $bestPackage, $operator)) {
|
if ($this->versionCompare($package, $bestPackage, $operator)) {
|
||||||
$bestPackage = $package;
|
$bestPackage = $package;
|
||||||
$bestLiterals = array($literal);
|
$bestLiterals = [$literal];
|
||||||
} elseif ($this->versionCompare($package, $bestPackage, '==')) {
|
} elseif ($this->versionCompare($package, $bestPackage, '==')) {
|
||||||
$bestLiterals[] = $literal;
|
$bestLiterals[] = $literal;
|
||||||
}
|
}
|
||||||
|
@ -254,7 +244,7 @@ class DefaultPolicy implements PolicyInterface
|
||||||
return $literals;
|
return $literals;
|
||||||
}
|
}
|
||||||
|
|
||||||
$selected = array();
|
$selected = [];
|
||||||
foreach ($literals as $literal) {
|
foreach ($literals as $literal) {
|
||||||
$package = $pool->literalToPackage($literal);
|
$package = $pool->literalToPackage($literal);
|
||||||
|
|
||||||
|
|
|
@ -64,9 +64,6 @@ class GenericRule extends Rule
|
||||||
return $this->literals === $rule->getLiterals();
|
return $this->literals === $rule->getLiterals();
|
||||||
}
|
}
|
||||||
|
|
||||||
/**
|
|
||||||
* @return bool
|
|
||||||
*/
|
|
||||||
public function isAssertion(): bool
|
public function isAssertion(): bool
|
||||||
{
|
{
|
||||||
return 1 === \count($this->literals);
|
return 1 === \count($this->literals);
|
||||||
|
@ -74,8 +71,6 @@ class GenericRule extends Rule
|
||||||
|
|
||||||
/**
|
/**
|
||||||
* Formats a rule as a string of the format (Literal1|Literal2|...)
|
* Formats a rule as a string of the format (Literal1|Literal2|...)
|
||||||
*
|
|
||||||
* @return string
|
|
||||||
*/
|
*/
|
||||||
public function __toString(): string
|
public function __toString(): string
|
||||||
{
|
{
|
||||||
|
|
|
@ -59,12 +59,10 @@ class LockTransaction extends Transaction
|
||||||
}
|
}
|
||||||
|
|
||||||
// TODO make this a bit prettier instead of the two text indexes?
|
// TODO make this a bit prettier instead of the two text indexes?
|
||||||
/**
|
|
||||||
* @return void
|
|
||||||
*/
|
|
||||||
public function setResultPackages(Pool $pool, Decisions $decisions): void
|
public function setResultPackages(Pool $pool, Decisions $decisions): void
|
||||||
{
|
{
|
||||||
$this->resultPackages = array('all' => array(), 'non-dev' => array(), 'dev' => array());
|
$this->resultPackages = ['all' => [], 'non-dev' => [], 'dev' => []];
|
||||||
foreach ($decisions as $i => $decision) {
|
foreach ($decisions as $i => $decision) {
|
||||||
$literal = $decision[Decisions::DECISION_LITERAL];
|
$literal = $decision[Decisions::DECISION_LITERAL];
|
||||||
|
|
||||||
|
@ -79,15 +77,12 @@ class LockTransaction extends Transaction
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
|
|
||||||
/**
|
|
||||||
* @return void
|
|
||||||
*/
|
|
||||||
public function setNonDevPackages(LockTransaction $extractionResult): void
|
public function setNonDevPackages(LockTransaction $extractionResult): void
|
||||||
{
|
{
|
||||||
$packages = $extractionResult->getNewLockPackages(false);
|
$packages = $extractionResult->getNewLockPackages(false);
|
||||||
|
|
||||||
$this->resultPackages['dev'] = $this->resultPackages['non-dev'];
|
$this->resultPackages['dev'] = $this->resultPackages['non-dev'];
|
||||||
$this->resultPackages['non-dev'] = array();
|
$this->resultPackages['non-dev'] = [];
|
||||||
|
|
||||||
foreach ($packages as $package) {
|
foreach ($packages as $package) {
|
||||||
foreach ($this->resultPackages['dev'] as $i => $resultPackage) {
|
foreach ($this->resultPackages['dev'] as $i => $resultPackage) {
|
||||||
|
@ -102,13 +97,11 @@ class LockTransaction extends Transaction
|
||||||
|
|
||||||
// TODO additionalFixedRepository needs to be looked at here as well?
|
// TODO additionalFixedRepository needs to be looked at here as well?
|
||||||
/**
|
/**
|
||||||
* @param bool $devMode
|
|
||||||
* @param bool $updateMirrors
|
|
||||||
* @return BasePackage[]
|
* @return BasePackage[]
|
||||||
*/
|
*/
|
||||||
public function getNewLockPackages(bool $devMode, bool $updateMirrors = false): array
|
public function getNewLockPackages(bool $devMode, bool $updateMirrors = false): array
|
||||||
{
|
{
|
||||||
$packages = array();
|
$packages = [];
|
||||||
foreach ($this->resultPackages[$devMode ? 'dev' : 'non-dev'] as $package) {
|
foreach ($this->resultPackages[$devMode ? 'dev' : 'non-dev'] as $package) {
|
||||||
if (!$package instanceof AliasPackage) {
|
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
|
// 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
|
||||||
|
@ -139,7 +132,7 @@ class LockTransaction extends Transaction
|
||||||
*/
|
*/
|
||||||
public function getAliases(array $aliases): array
|
public function getAliases(array $aliases): array
|
||||||
{
|
{
|
||||||
$usedAliases = array();
|
$usedAliases = [];
|
||||||
|
|
||||||
foreach ($this->resultPackages['all'] as $package) {
|
foreach ($this->resultPackages['all'] as $package) {
|
||||||
if ($package instanceof AliasPackage) {
|
if ($package instanceof AliasPackage) {
|
||||||
|
|
|
@ -74,9 +74,6 @@ class MultiConflictRule extends Rule
|
||||||
return false;
|
return false;
|
||||||
}
|
}
|
||||||
|
|
||||||
/**
|
|
||||||
* @return bool
|
|
||||||
*/
|
|
||||||
public function isAssertion(): bool
|
public function isAssertion(): bool
|
||||||
{
|
{
|
||||||
return false;
|
return false;
|
||||||
|
@ -93,8 +90,6 @@ class MultiConflictRule extends Rule
|
||||||
|
|
||||||
/**
|
/**
|
||||||
* Formats a rule as a string of the format (Literal1|Literal2|...)
|
* Formats a rule as a string of the format (Literal1|Literal2|...)
|
||||||
*
|
|
||||||
* @return string
|
|
||||||
*/
|
*/
|
||||||
public function __toString(): string
|
public function __toString(): string
|
||||||
{
|
{
|
||||||
|
|
|
@ -35,8 +35,6 @@ class InstallOperation extends SolverOperation implements OperationInterface
|
||||||
|
|
||||||
/**
|
/**
|
||||||
* Returns package instance.
|
* Returns package instance.
|
||||||
*
|
|
||||||
* @return PackageInterface
|
|
||||||
*/
|
*/
|
||||||
public function getPackage(): PackageInterface
|
public function getPackage(): PackageInterface
|
||||||
{
|
{
|
||||||
|
@ -51,10 +49,6 @@ class InstallOperation extends SolverOperation implements OperationInterface
|
||||||
return self::format($this->package, $lock);
|
return self::format($this->package, $lock);
|
||||||
}
|
}
|
||||||
|
|
||||||
/**
|
|
||||||
* @param bool $lock
|
|
||||||
* @return string
|
|
||||||
*/
|
|
||||||
public static function format(PackageInterface $package, bool $lock = false): string
|
public static function format(PackageInterface $package, bool $lock = false): string
|
||||||
{
|
{
|
||||||
return ($lock ? 'Locking ' : 'Installing ').'<info>'.$package->getPrettyName().'</info> (<comment>'.$package->getFullPrettyVersion().'</comment>)';
|
return ($lock ? 'Locking ' : 'Installing ').'<info>'.$package->getPrettyName().'</info> (<comment>'.$package->getFullPrettyVersion().'</comment>)';
|
||||||
|
|
|
@ -35,8 +35,6 @@ class MarkAliasInstalledOperation extends SolverOperation implements OperationIn
|
||||||
|
|
||||||
/**
|
/**
|
||||||
* Returns package instance.
|
* Returns package instance.
|
||||||
*
|
|
||||||
* @return AliasPackage
|
|
||||||
*/
|
*/
|
||||||
public function getPackage(): AliasPackage
|
public function getPackage(): AliasPackage
|
||||||
{
|
{
|
||||||
|
|
|
@ -35,8 +35,6 @@ class MarkAliasUninstalledOperation extends SolverOperation implements Operation
|
||||||
|
|
||||||
/**
|
/**
|
||||||
* Returns package instance.
|
* Returns package instance.
|
||||||
*
|
|
||||||
* @return AliasPackage
|
|
||||||
*/
|
*/
|
||||||
public function getPackage(): AliasPackage
|
public function getPackage(): AliasPackage
|
||||||
{
|
{
|
||||||
|
|
|
@ -26,8 +26,6 @@ abstract class SolverOperation implements OperationInterface
|
||||||
|
|
||||||
/**
|
/**
|
||||||
* Returns operation type.
|
* Returns operation type.
|
||||||
*
|
|
||||||
* @return string
|
|
||||||
*/
|
*/
|
||||||
public function getOperationType(): string
|
public function getOperationType(): string
|
||||||
{
|
{
|
||||||
|
|
|
@ -35,8 +35,6 @@ class UninstallOperation extends SolverOperation implements OperationInterface
|
||||||
|
|
||||||
/**
|
/**
|
||||||
* Returns package instance.
|
* Returns package instance.
|
||||||
*
|
|
||||||
* @return PackageInterface
|
|
||||||
*/
|
*/
|
||||||
public function getPackage(): PackageInterface
|
public function getPackage(): PackageInterface
|
||||||
{
|
{
|
||||||
|
@ -51,10 +49,6 @@ class UninstallOperation extends SolverOperation implements OperationInterface
|
||||||
return self::format($this->package, $lock);
|
return self::format($this->package, $lock);
|
||||||
}
|
}
|
||||||
|
|
||||||
/**
|
|
||||||
* @param bool $lock
|
|
||||||
* @return string
|
|
||||||
*/
|
|
||||||
public static function format(PackageInterface $package, bool $lock = false): string
|
public static function format(PackageInterface $package, bool $lock = false): string
|
||||||
{
|
{
|
||||||
return 'Removing <info>'.$package->getPrettyName().'</info> (<comment>'.$package->getFullPrettyVersion().'</comment>)';
|
return 'Removing <info>'.$package->getPrettyName().'</info> (<comment>'.$package->getFullPrettyVersion().'</comment>)';
|
||||||
|
|
|
@ -46,8 +46,6 @@ class UpdateOperation extends SolverOperation implements OperationInterface
|
||||||
|
|
||||||
/**
|
/**
|
||||||
* Returns initial package.
|
* Returns initial package.
|
||||||
*
|
|
||||||
* @return PackageInterface
|
|
||||||
*/
|
*/
|
||||||
public function getInitialPackage(): PackageInterface
|
public function getInitialPackage(): PackageInterface
|
||||||
{
|
{
|
||||||
|
@ -56,8 +54,6 @@ class UpdateOperation extends SolverOperation implements OperationInterface
|
||||||
|
|
||||||
/**
|
/**
|
||||||
* Returns target package.
|
* Returns target package.
|
||||||
*
|
|
||||||
* @return PackageInterface
|
|
||||||
*/
|
*/
|
||||||
public function getTargetPackage(): PackageInterface
|
public function getTargetPackage(): PackageInterface
|
||||||
{
|
{
|
||||||
|
@ -72,10 +68,6 @@ class UpdateOperation extends SolverOperation implements OperationInterface
|
||||||
return self::format($this->initialPackage, $this->targetPackage, $lock);
|
return self::format($this->initialPackage, $this->targetPackage, $lock);
|
||||||
}
|
}
|
||||||
|
|
||||||
/**
|
|
||||||
* @param bool $lock
|
|
||||||
* @return string
|
|
||||||
*/
|
|
||||||
public static function format(PackageInterface $initialPackage, PackageInterface $targetPackage, bool $lock = false): string
|
public static function format(PackageInterface $initialPackage, PackageInterface $targetPackage, bool $lock = false): string
|
||||||
{
|
{
|
||||||
$fromVersion = $initialPackage->getFullPrettyVersion();
|
$fromVersion = $initialPackage->getFullPrettyVersion();
|
||||||
|
|
|
@ -21,16 +21,12 @@ use Composer\Semver\Constraint\Constraint;
|
||||||
interface PolicyInterface
|
interface PolicyInterface
|
||||||
{
|
{
|
||||||
/**
|
/**
|
||||||
* @param string $operator
|
|
||||||
* @return bool
|
|
||||||
*
|
|
||||||
* @phpstan-param Constraint::STR_OP_* $operator
|
* @phpstan-param Constraint::STR_OP_* $operator
|
||||||
*/
|
*/
|
||||||
public function versionCompare(PackageInterface $a, PackageInterface $b, string $operator): bool;
|
public function versionCompare(PackageInterface $a, PackageInterface $b, string $operator): bool;
|
||||||
|
|
||||||
/**
|
/**
|
||||||
* @param int[] $literals
|
* @param int[] $literals
|
||||||
* @param null|string $requiredPackage
|
|
||||||
* @return int[]
|
* @return int[]
|
||||||
*/
|
*/
|
||||||
public function selectPreferredPackages(Pool $pool, array $literals, ?string $requiredPackage = null): array;
|
public function selectPreferredPackages(Pool $pool, array $literals, ?string $requiredPackage = null): array;
|
||||||
|
|
|
@ -27,19 +27,19 @@ use Composer\Semver\Constraint\Constraint;
|
||||||
class Pool implements \Countable
|
class Pool implements \Countable
|
||||||
{
|
{
|
||||||
/** @var BasePackage[] */
|
/** @var BasePackage[] */
|
||||||
protected $packages = array();
|
protected $packages = [];
|
||||||
/** @var array<string, BasePackage[]> */
|
/** @var array<string, BasePackage[]> */
|
||||||
protected $packageByName = array();
|
protected $packageByName = [];
|
||||||
/** @var VersionParser */
|
/** @var VersionParser */
|
||||||
protected $versionParser;
|
protected $versionParser;
|
||||||
/** @var array<string, array<string, BasePackage[]>> */
|
/** @var array<string, array<string, BasePackage[]>> */
|
||||||
protected $providerCache = array();
|
protected $providerCache = [];
|
||||||
/** @var BasePackage[] */
|
/** @var BasePackage[] */
|
||||||
protected $unacceptableFixedOrLockedPackages;
|
protected $unacceptableFixedOrLockedPackages;
|
||||||
/** @var array<string, array<string, string>> Map of package name => normalized version => pretty version */
|
/** @var array<string, array<string, string>> Map of package name => normalized version => pretty version */
|
||||||
protected $removedVersions = array();
|
protected $removedVersions = [];
|
||||||
/** @var array<string, array<string, string>> Map of package object hash => removed normalized versions => removed pretty version */
|
/** @var array<string, array<string, string>> Map of package object hash => removed normalized versions => removed pretty version */
|
||||||
protected $removedVersionsByPackage = array();
|
protected $removedVersionsByPackage = [];
|
||||||
|
|
||||||
/**
|
/**
|
||||||
* @param BasePackage[] $packages
|
* @param BasePackage[] $packages
|
||||||
|
@ -47,7 +47,7 @@ class Pool implements \Countable
|
||||||
* @param array<string, array<string, string>> $removedVersions
|
* @param array<string, array<string, string>> $removedVersions
|
||||||
* @param array<string, array<string, string>> $removedVersionsByPackage
|
* @param array<string, array<string, string>> $removedVersionsByPackage
|
||||||
*/
|
*/
|
||||||
public function __construct(array $packages = array(), array $unacceptableFixedOrLockedPackages = array(), array $removedVersions = array(), array $removedVersionsByPackage = array())
|
public function __construct(array $packages = [], array $unacceptableFixedOrLockedPackages = [], array $removedVersions = [], array $removedVersionsByPackage = [])
|
||||||
{
|
{
|
||||||
$this->versionParser = new VersionParser;
|
$this->versionParser = new VersionParser;
|
||||||
$this->setPackages($packages);
|
$this->setPackages($packages);
|
||||||
|
@ -57,16 +57,15 @@ class Pool implements \Countable
|
||||||
}
|
}
|
||||||
|
|
||||||
/**
|
/**
|
||||||
* @param string $name
|
|
||||||
* @return array<string, string>
|
* @return array<string, string>
|
||||||
*/
|
*/
|
||||||
public function getRemovedVersions(string $name, ConstraintInterface $constraint): array
|
public function getRemovedVersions(string $name, ConstraintInterface $constraint): array
|
||||||
{
|
{
|
||||||
if (!isset($this->removedVersions[$name])) {
|
if (!isset($this->removedVersions[$name])) {
|
||||||
return array();
|
return [];
|
||||||
}
|
}
|
||||||
|
|
||||||
$result = array();
|
$result = [];
|
||||||
foreach ($this->removedVersions[$name] as $version => $prettyVersion) {
|
foreach ($this->removedVersions[$name] as $version => $prettyVersion) {
|
||||||
if ($constraint->matches(new Constraint('==', $version))) {
|
if ($constraint->matches(new Constraint('==', $version))) {
|
||||||
$result[$version] = $prettyVersion;
|
$result[$version] = $prettyVersion;
|
||||||
|
@ -77,13 +76,12 @@ class Pool implements \Countable
|
||||||
}
|
}
|
||||||
|
|
||||||
/**
|
/**
|
||||||
* @param string $objectHash
|
|
||||||
* @return array<string, string>
|
* @return array<string, string>
|
||||||
*/
|
*/
|
||||||
public function getRemovedVersionsByPackage(string $objectHash): array
|
public function getRemovedVersionsByPackage(string $objectHash): array
|
||||||
{
|
{
|
||||||
if (!isset($this->removedVersionsByPackage[$objectHash])) {
|
if (!isset($this->removedVersionsByPackage[$objectHash])) {
|
||||||
return array();
|
return [];
|
||||||
}
|
}
|
||||||
|
|
||||||
return $this->removedVersionsByPackage[$objectHash];
|
return $this->removedVersionsByPackage[$objectHash];
|
||||||
|
@ -91,7 +89,6 @@ class Pool implements \Countable
|
||||||
|
|
||||||
/**
|
/**
|
||||||
* @param BasePackage[] $packages
|
* @param BasePackage[] $packages
|
||||||
* @return void
|
|
||||||
*/
|
*/
|
||||||
private function setPackages(array $packages): void
|
private function setPackages(array $packages): void
|
||||||
{
|
{
|
||||||
|
@ -118,9 +115,6 @@ class Pool implements \Countable
|
||||||
|
|
||||||
/**
|
/**
|
||||||
* Retrieves the package object for a given package id.
|
* Retrieves the package object for a given package id.
|
||||||
*
|
|
||||||
* @param int $id
|
|
||||||
* @return BasePackage
|
|
||||||
*/
|
*/
|
||||||
public function packageById(int $id): BasePackage
|
public function packageById(int $id): BasePackage
|
||||||
{
|
{
|
||||||
|
@ -143,7 +137,7 @@ class Pool implements \Countable
|
||||||
* packages must match or null to return all
|
* packages must match or null to return all
|
||||||
* @return BasePackage[] A set of packages
|
* @return BasePackage[] A set of packages
|
||||||
*/
|
*/
|
||||||
public function whatProvides(string $name, ConstraintInterface $constraint = null): array
|
public function whatProvides(string $name, ?ConstraintInterface $constraint = null): array
|
||||||
{
|
{
|
||||||
$key = (string) $constraint;
|
$key = (string) $constraint;
|
||||||
if (isset($this->providerCache[$name][$key])) {
|
if (isset($this->providerCache[$name][$key])) {
|
||||||
|
@ -159,13 +153,13 @@ class Pool implements \Countable
|
||||||
* packages must match or null to return all
|
* packages must match or null to return all
|
||||||
* @return BasePackage[]
|
* @return BasePackage[]
|
||||||
*/
|
*/
|
||||||
private function computeWhatProvides(string $name, ConstraintInterface $constraint = null): array
|
private function computeWhatProvides(string $name, ?ConstraintInterface $constraint = null): array
|
||||||
{
|
{
|
||||||
if (!isset($this->packageByName[$name])) {
|
if (!isset($this->packageByName[$name])) {
|
||||||
return array();
|
return [];
|
||||||
}
|
}
|
||||||
|
|
||||||
$matches = array();
|
$matches = [];
|
||||||
|
|
||||||
foreach ($this->packageByName[$name] as $candidate) {
|
foreach ($this->packageByName[$name] as $candidate) {
|
||||||
if ($this->match($candidate, $name, $constraint)) {
|
if ($this->match($candidate, $name, $constraint)) {
|
||||||
|
@ -176,10 +170,6 @@ class Pool implements \Countable
|
||||||
return $matches;
|
return $matches;
|
||||||
}
|
}
|
||||||
|
|
||||||
/**
|
|
||||||
* @param int $literal
|
|
||||||
* @return BasePackage
|
|
||||||
*/
|
|
||||||
public function literalToPackage(int $literal): BasePackage
|
public function literalToPackage(int $literal): BasePackage
|
||||||
{
|
{
|
||||||
$packageId = abs($literal);
|
$packageId = abs($literal);
|
||||||
|
@ -188,9 +178,7 @@ class Pool implements \Countable
|
||||||
}
|
}
|
||||||
|
|
||||||
/**
|
/**
|
||||||
* @param int $literal
|
|
||||||
* @param array<int, BasePackage> $installedMap
|
* @param array<int, BasePackage> $installedMap
|
||||||
* @return string
|
|
||||||
*/
|
*/
|
||||||
public function literalToPrettyString(int $literal, array $installedMap): string
|
public function literalToPrettyString(int $literal, array $installedMap): string
|
||||||
{
|
{
|
||||||
|
@ -210,9 +198,8 @@ class Pool implements \Countable
|
||||||
* provided or replaced packages
|
* provided or replaced packages
|
||||||
*
|
*
|
||||||
* @param string $name Name of the package to be matched
|
* @param string $name Name of the package to be matched
|
||||||
* @return bool
|
|
||||||
*/
|
*/
|
||||||
public function match(BasePackage $candidate, string $name, ConstraintInterface $constraint = null): bool
|
public function match(BasePackage $candidate, string $name, ?ConstraintInterface $constraint = null): bool
|
||||||
{
|
{
|
||||||
$candidateName = $candidate->getName();
|
$candidateName = $candidate->getName();
|
||||||
$candidateVersion = $candidate->getVersion();
|
$candidateVersion = $candidate->getVersion();
|
||||||
|
@ -252,9 +239,6 @@ class Pool implements \Countable
|
||||||
return false;
|
return false;
|
||||||
}
|
}
|
||||||
|
|
||||||
/**
|
|
||||||
* @return bool
|
|
||||||
*/
|
|
||||||
public function isUnacceptableFixedOrLockedPackage(BasePackage $package): bool
|
public function isUnacceptableFixedOrLockedPackage(BasePackage $package): bool
|
||||||
{
|
{
|
||||||
return \in_array($package, $this->unacceptableFixedOrLockedPackages, true);
|
return \in_array($package, $this->unacceptableFixedOrLockedPackages, true);
|
||||||
|
|
|
@ -78,34 +78,34 @@ class PoolBuilder
|
||||||
* @var array[]
|
* @var array[]
|
||||||
* @phpstan-var array<string, AliasPackage[]>
|
* @phpstan-var array<string, AliasPackage[]>
|
||||||
*/
|
*/
|
||||||
private $aliasMap = array();
|
private $aliasMap = [];
|
||||||
/**
|
/**
|
||||||
* @var ConstraintInterface[]
|
* @var ConstraintInterface[]
|
||||||
* @phpstan-var array<string, ConstraintInterface>
|
* @phpstan-var array<string, ConstraintInterface>
|
||||||
*/
|
*/
|
||||||
private $packagesToLoad = array();
|
private $packagesToLoad = [];
|
||||||
/**
|
/**
|
||||||
* @var ConstraintInterface[]
|
* @var ConstraintInterface[]
|
||||||
* @phpstan-var array<string, ConstraintInterface>
|
* @phpstan-var array<string, ConstraintInterface>
|
||||||
*/
|
*/
|
||||||
private $loadedPackages = array();
|
private $loadedPackages = [];
|
||||||
/**
|
/**
|
||||||
* @var array[]
|
* @var array[]
|
||||||
* @phpstan-var array<int, array<string, array<string, PackageInterface>>>
|
* @phpstan-var array<int, array<string, array<string, PackageInterface>>>
|
||||||
*/
|
*/
|
||||||
private $loadedPerRepo = array();
|
private $loadedPerRepo = [];
|
||||||
/**
|
/**
|
||||||
* @var BasePackage[]
|
* @var BasePackage[]
|
||||||
*/
|
*/
|
||||||
private $packages = array();
|
private $packages = [];
|
||||||
/**
|
/**
|
||||||
* @var BasePackage[]
|
* @var BasePackage[]
|
||||||
*/
|
*/
|
||||||
private $unacceptableFixedOrLockedPackages = array();
|
private $unacceptableFixedOrLockedPackages = [];
|
||||||
/** @var string[] */
|
/** @var string[] */
|
||||||
private $updateAllowList = array();
|
private $updateAllowList = [];
|
||||||
/** @var array<string, array<PackageInterface>> */
|
/** @var array<string, array<PackageInterface>> */
|
||||||
private $skippedLoad = array();
|
private $skippedLoad = [];
|
||||||
|
|
||||||
/**
|
/**
|
||||||
* Keeps a list of dependencies which are locked but were auto-unlocked as they are path repositories
|
* Keeps a list of dependencies which are locked but were auto-unlocked as they are path repositories
|
||||||
|
@ -115,7 +115,7 @@ class PoolBuilder
|
||||||
*
|
*
|
||||||
* @var array<string, true>
|
* @var array<string, true>
|
||||||
*/
|
*/
|
||||||
private $pathRepoUnlocked = array();
|
private $pathRepoUnlocked = [];
|
||||||
|
|
||||||
/**
|
/**
|
||||||
* Keeps a list of dependencies which are root requirements, and as such
|
* Keeps a list of dependencies which are root requirements, and as such
|
||||||
|
@ -127,12 +127,12 @@ class PoolBuilder
|
||||||
*
|
*
|
||||||
* @var array<string, true>
|
* @var array<string, true>
|
||||||
*/
|
*/
|
||||||
private $maxExtendedReqs = array();
|
private $maxExtendedReqs = [];
|
||||||
/**
|
/**
|
||||||
* @var array
|
* @var array
|
||||||
* @phpstan-var array<string, bool>
|
* @phpstan-var array<string, bool>
|
||||||
*/
|
*/
|
||||||
private $updateAllowWarned = array();
|
private $updateAllowWarned = [];
|
||||||
|
|
||||||
/** @var int */
|
/** @var int */
|
||||||
private $indexCounter = 0;
|
private $indexCounter = 0;
|
||||||
|
@ -148,7 +148,7 @@ class PoolBuilder
|
||||||
* @phpstan-param array<string, string> $rootReferences
|
* @phpstan-param array<string, string> $rootReferences
|
||||||
* @param array<string, ConstraintInterface> $temporaryConstraints Runtime temporary constraints that will be used to filter packages
|
* @param array<string, ConstraintInterface> $temporaryConstraints Runtime temporary constraints that will be used to filter packages
|
||||||
*/
|
*/
|
||||||
public function __construct(array $acceptableStabilities, array $stabilityFlags, array $rootAliases, array $rootReferences, IOInterface $io, EventDispatcher $eventDispatcher = null, PoolOptimizer $poolOptimizer = null, array $temporaryConstraints = [])
|
public function __construct(array $acceptableStabilities, array $stabilityFlags, array $rootAliases, array $rootReferences, IOInterface $io, ?EventDispatcher $eventDispatcher = null, ?PoolOptimizer $poolOptimizer = null, array $temporaryConstraints = [])
|
||||||
{
|
{
|
||||||
$this->acceptableStabilities = $acceptableStabilities;
|
$this->acceptableStabilities = $acceptableStabilities;
|
||||||
$this->stabilityFlags = $stabilityFlags;
|
$this->stabilityFlags = $stabilityFlags;
|
||||||
|
@ -162,7 +162,6 @@ class PoolBuilder
|
||||||
|
|
||||||
/**
|
/**
|
||||||
* @param RepositoryInterface[] $repositories
|
* @param RepositoryInterface[] $repositories
|
||||||
* @return Pool
|
|
||||||
*/
|
*/
|
||||||
public function buildPool(array $repositories, Request $request): Pool
|
public function buildPool(array $repositories, Request $request): Pool
|
||||||
{
|
{
|
||||||
|
@ -248,7 +247,7 @@ class PoolBuilder
|
||||||
}
|
}
|
||||||
|
|
||||||
$constraint = $this->temporaryConstraints[$package->getName()];
|
$constraint = $this->temporaryConstraints[$package->getName()];
|
||||||
$packageAndAliases = array($i => $package);
|
$packageAndAliases = [$i => $package];
|
||||||
if (isset($this->aliasMap[spl_object_hash($package)])) {
|
if (isset($this->aliasMap[spl_object_hash($package)])) {
|
||||||
$packageAndAliases += $this->aliasMap[spl_object_hash($package)];
|
$packageAndAliases += $this->aliasMap[spl_object_hash($package)];
|
||||||
}
|
}
|
||||||
|
@ -287,14 +286,14 @@ class PoolBuilder
|
||||||
|
|
||||||
$pool = new Pool($this->packages, $this->unacceptableFixedOrLockedPackages);
|
$pool = new Pool($this->packages, $this->unacceptableFixedOrLockedPackages);
|
||||||
|
|
||||||
$this->aliasMap = array();
|
$this->aliasMap = [];
|
||||||
$this->packagesToLoad = array();
|
$this->packagesToLoad = [];
|
||||||
$this->loadedPackages = array();
|
$this->loadedPackages = [];
|
||||||
$this->loadedPerRepo = array();
|
$this->loadedPerRepo = [];
|
||||||
$this->packages = array();
|
$this->packages = [];
|
||||||
$this->unacceptableFixedOrLockedPackages = array();
|
$this->unacceptableFixedOrLockedPackages = [];
|
||||||
$this->maxExtendedReqs = array();
|
$this->maxExtendedReqs = [];
|
||||||
$this->skippedLoad = array();
|
$this->skippedLoad = [];
|
||||||
$this->indexCounter = 0;
|
$this->indexCounter = 0;
|
||||||
|
|
||||||
$this->io->debug('Built pool.');
|
$this->io->debug('Built pool.');
|
||||||
|
@ -306,10 +305,6 @@ class PoolBuilder
|
||||||
return $pool;
|
return $pool;
|
||||||
}
|
}
|
||||||
|
|
||||||
/**
|
|
||||||
* @param string $name
|
|
||||||
* @return void
|
|
||||||
*/
|
|
||||||
private function markPackageNameForLoading(Request $request, string $name, ConstraintInterface $constraint): void
|
private function markPackageNameForLoading(Request $request, string $name, ConstraintInterface $constraint): void
|
||||||
{
|
{
|
||||||
// Skip platform requires at this stage
|
// Skip platform requires at this stage
|
||||||
|
@ -344,7 +339,7 @@ class PoolBuilder
|
||||||
}
|
}
|
||||||
|
|
||||||
// extend the constraint to be loaded
|
// extend the constraint to be loaded
|
||||||
$constraint = Intervals::compactConstraint(MultiConstraint::create(array($this->packagesToLoad[$name], $constraint), false));
|
$constraint = Intervals::compactConstraint(MultiConstraint::create([$this->packagesToLoad[$name], $constraint], false));
|
||||||
}
|
}
|
||||||
|
|
||||||
$this->packagesToLoad[$name] = $constraint;
|
$this->packagesToLoad[$name] = $constraint;
|
||||||
|
@ -361,13 +356,12 @@ class PoolBuilder
|
||||||
// We have already loaded that package but not in the constraint that's
|
// We have already loaded that package but not in the constraint that's
|
||||||
// required. We extend the constraint and mark that package as not being loaded
|
// required. We extend the constraint and mark that package as not being loaded
|
||||||
// yet so we get the required package versions
|
// yet so we get the required package versions
|
||||||
$this->packagesToLoad[$name] = Intervals::compactConstraint(MultiConstraint::create(array($this->loadedPackages[$name], $constraint), false));
|
$this->packagesToLoad[$name] = Intervals::compactConstraint(MultiConstraint::create([$this->loadedPackages[$name], $constraint], false));
|
||||||
unset($this->loadedPackages[$name]);
|
unset($this->loadedPackages[$name]);
|
||||||
}
|
}
|
||||||
|
|
||||||
/**
|
/**
|
||||||
* @param RepositoryInterface[] $repositories
|
* @param RepositoryInterface[] $repositories
|
||||||
* @return void
|
|
||||||
*/
|
*/
|
||||||
private function loadPackagesMarkedForLoading(Request $request, array $repositories): void
|
private function loadPackagesMarkedForLoading(Request $request, array $repositories): void
|
||||||
{
|
{
|
||||||
|
@ -376,7 +370,7 @@ class PoolBuilder
|
||||||
}
|
}
|
||||||
|
|
||||||
$packageBatch = $this->packagesToLoad;
|
$packageBatch = $this->packagesToLoad;
|
||||||
$this->packagesToLoad = array();
|
$this->packagesToLoad = [];
|
||||||
|
|
||||||
foreach ($repositories as $repoIndex => $repository) {
|
foreach ($repositories as $repoIndex => $repository) {
|
||||||
if (empty($packageBatch)) {
|
if (empty($packageBatch)) {
|
||||||
|
@ -388,7 +382,7 @@ class PoolBuilder
|
||||||
if ($repository instanceof PlatformRepository || $repository === $request->getLockedRepository()) {
|
if ($repository instanceof PlatformRepository || $repository === $request->getLockedRepository()) {
|
||||||
continue;
|
continue;
|
||||||
}
|
}
|
||||||
$result = $repository->loadPackages($packageBatch, $this->acceptableStabilities, $this->stabilityFlags, $this->loadedPerRepo[$repoIndex] ?? array());
|
$result = $repository->loadPackages($packageBatch, $this->acceptableStabilities, $this->stabilityFlags, $this->loadedPerRepo[$repoIndex] ?? []);
|
||||||
|
|
||||||
foreach ($result['namesFound'] as $name) {
|
foreach ($result['namesFound'] as $name) {
|
||||||
// avoid loading the same package again from other repositories once it has been found
|
// avoid loading the same package again from other repositories once it has been found
|
||||||
|
@ -402,9 +396,7 @@ class PoolBuilder
|
||||||
}
|
}
|
||||||
|
|
||||||
/**
|
/**
|
||||||
* @param bool $propagateUpdate
|
|
||||||
* @param RepositoryInterface[] $repositories
|
* @param RepositoryInterface[] $repositories
|
||||||
* @return void
|
|
||||||
*/
|
*/
|
||||||
private function loadPackage(Request $request, array $repositories, BasePackage $package, bool $propagateUpdate): void
|
private function loadPackage(Request $request, array $repositories, BasePackage $package, bool $propagateUpdate): void
|
||||||
{
|
{
|
||||||
|
@ -509,7 +501,6 @@ class PoolBuilder
|
||||||
* Checks if a particular name is required directly in the request
|
* Checks if a particular name is required directly in the request
|
||||||
*
|
*
|
||||||
* @param string $name packageName
|
* @param string $name packageName
|
||||||
* @return bool
|
|
||||||
*/
|
*/
|
||||||
private function isRootRequire(Request $request, string $name): bool
|
private function isRootRequire(Request $request, string $name): bool
|
||||||
{
|
{
|
||||||
|
@ -519,17 +510,16 @@ class PoolBuilder
|
||||||
}
|
}
|
||||||
|
|
||||||
/**
|
/**
|
||||||
* @param string $name
|
|
||||||
* @return string[]
|
* @return string[]
|
||||||
*/
|
*/
|
||||||
private function getSkippedRootRequires(Request $request, string $name): array
|
private function getSkippedRootRequires(Request $request, string $name): array
|
||||||
{
|
{
|
||||||
if (!isset($this->skippedLoad[$name])) {
|
if (!isset($this->skippedLoad[$name])) {
|
||||||
return array();
|
return [];
|
||||||
}
|
}
|
||||||
|
|
||||||
$rootRequires = $request->getRequires();
|
$rootRequires = $request->getRequires();
|
||||||
$matches = array();
|
$matches = [];
|
||||||
|
|
||||||
if (isset($rootRequires[$name])) {
|
if (isset($rootRequires[$name])) {
|
||||||
return array_map(static function (PackageInterface $package) use ($name): string {
|
return array_map(static function (PackageInterface $package) use ($name): string {
|
||||||
|
@ -562,8 +552,6 @@ class PoolBuilder
|
||||||
|
|
||||||
/**
|
/**
|
||||||
* Checks whether the update allow list allows this package in the lock file to be updated
|
* Checks whether the update allow list allows this package in the lock file to be updated
|
||||||
*
|
|
||||||
* @return bool
|
|
||||||
*/
|
*/
|
||||||
private function isUpdateAllowed(BasePackage $package): bool
|
private function isUpdateAllowed(BasePackage $package): bool
|
||||||
{
|
{
|
||||||
|
@ -577,9 +565,6 @@ class PoolBuilder
|
||||||
return false;
|
return false;
|
||||||
}
|
}
|
||||||
|
|
||||||
/**
|
|
||||||
* @return void
|
|
||||||
*/
|
|
||||||
private function warnAboutNonMatchingUpdateAllowList(Request $request): void
|
private function warnAboutNonMatchingUpdateAllowList(Request $request): void
|
||||||
{
|
{
|
||||||
foreach ($this->updateAllowList as $pattern => $void) {
|
foreach ($this->updateAllowList as $pattern => $void) {
|
||||||
|
@ -609,8 +594,6 @@ class PoolBuilder
|
||||||
* found that this package actually needs to be updated
|
* found that this package actually needs to be updated
|
||||||
*
|
*
|
||||||
* @param RepositoryInterface[] $repositories
|
* @param RepositoryInterface[] $repositories
|
||||||
* @param string $name
|
|
||||||
* @return void
|
|
||||||
*/
|
*/
|
||||||
private function unlockPackage(Request $request, array $repositories, string $name): void
|
private function unlockPackage(Request $request, array $repositories, string $name): void
|
||||||
{
|
{
|
||||||
|
@ -675,8 +658,6 @@ class PoolBuilder
|
||||||
|
|
||||||
/**
|
/**
|
||||||
* @param RepositoryInterface[] $repositories
|
* @param RepositoryInterface[] $repositories
|
||||||
* @param int $index
|
|
||||||
* @return void
|
|
||||||
*/
|
*/
|
||||||
private function removeLoadedPackage(Request $request, array $repositories, BasePackage $package, int $index): void
|
private function removeLoadedPackage(Request $request, array $repositories, BasePackage $package, int $index): void
|
||||||
{
|
{
|
||||||
|
@ -693,9 +674,6 @@ class PoolBuilder
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
|
|
||||||
/**
|
|
||||||
* @return Pool
|
|
||||||
*/
|
|
||||||
private function runOptimizer(Request $request, Pool $pool): Pool
|
private function runOptimizer(Request $request, Pool $pool): Pool
|
||||||
{
|
{
|
||||||
if (null === $this->poolOptimizer) {
|
if (null === $this->poolOptimizer) {
|
||||||
|
|
|
@ -36,41 +36,38 @@ class PoolOptimizer
|
||||||
/**
|
/**
|
||||||
* @var array<int, true>
|
* @var array<int, true>
|
||||||
*/
|
*/
|
||||||
private $irremovablePackages = array();
|
private $irremovablePackages = [];
|
||||||
|
|
||||||
/**
|
/**
|
||||||
* @var array<string, array<string, ConstraintInterface>>
|
* @var array<string, array<string, ConstraintInterface>>
|
||||||
*/
|
*/
|
||||||
private $requireConstraintsPerPackage = array();
|
private $requireConstraintsPerPackage = [];
|
||||||
|
|
||||||
/**
|
/**
|
||||||
* @var array<string, array<string, ConstraintInterface>>
|
* @var array<string, array<string, ConstraintInterface>>
|
||||||
*/
|
*/
|
||||||
private $conflictConstraintsPerPackage = array();
|
private $conflictConstraintsPerPackage = [];
|
||||||
|
|
||||||
/**
|
/**
|
||||||
* @var array<int, true>
|
* @var array<int, true>
|
||||||
*/
|
*/
|
||||||
private $packagesToRemove = array();
|
private $packagesToRemove = [];
|
||||||
|
|
||||||
/**
|
/**
|
||||||
* @var array<int, BasePackage[]>
|
* @var array<int, BasePackage[]>
|
||||||
*/
|
*/
|
||||||
private $aliasesPerPackage = array();
|
private $aliasesPerPackage = [];
|
||||||
|
|
||||||
/**
|
/**
|
||||||
* @var array<string, array<string, string>>
|
* @var array<string, array<string, string>>
|
||||||
*/
|
*/
|
||||||
private $removedVersionsByPackage = array();
|
private $removedVersionsByPackage = [];
|
||||||
|
|
||||||
public function __construct(PolicyInterface $policy)
|
public function __construct(PolicyInterface $policy)
|
||||||
{
|
{
|
||||||
$this->policy = $policy;
|
$this->policy = $policy;
|
||||||
}
|
}
|
||||||
|
|
||||||
/**
|
|
||||||
* @return Pool
|
|
||||||
*/
|
|
||||||
public function optimize(Request $request, Pool $pool): Pool
|
public function optimize(Request $request, Pool $pool): Pool
|
||||||
{
|
{
|
||||||
$this->prepare($request, $pool);
|
$this->prepare($request, $pool);
|
||||||
|
@ -86,22 +83,19 @@ class PoolOptimizer
|
||||||
// even more gains when ran again. Might change
|
// even more gains when ran again. Might change
|
||||||
// in the future with additional optimizations.
|
// in the future with additional optimizations.
|
||||||
|
|
||||||
$this->irremovablePackages = array();
|
$this->irremovablePackages = [];
|
||||||
$this->requireConstraintsPerPackage = array();
|
$this->requireConstraintsPerPackage = [];
|
||||||
$this->conflictConstraintsPerPackage = array();
|
$this->conflictConstraintsPerPackage = [];
|
||||||
$this->packagesToRemove = array();
|
$this->packagesToRemove = [];
|
||||||
$this->aliasesPerPackage = array();
|
$this->aliasesPerPackage = [];
|
||||||
$this->removedVersionsByPackage = array();
|
$this->removedVersionsByPackage = [];
|
||||||
|
|
||||||
return $optimizedPool;
|
return $optimizedPool;
|
||||||
}
|
}
|
||||||
|
|
||||||
/**
|
|
||||||
* @return void
|
|
||||||
*/
|
|
||||||
private function prepare(Request $request, Pool $pool): void
|
private function prepare(Request $request, Pool $pool): void
|
||||||
{
|
{
|
||||||
$irremovablePackageConstraintGroups = array();
|
$irremovablePackageConstraintGroups = [];
|
||||||
|
|
||||||
// Mark fixed or locked packages as irremovable
|
// Mark fixed or locked packages as irremovable
|
||||||
foreach ($request->getFixedOrLockedPackages() as $package) {
|
foreach ($request->getFixedOrLockedPackages() as $package) {
|
||||||
|
@ -131,7 +125,7 @@ class PoolOptimizer
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
|
|
||||||
$irremovablePackageConstraints = array();
|
$irremovablePackageConstraints = [];
|
||||||
foreach ($irremovablePackageConstraintGroups as $packageName => $constraints) {
|
foreach ($irremovablePackageConstraintGroups as $packageName => $constraints) {
|
||||||
$irremovablePackageConstraints[$packageName] = 1 === \count($constraints) ? $constraints[0] : new MultiConstraint($constraints, false);
|
$irremovablePackageConstraints[$packageName] = 1 === \count($constraints) ? $constraints[0] : new MultiConstraint($constraints, false);
|
||||||
}
|
}
|
||||||
|
@ -149,9 +143,6 @@ class PoolOptimizer
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
|
|
||||||
/**
|
|
||||||
* @return void
|
|
||||||
*/
|
|
||||||
private function markPackageIrremovable(BasePackage $package): void
|
private function markPackageIrremovable(BasePackage $package): void
|
||||||
{
|
{
|
||||||
$this->irremovablePackages[$package->id] = true;
|
$this->irremovablePackages[$package->id] = true;
|
||||||
|
@ -172,8 +163,8 @@ class PoolOptimizer
|
||||||
*/
|
*/
|
||||||
private function applyRemovalsToPool(Pool $pool): Pool
|
private function applyRemovalsToPool(Pool $pool): Pool
|
||||||
{
|
{
|
||||||
$packages = array();
|
$packages = [];
|
||||||
$removedVersions = array();
|
$removedVersions = [];
|
||||||
foreach ($pool->getPackages() as $package) {
|
foreach ($pool->getPackages() as $package) {
|
||||||
if (!isset($this->packagesToRemove[$package->id])) {
|
if (!isset($this->packagesToRemove[$package->id])) {
|
||||||
$packages[] = $package;
|
$packages[] = $package;
|
||||||
|
@ -187,13 +178,10 @@ class PoolOptimizer
|
||||||
return $optimizedPool;
|
return $optimizedPool;
|
||||||
}
|
}
|
||||||
|
|
||||||
/**
|
|
||||||
* @return void
|
|
||||||
*/
|
|
||||||
private function optimizeByIdenticalDependencies(Request $request, Pool $pool): void
|
private function optimizeByIdenticalDependencies(Request $request, Pool $pool): void
|
||||||
{
|
{
|
||||||
$identicalDefinitionsPerPackage = array();
|
$identicalDefinitionsPerPackage = [];
|
||||||
$packageIdenticalDefinitionLookup = array();
|
$packageIdenticalDefinitionLookup = [];
|
||||||
|
|
||||||
foreach ($pool->getPackages() as $package) {
|
foreach ($pool->getPackages() as $package) {
|
||||||
|
|
||||||
|
@ -213,7 +201,7 @@ class PoolOptimizer
|
||||||
}
|
}
|
||||||
|
|
||||||
foreach ($this->requireConstraintsPerPackage[$packageName] as $requireConstraint) {
|
foreach ($this->requireConstraintsPerPackage[$packageName] as $requireConstraint) {
|
||||||
$groupHashParts = array();
|
$groupHashParts = [];
|
||||||
|
|
||||||
if (CompilingMatcher::match($requireConstraint, Constraint::OP_EQ, $package->getVersion())) {
|
if (CompilingMatcher::match($requireConstraint, Constraint::OP_EQ, $package->getVersion())) {
|
||||||
$groupHashParts[] = 'require:' . (string) $requireConstraint;
|
$groupHashParts[] = 'require:' . (string) $requireConstraint;
|
||||||
|
@ -242,7 +230,7 @@ class PoolOptimizer
|
||||||
|
|
||||||
$groupHash = implode('', $groupHashParts);
|
$groupHash = implode('', $groupHashParts);
|
||||||
$identicalDefinitionsPerPackage[$packageName][$groupHash][$dependencyHash][] = $package;
|
$identicalDefinitionsPerPackage[$packageName][$groupHash][$dependencyHash][] = $package;
|
||||||
$packageIdenticalDefinitionLookup[$package->id][$packageName] = array('groupHash' => $groupHash, 'dependencyHash' => $dependencyHash);
|
$packageIdenticalDefinitionLookup[$package->id][$packageName] = ['groupHash' => $groupHash, 'dependencyHash' => $dependencyHash];
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
|
@ -258,7 +246,7 @@ class PoolOptimizer
|
||||||
|
|
||||||
// Otherwise we find out which one is the preferred package in this constraint group which is
|
// Otherwise we find out which one is the preferred package in this constraint group which is
|
||||||
// then not allowed to be removed either
|
// then not allowed to be removed either
|
||||||
$literals = array();
|
$literals = [];
|
||||||
|
|
||||||
foreach ($packages as $package) {
|
foreach ($packages as $package) {
|
||||||
$literals[] = $package->id;
|
$literals[] = $package->id;
|
||||||
|
@ -272,19 +260,16 @@ class PoolOptimizer
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
|
|
||||||
/**
|
|
||||||
* @return string
|
|
||||||
*/
|
|
||||||
private function calculateDependencyHash(BasePackage $package): string
|
private function calculateDependencyHash(BasePackage $package): string
|
||||||
{
|
{
|
||||||
$hash = '';
|
$hash = '';
|
||||||
|
|
||||||
$hashRelevantLinks = array(
|
$hashRelevantLinks = [
|
||||||
'requires' => $package->getRequires(),
|
'requires' => $package->getRequires(),
|
||||||
'conflicts' => $package->getConflicts(),
|
'conflicts' => $package->getConflicts(),
|
||||||
'replaces' => $package->getReplaces(),
|
'replaces' => $package->getReplaces(),
|
||||||
'provides' => $package->getProvides(),
|
'provides' => $package->getProvides(),
|
||||||
);
|
];
|
||||||
|
|
||||||
foreach ($hashRelevantLinks as $key => $links) {
|
foreach ($hashRelevantLinks as $key => $links) {
|
||||||
if (0 === \count($links)) {
|
if (0 === \count($links)) {
|
||||||
|
@ -294,7 +279,7 @@ class PoolOptimizer
|
||||||
// start new hash section
|
// start new hash section
|
||||||
$hash .= $key . ':';
|
$hash .= $key . ':';
|
||||||
|
|
||||||
$subhash = array();
|
$subhash = [];
|
||||||
|
|
||||||
foreach ($links as $link) {
|
foreach ($links as $link) {
|
||||||
// To get the best dependency hash matches we should use Intervals::compactConstraint() here.
|
// To get the best dependency hash matches we should use Intervals::compactConstraint() here.
|
||||||
|
@ -315,10 +300,6 @@ class PoolOptimizer
|
||||||
return $hash;
|
return $hash;
|
||||||
}
|
}
|
||||||
|
|
||||||
/**
|
|
||||||
* @param int $id
|
|
||||||
* @return void
|
|
||||||
*/
|
|
||||||
private function markPackageForRemoval(int $id): void
|
private function markPackageForRemoval(int $id): void
|
||||||
{
|
{
|
||||||
// We are not allowed to remove packages if they have been marked as irremovable
|
// We are not allowed to remove packages if they have been marked as irremovable
|
||||||
|
@ -332,7 +313,6 @@ class PoolOptimizer
|
||||||
/**
|
/**
|
||||||
* @param array<string, array<string, array<string, list<BasePackage>>>> $identicalDefinitionsPerPackage
|
* @param array<string, array<string, array<string, list<BasePackage>>>> $identicalDefinitionsPerPackage
|
||||||
* @param array<int, array<string, array{groupHash: string, dependencyHash: string}>> $packageIdenticalDefinitionLookup
|
* @param array<int, array<string, array{groupHash: string, dependencyHash: string}>> $packageIdenticalDefinitionLookup
|
||||||
* @return void
|
|
||||||
*/
|
*/
|
||||||
private function keepPackage(BasePackage $package, array $identicalDefinitionsPerPackage, array $packageIdenticalDefinitionLookup): void
|
private function keepPackage(BasePackage $package, array $identicalDefinitionsPerPackage, array $packageIdenticalDefinitionLookup): void
|
||||||
{
|
{
|
||||||
|
@ -388,8 +368,6 @@ class PoolOptimizer
|
||||||
* Use the list of locked packages to constrain the loaded packages
|
* Use the list of locked packages to constrain the loaded packages
|
||||||
* This will reduce packages with significant numbers of historical versions to a smaller number
|
* This will reduce packages with significant numbers of historical versions to a smaller number
|
||||||
* and reduce the resulting rule set that is generated
|
* and reduce the resulting rule set that is generated
|
||||||
*
|
|
||||||
* @return void
|
|
||||||
*/
|
*/
|
||||||
private function optimizeImpossiblePackagesAway(Request $request, Pool $pool): void
|
private function optimizeImpossiblePackagesAway(Request $request, Pool $pool): void
|
||||||
{
|
{
|
||||||
|
@ -397,7 +375,7 @@ class PoolOptimizer
|
||||||
return;
|
return;
|
||||||
}
|
}
|
||||||
|
|
||||||
$packageIndex = array();
|
$packageIndex = [];
|
||||||
|
|
||||||
foreach ($pool->getPackages() as $package) {
|
foreach ($pool->getPackages() as $package) {
|
||||||
$id = $package->id;
|
$id = $package->id;
|
||||||
|
@ -455,11 +433,9 @@ class PoolOptimizer
|
||||||
* two require constraint groups in order for us to keep the best matching package for "^2.14" AND "^3.3" as otherwise, we'd
|
* two require constraint groups in order for us to keep the best matching package for "^2.14" AND "^3.3" as otherwise, we'd
|
||||||
* only keep either one which can cause trouble (e.g. when using --prefer-lowest).
|
* only keep either one which can cause trouble (e.g. when using --prefer-lowest).
|
||||||
*
|
*
|
||||||
* @param string $package
|
|
||||||
* @param ConstraintInterface $constraint
|
|
||||||
* @return void
|
* @return void
|
||||||
*/
|
*/
|
||||||
private function extractRequireConstraintsPerPackage($package, ConstraintInterface $constraint)
|
private function extractRequireConstraintsPerPackage(string $package, ConstraintInterface $constraint)
|
||||||
{
|
{
|
||||||
foreach ($this->expandDisjunctiveMultiConstraints($constraint) as $expanded) {
|
foreach ($this->expandDisjunctiveMultiConstraints($constraint) as $expanded) {
|
||||||
$this->requireConstraintsPerPackage[$package][(string) $expanded] = $expanded;
|
$this->requireConstraintsPerPackage[$package][(string) $expanded] = $expanded;
|
||||||
|
@ -471,11 +447,9 @@ class PoolOptimizer
|
||||||
* two conflict constraint groups in order for us to keep the best matching package for "^2.14" AND "^3.3" as otherwise, we'd
|
* two conflict constraint groups in order for us to keep the best matching package for "^2.14" AND "^3.3" as otherwise, we'd
|
||||||
* only keep either one which can cause trouble (e.g. when using --prefer-lowest).
|
* only keep either one which can cause trouble (e.g. when using --prefer-lowest).
|
||||||
*
|
*
|
||||||
* @param string $package
|
|
||||||
* @param ConstraintInterface $constraint
|
|
||||||
* @return void
|
* @return void
|
||||||
*/
|
*/
|
||||||
private function extractConflictConstraintsPerPackage($package, ConstraintInterface $constraint)
|
private function extractConflictConstraintsPerPackage(string $package, ConstraintInterface $constraint)
|
||||||
{
|
{
|
||||||
foreach ($this->expandDisjunctiveMultiConstraints($constraint) as $expanded) {
|
foreach ($this->expandDisjunctiveMultiConstraints($constraint) as $expanded) {
|
||||||
$this->conflictConstraintsPerPackage[$package][(string) $expanded] = $expanded;
|
$this->conflictConstraintsPerPackage[$package][(string) $expanded] = $expanded;
|
||||||
|
@ -483,8 +457,6 @@ class PoolOptimizer
|
||||||
}
|
}
|
||||||
|
|
||||||
/**
|
/**
|
||||||
*
|
|
||||||
* @param ConstraintInterface $constraint
|
|
||||||
* @return ConstraintInterface[]
|
* @return ConstraintInterface[]
|
||||||
*/
|
*/
|
||||||
private function expandDisjunctiveMultiConstraints(ConstraintInterface $constraint)
|
private function expandDisjunctiveMultiConstraints(ConstraintInterface $constraint)
|
||||||
|
@ -498,6 +470,6 @@ class PoolOptimizer
|
||||||
}
|
}
|
||||||
|
|
||||||
// Regular constraints and conjunctive MultiConstraints
|
// Regular constraints and conjunctive MultiConstraints
|
||||||
return array($constraint);
|
return [$constraint];
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
|
|
|
@ -43,7 +43,7 @@ class Problem
|
||||||
* A set of reasons for the problem, each is a rule or a root require and a rule
|
* A set of reasons for the problem, each is a rule or a root require and a rule
|
||||||
* @var array<int, array<int, Rule>>
|
* @var array<int, array<int, Rule>>
|
||||||
*/
|
*/
|
||||||
protected $reasons = array();
|
protected $reasons = [];
|
||||||
|
|
||||||
/** @var int */
|
/** @var int */
|
||||||
protected $section = 0;
|
protected $section = 0;
|
||||||
|
@ -52,7 +52,6 @@ class Problem
|
||||||
* Add a rule as a reason
|
* Add a rule as a reason
|
||||||
*
|
*
|
||||||
* @param Rule $rule A rule which is a reason for this problem
|
* @param Rule $rule A rule which is a reason for this problem
|
||||||
* @return void
|
|
||||||
*/
|
*/
|
||||||
public function addRule(Rule $rule): void
|
public function addRule(Rule $rule): void
|
||||||
{
|
{
|
||||||
|
@ -72,22 +71,20 @@ class Problem
|
||||||
/**
|
/**
|
||||||
* A human readable textual representation of the problem's reasons
|
* A human readable textual representation of the problem's reasons
|
||||||
*
|
*
|
||||||
* @param bool $isVerbose
|
|
||||||
* @param array<int|string, BasePackage> $installedMap A map of all present packages
|
* @param array<int|string, BasePackage> $installedMap A map of all present packages
|
||||||
* @param array<Rule[]> $learnedPool
|
* @param array<Rule[]> $learnedPool
|
||||||
* @return string
|
|
||||||
*/
|
*/
|
||||||
public function getPrettyString(RepositorySet $repositorySet, Request $request, Pool $pool, bool $isVerbose, array $installedMap = array(), array $learnedPool = array()): string
|
public function getPrettyString(RepositorySet $repositorySet, Request $request, Pool $pool, bool $isVerbose, array $installedMap = [], array $learnedPool = []): string
|
||||||
{
|
{
|
||||||
// TODO doesn't this entirely defeat the purpose of the problem sections? what's the point of sections?
|
// TODO doesn't this entirely defeat the purpose of the problem sections? what's the point of sections?
|
||||||
$reasons = call_user_func_array('array_merge', array_reverse($this->reasons));
|
$reasons = array_merge(...array_reverse($this->reasons));
|
||||||
|
|
||||||
if (count($reasons) === 1) {
|
if (count($reasons) === 1) {
|
||||||
reset($reasons);
|
reset($reasons);
|
||||||
$rule = current($reasons);
|
$rule = current($reasons);
|
||||||
|
|
||||||
if (!in_array($rule->getReason(), array(Rule::RULE_ROOT_REQUIRE, Rule::RULE_FIXED), true)) {
|
if ($rule->getReason() !== Rule::RULE_ROOT_REQUIRE) {
|
||||||
throw new \LogicException("Single reason problems must contain a request rule.");
|
throw new \LogicException("Single reason problems must contain a root require rule.");
|
||||||
}
|
}
|
||||||
|
|
||||||
$reasonData = $rule->getReasonData();
|
$reasonData = $rule->getReasonData();
|
||||||
|
@ -97,7 +94,7 @@ class Problem
|
||||||
if (isset($constraint)) {
|
if (isset($constraint)) {
|
||||||
$packages = $pool->whatProvides($packageName, $constraint);
|
$packages = $pool->whatProvides($packageName, $constraint);
|
||||||
} else {
|
} else {
|
||||||
$packages = array();
|
$packages = [];
|
||||||
}
|
}
|
||||||
|
|
||||||
if (empty($packages)) {
|
if (empty($packages)) {
|
||||||
|
@ -110,19 +107,16 @@ class Problem
|
||||||
|
|
||||||
/**
|
/**
|
||||||
* @param Rule[] $rules
|
* @param Rule[] $rules
|
||||||
* @param string $indent
|
|
||||||
* @param bool $isVerbose
|
|
||||||
* @param array<int|string, BasePackage> $installedMap A map of all present packages
|
* @param array<int|string, BasePackage> $installedMap A map of all present packages
|
||||||
* @param array<Rule[]> $learnedPool
|
* @param array<Rule[]> $learnedPool
|
||||||
* @return string
|
|
||||||
* @internal
|
* @internal
|
||||||
*/
|
*/
|
||||||
public static function formatDeduplicatedRules(array $rules, string $indent, RepositorySet $repositorySet, Request $request, Pool $pool, bool $isVerbose, array $installedMap = array(), array $learnedPool = array()): string
|
public static function formatDeduplicatedRules(array $rules, string $indent, RepositorySet $repositorySet, Request $request, Pool $pool, bool $isVerbose, array $installedMap = [], array $learnedPool = []): string
|
||||||
{
|
{
|
||||||
$messages = array();
|
$messages = [];
|
||||||
$templates = array();
|
$templates = [];
|
||||||
$parser = new VersionParser;
|
$parser = new VersionParser;
|
||||||
$deduplicatableRuleTypes = array(Rule::RULE_PACKAGE_REQUIRES, Rule::RULE_PACKAGE_CONFLICT);
|
$deduplicatableRuleTypes = [Rule::RULE_PACKAGE_REQUIRES, Rule::RULE_PACKAGE_CONFLICT];
|
||||||
foreach ($rules as $rule) {
|
foreach ($rules as $rule) {
|
||||||
$message = $rule->getPrettyString($repositorySet, $request, $pool, $isVerbose, $installedMap, $learnedPool);
|
$message = $rule->getPrettyString($repositorySet, $request, $pool, $isVerbose, $installedMap, $learnedPool);
|
||||||
if (in_array($rule->getReason(), $deduplicatableRuleTypes, true) && Preg::isMatch('{^(?P<package>\S+) (?P<version>\S+) (?P<type>requires|conflicts)}', $message, $m)) {
|
if (in_array($rule->getReason(), $deduplicatableRuleTypes, true) && Preg::isMatch('{^(?P<package>\S+) (?P<version>\S+) (?P<type>requires|conflicts)}', $message, $m)) {
|
||||||
|
@ -138,7 +132,7 @@ class Problem
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
|
|
||||||
$result = array();
|
$result = [];
|
||||||
foreach (array_unique($messages) as $message) {
|
foreach (array_unique($messages) as $message) {
|
||||||
if (isset($templates[$message])) {
|
if (isset($templates[$message])) {
|
||||||
foreach ($templates[$message] as $package => $versions) {
|
foreach ($templates[$message] as $package => $versions) {
|
||||||
|
@ -162,9 +156,6 @@ class Problem
|
||||||
return "\n$indent- ".implode("\n$indent- ", $result);
|
return "\n$indent- ".implode("\n$indent- ", $result);
|
||||||
}
|
}
|
||||||
|
|
||||||
/**
|
|
||||||
* @return bool
|
|
||||||
*/
|
|
||||||
public function isCausedByLock(RepositorySet $repositorySet, Request $request, Pool $pool): bool
|
public function isCausedByLock(RepositorySet $repositorySet, Request $request, Pool $pool): bool
|
||||||
{
|
{
|
||||||
foreach ($this->reasons as $sectionRules) {
|
foreach ($this->reasons as $sectionRules) {
|
||||||
|
@ -183,7 +174,6 @@ class Problem
|
||||||
*
|
*
|
||||||
* @param string $id A canonical identifier for the reason
|
* @param string $id A canonical identifier for the reason
|
||||||
* @param Rule $reason The reason descriptor
|
* @param Rule $reason The reason descriptor
|
||||||
* @return void
|
|
||||||
*/
|
*/
|
||||||
protected function addReason(string $id, Rule $reason): void
|
protected function addReason(string $id, Rule $reason): void
|
||||||
{
|
{
|
||||||
|
@ -196,9 +186,6 @@ class Problem
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
|
|
||||||
/**
|
|
||||||
* @return void
|
|
||||||
*/
|
|
||||||
public function nextSection(): void
|
public function nextSection(): void
|
||||||
{
|
{
|
||||||
$this->section++;
|
$this->section++;
|
||||||
|
@ -206,11 +193,9 @@ class Problem
|
||||||
|
|
||||||
/**
|
/**
|
||||||
* @internal
|
* @internal
|
||||||
* @param bool $isVerbose
|
|
||||||
* @param string $packageName
|
|
||||||
* @return array{0: string, 1: string}
|
* @return array{0: string, 1: string}
|
||||||
*/
|
*/
|
||||||
public static function getMissingPackageReason(RepositorySet $repositorySet, Request $request, Pool $pool, bool $isVerbose, string $packageName, ConstraintInterface $constraint = null): array
|
public static function getMissingPackageReason(RepositorySet $repositorySet, Request $request, Pool $pool, bool $isVerbose, string $packageName, ?ConstraintInterface $constraint = null): array
|
||||||
{
|
{
|
||||||
if (PlatformRepository::isPlatformPackage($packageName)) {
|
if (PlatformRepository::isPlatformPackage($packageName)) {
|
||||||
// handle php/php-*/hhvm
|
// handle php/php-*/hhvm
|
||||||
|
@ -220,24 +205,24 @@ class Problem
|
||||||
$msg = "- Root composer.json requires ".$packageName.self::constraintToText($constraint).' but ';
|
$msg = "- Root composer.json requires ".$packageName.self::constraintToText($constraint).' but ';
|
||||||
|
|
||||||
if (defined('HHVM_VERSION') || ($packageName === 'hhvm' && count($pool->whatProvides($packageName)) > 0)) {
|
if (defined('HHVM_VERSION') || ($packageName === 'hhvm' && count($pool->whatProvides($packageName)) > 0)) {
|
||||||
return array($msg, 'your HHVM version does not satisfy that requirement.');
|
return [$msg, 'your HHVM version does not satisfy that requirement.'];
|
||||||
}
|
}
|
||||||
|
|
||||||
if ($packageName === 'hhvm') {
|
if ($packageName === 'hhvm') {
|
||||||
return array($msg, 'HHVM was not detected on this machine, make sure it is in your PATH.');
|
return [$msg, 'HHVM was not detected on this machine, make sure it is in your PATH.'];
|
||||||
}
|
}
|
||||||
|
|
||||||
if (null === $version) {
|
if (null === $version) {
|
||||||
return array($msg, 'the '.$packageName.' package is disabled by your platform config. Enable it again with "composer config platform.'.$packageName.' --unset".');
|
return [$msg, 'the '.$packageName.' package is disabled by your platform config. Enable it again with "composer config platform.'.$packageName.' --unset".'];
|
||||||
}
|
}
|
||||||
|
|
||||||
return array($msg, 'your '.$packageName.' version ('. $version .') does not satisfy that requirement.');
|
return [$msg, 'your '.$packageName.' version ('. $version .') does not satisfy that requirement.'];
|
||||||
}
|
}
|
||||||
|
|
||||||
// handle php extensions
|
// handle php extensions
|
||||||
if (0 === stripos($packageName, 'ext-')) {
|
if (0 === stripos($packageName, 'ext-')) {
|
||||||
if (false !== strpos($packageName, ' ')) {
|
if (false !== strpos($packageName, ' ')) {
|
||||||
return array('- ', "PHP extension ".$packageName.' should be required as '.str_replace(' ', '-', $packageName).'.');
|
return ['- ', "PHP extension ".$packageName.' should be required as '.str_replace(' ', '-', $packageName).'.'];
|
||||||
}
|
}
|
||||||
|
|
||||||
$ext = substr($packageName, 4);
|
$ext = substr($packageName, 4);
|
||||||
|
@ -246,16 +231,16 @@ class Problem
|
||||||
$version = self::getPlatformPackageVersion($pool, $packageName, phpversion($ext) ?: '0');
|
$version = self::getPlatformPackageVersion($pool, $packageName, phpversion($ext) ?: '0');
|
||||||
if (null === $version) {
|
if (null === $version) {
|
||||||
if (extension_loaded($ext)) {
|
if (extension_loaded($ext)) {
|
||||||
return array(
|
return [
|
||||||
$msg,
|
$msg,
|
||||||
'the '.$packageName.' package is disabled by your platform config. Enable it again with "composer config platform.'.$packageName.' --unset".',
|
'the '.$packageName.' package is disabled by your platform config. Enable it again with "composer config platform.'.$packageName.' --unset".',
|
||||||
);
|
];
|
||||||
}
|
}
|
||||||
|
|
||||||
return array($msg, 'it is missing from your system. Install or enable PHP\'s '.$ext.' extension.');
|
return [$msg, 'it is missing from your system. Install or enable PHP\'s '.$ext.' extension.'];
|
||||||
}
|
}
|
||||||
|
|
||||||
return array($msg, 'it has the wrong version installed ('.$version.').');
|
return [$msg, 'it has the wrong version installed ('.$version.').'];
|
||||||
}
|
}
|
||||||
|
|
||||||
// handle linked libs
|
// handle linked libs
|
||||||
|
@ -263,10 +248,10 @@ class Problem
|
||||||
if (strtolower($packageName) === 'lib-icu') {
|
if (strtolower($packageName) === 'lib-icu') {
|
||||||
$error = extension_loaded('intl') ? 'it has the wrong version installed, try upgrading the intl extension.' : 'it is missing from your system, make sure the intl extension is loaded.';
|
$error = extension_loaded('intl') ? 'it has the wrong version installed, try upgrading the intl extension.' : 'it is missing from your system, make sure the intl extension is loaded.';
|
||||||
|
|
||||||
return array("- Root composer.json requires linked library ".$packageName.self::constraintToText($constraint).' but ', $error);
|
return ["- Root composer.json requires linked library ".$packageName.self::constraintToText($constraint).' but ', $error];
|
||||||
}
|
}
|
||||||
|
|
||||||
return array("- Root composer.json requires linked library ".$packageName.self::constraintToText($constraint).' but ', 'it has the wrong version installed or is missing from your system, make sure to load the extension providing it.');
|
return ["- Root composer.json requires linked library ".$packageName.self::constraintToText($constraint).' but ', 'it has the wrong version installed or is missing from your system, make sure to load the extension providing it.'];
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
|
|
||||||
|
@ -275,7 +260,7 @@ class Problem
|
||||||
if ($package->getName() === $packageName) {
|
if ($package->getName() === $packageName) {
|
||||||
$lockedPackage = $package;
|
$lockedPackage = $package;
|
||||||
if ($pool->isUnacceptableFixedOrLockedPackage($package)) {
|
if ($pool->isUnacceptableFixedOrLockedPackage($package)) {
|
||||||
return array("- ", $package->getPrettyName().' is fixed to '.$package->getPrettyVersion().' (lock file version) by a partial update but that version is rejected by your minimum-stability. Make sure you list it as an argument for the update command.');
|
return ["- ", $package->getPrettyName().' is fixed to '.$package->getPrettyVersion().' (lock file version) by a partial update but that version is rejected by your minimum-stability. Make sure you list it as an argument for the update command.'];
|
||||||
}
|
}
|
||||||
break;
|
break;
|
||||||
}
|
}
|
||||||
|
@ -290,7 +275,7 @@ class Problem
|
||||||
return $rootReqs[$packageName]->matches(new Constraint('==', $p->getVersion()));
|
return $rootReqs[$packageName]->matches(new Constraint('==', $p->getVersion()));
|
||||||
});
|
});
|
||||||
if (0 === count($filtered)) {
|
if (0 === count($filtered)) {
|
||||||
return array("- Root composer.json requires $packageName".self::constraintToText($constraint) . ', ', 'found '.self::getPackageList($packages, $isVerbose, $pool, $constraint).' but '.(self::hasMultipleNames($packages) ? 'these conflict' : 'it conflicts').' with your root composer.json require ('.$rootReqs[$packageName]->getPrettyString().').');
|
return ["- Root composer.json requires $packageName".self::constraintToText($constraint) . ', ', 'found '.self::getPackageList($packages, $isVerbose, $pool, $constraint).' but '.(self::hasMultipleNames($packages) ? 'these conflict' : 'it conflicts').' with your root composer.json require ('.$rootReqs[$packageName]->getPrettyString().').'];
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
|
|
||||||
|
@ -300,7 +285,7 @@ class Problem
|
||||||
return $tempReqs[$packageName]->matches(new Constraint('==', $p->getVersion()));
|
return $tempReqs[$packageName]->matches(new Constraint('==', $p->getVersion()));
|
||||||
});
|
});
|
||||||
if (0 === count($filtered)) {
|
if (0 === count($filtered)) {
|
||||||
return array("- Root composer.json requires $packageName".self::constraintToText($constraint) . ', ', 'found '.self::getPackageList($packages, $isVerbose, $pool, $constraint).' but '.(self::hasMultipleNames($packages) ? 'these conflict' : 'it conflicts').' with your temporary update constraint ('.$packageName.':'.$tempReqs[$packageName]->getPrettyString().').');
|
return ["- Root composer.json requires $packageName".self::constraintToText($constraint) . ', ', 'found '.self::getPackageList($packages, $isVerbose, $pool, $constraint).' but '.(self::hasMultipleNames($packages) ? 'these conflict' : 'it conflicts').' with your temporary update constraint ('.$packageName.':'.$tempReqs[$packageName]->getPrettyString().').'];
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
|
|
||||||
|
@ -310,7 +295,7 @@ class Problem
|
||||||
return $fixedConstraint->matches(new Constraint('==', $p->getVersion()));
|
return $fixedConstraint->matches(new Constraint('==', $p->getVersion()));
|
||||||
});
|
});
|
||||||
if (0 === count($filtered)) {
|
if (0 === count($filtered)) {
|
||||||
return array("- Root composer.json requires $packageName".self::constraintToText($constraint) . ', ', 'found '.self::getPackageList($packages, $isVerbose, $pool, $constraint).' but the package is fixed to '.$lockedPackage->getPrettyVersion().' (lock file version) by a partial update and that version does not match. Make sure you list it as an argument for the update command.');
|
return ["- Root composer.json requires $packageName".self::constraintToText($constraint) . ', ', 'found '.self::getPackageList($packages, $isVerbose, $pool, $constraint).' but the package is fixed to '.$lockedPackage->getPrettyVersion().' (lock file version) by a partial update and that version does not match. Make sure you list it as an argument for the update command.'];
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
|
|
||||||
|
@ -319,10 +304,10 @@ class Problem
|
||||||
});
|
});
|
||||||
|
|
||||||
if (!$nonLockedPackages) {
|
if (!$nonLockedPackages) {
|
||||||
return array("- Root composer.json requires $packageName".self::constraintToText($constraint) . ', ', 'found '.self::getPackageList($packages, $isVerbose, $pool, $constraint).' in the lock file but not in remote repositories, make sure you avoid updating this package to keep the one from the lock file.');
|
return ["- Root composer.json requires $packageName".self::constraintToText($constraint) . ', ', 'found '.self::getPackageList($packages, $isVerbose, $pool, $constraint).' in the lock file but not in remote repositories, make sure you avoid updating this package to keep the one from the lock file.'];
|
||||||
}
|
}
|
||||||
|
|
||||||
return array("- Root composer.json requires $packageName".self::constraintToText($constraint) . ', ', 'found '.self::getPackageList($packages, $isVerbose, $pool, $constraint).' but these were not loaded, likely because '.(self::hasMultipleNames($packages) ? 'they conflict' : 'it conflicts').' with another require.');
|
return ["- Root composer.json requires $packageName".self::constraintToText($constraint) . ', ', 'found '.self::getPackageList($packages, $isVerbose, $pool, $constraint).' but these were not loaded, likely because '.(self::hasMultipleNames($packages) ? 'they conflict' : 'it conflicts').' with another require.'];
|
||||||
}
|
}
|
||||||
|
|
||||||
// check if the package is found when bypassing stability checks
|
// check if the package is found when bypassing stability checks
|
||||||
|
@ -332,7 +317,7 @@ class Problem
|
||||||
return self::computeCheckForLowerPrioRepo($pool, $isVerbose, $packageName, $packages, $allReposPackages, 'minimum-stability', $constraint);
|
return self::computeCheckForLowerPrioRepo($pool, $isVerbose, $packageName, $packages, $allReposPackages, 'minimum-stability', $constraint);
|
||||||
}
|
}
|
||||||
|
|
||||||
return array("- Root composer.json requires $packageName".self::constraintToText($constraint) . ', ', 'found '.self::getPackageList($packages, $isVerbose, $pool, $constraint).' but '.(self::hasMultipleNames($packages) ? 'these do' : 'it does').' not match your minimum-stability.');
|
return ["- Root composer.json requires $packageName".self::constraintToText($constraint) . ', ', 'found '.self::getPackageList($packages, $isVerbose, $pool, $constraint).' but '.(self::hasMultipleNames($packages) ? 'these do' : 'it does').' not match your minimum-stability.'];
|
||||||
}
|
}
|
||||||
|
|
||||||
// check if the package is found when bypassing the constraint and stability checks
|
// check if the package is found when bypassing the constraint and stability checks
|
||||||
|
@ -345,7 +330,7 @@ class Problem
|
||||||
$suffix = '';
|
$suffix = '';
|
||||||
if ($constraint instanceof Constraint && $constraint->getVersion() === 'dev-master') {
|
if ($constraint instanceof Constraint && $constraint->getVersion() === 'dev-master') {
|
||||||
foreach ($packages as $candidate) {
|
foreach ($packages as $candidate) {
|
||||||
if (in_array($candidate->getVersion(), array('dev-default', 'dev-main'), true)) {
|
if (in_array($candidate->getVersion(), ['dev-default', 'dev-main'], true)) {
|
||||||
$suffix = ' Perhaps dev-master was renamed to '.$candidate->getPrettyVersion().'?';
|
$suffix = ' Perhaps dev-master was renamed to '.$candidate->getPrettyVersion().'?';
|
||||||
break;
|
break;
|
||||||
}
|
}
|
||||||
|
@ -359,13 +344,13 @@ class Problem
|
||||||
$suffix = ' See https://getcomposer.org/dep-on-root for details and assistance.';
|
$suffix = ' See https://getcomposer.org/dep-on-root for details and assistance.';
|
||||||
}
|
}
|
||||||
|
|
||||||
return array("- Root composer.json requires $packageName".self::constraintToText($constraint) . ', ', 'found '.self::getPackageList($packages, $isVerbose, $pool, $constraint).' but '.(self::hasMultipleNames($packages) ? 'these do' : 'it does').' not match the constraint.' . $suffix);
|
return ["- Root composer.json requires $packageName".self::constraintToText($constraint) . ', ', 'found '.self::getPackageList($packages, $isVerbose, $pool, $constraint).' but '.(self::hasMultipleNames($packages) ? 'these do' : 'it does').' not match the constraint.' . $suffix];
|
||||||
}
|
}
|
||||||
|
|
||||||
if (!Preg::isMatch('{^[A-Za-z0-9_./-]+$}', $packageName)) {
|
if (!Preg::isMatch('{^[A-Za-z0-9_./-]+$}', $packageName)) {
|
||||||
$illegalChars = Preg::replace('{[A-Za-z0-9_./-]+}', '', $packageName);
|
$illegalChars = Preg::replace('{[A-Za-z0-9_./-]+}', '', $packageName);
|
||||||
|
|
||||||
return array("- Root composer.json requires $packageName, it ", 'could not be found, it looks like its name is invalid, "'.$illegalChars.'" is not allowed in package names.');
|
return ["- Root composer.json requires $packageName, it ", 'could not be found, it looks like its name is invalid, "'.$illegalChars.'" is not allowed in package names.'];
|
||||||
}
|
}
|
||||||
|
|
||||||
if ($providers = $repositorySet->getProviders($packageName)) {
|
if ($providers = $repositorySet->getProviders($packageName)) {
|
||||||
|
@ -379,23 +364,20 @@ class Problem
|
||||||
$providersStr .= ' ... and '.(count($providers) - $maxProviders).' more.'."\n";
|
$providersStr .= ' ... and '.(count($providers) - $maxProviders).' more.'."\n";
|
||||||
}
|
}
|
||||||
|
|
||||||
return array("- Root composer.json requires $packageName".self::constraintToText($constraint).", it ", "could not be found in any version, but the following packages provide it:\n".$providersStr." Consider requiring one of these to satisfy the $packageName requirement.");
|
return ["- Root composer.json requires $packageName".self::constraintToText($constraint).", it ", "could not be found in any version, but the following packages provide it:\n".$providersStr." Consider requiring one of these to satisfy the $packageName requirement."];
|
||||||
}
|
}
|
||||||
|
|
||||||
return array("- Root composer.json requires $packageName, it ", "could not be found in any version, there may be a typo in the package name.");
|
return ["- Root composer.json requires $packageName, it ", "could not be found in any version, there may be a typo in the package name."];
|
||||||
}
|
}
|
||||||
|
|
||||||
/**
|
/**
|
||||||
* @internal
|
* @internal
|
||||||
* @param PackageInterface[] $packages
|
* @param PackageInterface[] $packages
|
||||||
* @param bool $isVerbose
|
|
||||||
* @param bool $useRemovedVersionGroup
|
|
||||||
* @return string
|
|
||||||
*/
|
*/
|
||||||
public static function getPackageList(array $packages, bool $isVerbose, Pool $pool = null, ConstraintInterface $constraint = null, bool $useRemovedVersionGroup = false): string
|
public static function getPackageList(array $packages, bool $isVerbose, ?Pool $pool = null, ?ConstraintInterface $constraint = null, bool $useRemovedVersionGroup = false): string
|
||||||
{
|
{
|
||||||
$prepared = array();
|
$prepared = [];
|
||||||
$hasDefaultBranch = array();
|
$hasDefaultBranch = [];
|
||||||
foreach ($packages as $package) {
|
foreach ($packages as $package) {
|
||||||
$prepared[$package->getName()]['name'] = $package->getPrettyName();
|
$prepared[$package->getName()]['name'] = $package->getPrettyName();
|
||||||
$prepared[$package->getName()]['versions'][$package->getVersion()] = $package->getPrettyVersion().($package instanceof AliasPackage ? ' (alias of '.$package->getAliasOf()->getPrettyVersion().')' : '');
|
$prepared[$package->getName()]['versions'][$package->getVersion()] = $package->getPrettyVersion().($package instanceof AliasPackage ? ' (alias of '.$package->getAliasOf()->getPrettyVersion().')' : '');
|
||||||
|
@ -414,7 +396,7 @@ class Problem
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
|
|
||||||
$preparedStrings = array();
|
$preparedStrings = [];
|
||||||
foreach ($prepared as $name => $package) {
|
foreach ($prepared as $name => $package) {
|
||||||
// remove the implicit default branch alias to avoid cruft in the display
|
// remove the implicit default branch alias to avoid cruft in the display
|
||||||
if (isset($package['versions'][VersionParser::DEFAULT_BRANCH_ALIAS], $hasDefaultBranch[$name])) {
|
if (isset($package['versions'][VersionParser::DEFAULT_BRANCH_ALIAS], $hasDefaultBranch[$name])) {
|
||||||
|
@ -433,7 +415,6 @@ class Problem
|
||||||
}
|
}
|
||||||
|
|
||||||
/**
|
/**
|
||||||
* @param string $packageName
|
|
||||||
* @param string $version the effective runtime version of the platform package
|
* @param string $version the effective runtime version of the platform package
|
||||||
* @return ?string a version string or null if it appears the package was artificially disabled
|
* @return ?string a version string or null if it appears the package was artificially disabled
|
||||||
*/
|
*/
|
||||||
|
@ -477,8 +458,6 @@ class Problem
|
||||||
|
|
||||||
/**
|
/**
|
||||||
* @param string[] $versions an array of pretty versions, with normalized versions as keys
|
* @param string[] $versions an array of pretty versions, with normalized versions as keys
|
||||||
* @param int $max
|
|
||||||
* @param int $maxDev
|
|
||||||
* @return list<string> a list of pretty versions and '...' where versions were removed
|
* @return list<string> a list of pretty versions and '...' where versions were removed
|
||||||
*/
|
*/
|
||||||
private static function condenseVersionList(array $versions, int $max, int $maxDev = 16): array
|
private static function condenseVersionList(array $versions, int $max, int $maxDev = 16): array
|
||||||
|
@ -487,8 +466,8 @@ class Problem
|
||||||
return $versions;
|
return $versions;
|
||||||
}
|
}
|
||||||
|
|
||||||
$filtered = array();
|
$filtered = [];
|
||||||
$byMajor = array();
|
$byMajor = [];
|
||||||
foreach ($versions as $version => $pretty) {
|
foreach ($versions as $version => $pretty) {
|
||||||
if (0 === stripos($version, 'dev-')) {
|
if (0 === stripos($version, 'dev-')) {
|
||||||
$byMajor['dev'][] = $pretty;
|
$byMajor['dev'][] = $pretty;
|
||||||
|
@ -513,7 +492,6 @@ class Problem
|
||||||
|
|
||||||
/**
|
/**
|
||||||
* @param PackageInterface[] $packages
|
* @param PackageInterface[] $packages
|
||||||
* @return bool
|
|
||||||
*/
|
*/
|
||||||
private static function hasMultipleNames(array $packages): bool
|
private static function hasMultipleNames(array $packages): bool
|
||||||
{
|
{
|
||||||
|
@ -530,16 +508,13 @@ class Problem
|
||||||
}
|
}
|
||||||
|
|
||||||
/**
|
/**
|
||||||
* @param bool $isVerbose
|
|
||||||
* @param string $packageName
|
|
||||||
* @param PackageInterface[] $higherRepoPackages
|
* @param PackageInterface[] $higherRepoPackages
|
||||||
* @param PackageInterface[] $allReposPackages
|
* @param PackageInterface[] $allReposPackages
|
||||||
* @param string $reason
|
|
||||||
* @return array{0: string, 1: string}
|
* @return array{0: string, 1: string}
|
||||||
*/
|
*/
|
||||||
private static function computeCheckForLowerPrioRepo(Pool $pool, bool $isVerbose, string $packageName, array $higherRepoPackages, array $allReposPackages, string $reason, ConstraintInterface $constraint = null): array
|
private static function computeCheckForLowerPrioRepo(Pool $pool, bool $isVerbose, string $packageName, array $higherRepoPackages, array $allReposPackages, string $reason, ?ConstraintInterface $constraint = null): array
|
||||||
{
|
{
|
||||||
$nextRepoPackages = array();
|
$nextRepoPackages = [];
|
||||||
$nextRepo = null;
|
$nextRepo = null;
|
||||||
|
|
||||||
foreach ($allReposPackages as $package) {
|
foreach ($allReposPackages as $package) {
|
||||||
|
@ -554,10 +529,10 @@ class Problem
|
||||||
if ($higherRepoPackages) {
|
if ($higherRepoPackages) {
|
||||||
$topPackage = reset($higherRepoPackages);
|
$topPackage = reset($higherRepoPackages);
|
||||||
if ($topPackage instanceof RootPackageInterface) {
|
if ($topPackage instanceof RootPackageInterface) {
|
||||||
return array(
|
return [
|
||||||
"- Root composer.json requires $packageName".self::constraintToText($constraint).', it is ',
|
"- Root composer.json requires $packageName".self::constraintToText($constraint).', it is ',
|
||||||
'satisfiable by '.self::getPackageList($nextRepoPackages, $isVerbose, $pool, $constraint).' from '.$nextRepo->getRepoName().' but '.$topPackage->getPrettyName().' is the root package and cannot be modified. See https://getcomposer.org/dep-on-root for details and assistance.',
|
'satisfiable by '.self::getPackageList($nextRepoPackages, $isVerbose, $pool, $constraint).' from '.$nextRepo->getRepoName().' but '.$topPackage->getPrettyName().' is the root package and cannot be modified. See https://getcomposer.org/dep-on-root for details and assistance.',
|
||||||
);
|
];
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
|
|
||||||
|
@ -573,20 +548,18 @@ class Problem
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
|
|
||||||
return array("- Root composer.json requires $packageName".self::constraintToText($constraint) . ', ',
|
return ["- Root composer.json requires $packageName".self::constraintToText($constraint) . ', ',
|
||||||
'found ' . self::getPackageList($higherRepoPackages, $isVerbose, $pool, $constraint).' but ' . ($singular ? 'it does' : 'these do') . ' not match your '.$reason.' and ' . ($singular ? 'is' : 'are') . ' therefore not installable. '.$suggestion,
|
'found ' . self::getPackageList($higherRepoPackages, $isVerbose, $pool, $constraint).' but ' . ($singular ? 'it does' : 'these do') . ' not match your '.$reason.' and ' . ($singular ? 'is' : 'are') . ' therefore not installable. '.$suggestion,
|
||||||
);
|
];
|
||||||
}
|
}
|
||||||
|
|
||||||
return array("- Root composer.json requires $packageName".self::constraintToText($constraint) . ', it is ', 'satisfiable by '.self::getPackageList($nextRepoPackages, $isVerbose, $pool, $constraint).' from '.$nextRepo->getRepoName().' but '.self::getPackageList($higherRepoPackages, $isVerbose, $pool, $constraint).' from '.reset($higherRepoPackages)->getRepository()->getRepoName().' has higher repository priority. The packages from the higher priority repository do not match your '.$reason.' and are therefore not installable. That repository is canonical so the lower priority repo\'s packages are not installable. See https://getcomposer.org/repoprio for details and assistance.');
|
return ["- Root composer.json requires $packageName".self::constraintToText($constraint) . ', it is ', 'satisfiable by '.self::getPackageList($nextRepoPackages, $isVerbose, $pool, $constraint).' from '.$nextRepo->getRepoName().' but '.self::getPackageList($higherRepoPackages, $isVerbose, $pool, $constraint).' from '.reset($higherRepoPackages)->getRepository()->getRepoName().' has higher repository priority. The packages from the higher priority repository do not match your '.$reason.' and are therefore not installable. That repository is canonical so the lower priority repo\'s packages are not installable. See https://getcomposer.org/repoprio for details and assistance.'];
|
||||||
}
|
}
|
||||||
|
|
||||||
/**
|
/**
|
||||||
* Turns a constraint into text usable in a sentence describing a request
|
* Turns a constraint into text usable in a sentence describing a request
|
||||||
*
|
|
||||||
* @return string
|
|
||||||
*/
|
*/
|
||||||
protected static function constraintToText(ConstraintInterface $constraint = null): string
|
protected static function constraintToText(?ConstraintInterface $constraint = null): string
|
||||||
{
|
{
|
||||||
return $constraint ? ' '.$constraint->getPrettyString() : '';
|
return $constraint ? ' '.$constraint->getPrettyString() : '';
|
||||||
}
|
}
|
||||||
|
|
|
@ -43,28 +43,24 @@ class Request
|
||||||
/** @var ?LockArrayRepository */
|
/** @var ?LockArrayRepository */
|
||||||
protected $lockedRepository;
|
protected $lockedRepository;
|
||||||
/** @var array<string, ConstraintInterface> */
|
/** @var array<string, ConstraintInterface> */
|
||||||
protected $requires = array();
|
protected $requires = [];
|
||||||
/** @var array<string, BasePackage> */
|
/** @var array<string, BasePackage> */
|
||||||
protected $fixedPackages = array();
|
protected $fixedPackages = [];
|
||||||
/** @var array<string, BasePackage> */
|
/** @var array<string, BasePackage> */
|
||||||
protected $lockedPackages = array();
|
protected $lockedPackages = [];
|
||||||
/** @var array<string, BasePackage> */
|
/** @var array<string, BasePackage> */
|
||||||
protected $fixedLockedPackages = array();
|
protected $fixedLockedPackages = [];
|
||||||
/** @var string[] */
|
/** @var string[] */
|
||||||
protected $updateAllowList = array();
|
protected $updateAllowList = [];
|
||||||
/** @var false|self::UPDATE_* */
|
/** @var false|self::UPDATE_* */
|
||||||
protected $updateAllowTransitiveDependencies = false;
|
protected $updateAllowTransitiveDependencies = false;
|
||||||
|
|
||||||
public function __construct(LockArrayRepository $lockedRepository = null)
|
public function __construct(?LockArrayRepository $lockedRepository = null)
|
||||||
{
|
{
|
||||||
$this->lockedRepository = $lockedRepository;
|
$this->lockedRepository = $lockedRepository;
|
||||||
}
|
}
|
||||||
|
|
||||||
/**
|
public function requireName(string $packageName, ?ConstraintInterface $constraint = null): void
|
||||||
* @param string $packageName
|
|
||||||
* @return void
|
|
||||||
*/
|
|
||||||
public function requireName(string $packageName, ConstraintInterface $constraint = null): void
|
|
||||||
{
|
{
|
||||||
$packageName = strtolower($packageName);
|
$packageName = strtolower($packageName);
|
||||||
|
|
||||||
|
@ -82,8 +78,6 @@ class Request
|
||||||
*
|
*
|
||||||
* This is used for platform packages which cannot be modified by Composer. A rule enforcing their installation is
|
* This is used for platform packages which cannot be modified by Composer. A rule enforcing their installation is
|
||||||
* generated for dependency resolution. Partial updates with dependencies cannot in any way modify these packages.
|
* generated for dependency resolution. Partial updates with dependencies cannot in any way modify these packages.
|
||||||
*
|
|
||||||
* @return void
|
|
||||||
*/
|
*/
|
||||||
public function fixPackage(BasePackage $package): void
|
public function fixPackage(BasePackage $package): void
|
||||||
{
|
{
|
||||||
|
@ -99,8 +93,6 @@ class Request
|
||||||
* However unlike fixed packages there will not be a special rule enforcing their installation for the solver, so
|
* However unlike fixed packages there will not be a special rule enforcing their installation for the solver, so
|
||||||
* if nothing requires these packages they will be removed. Additionally in a partial update these packages can be
|
* if nothing requires these packages they will be removed. Additionally in a partial update these packages can be
|
||||||
* unlocked, meaning other versions can be installed if explicitly requested as part of the update.
|
* unlocked, meaning other versions can be installed if explicitly requested as part of the update.
|
||||||
*
|
|
||||||
* @return void
|
|
||||||
*/
|
*/
|
||||||
public function lockPackage(BasePackage $package): void
|
public function lockPackage(BasePackage $package): void
|
||||||
{
|
{
|
||||||
|
@ -113,8 +105,6 @@ class Request
|
||||||
* This is necessary for the composer install step which verifies the lock file integrity and should not allow
|
* This is necessary for the composer install step which verifies the lock file integrity and should not allow
|
||||||
* removal of any packages. At the same time lock packages there cannot simply be marked fixed, as error reporting
|
* removal of any packages. At the same time lock packages there cannot simply be marked fixed, as error reporting
|
||||||
* would then report them as platform packages, so this still marks them as locked packages at the same time.
|
* would then report them as platform packages, so this still marks them as locked packages at the same time.
|
||||||
*
|
|
||||||
* @return void
|
|
||||||
*/
|
*/
|
||||||
public function fixLockedPackage(BasePackage $package): void
|
public function fixLockedPackage(BasePackage $package): void
|
||||||
{
|
{
|
||||||
|
@ -122,9 +112,6 @@ class Request
|
||||||
$this->fixedLockedPackages[spl_object_hash($package)] = $package;
|
$this->fixedLockedPackages[spl_object_hash($package)] = $package;
|
||||||
}
|
}
|
||||||
|
|
||||||
/**
|
|
||||||
* @return void
|
|
||||||
*/
|
|
||||||
public function unlockPackage(BasePackage $package): void
|
public function unlockPackage(BasePackage $package): void
|
||||||
{
|
{
|
||||||
unset($this->lockedPackages[spl_object_hash($package)]);
|
unset($this->lockedPackages[spl_object_hash($package)]);
|
||||||
|
@ -133,7 +120,6 @@ class Request
|
||||||
/**
|
/**
|
||||||
* @param string[] $updateAllowList
|
* @param string[] $updateAllowList
|
||||||
* @param false|self::UPDATE_* $updateAllowTransitiveDependencies
|
* @param false|self::UPDATE_* $updateAllowTransitiveDependencies
|
||||||
* @return void
|
|
||||||
*/
|
*/
|
||||||
public function setUpdateAllowList(array $updateAllowList, $updateAllowTransitiveDependencies): void
|
public function setUpdateAllowList(array $updateAllowList, $updateAllowTransitiveDependencies): void
|
||||||
{
|
{
|
||||||
|
@ -149,17 +135,11 @@ class Request
|
||||||
return $this->updateAllowList;
|
return $this->updateAllowList;
|
||||||
}
|
}
|
||||||
|
|
||||||
/**
|
|
||||||
* @return bool
|
|
||||||
*/
|
|
||||||
public function getUpdateAllowTransitiveDependencies(): bool
|
public function getUpdateAllowTransitiveDependencies(): bool
|
||||||
{
|
{
|
||||||
return $this->updateAllowTransitiveDependencies !== self::UPDATE_ONLY_LISTED;
|
return $this->updateAllowTransitiveDependencies !== self::UPDATE_ONLY_LISTED;
|
||||||
}
|
}
|
||||||
|
|
||||||
/**
|
|
||||||
* @return bool
|
|
||||||
*/
|
|
||||||
public function getUpdateAllowTransitiveRootDependencies(): bool
|
public function getUpdateAllowTransitiveRootDependencies(): bool
|
||||||
{
|
{
|
||||||
return $this->updateAllowTransitiveDependencies === self::UPDATE_LISTED_WITH_TRANSITIVE_DEPS;
|
return $this->updateAllowTransitiveDependencies === self::UPDATE_LISTED_WITH_TRANSITIVE_DEPS;
|
||||||
|
@ -181,9 +161,6 @@ class Request
|
||||||
return $this->fixedPackages;
|
return $this->fixedPackages;
|
||||||
}
|
}
|
||||||
|
|
||||||
/**
|
|
||||||
* @return bool
|
|
||||||
*/
|
|
||||||
public function isFixedPackage(BasePackage $package): bool
|
public function isFixedPackage(BasePackage $package): bool
|
||||||
{
|
{
|
||||||
return isset($this->fixedPackages[spl_object_hash($package)]);
|
return isset($this->fixedPackages[spl_object_hash($package)]);
|
||||||
|
@ -197,9 +174,6 @@ class Request
|
||||||
return $this->lockedPackages;
|
return $this->lockedPackages;
|
||||||
}
|
}
|
||||||
|
|
||||||
/**
|
|
||||||
* @return bool
|
|
||||||
*/
|
|
||||||
public function isLockedPackage(PackageInterface $package): bool
|
public function isLockedPackage(PackageInterface $package): bool
|
||||||
{
|
{
|
||||||
return isset($this->lockedPackages[spl_object_hash($package)]) || isset($this->fixedLockedPackages[spl_object_hash($package)]);
|
return isset($this->lockedPackages[spl_object_hash($package)]) || isset($this->fixedLockedPackages[spl_object_hash($package)]);
|
||||||
|
@ -214,7 +188,6 @@ class Request
|
||||||
}
|
}
|
||||||
|
|
||||||
/**
|
/**
|
||||||
* @param bool $packageIds
|
|
||||||
* @return array<int|string, BasePackage>
|
* @return array<int|string, BasePackage>
|
||||||
*
|
*
|
||||||
* @TODO look into removing the packageIds option, the only place true is used
|
* @TODO look into removing the packageIds option, the only place true is used
|
||||||
|
@ -224,7 +197,7 @@ class Request
|
||||||
*/
|
*/
|
||||||
public function getPresentMap(bool $packageIds = false): array
|
public function getPresentMap(bool $packageIds = false): array
|
||||||
{
|
{
|
||||||
$presentMap = array();
|
$presentMap = [];
|
||||||
|
|
||||||
if ($this->lockedRepository) {
|
if ($this->lockedRepository) {
|
||||||
foreach ($this->lockedRepository->getPackages() as $package) {
|
foreach ($this->lockedRepository->getPackages() as $package) {
|
||||||
|
@ -244,7 +217,7 @@ class Request
|
||||||
*/
|
*/
|
||||||
public function getFixedPackagesMap(): array
|
public function getFixedPackagesMap(): array
|
||||||
{
|
{
|
||||||
$fixedPackagesMap = array();
|
$fixedPackagesMap = [];
|
||||||
|
|
||||||
foreach ($this->fixedPackages as $package) {
|
foreach ($this->fixedPackages as $package) {
|
||||||
$fixedPackagesMap[$package->getId()] = $package;
|
$fixedPackagesMap[$package->getId()] = $package;
|
||||||
|
|
|
@ -80,14 +80,10 @@ abstract class Rule
|
||||||
|
|
||||||
abstract public function __toString(): string;
|
abstract public function __toString(): string;
|
||||||
|
|
||||||
/**
|
|
||||||
* @param Rule $rule
|
|
||||||
* @return bool
|
|
||||||
*/
|
|
||||||
abstract public function equals(Rule $rule): bool;
|
abstract public function equals(Rule $rule): bool;
|
||||||
|
|
||||||
/**
|
/**
|
||||||
* @return int
|
* @return self::RULE_*
|
||||||
*/
|
*/
|
||||||
public function getReason(): int
|
public function getReason(): int
|
||||||
{
|
{
|
||||||
|
@ -102,9 +98,6 @@ abstract class Rule
|
||||||
return $this->reasonData;
|
return $this->reasonData;
|
||||||
}
|
}
|
||||||
|
|
||||||
/**
|
|
||||||
* @return string|null
|
|
||||||
*/
|
|
||||||
public function getRequiredPackage(): ?string
|
public function getRequiredPackage(): ?string
|
||||||
{
|
{
|
||||||
$reason = $this->getReason();
|
$reason = $this->getReason();
|
||||||
|
@ -126,61 +119,39 @@ abstract class Rule
|
||||||
|
|
||||||
/**
|
/**
|
||||||
* @param RuleSet::TYPE_* $type
|
* @param RuleSet::TYPE_* $type
|
||||||
* @return void
|
|
||||||
*/
|
*/
|
||||||
public function setType($type): void
|
public function setType($type): void
|
||||||
{
|
{
|
||||||
$this->bitfield = ($this->bitfield & ~(255 << self::BITFIELD_TYPE)) | ((255 & $type) << self::BITFIELD_TYPE);
|
$this->bitfield = ($this->bitfield & ~(255 << self::BITFIELD_TYPE)) | ((255 & $type) << self::BITFIELD_TYPE);
|
||||||
}
|
}
|
||||||
|
|
||||||
/**
|
|
||||||
* @return int
|
|
||||||
*/
|
|
||||||
public function getType(): int
|
public function getType(): int
|
||||||
{
|
{
|
||||||
return ($this->bitfield & (255 << self::BITFIELD_TYPE)) >> self::BITFIELD_TYPE;
|
return ($this->bitfield & (255 << self::BITFIELD_TYPE)) >> self::BITFIELD_TYPE;
|
||||||
}
|
}
|
||||||
|
|
||||||
/**
|
|
||||||
* @return void
|
|
||||||
*/
|
|
||||||
public function disable(): void
|
public function disable(): void
|
||||||
{
|
{
|
||||||
$this->bitfield = ($this->bitfield & ~(255 << self::BITFIELD_DISABLED)) | (1 << self::BITFIELD_DISABLED);
|
$this->bitfield = ($this->bitfield & ~(255 << self::BITFIELD_DISABLED)) | (1 << self::BITFIELD_DISABLED);
|
||||||
}
|
}
|
||||||
|
|
||||||
/**
|
|
||||||
* @return void
|
|
||||||
*/
|
|
||||||
public function enable(): void
|
public function enable(): void
|
||||||
{
|
{
|
||||||
$this->bitfield &= ~(255 << self::BITFIELD_DISABLED);
|
$this->bitfield &= ~(255 << self::BITFIELD_DISABLED);
|
||||||
}
|
}
|
||||||
|
|
||||||
/**
|
|
||||||
* @return bool
|
|
||||||
*/
|
|
||||||
public function isDisabled(): bool
|
public function isDisabled(): bool
|
||||||
{
|
{
|
||||||
return (bool) (($this->bitfield & (255 << self::BITFIELD_DISABLED)) >> self::BITFIELD_DISABLED);
|
return (bool) (($this->bitfield & (255 << self::BITFIELD_DISABLED)) >> self::BITFIELD_DISABLED);
|
||||||
}
|
}
|
||||||
|
|
||||||
/**
|
|
||||||
* @return bool
|
|
||||||
*/
|
|
||||||
public function isEnabled(): bool
|
public function isEnabled(): bool
|
||||||
{
|
{
|
||||||
return !(($this->bitfield & (255 << self::BITFIELD_DISABLED)) >> self::BITFIELD_DISABLED);
|
return !(($this->bitfield & (255 << self::BITFIELD_DISABLED)) >> self::BITFIELD_DISABLED);
|
||||||
}
|
}
|
||||||
|
|
||||||
/**
|
|
||||||
* @return bool
|
|
||||||
*/
|
|
||||||
abstract public function isAssertion(): bool;
|
abstract public function isAssertion(): bool;
|
||||||
|
|
||||||
/**
|
|
||||||
* @return bool
|
|
||||||
*/
|
|
||||||
public function isCausedByLock(RepositorySet $repositorySet, Request $request, Pool $pool): bool
|
public function isCausedByLock(RepositorySet $repositorySet, Request $request, Pool $pool): bool
|
||||||
{
|
{
|
||||||
if ($this->getReason() === self::RULE_PACKAGE_REQUIRES) {
|
if ($this->getReason() === self::RULE_PACKAGE_REQUIRES) {
|
||||||
|
@ -230,7 +201,6 @@ abstract class Rule
|
||||||
|
|
||||||
/**
|
/**
|
||||||
* @internal
|
* @internal
|
||||||
* @return BasePackage
|
|
||||||
*/
|
*/
|
||||||
public function getSourcePackage(Pool $pool): BasePackage
|
public function getSourcePackage(Pool $pool): BasePackage
|
||||||
{
|
{
|
||||||
|
@ -244,7 +214,7 @@ abstract class Rule
|
||||||
if ($reasonData = $this->getReasonData()) {
|
if ($reasonData = $this->getReasonData()) {
|
||||||
// swap literals if they are not in the right order with package2 being the conflicter
|
// swap literals if they are not in the right order with package2 being the conflicter
|
||||||
if ($reasonData->getSource() === $package1->getName()) {
|
if ($reasonData->getSource() === $package1->getName()) {
|
||||||
list($package2, $package1) = array($package1, $package2);
|
[$package2, $package1] = [$package1, $package2];
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
|
|
||||||
|
@ -262,12 +232,10 @@ abstract class Rule
|
||||||
}
|
}
|
||||||
|
|
||||||
/**
|
/**
|
||||||
* @param bool $isVerbose
|
|
||||||
* @param BasePackage[] $installedMap
|
* @param BasePackage[] $installedMap
|
||||||
* @param array<Rule[]> $learnedPool
|
* @param array<Rule[]> $learnedPool
|
||||||
* @return string
|
|
||||||
*/
|
*/
|
||||||
public function getPrettyString(RepositorySet $repositorySet, Request $request, Pool $pool, bool $isVerbose, array $installedMap = array(), array $learnedPool = array()): string
|
public function getPrettyString(RepositorySet $repositorySet, Request $request, Pool $pool, bool $isVerbose, array $installedMap = [], array $learnedPool = []): string
|
||||||
{
|
{
|
||||||
$literals = $this->getLiterals();
|
$literals = $this->getLiterals();
|
||||||
|
|
||||||
|
@ -312,7 +280,7 @@ abstract class Rule
|
||||||
|
|
||||||
// swap literals if they are not in the right order with package2 being the conflicter
|
// swap literals if they are not in the right order with package2 being the conflicter
|
||||||
if ($reasonData->getSource() === $package1->getName()) {
|
if ($reasonData->getSource() === $package1->getName()) {
|
||||||
list($package2, $package1) = array($package1, $package2);
|
[$package2, $package1] = [$package1, $package2];
|
||||||
$conflictTarget = $package1->getPrettyName().' '.$reasonData->getPrettyConstraint();
|
$conflictTarget = $package1->getPrettyName().' '.$reasonData->getPrettyConstraint();
|
||||||
}
|
}
|
||||||
|
|
||||||
|
@ -349,7 +317,7 @@ abstract class Rule
|
||||||
/** @var Link */
|
/** @var Link */
|
||||||
$reasonData = $this->reasonData;
|
$reasonData = $this->reasonData;
|
||||||
|
|
||||||
$requires = array();
|
$requires = [];
|
||||||
foreach ($literals as $literal) {
|
foreach ($literals as $literal) {
|
||||||
$requires[] = $pool->literalToPackage($literal);
|
$requires[] = $pool->literalToPackage($literal);
|
||||||
}
|
}
|
||||||
|
@ -368,7 +336,7 @@ abstract class Rule
|
||||||
return $text;
|
return $text;
|
||||||
|
|
||||||
case self::RULE_PACKAGE_SAME_NAME:
|
case self::RULE_PACKAGE_SAME_NAME:
|
||||||
$packageNames = array();
|
$packageNames = [];
|
||||||
foreach ($literals as $literal) {
|
foreach ($literals as $literal) {
|
||||||
$package = $pool->literalToPackage($literal);
|
$package = $pool->literalToPackage($literal);
|
||||||
$packageNames[$package->getName()] = true;
|
$packageNames[$package->getName()] = true;
|
||||||
|
@ -394,8 +362,8 @@ abstract class Rule
|
||||||
$reason .= $replacedName.' and thus cannot coexist with it.';
|
$reason .= $replacedName.' and thus cannot coexist with it.';
|
||||||
}
|
}
|
||||||
|
|
||||||
$installedPackages = array();
|
$installedPackages = [];
|
||||||
$removablePackages = array();
|
$removablePackages = [];
|
||||||
foreach ($literals as $literal) {
|
foreach ($literals as $literal) {
|
||||||
if (isset($installedMap[abs($literal)])) {
|
if (isset($installedMap[abs($literal)])) {
|
||||||
$installedPackages[] = $pool->literalToPackage($literal);
|
$installedPackages[] = $pool->literalToPackage($literal);
|
||||||
|
@ -425,7 +393,7 @@ abstract class Rule
|
||||||
if (count($literals) === 1) {
|
if (count($literals) === 1) {
|
||||||
$ruleText = $pool->literalToPrettyString($literals[0], $installedMap);
|
$ruleText = $pool->literalToPrettyString($literals[0], $installedMap);
|
||||||
} else {
|
} else {
|
||||||
$groups = array();
|
$groups = [];
|
||||||
foreach ($literals as $literal) {
|
foreach ($literals as $literal) {
|
||||||
$package = $pool->literalToPackage($literal);
|
$package = $pool->literalToPackage($literal);
|
||||||
if (isset($installedMap[$package->id])) {
|
if (isset($installedMap[$package->id])) {
|
||||||
|
@ -436,7 +404,7 @@ abstract class Rule
|
||||||
|
|
||||||
$groups[$group][] = $this->deduplicateDefaultBranchAlias($package);
|
$groups[$group][] = $this->deduplicateDefaultBranchAlias($package);
|
||||||
}
|
}
|
||||||
$ruleTexts = array();
|
$ruleTexts = [];
|
||||||
foreach ($groups as $group => $packages) {
|
foreach ($groups as $group => $packages) {
|
||||||
$ruleTexts[] = $group . (count($packages) > 1 ? ' one of' : '').' ' . $this->formatPackagesUnique($pool, $packages, $isVerbose);
|
$ruleTexts[] = $group . (count($packages) > 1 ? ' one of' : '').' ' . $this->formatPackagesUnique($pool, $packages, $isVerbose);
|
||||||
}
|
}
|
||||||
|
@ -481,11 +449,8 @@ abstract class Rule
|
||||||
|
|
||||||
/**
|
/**
|
||||||
* @param array<int|BasePackage> $packages An array containing packages or literals
|
* @param array<int|BasePackage> $packages An array containing packages or literals
|
||||||
* @param bool $isVerbose
|
|
||||||
* @param bool $useRemovedVersionGroup
|
|
||||||
* @return string
|
|
||||||
*/
|
*/
|
||||||
protected function formatPackagesUnique(Pool $pool, array $packages, bool $isVerbose, ConstraintInterface $constraint = null, bool $useRemovedVersionGroup = false): string
|
protected function formatPackagesUnique(Pool $pool, array $packages, bool $isVerbose, ?ConstraintInterface $constraint = null, bool $useRemovedVersionGroup = false): string
|
||||||
{
|
{
|
||||||
foreach ($packages as $index => $package) {
|
foreach ($packages as $index => $package) {
|
||||||
if (!\is_object($package)) {
|
if (!\is_object($package)) {
|
||||||
|
@ -496,9 +461,6 @@ abstract class Rule
|
||||||
return Problem::getPackageList($packages, $isVerbose, $pool, $constraint, $useRemovedVersionGroup);
|
return Problem::getPackageList($packages, $isVerbose, $pool, $constraint, $useRemovedVersionGroup);
|
||||||
}
|
}
|
||||||
|
|
||||||
/**
|
|
||||||
* @return BasePackage
|
|
||||||
*/
|
|
||||||
private function deduplicateDefaultBranchAlias(BasePackage $package): BasePackage
|
private function deduplicateDefaultBranchAlias(BasePackage $package): BasePackage
|
||||||
{
|
{
|
||||||
if ($package instanceof AliasPackage && $package->getPrettyVersion() === VersionParser::DEFAULT_BRANCH_ALIAS) {
|
if ($package instanceof AliasPackage && $package->getPrettyVersion() === VersionParser::DEFAULT_BRANCH_ALIAS) {
|
||||||
|
|
|
@ -24,8 +24,6 @@ class Rule2Literals extends Rule
|
||||||
protected $literal2;
|
protected $literal2;
|
||||||
|
|
||||||
/**
|
/**
|
||||||
* @param int $literal1
|
|
||||||
* @param int $literal2
|
|
||||||
* @param Rule::RULE_* $reason A RULE_* constant
|
* @param Rule::RULE_* $reason A RULE_* constant
|
||||||
* @param mixed $reasonData
|
* @param mixed $reasonData
|
||||||
*
|
*
|
||||||
|
@ -49,7 +47,7 @@ class Rule2Literals extends Rule
|
||||||
*/
|
*/
|
||||||
public function getLiterals(): array
|
public function getLiterals(): array
|
||||||
{
|
{
|
||||||
return array($this->literal1, $this->literal2);
|
return [$this->literal1, $this->literal2];
|
||||||
}
|
}
|
||||||
|
|
||||||
/**
|
/**
|
||||||
|
@ -107,8 +105,6 @@ class Rule2Literals extends Rule
|
||||||
|
|
||||||
/**
|
/**
|
||||||
* Formats a rule as a string of the format (Literal1|Literal2|...)
|
* Formats a rule as a string of the format (Literal1|Literal2|...)
|
||||||
*
|
|
||||||
* @return string
|
|
||||||
*/
|
*/
|
||||||
public function __toString(): string
|
public function __toString(): string
|
||||||
{
|
{
|
||||||
|
|
|
@ -30,14 +30,14 @@ class RuleSet implements \IteratorAggregate, \Countable
|
||||||
*
|
*
|
||||||
* @var array<int, Rule>
|
* @var array<int, Rule>
|
||||||
*/
|
*/
|
||||||
public $ruleById = array();
|
public $ruleById = [];
|
||||||
|
|
||||||
/** @var array<0|1|4, string> */
|
/** @var array<0|1|4, string> */
|
||||||
protected static $types = array(
|
protected static $types = [
|
||||||
self::TYPE_PACKAGE => 'PACKAGE',
|
self::TYPE_PACKAGE => 'PACKAGE',
|
||||||
self::TYPE_REQUEST => 'REQUEST',
|
self::TYPE_REQUEST => 'REQUEST',
|
||||||
self::TYPE_LEARNED => 'LEARNED',
|
self::TYPE_LEARNED => 'LEARNED',
|
||||||
);
|
];
|
||||||
|
|
||||||
/** @var array<self::TYPE_*, Rule[]> */
|
/** @var array<self::TYPE_*, Rule[]> */
|
||||||
protected $rules;
|
protected $rules;
|
||||||
|
@ -46,18 +46,17 @@ class RuleSet implements \IteratorAggregate, \Countable
|
||||||
protected $nextRuleId = 0;
|
protected $nextRuleId = 0;
|
||||||
|
|
||||||
/** @var array<int|string, Rule|Rule[]> */
|
/** @var array<int|string, Rule|Rule[]> */
|
||||||
protected $rulesByHash = array();
|
protected $rulesByHash = [];
|
||||||
|
|
||||||
public function __construct()
|
public function __construct()
|
||||||
{
|
{
|
||||||
foreach ($this->getTypes() as $type) {
|
foreach ($this->getTypes() as $type) {
|
||||||
$this->rules[$type] = array();
|
$this->rules[$type] = [];
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
|
|
||||||
/**
|
/**
|
||||||
* @param self::TYPE_* $type
|
* @param self::TYPE_* $type
|
||||||
* @return void
|
|
||||||
*/
|
*/
|
||||||
public function add(Rule $rule, $type): void
|
public function add(Rule $rule, $type): void
|
||||||
{
|
{
|
||||||
|
@ -84,7 +83,7 @@ class RuleSet implements \IteratorAggregate, \Countable
|
||||||
}
|
}
|
||||||
|
|
||||||
if (!isset($this->rules[$type])) {
|
if (!isset($this->rules[$type])) {
|
||||||
$this->rules[$type] = array();
|
$this->rules[$type] = [];
|
||||||
}
|
}
|
||||||
|
|
||||||
$this->rules[$type][] = $rule;
|
$this->rules[$type][] = $rule;
|
||||||
|
@ -99,7 +98,7 @@ class RuleSet implements \IteratorAggregate, \Countable
|
||||||
$this->rulesByHash[$hash][] = $rule;
|
$this->rulesByHash[$hash][] = $rule;
|
||||||
} else {
|
} else {
|
||||||
$originalRule = $this->rulesByHash[$hash];
|
$originalRule = $this->rulesByHash[$hash];
|
||||||
$this->rulesByHash[$hash] = array($originalRule, $rule);
|
$this->rulesByHash[$hash] = [$originalRule, $rule];
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
|
|
||||||
|
@ -108,10 +107,6 @@ class RuleSet implements \IteratorAggregate, \Countable
|
||||||
return $this->nextRuleId;
|
return $this->nextRuleId;
|
||||||
}
|
}
|
||||||
|
|
||||||
/**
|
|
||||||
* @param int $id
|
|
||||||
* @return Rule
|
|
||||||
*/
|
|
||||||
public function ruleById(int $id): Rule
|
public function ruleById(int $id): Rule
|
||||||
{
|
{
|
||||||
return $this->ruleById[$id];
|
return $this->ruleById[$id];
|
||||||
|
@ -130,18 +125,17 @@ class RuleSet implements \IteratorAggregate, \Countable
|
||||||
|
|
||||||
/**
|
/**
|
||||||
* @param self::TYPE_*|array<self::TYPE_*> $types
|
* @param self::TYPE_*|array<self::TYPE_*> $types
|
||||||
* @return RuleSetIterator
|
|
||||||
*/
|
*/
|
||||||
public function getIteratorFor($types): RuleSetIterator
|
public function getIteratorFor($types): RuleSetIterator
|
||||||
{
|
{
|
||||||
if (!\is_array($types)) {
|
if (!\is_array($types)) {
|
||||||
$types = array($types);
|
$types = [$types];
|
||||||
}
|
}
|
||||||
|
|
||||||
$allRules = $this->getRules();
|
$allRules = $this->getRules();
|
||||||
|
|
||||||
/** @var array<self::TYPE_*, Rule[]> $rules */
|
/** @var array<self::TYPE_*, Rule[]> $rules */
|
||||||
$rules = array();
|
$rules = [];
|
||||||
|
|
||||||
foreach ($types as $type) {
|
foreach ($types as $type) {
|
||||||
$rules[$type] = $allRules[$type];
|
$rules[$type] = $allRules[$type];
|
||||||
|
@ -152,12 +146,11 @@ class RuleSet implements \IteratorAggregate, \Countable
|
||||||
|
|
||||||
/**
|
/**
|
||||||
* @param array<self::TYPE_*>|self::TYPE_* $types
|
* @param array<self::TYPE_*>|self::TYPE_* $types
|
||||||
* @return RuleSetIterator
|
|
||||||
*/
|
*/
|
||||||
public function getIteratorWithout($types): RuleSetIterator
|
public function getIteratorWithout($types): RuleSetIterator
|
||||||
{
|
{
|
||||||
if (!\is_array($types)) {
|
if (!\is_array($types)) {
|
||||||
$types = array($types);
|
$types = [$types];
|
||||||
}
|
}
|
||||||
|
|
||||||
$rules = $this->getRules();
|
$rules = $this->getRules();
|
||||||
|
@ -177,11 +170,7 @@ class RuleSet implements \IteratorAggregate, \Countable
|
||||||
return array_keys($types);
|
return array_keys($types);
|
||||||
}
|
}
|
||||||
|
|
||||||
/**
|
public function getPrettyString(?RepositorySet $repositorySet = null, ?Request $request = null, ?Pool $pool = null, bool $isVerbose = false): string
|
||||||
* @param bool $isVerbose
|
|
||||||
* @return string
|
|
||||||
*/
|
|
||||||
public function getPrettyString(RepositorySet $repositorySet = null, Request $request = null, Pool $pool = null, bool $isVerbose = false): string
|
|
||||||
{
|
{
|
||||||
$string = "\n";
|
$string = "\n";
|
||||||
foreach ($this->rules as $type => $rules) {
|
foreach ($this->rules as $type => $rules) {
|
||||||
|
|
|
@ -31,9 +31,9 @@ class RuleSetGenerator
|
||||||
/** @var RuleSet */
|
/** @var RuleSet */
|
||||||
protected $rules;
|
protected $rules;
|
||||||
/** @var array<int, BasePackage> */
|
/** @var array<int, BasePackage> */
|
||||||
protected $addedMap = array();
|
protected $addedMap = [];
|
||||||
/** @var array<string, BasePackage[]> */
|
/** @var array<string, BasePackage[]> */
|
||||||
protected $addedPackagesByNames = array();
|
protected $addedPackagesByNames = [];
|
||||||
|
|
||||||
public function __construct(PolicyInterface $policy, Pool $pool)
|
public function __construct(PolicyInterface $policy, Pool $pool)
|
||||||
{
|
{
|
||||||
|
@ -58,7 +58,7 @@ class RuleSetGenerator
|
||||||
*/
|
*/
|
||||||
protected function createRequireRule(BasePackage $package, array $providers, $reason, $reasonData = null): ?Rule
|
protected function createRequireRule(BasePackage $package, array $providers, $reason, $reasonData = null): ?Rule
|
||||||
{
|
{
|
||||||
$literals = array(-$package->id);
|
$literals = [-$package->id];
|
||||||
|
|
||||||
foreach ($providers as $provider) {
|
foreach ($providers as $provider) {
|
||||||
// self fulfilling rule?
|
// self fulfilling rule?
|
||||||
|
@ -87,7 +87,7 @@ class RuleSetGenerator
|
||||||
*/
|
*/
|
||||||
protected function createInstallOneOfRule(array $packages, $reason, $reasonData): Rule
|
protected function createInstallOneOfRule(array $packages, $reason, $reasonData): Rule
|
||||||
{
|
{
|
||||||
$literals = array();
|
$literals = [];
|
||||||
foreach ($packages as $package) {
|
foreach ($packages as $package) {
|
||||||
$literals[] = $package->id;
|
$literals[] = $package->id;
|
||||||
}
|
}
|
||||||
|
@ -123,13 +123,12 @@ class RuleSetGenerator
|
||||||
* @param BasePackage[] $packages
|
* @param BasePackage[] $packages
|
||||||
* @param Rule::RULE_* $reason A RULE_* constant
|
* @param Rule::RULE_* $reason A RULE_* constant
|
||||||
* @param mixed $reasonData
|
* @param mixed $reasonData
|
||||||
* @return Rule
|
|
||||||
*
|
*
|
||||||
* @phpstan-param ReasonData $reasonData
|
* @phpstan-param ReasonData $reasonData
|
||||||
*/
|
*/
|
||||||
protected function createMultiConflictRule(array $packages, $reason, $reasonData): Rule
|
protected function createMultiConflictRule(array $packages, $reason, $reasonData): Rule
|
||||||
{
|
{
|
||||||
$literals = array();
|
$literals = [];
|
||||||
foreach ($packages as $package) {
|
foreach ($packages as $package) {
|
||||||
$literals[] = -$package->id;
|
$literals[] = -$package->id;
|
||||||
}
|
}
|
||||||
|
@ -149,10 +148,8 @@ class RuleSetGenerator
|
||||||
*
|
*
|
||||||
* @param RuleSet::TYPE_* $type A TYPE_* constant defining the rule type
|
* @param RuleSet::TYPE_* $type A TYPE_* constant defining the rule type
|
||||||
* @param Rule $newRule The rule about to be added
|
* @param Rule $newRule The rule about to be added
|
||||||
*
|
|
||||||
* @return void
|
|
||||||
*/
|
*/
|
||||||
private function addRule($type, Rule $newRule = null): void
|
private function addRule($type, ?Rule $newRule = null): void
|
||||||
{
|
{
|
||||||
if (!$newRule) {
|
if (!$newRule) {
|
||||||
return;
|
return;
|
||||||
|
@ -161,9 +158,6 @@ class RuleSetGenerator
|
||||||
$this->rules->add($newRule, $type);
|
$this->rules->add($newRule, $type);
|
||||||
}
|
}
|
||||||
|
|
||||||
/**
|
|
||||||
* @return void
|
|
||||||
*/
|
|
||||||
protected function addRulesForPackage(BasePackage $package, PlatformRequirementFilterInterface $platformRequirementFilter): void
|
protected function addRulesForPackage(BasePackage $package, PlatformRequirementFilterInterface $platformRequirementFilter): void
|
||||||
{
|
{
|
||||||
/** @var \SplQueue<BasePackage> */
|
/** @var \SplQueue<BasePackage> */
|
||||||
|
@ -184,10 +178,10 @@ class RuleSetGenerator
|
||||||
}
|
}
|
||||||
} else {
|
} else {
|
||||||
$workQueue->enqueue($package->getAliasOf());
|
$workQueue->enqueue($package->getAliasOf());
|
||||||
$this->addRule(RuleSet::TYPE_PACKAGE, $this->createRequireRule($package, array($package->getAliasOf()), Rule::RULE_PACKAGE_ALIAS, $package));
|
$this->addRule(RuleSet::TYPE_PACKAGE, $this->createRequireRule($package, [$package->getAliasOf()], Rule::RULE_PACKAGE_ALIAS, $package));
|
||||||
|
|
||||||
// aliases must be installed with their main package, so create a rule the other way around as well
|
// aliases must be installed with their main package, so create a rule the other way around as well
|
||||||
$this->addRule(RuleSet::TYPE_PACKAGE, $this->createRequireRule($package->getAliasOf(), array($package), Rule::RULE_PACKAGE_INVERSE_ALIAS, $package->getAliasOf()));
|
$this->addRule(RuleSet::TYPE_PACKAGE, $this->createRequireRule($package->getAliasOf(), [$package], Rule::RULE_PACKAGE_INVERSE_ALIAS, $package->getAliasOf()));
|
||||||
|
|
||||||
// if alias package has no self.version requires, its requirements do not
|
// if alias package has no self.version requires, its requirements do not
|
||||||
// need to be added as the aliased package processing will take care of it
|
// need to be added as the aliased package processing will take care of it
|
||||||
|
@ -215,9 +209,6 @@ class RuleSetGenerator
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
|
|
||||||
/**
|
|
||||||
* @return void
|
|
||||||
*/
|
|
||||||
protected function addConflictRules(PlatformRequirementFilterInterface $platformRequirementFilter): void
|
protected function addConflictRules(PlatformRequirementFilterInterface $platformRequirementFilter): void
|
||||||
{
|
{
|
||||||
/** @var BasePackage $package */
|
/** @var BasePackage $package */
|
||||||
|
@ -256,9 +247,6 @@ class RuleSetGenerator
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
|
|
||||||
/**
|
|
||||||
* @return void
|
|
||||||
*/
|
|
||||||
protected function addRulesForRequest(Request $request, PlatformRequirementFilterInterface $platformRequirementFilter): void
|
protected function addRulesForRequest(Request $request, PlatformRequirementFilterInterface $platformRequirementFilter): void
|
||||||
{
|
{
|
||||||
foreach ($request->getFixedPackages() as $package) {
|
foreach ($request->getFixedPackages() as $package) {
|
||||||
|
@ -274,9 +262,9 @@ class RuleSetGenerator
|
||||||
|
|
||||||
$this->addRulesForPackage($package, $platformRequirementFilter);
|
$this->addRulesForPackage($package, $platformRequirementFilter);
|
||||||
|
|
||||||
$rule = $this->createInstallOneOfRule(array($package), Rule::RULE_FIXED, array(
|
$rule = $this->createInstallOneOfRule([$package], Rule::RULE_FIXED, [
|
||||||
'package' => $package,
|
'package' => $package,
|
||||||
));
|
]);
|
||||||
$this->addRule(RuleSet::TYPE_REQUEST, $rule);
|
$this->addRule(RuleSet::TYPE_REQUEST, $rule);
|
||||||
}
|
}
|
||||||
|
|
||||||
|
@ -293,18 +281,15 @@ class RuleSetGenerator
|
||||||
$this->addRulesForPackage($package, $platformRequirementFilter);
|
$this->addRulesForPackage($package, $platformRequirementFilter);
|
||||||
}
|
}
|
||||||
|
|
||||||
$rule = $this->createInstallOneOfRule($packages, Rule::RULE_ROOT_REQUIRE, array(
|
$rule = $this->createInstallOneOfRule($packages, Rule::RULE_ROOT_REQUIRE, [
|
||||||
'packageName' => $packageName,
|
'packageName' => $packageName,
|
||||||
'constraint' => $constraint,
|
'constraint' => $constraint,
|
||||||
));
|
]);
|
||||||
$this->addRule(RuleSet::TYPE_REQUEST, $rule);
|
$this->addRule(RuleSet::TYPE_REQUEST, $rule);
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
|
|
||||||
/**
|
|
||||||
* @return void
|
|
||||||
*/
|
|
||||||
protected function addRulesForRootAliases(PlatformRequirementFilterInterface $platformRequirementFilter): void
|
protected function addRulesForRootAliases(PlatformRequirementFilterInterface $platformRequirementFilter): void
|
||||||
{
|
{
|
||||||
foreach ($this->pool->getPackages() as $package) {
|
foreach ($this->pool->getPackages() as $package) {
|
||||||
|
@ -320,10 +305,7 @@ class RuleSetGenerator
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
|
|
||||||
/**
|
public function getRulesFor(Request $request, ?PlatformRequirementFilterInterface $platformRequirementFilter = null): RuleSet
|
||||||
* @return RuleSet
|
|
||||||
*/
|
|
||||||
public function getRulesFor(Request $request, PlatformRequirementFilterInterface $platformRequirementFilter = null): RuleSet
|
|
||||||
{
|
{
|
||||||
$platformRequirementFilter = $platformRequirementFilter ?: PlatformRequirementFilterFactory::ignoreNothing();
|
$platformRequirementFilter = $platformRequirementFilter ?: PlatformRequirementFilterFactory::ignoreNothing();
|
||||||
|
|
||||||
|
@ -334,7 +316,7 @@ class RuleSetGenerator
|
||||||
$this->addConflictRules($platformRequirementFilter);
|
$this->addConflictRules($platformRequirementFilter);
|
||||||
|
|
||||||
// Remove references to packages
|
// Remove references to packages
|
||||||
$this->addedMap = $this->addedPackagesByNames = array();
|
$this->addedMap = $this->addedPackagesByNames = [];
|
||||||
|
|
||||||
$rules = $this->rules;
|
$rules = $this->rules;
|
||||||
|
|
||||||
|
|
|
@ -27,7 +27,6 @@ class RuleWatchChain extends \SplDoublyLinkedList
|
||||||
* Moves the internal iterator to the specified offset
|
* Moves the internal iterator to the specified offset
|
||||||
*
|
*
|
||||||
* @param int $offset The offset to seek to.
|
* @param int $offset The offset to seek to.
|
||||||
* @return void
|
|
||||||
*/
|
*/
|
||||||
public function seek(int $offset): void
|
public function seek(int $offset): void
|
||||||
{
|
{
|
||||||
|
@ -42,8 +41,6 @@ class RuleWatchChain extends \SplDoublyLinkedList
|
||||||
* incorrectly sets the internal iterator if you delete the current value
|
* incorrectly sets the internal iterator if you delete the current value
|
||||||
* this method sets the internal iterator back to the following element
|
* this method sets the internal iterator back to the following element
|
||||||
* using the seek method.
|
* using the seek method.
|
||||||
*
|
|
||||||
* @return void
|
|
||||||
*/
|
*/
|
||||||
public function remove(): void
|
public function remove(): void
|
||||||
{
|
{
|
||||||
|
|
|
@ -25,7 +25,7 @@ namespace Composer\DependencyResolver;
|
||||||
class RuleWatchGraph
|
class RuleWatchGraph
|
||||||
{
|
{
|
||||||
/** @var array<int, RuleWatchChain> */
|
/** @var array<int, RuleWatchChain> */
|
||||||
protected $watchChains = array();
|
protected $watchChains = [];
|
||||||
|
|
||||||
/**
|
/**
|
||||||
* Inserts a rule node into the appropriate chains within the graph
|
* Inserts a rule node into the appropriate chains within the graph
|
||||||
|
@ -38,7 +38,6 @@ class RuleWatchGraph
|
||||||
* watch changes in any literals.
|
* watch changes in any literals.
|
||||||
*
|
*
|
||||||
* @param RuleWatchNode $node The rule node to be inserted into the graph
|
* @param RuleWatchNode $node The rule node to be inserted into the graph
|
||||||
* @return void
|
|
||||||
*/
|
*/
|
||||||
public function insert(RuleWatchNode $node): void
|
public function insert(RuleWatchNode $node): void
|
||||||
{
|
{
|
||||||
|
@ -47,7 +46,7 @@ class RuleWatchGraph
|
||||||
}
|
}
|
||||||
|
|
||||||
if (!$node->getRule() instanceof MultiConflictRule) {
|
if (!$node->getRule() instanceof MultiConflictRule) {
|
||||||
foreach (array($node->watch1, $node->watch2) as $literal) {
|
foreach ([$node->watch1, $node->watch2] as $literal) {
|
||||||
if (!isset($this->watchChains[$literal])) {
|
if (!isset($this->watchChains[$literal])) {
|
||||||
$this->watchChains[$literal] = new RuleWatchChain;
|
$this->watchChains[$literal] = new RuleWatchChain;
|
||||||
}
|
}
|
||||||
|
@ -154,7 +153,6 @@ class RuleWatchGraph
|
||||||
* @param int $fromLiteral A literal the node used to watch
|
* @param int $fromLiteral A literal the node used to watch
|
||||||
* @param int $toLiteral A literal the node should watch now
|
* @param int $toLiteral A literal the node should watch now
|
||||||
* @param RuleWatchNode $node The rule node to be moved
|
* @param RuleWatchNode $node The rule node to be moved
|
||||||
* @return void
|
|
||||||
*/
|
*/
|
||||||
protected function moveWatch(int $fromLiteral, int $toLiteral, RuleWatchNode $node): void
|
protected function moveWatch(int $fromLiteral, int $toLiteral, RuleWatchNode $node): void
|
||||||
{
|
{
|
||||||
|
|
|
@ -52,7 +52,6 @@ class RuleWatchNode
|
||||||
* likely to quickly lead to further decisions.
|
* likely to quickly lead to further decisions.
|
||||||
*
|
*
|
||||||
* @param Decisions $decisions The decisions made so far by the solver
|
* @param Decisions $decisions The decisions made so far by the solver
|
||||||
* @return void
|
|
||||||
*/
|
*/
|
||||||
public function watch2OnHighest(Decisions $decisions): void
|
public function watch2OnHighest(Decisions $decisions): void
|
||||||
{
|
{
|
||||||
|
@ -77,8 +76,6 @@ class RuleWatchNode
|
||||||
|
|
||||||
/**
|
/**
|
||||||
* Returns the rule this node wraps
|
* Returns the rule this node wraps
|
||||||
*
|
|
||||||
* @return Rule
|
|
||||||
*/
|
*/
|
||||||
public function getRule(): Rule
|
public function getRule(): Rule
|
||||||
{
|
{
|
||||||
|
@ -105,7 +102,6 @@ class RuleWatchNode
|
||||||
*
|
*
|
||||||
* @param int $from The previously watched literal
|
* @param int $from The previously watched literal
|
||||||
* @param int $to The literal to be watched now
|
* @param int $to The literal to be watched now
|
||||||
* @return void
|
|
||||||
*/
|
*/
|
||||||
public function moveWatch(int $from, int $to): void
|
public function moveWatch(int $from, int $to): void
|
||||||
{
|
{
|
||||||
|
|
|
@ -44,13 +44,13 @@ class Solver
|
||||||
/** @var int */
|
/** @var int */
|
||||||
protected $propagateIndex;
|
protected $propagateIndex;
|
||||||
/** @var mixed[] */
|
/** @var mixed[] */
|
||||||
protected $branches = array();
|
protected $branches = [];
|
||||||
/** @var Problem[] */
|
/** @var Problem[] */
|
||||||
protected $problems = array();
|
protected $problems = [];
|
||||||
/** @var array<Rule[]> */
|
/** @var array<Rule[]> */
|
||||||
protected $learnedPool = array();
|
protected $learnedPool = [];
|
||||||
/** @var array<string, int> */
|
/** @var array<string, int> */
|
||||||
protected $learnedWhy = array();
|
protected $learnedWhy = [];
|
||||||
|
|
||||||
/** @var bool */
|
/** @var bool */
|
||||||
public $testFlagLearnedPositiveLiteral = false;
|
public $testFlagLearnedPositiveLiteral = false;
|
||||||
|
@ -65,17 +65,11 @@ class Solver
|
||||||
$this->pool = $pool;
|
$this->pool = $pool;
|
||||||
}
|
}
|
||||||
|
|
||||||
/**
|
|
||||||
* @return int
|
|
||||||
*/
|
|
||||||
public function getRuleSetSize(): int
|
public function getRuleSetSize(): int
|
||||||
{
|
{
|
||||||
return \count($this->rules);
|
return \count($this->rules);
|
||||||
}
|
}
|
||||||
|
|
||||||
/**
|
|
||||||
* @return Pool
|
|
||||||
*/
|
|
||||||
public function getPool(): Pool
|
public function getPool(): Pool
|
||||||
{
|
{
|
||||||
return $this->pool;
|
return $this->pool;
|
||||||
|
@ -83,9 +77,6 @@ class Solver
|
||||||
|
|
||||||
// aka solver_makeruledecisions
|
// aka solver_makeruledecisions
|
||||||
|
|
||||||
/**
|
|
||||||
* @return void
|
|
||||||
*/
|
|
||||||
private function makeAssertionRuleDecisions(): void
|
private function makeAssertionRuleDecisions(): void
|
||||||
{
|
{
|
||||||
$decisionStart = \count($this->decisions) - 1;
|
$decisionStart = \count($this->decisions) - 1;
|
||||||
|
@ -156,20 +147,14 @@ class Solver
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
|
|
||||||
/**
|
|
||||||
* @return void
|
|
||||||
*/
|
|
||||||
protected function setupFixedMap(Request $request): void
|
protected function setupFixedMap(Request $request): void
|
||||||
{
|
{
|
||||||
$this->fixedMap = array();
|
$this->fixedMap = [];
|
||||||
foreach ($request->getFixedPackages() as $package) {
|
foreach ($request->getFixedPackages() as $package) {
|
||||||
$this->fixedMap[$package->id] = $package;
|
$this->fixedMap[$package->id] = $package;
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
|
|
||||||
/**
|
|
||||||
* @return void
|
|
||||||
*/
|
|
||||||
protected function checkForRootRequireProblems(Request $request, PlatformRequirementFilterInterface $platformRequirementFilter): void
|
protected function checkForRootRequireProblems(Request $request, PlatformRequirementFilterInterface $platformRequirementFilter): void
|
||||||
{
|
{
|
||||||
foreach ($request->getRequires() as $packageName => $constraint) {
|
foreach ($request->getRequires() as $packageName => $constraint) {
|
||||||
|
@ -181,16 +166,13 @@ class Solver
|
||||||
|
|
||||||
if (!$this->pool->whatProvides($packageName, $constraint)) {
|
if (!$this->pool->whatProvides($packageName, $constraint)) {
|
||||||
$problem = new Problem();
|
$problem = new Problem();
|
||||||
$problem->addRule(new GenericRule(array(), Rule::RULE_ROOT_REQUIRE, array('packageName' => $packageName, 'constraint' => $constraint)));
|
$problem->addRule(new GenericRule([], Rule::RULE_ROOT_REQUIRE, ['packageName' => $packageName, 'constraint' => $constraint]));
|
||||||
$this->problems[] = $problem;
|
$this->problems[] = $problem;
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
|
|
||||||
/**
|
public function solve(Request $request, ?PlatformRequirementFilterInterface $platformRequirementFilter = null): LockTransaction
|
||||||
* @return LockTransaction
|
|
||||||
*/
|
|
||||||
public function solve(Request $request, PlatformRequirementFilterInterface $platformRequirementFilter = null): LockTransaction
|
|
||||||
{
|
{
|
||||||
$platformRequirementFilter = $platformRequirementFilter ?: PlatformRequirementFilterFactory::ignoreNothing();
|
$platformRequirementFilter = $platformRequirementFilter ?: PlatformRequirementFilterFactory::ignoreNothing();
|
||||||
|
|
||||||
|
@ -230,7 +212,6 @@ class Solver
|
||||||
* Evaluates each term affected by the decision (linked through watches)
|
* Evaluates each term affected by the decision (linked through watches)
|
||||||
* If we find unit rules we make new decisions based on them
|
* If we find unit rules we make new decisions based on them
|
||||||
*
|
*
|
||||||
* @param int $level
|
|
||||||
* @return Rule|null A rule on conflict, otherwise null.
|
* @return Rule|null A rule on conflict, otherwise null.
|
||||||
*/
|
*/
|
||||||
protected function propagate(int $level): ?Rule
|
protected function propagate(int $level): ?Rule
|
||||||
|
@ -256,10 +237,6 @@ class Solver
|
||||||
|
|
||||||
/**
|
/**
|
||||||
* Reverts a decision at the given level.
|
* Reverts a decision at the given level.
|
||||||
*
|
|
||||||
* @param int $level
|
|
||||||
*
|
|
||||||
* @return void
|
|
||||||
*/
|
*/
|
||||||
private function revert(int $level): void
|
private function revert(int $level): void
|
||||||
{
|
{
|
||||||
|
@ -298,9 +275,7 @@ class Solver
|
||||||
*
|
*
|
||||||
* returns the new solver level or 0 if unsolvable
|
* returns the new solver level or 0 if unsolvable
|
||||||
*
|
*
|
||||||
* @param int $level
|
|
||||||
* @param string|int $literal
|
* @param string|int $literal
|
||||||
* @return int
|
|
||||||
*/
|
*/
|
||||||
private function setPropagateLearn(int $level, $literal, Rule $rule): int
|
private function setPropagateLearn(int $level, $literal, Rule $rule): int
|
||||||
{
|
{
|
||||||
|
@ -320,7 +295,7 @@ class Solver
|
||||||
}
|
}
|
||||||
|
|
||||||
// conflict
|
// conflict
|
||||||
list($learnLiteral, $newLevel, $newRule, $why) = $this->analyze($level, $rule);
|
[$learnLiteral, $newLevel, $newRule, $why] = $this->analyze($level, $rule);
|
||||||
|
|
||||||
if ($newLevel <= 0 || $newLevel >= $level) {
|
if ($newLevel <= 0 || $newLevel >= $level) {
|
||||||
throw new SolverBugException(
|
throw new SolverBugException(
|
||||||
|
@ -347,9 +322,7 @@ class Solver
|
||||||
}
|
}
|
||||||
|
|
||||||
/**
|
/**
|
||||||
* @param int $level
|
|
||||||
* @param int[] $decisionQueue
|
* @param int[] $decisionQueue
|
||||||
* @return int
|
|
||||||
*/
|
*/
|
||||||
private function selectAndInstall(int $level, array $decisionQueue, Rule $rule): int
|
private function selectAndInstall(int $level, array $decisionQueue, Rule $rule): int
|
||||||
{
|
{
|
||||||
|
@ -360,14 +333,13 @@ class Solver
|
||||||
|
|
||||||
// if there are multiple candidates, then branch
|
// if there are multiple candidates, then branch
|
||||||
if (\count($literals)) {
|
if (\count($literals)) {
|
||||||
$this->branches[] = array($literals, $level);
|
$this->branches[] = [$literals, $level];
|
||||||
}
|
}
|
||||||
|
|
||||||
return $this->setPropagateLearn($level, $selectedLiteral, $rule);
|
return $this->setPropagateLearn($level, $selectedLiteral, $rule);
|
||||||
}
|
}
|
||||||
|
|
||||||
/**
|
/**
|
||||||
* @param int $level
|
|
||||||
* @return array{int, int, GenericRule, int}
|
* @return array{int, int, GenericRule, int}
|
||||||
*/
|
*/
|
||||||
protected function analyze(int $level, Rule $rule): array
|
protected function analyze(int $level, Rule $rule): array
|
||||||
|
@ -376,12 +348,12 @@ class Solver
|
||||||
$ruleLevel = 1;
|
$ruleLevel = 1;
|
||||||
$num = 0;
|
$num = 0;
|
||||||
$l1num = 0;
|
$l1num = 0;
|
||||||
$seen = array();
|
$seen = [];
|
||||||
$learnedLiterals = array(null);
|
$learnedLiterals = [null];
|
||||||
|
|
||||||
$decisionId = \count($this->decisions);
|
$decisionId = \count($this->decisions);
|
||||||
|
|
||||||
$this->learnedPool[] = array();
|
$this->learnedPool[] = [];
|
||||||
|
|
||||||
while (true) {
|
while (true) {
|
||||||
$this->learnedPool[\count($this->learnedPool) - 1][] = $rule;
|
$this->learnedPool[\count($this->learnedPool) - 1][] = $rule;
|
||||||
|
@ -511,12 +483,11 @@ class Solver
|
||||||
|
|
||||||
$newRule = new GenericRule($learnedLiterals, Rule::RULE_LEARNED, $why);
|
$newRule = new GenericRule($learnedLiterals, Rule::RULE_LEARNED, $why);
|
||||||
|
|
||||||
return array($learnedLiterals[0], $ruleLevel, $newRule, $why);
|
return [$learnedLiterals[0], $ruleLevel, $newRule, $why];
|
||||||
}
|
}
|
||||||
|
|
||||||
/**
|
/**
|
||||||
* @param array<string, true> $ruleSeen
|
* @param array<string, true> $ruleSeen
|
||||||
* @return void
|
|
||||||
*/
|
*/
|
||||||
private function analyzeUnsolvableRule(Problem $problem, Rule $conflictRule, array &$ruleSeen): void
|
private function analyzeUnsolvableRule(Problem $problem, Rule $conflictRule, array &$ruleSeen): void
|
||||||
{
|
{
|
||||||
|
@ -545,21 +516,18 @@ class Solver
|
||||||
$problem->addRule($conflictRule);
|
$problem->addRule($conflictRule);
|
||||||
}
|
}
|
||||||
|
|
||||||
/**
|
|
||||||
* @return int
|
|
||||||
*/
|
|
||||||
private function analyzeUnsolvable(Rule $conflictRule): int
|
private function analyzeUnsolvable(Rule $conflictRule): int
|
||||||
{
|
{
|
||||||
$problem = new Problem();
|
$problem = new Problem();
|
||||||
$problem->addRule($conflictRule);
|
$problem->addRule($conflictRule);
|
||||||
|
|
||||||
$ruleSeen = array();
|
$ruleSeen = [];
|
||||||
|
|
||||||
$this->analyzeUnsolvableRule($problem, $conflictRule, $ruleSeen);
|
$this->analyzeUnsolvableRule($problem, $conflictRule, $ruleSeen);
|
||||||
|
|
||||||
$this->problems[] = $problem;
|
$this->problems[] = $problem;
|
||||||
|
|
||||||
$seen = array();
|
$seen = [];
|
||||||
$literals = $conflictRule->getLiterals();
|
$literals = $conflictRule->getLiterals();
|
||||||
|
|
||||||
foreach ($literals as $literal) {
|
foreach ($literals as $literal) {
|
||||||
|
@ -603,8 +571,6 @@ class Solver
|
||||||
* we have enabled or disabled some of our rules. We now re-enable all
|
* we have enabled or disabled some of our rules. We now re-enable all
|
||||||
* of our learnt rules except the ones that were learnt from rules that
|
* of our learnt rules except the ones that were learnt from rules that
|
||||||
* are now disabled.
|
* are now disabled.
|
||||||
*
|
|
||||||
* @return void
|
|
||||||
*/
|
*/
|
||||||
private function enableDisableLearnedRules(): void
|
private function enableDisableLearnedRules(): void
|
||||||
{
|
{
|
||||||
|
@ -628,9 +594,6 @@ class Solver
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
|
|
||||||
/**
|
|
||||||
* @return void
|
|
||||||
*/
|
|
||||||
private function runSat(): void
|
private function runSat(): void
|
||||||
{
|
{
|
||||||
$this->propagateIndex = 0;
|
$this->propagateIndex = 0;
|
||||||
|
@ -665,7 +628,7 @@ class Solver
|
||||||
$iterator = $this->rules->getIteratorFor(RuleSet::TYPE_REQUEST);
|
$iterator = $this->rules->getIteratorFor(RuleSet::TYPE_REQUEST);
|
||||||
foreach ($iterator as $rule) {
|
foreach ($iterator as $rule) {
|
||||||
if ($rule->isEnabled()) {
|
if ($rule->isEnabled()) {
|
||||||
$decisionQueue = array();
|
$decisionQueue = [];
|
||||||
$noneSatisfied = true;
|
$noneSatisfied = true;
|
||||||
|
|
||||||
foreach ($rule->getLiterals() as $literal) {
|
foreach ($rule->getLiterals() as $literal) {
|
||||||
|
@ -680,7 +643,7 @@ class Solver
|
||||||
|
|
||||||
if ($noneSatisfied && \count($decisionQueue)) {
|
if ($noneSatisfied && \count($decisionQueue)) {
|
||||||
// if any of the options in the decision queue are fixed, only use those
|
// if any of the options in the decision queue are fixed, only use those
|
||||||
$prunedQueue = array();
|
$prunedQueue = [];
|
||||||
foreach ($decisionQueue as $literal) {
|
foreach ($decisionQueue as $literal) {
|
||||||
if (isset($this->fixedMap[abs($literal)])) {
|
if (isset($this->fixedMap[abs($literal)])) {
|
||||||
$prunedQueue[] = $literal;
|
$prunedQueue[] = $literal;
|
||||||
|
@ -741,7 +704,7 @@ class Solver
|
||||||
continue;
|
continue;
|
||||||
}
|
}
|
||||||
|
|
||||||
$decisionQueue = array();
|
$decisionQueue = [];
|
||||||
|
|
||||||
// make sure that
|
// make sure that
|
||||||
// * all negative literals are installed
|
// * all negative literals are installed
|
||||||
|
@ -792,7 +755,7 @@ class Solver
|
||||||
$lastBranchOffset = 0;
|
$lastBranchOffset = 0;
|
||||||
|
|
||||||
for ($i = \count($this->branches) - 1; $i >= 0; $i--) {
|
for ($i = \count($this->branches) - 1; $i >= 0; $i--) {
|
||||||
list($literals, $l) = $this->branches[$i];
|
[$literals, $l] = $this->branches[$i];
|
||||||
|
|
||||||
foreach ($literals as $offset => $literal) {
|
foreach ($literals as $offset => $literal) {
|
||||||
if ($literal && $literal > 0 && $this->decisions->decisionLevel($literal) > $l + 1) {
|
if ($literal && $literal > 0 && $this->decisions->decisionLevel($literal) > $l + 1) {
|
||||||
|
|
|
@ -17,9 +17,6 @@ namespace Composer\DependencyResolver;
|
||||||
*/
|
*/
|
||||||
class SolverBugException extends \RuntimeException
|
class SolverBugException extends \RuntimeException
|
||||||
{
|
{
|
||||||
/**
|
|
||||||
* @param string $message
|
|
||||||
*/
|
|
||||||
public function __construct(string $message)
|
public function __construct(string $message)
|
||||||
{
|
{
|
||||||
parent::__construct(
|
parent::__construct(
|
||||||
|
|
|
@ -41,18 +41,13 @@ class SolverProblemsException extends \RuntimeException
|
||||||
parent::__construct('Failed resolving dependencies with '.count($problems).' problems, call getPrettyString to get formatted details', self::ERROR_DEPENDENCY_RESOLUTION_FAILED);
|
parent::__construct('Failed resolving dependencies with '.count($problems).' problems, call getPrettyString to get formatted details', self::ERROR_DEPENDENCY_RESOLUTION_FAILED);
|
||||||
}
|
}
|
||||||
|
|
||||||
/**
|
|
||||||
* @param bool $isVerbose
|
|
||||||
* @param bool $isDevExtraction
|
|
||||||
* @return string
|
|
||||||
*/
|
|
||||||
public function getPrettyString(RepositorySet $repositorySet, Request $request, Pool $pool, bool $isVerbose, bool $isDevExtraction = false): string
|
public function getPrettyString(RepositorySet $repositorySet, Request $request, Pool $pool, bool $isVerbose, bool $isDevExtraction = false): string
|
||||||
{
|
{
|
||||||
$installedMap = $request->getPresentMap(true);
|
$installedMap = $request->getPresentMap(true);
|
||||||
$missingExtensions = array();
|
$missingExtensions = [];
|
||||||
$isCausedByLock = false;
|
$isCausedByLock = false;
|
||||||
|
|
||||||
$problems = array();
|
$problems = [];
|
||||||
foreach ($this->problems as $problem) {
|
foreach ($this->problems as $problem) {
|
||||||
$problems[] = $problem->getPrettyString($repositorySet, $request, $pool, $isVerbose, $installedMap, $this->learnedPool)."\n";
|
$problems[] = $problem->getPrettyString($repositorySet, $request, $pool, $isVerbose, $installedMap, $this->learnedPool)."\n";
|
||||||
|
|
||||||
|
@ -67,7 +62,7 @@ class SolverProblemsException extends \RuntimeException
|
||||||
$text .= " Problem ".($i++).$problem;
|
$text .= " Problem ".($i++).$problem;
|
||||||
}
|
}
|
||||||
|
|
||||||
$hints = array();
|
$hints = [];
|
||||||
if (!$isDevExtraction && (strpos($text, 'could not be found') || strpos($text, 'no matching package found'))) {
|
if (!$isDevExtraction && (strpos($text, 'could not be found') || strpos($text, 'no matching package found'))) {
|
||||||
$hints[] = "Potential causes:\n - A typo in the package name\n - The package is not available in a stable-enough version according to your minimum-stability setting\n see <https://getcomposer.org/doc/04-schema.md#minimum-stability> for more details.\n - It's a private package and you forgot to add a custom repository to find it\n\nRead <https://getcomposer.org/doc/articles/troubleshooting.md> for further common problems.";
|
$hints[] = "Potential causes:\n - A typo in the package name\n - The package is not available in a stable-enough version according to your minimum-stability setting\n see <https://getcomposer.org/doc/04-schema.md#minimum-stability> for more details.\n - It's a private package and you forgot to add a custom repository to find it\n\nRead <https://getcomposer.org/doc/articles/troubleshooting.md> for further common problems.";
|
||||||
}
|
}
|
||||||
|
@ -107,7 +102,6 @@ class SolverProblemsException extends \RuntimeException
|
||||||
|
|
||||||
/**
|
/**
|
||||||
* @param string[] $missingExtensions
|
* @param string[] $missingExtensions
|
||||||
* @return string
|
|
||||||
*/
|
*/
|
||||||
private function createExtensionHint(array $missingExtensions): string
|
private function createExtensionHint(array $missingExtensions): string
|
||||||
{
|
{
|
||||||
|
@ -139,7 +133,7 @@ class SolverProblemsException extends \RuntimeException
|
||||||
*/
|
*/
|
||||||
private function getExtensionProblems(array $reasonSets): array
|
private function getExtensionProblems(array $reasonSets): array
|
||||||
{
|
{
|
||||||
$missingExtensions = array();
|
$missingExtensions = [];
|
||||||
foreach ($reasonSets as $reasonSet) {
|
foreach ($reasonSets as $reasonSet) {
|
||||||
foreach ($reasonSet as $rule) {
|
foreach ($reasonSet as $rule) {
|
||||||
$required = $rule->getRequiredPackage();
|
$required = $rule->getRequiredPackage();
|
||||||
|
|
|
@ -44,7 +44,7 @@ class Transaction
|
||||||
/**
|
/**
|
||||||
* @var array<string, PackageInterface[]>
|
* @var array<string, PackageInterface[]>
|
||||||
*/
|
*/
|
||||||
protected $resultPackagesByName = array();
|
protected $resultPackagesByName = [];
|
||||||
|
|
||||||
/**
|
/**
|
||||||
* @param PackageInterface[] $presentPackages
|
* @param PackageInterface[] $presentPackages
|
||||||
|
@ -67,7 +67,6 @@ class Transaction
|
||||||
|
|
||||||
/**
|
/**
|
||||||
* @param PackageInterface[] $resultPackages
|
* @param PackageInterface[] $resultPackages
|
||||||
* @return void
|
|
||||||
*/
|
*/
|
||||||
private function setResultPackageMaps(array $resultPackages): void
|
private function setResultPackageMaps(array $resultPackages): void
|
||||||
{
|
{
|
||||||
|
@ -84,7 +83,7 @@ class Transaction
|
||||||
return strcmp($b->getName(), $a->getName());
|
return strcmp($b->getName(), $a->getName());
|
||||||
};
|
};
|
||||||
|
|
||||||
$this->resultPackageMap = array();
|
$this->resultPackageMap = [];
|
||||||
foreach ($resultPackages as $package) {
|
foreach ($resultPackages as $package) {
|
||||||
$this->resultPackageMap[spl_object_hash($package)] = $package;
|
$this->resultPackageMap[spl_object_hash($package)] = $package;
|
||||||
foreach ($package->getNames() as $name) {
|
foreach ($package->getNames() as $name) {
|
||||||
|
@ -103,12 +102,12 @@ class Transaction
|
||||||
*/
|
*/
|
||||||
protected function calculateOperations(): array
|
protected function calculateOperations(): array
|
||||||
{
|
{
|
||||||
$operations = array();
|
$operations = [];
|
||||||
|
|
||||||
$presentPackageMap = array();
|
$presentPackageMap = [];
|
||||||
$removeMap = array();
|
$removeMap = [];
|
||||||
$presentAliasMap = array();
|
$presentAliasMap = [];
|
||||||
$removeAliasMap = array();
|
$removeAliasMap = [];
|
||||||
foreach ($this->presentPackages as $package) {
|
foreach ($this->presentPackages as $package) {
|
||||||
if ($package instanceof AliasPackage) {
|
if ($package instanceof AliasPackage) {
|
||||||
$presentAliasMap[$package->getName().'::'.$package->getVersion()] = $package;
|
$presentAliasMap[$package->getName().'::'.$package->getVersion()] = $package;
|
||||||
|
@ -121,8 +120,8 @@ class Transaction
|
||||||
|
|
||||||
$stack = $this->getRootPackages();
|
$stack = $this->getRootPackages();
|
||||||
|
|
||||||
$visited = array();
|
$visited = [];
|
||||||
$processed = array();
|
$processed = [];
|
||||||
|
|
||||||
while (!empty($stack)) {
|
while (!empty($stack)) {
|
||||||
$package = array_pop($stack);
|
$package = array_pop($stack);
|
||||||
|
@ -247,7 +246,7 @@ class Transaction
|
||||||
protected function getProvidersInResult(Link $link): array
|
protected function getProvidersInResult(Link $link): array
|
||||||
{
|
{
|
||||||
if (!isset($this->resultPackagesByName[$link->getTarget()])) {
|
if (!isset($this->resultPackagesByName[$link->getTarget()])) {
|
||||||
return array();
|
return [];
|
||||||
}
|
}
|
||||||
|
|
||||||
return $this->resultPackagesByName[$link->getTarget()];
|
return $this->resultPackagesByName[$link->getTarget()];
|
||||||
|
@ -268,12 +267,12 @@ class Transaction
|
||||||
*/
|
*/
|
||||||
private function movePluginsToFront(array $operations): array
|
private function movePluginsToFront(array $operations): array
|
||||||
{
|
{
|
||||||
$dlModifyingPluginsNoDeps = array();
|
$dlModifyingPluginsNoDeps = [];
|
||||||
$dlModifyingPluginsWithDeps = array();
|
$dlModifyingPluginsWithDeps = [];
|
||||||
$dlModifyingPluginRequires = array();
|
$dlModifyingPluginRequires = [];
|
||||||
$pluginsNoDeps = array();
|
$pluginsNoDeps = [];
|
||||||
$pluginsWithDeps = array();
|
$pluginsWithDeps = [];
|
||||||
$pluginRequires = array();
|
$pluginRequires = [];
|
||||||
|
|
||||||
foreach (array_reverse($operations, true) as $idx => $op) {
|
foreach (array_reverse($operations, true) as $idx => $op) {
|
||||||
if ($op instanceof Operation\InstallOperation) {
|
if ($op instanceof Operation\InstallOperation) {
|
||||||
|
@ -345,7 +344,7 @@ class Transaction
|
||||||
*/
|
*/
|
||||||
private function moveUninstallsToFront(array $operations): array
|
private function moveUninstallsToFront(array $operations): array
|
||||||
{
|
{
|
||||||
$uninstOps = array();
|
$uninstOps = [];
|
||||||
foreach ($operations as $idx => $op) {
|
foreach ($operations as $idx => $op) {
|
||||||
if ($op instanceof Operation\UninstallOperation || $op instanceof Operation\MarkAliasUninstalledOperation) {
|
if ($op instanceof Operation\UninstallOperation || $op instanceof Operation\MarkAliasUninstalledOperation) {
|
||||||
$uninstOps[] = $op;
|
$uninstOps[] = $op;
|
||||||
|
|
|
@ -30,22 +30,16 @@ abstract class ArchiveDownloader extends FileDownloader
|
||||||
/**
|
/**
|
||||||
* @var array<string, true>
|
* @var array<string, true>
|
||||||
*/
|
*/
|
||||||
protected $cleanupExecuted = array();
|
protected $cleanupExecuted = [];
|
||||||
|
|
||||||
/**
|
public function prepare(string $type, PackageInterface $package, string $path, ?PackageInterface $prevPackage = null): PromiseInterface
|
||||||
* @return PromiseInterface
|
|
||||||
*/
|
|
||||||
public function prepare(string $type, PackageInterface $package, string $path, PackageInterface $prevPackage = null): PromiseInterface
|
|
||||||
{
|
{
|
||||||
unset($this->cleanupExecuted[$package->getName()]);
|
unset($this->cleanupExecuted[$package->getName()]);
|
||||||
|
|
||||||
return parent::prepare($type, $package, $path, $prevPackage);
|
return parent::prepare($type, $package, $path, $prevPackage);
|
||||||
}
|
}
|
||||||
|
|
||||||
/**
|
public function cleanup(string $type, PackageInterface $package, string $path, ?PackageInterface $prevPackage = null): PromiseInterface
|
||||||
* @return PromiseInterface
|
|
||||||
*/
|
|
||||||
public function cleanup(string $type, PackageInterface $package, string $path, PackageInterface $prevPackage = null): PromiseInterface
|
|
||||||
{
|
{
|
||||||
$this->cleanupExecuted[$package->getName()] = true;
|
$this->cleanupExecuted[$package->getName()] = true;
|
||||||
|
|
||||||
|
@ -55,9 +49,7 @@ abstract class ArchiveDownloader extends FileDownloader
|
||||||
/**
|
/**
|
||||||
* @inheritDoc
|
* @inheritDoc
|
||||||
*
|
*
|
||||||
* @param bool $output
|
|
||||||
*
|
*
|
||||||
* @return PromiseInterface
|
|
||||||
*
|
*
|
||||||
* @throws \RuntimeException
|
* @throws \RuntimeException
|
||||||
* @throws \UnexpectedValueException
|
* @throws \UnexpectedValueException
|
||||||
|
|
|
@ -33,11 +33,11 @@ class DownloadManager
|
||||||
/** @var bool */
|
/** @var bool */
|
||||||
private $preferSource;
|
private $preferSource;
|
||||||
/** @var array<string, string> */
|
/** @var array<string, string> */
|
||||||
private $packagePreferences = array();
|
private $packagePreferences = [];
|
||||||
/** @var Filesystem */
|
/** @var Filesystem */
|
||||||
private $filesystem;
|
private $filesystem;
|
||||||
/** @var array<string, DownloaderInterface> */
|
/** @var array<string, DownloaderInterface> */
|
||||||
private $downloaders = array();
|
private $downloaders = [];
|
||||||
|
|
||||||
/**
|
/**
|
||||||
* Initializes download manager.
|
* Initializes download manager.
|
||||||
|
@ -46,7 +46,7 @@ class DownloadManager
|
||||||
* @param bool $preferSource prefer downloading from source
|
* @param bool $preferSource prefer downloading from source
|
||||||
* @param Filesystem|null $filesystem custom Filesystem object
|
* @param Filesystem|null $filesystem custom Filesystem object
|
||||||
*/
|
*/
|
||||||
public function __construct(IOInterface $io, bool $preferSource = false, Filesystem $filesystem = null)
|
public function __construct(IOInterface $io, bool $preferSource = false, ?Filesystem $filesystem = null)
|
||||||
{
|
{
|
||||||
$this->io = $io;
|
$this->io = $io;
|
||||||
$this->preferSource = $preferSource;
|
$this->preferSource = $preferSource;
|
||||||
|
@ -113,7 +113,6 @@ class DownloadManager
|
||||||
*
|
*
|
||||||
* @param string $type installation type
|
* @param string $type installation type
|
||||||
* @throws \InvalidArgumentException if downloader for provided type is not registered
|
* @throws \InvalidArgumentException if downloader for provided type is not registered
|
||||||
* @return DownloaderInterface
|
|
||||||
*/
|
*/
|
||||||
public function getDownloader(string $type): DownloaderInterface
|
public function getDownloader(string $type): DownloaderInterface
|
||||||
{
|
{
|
||||||
|
@ -132,7 +131,6 @@ class DownloadManager
|
||||||
* @throws \InvalidArgumentException if package has no installation source specified
|
* @throws \InvalidArgumentException if package has no installation source specified
|
||||||
* @throws \LogicException if specific downloader used to load package with
|
* @throws \LogicException if specific downloader used to load package with
|
||||||
* wrong type
|
* wrong type
|
||||||
* @return DownloaderInterface|null
|
|
||||||
*/
|
*/
|
||||||
public function getDownloaderForPackage(PackageInterface $package): ?DownloaderInterface
|
public function getDownloaderForPackage(PackageInterface $package): ?DownloaderInterface
|
||||||
{
|
{
|
||||||
|
@ -165,9 +163,6 @@ class DownloadManager
|
||||||
return $downloader;
|
return $downloader;
|
||||||
}
|
}
|
||||||
|
|
||||||
/**
|
|
||||||
* @return string
|
|
||||||
*/
|
|
||||||
public function getDownloaderType(DownloaderInterface $downloader): string
|
public function getDownloaderType(DownloaderInterface $downloader): string
|
||||||
{
|
{
|
||||||
return array_search($downloader, $this->downloaders);
|
return array_search($downloader, $this->downloaders);
|
||||||
|
@ -182,9 +177,8 @@ class DownloadManager
|
||||||
*
|
*
|
||||||
* @throws \InvalidArgumentException if package have no urls to download from
|
* @throws \InvalidArgumentException if package have no urls to download from
|
||||||
* @throws \RuntimeException
|
* @throws \RuntimeException
|
||||||
* @return PromiseInterface
|
|
||||||
*/
|
*/
|
||||||
public function download(PackageInterface $package, string $targetDir, PackageInterface $prevPackage = null): PromiseInterface
|
public function download(PackageInterface $package, string $targetDir, ?PackageInterface $prevPackage = null): PromiseInterface
|
||||||
{
|
{
|
||||||
$targetDir = $this->normalizeTargetDir($targetDir);
|
$targetDir = $this->normalizeTargetDir($targetDir);
|
||||||
$this->filesystem->ensureDirectoryExists(dirname($targetDir));
|
$this->filesystem->ensureDirectoryExists(dirname($targetDir));
|
||||||
|
@ -247,10 +241,8 @@ class DownloadManager
|
||||||
* @param PackageInterface $package package instance
|
* @param PackageInterface $package package instance
|
||||||
* @param string $targetDir target dir
|
* @param string $targetDir target dir
|
||||||
* @param PackageInterface|null $prevPackage previous package instance in case of updates
|
* @param PackageInterface|null $prevPackage previous package instance in case of updates
|
||||||
*
|
|
||||||
* @return PromiseInterface
|
|
||||||
*/
|
*/
|
||||||
public function prepare(string $type, PackageInterface $package, string $targetDir, PackageInterface $prevPackage = null): PromiseInterface
|
public function prepare(string $type, PackageInterface $package, string $targetDir, ?PackageInterface $prevPackage = null): PromiseInterface
|
||||||
{
|
{
|
||||||
$targetDir = $this->normalizeTargetDir($targetDir);
|
$targetDir = $this->normalizeTargetDir($targetDir);
|
||||||
$downloader = $this->getDownloaderForPackage($package);
|
$downloader = $this->getDownloaderForPackage($package);
|
||||||
|
@ -269,7 +261,6 @@ class DownloadManager
|
||||||
*
|
*
|
||||||
* @throws \InvalidArgumentException if package have no urls to download from
|
* @throws \InvalidArgumentException if package have no urls to download from
|
||||||
* @throws \RuntimeException
|
* @throws \RuntimeException
|
||||||
* @return PromiseInterface
|
|
||||||
*/
|
*/
|
||||||
public function install(PackageInterface $package, string $targetDir): PromiseInterface
|
public function install(PackageInterface $package, string $targetDir): PromiseInterface
|
||||||
{
|
{
|
||||||
|
@ -290,7 +281,6 @@ class DownloadManager
|
||||||
* @param string $targetDir target dir
|
* @param string $targetDir target dir
|
||||||
*
|
*
|
||||||
* @throws \InvalidArgumentException if initial package is not installed
|
* @throws \InvalidArgumentException if initial package is not installed
|
||||||
* @return PromiseInterface
|
|
||||||
*/
|
*/
|
||||||
public function update(PackageInterface $initial, PackageInterface $target, string $targetDir): PromiseInterface
|
public function update(PackageInterface $initial, PackageInterface $target, string $targetDir): PromiseInterface
|
||||||
{
|
{
|
||||||
|
@ -338,8 +328,6 @@ class DownloadManager
|
||||||
*
|
*
|
||||||
* @param PackageInterface $package package instance
|
* @param PackageInterface $package package instance
|
||||||
* @param string $targetDir target dir
|
* @param string $targetDir target dir
|
||||||
*
|
|
||||||
* @return PromiseInterface
|
|
||||||
*/
|
*/
|
||||||
public function remove(PackageInterface $package, string $targetDir): PromiseInterface
|
public function remove(PackageInterface $package, string $targetDir): PromiseInterface
|
||||||
{
|
{
|
||||||
|
@ -359,10 +347,8 @@ class DownloadManager
|
||||||
* @param PackageInterface $package package instance
|
* @param PackageInterface $package package instance
|
||||||
* @param string $targetDir target dir
|
* @param string $targetDir target dir
|
||||||
* @param PackageInterface|null $prevPackage previous package instance in case of updates
|
* @param PackageInterface|null $prevPackage previous package instance in case of updates
|
||||||
*
|
|
||||||
* @return PromiseInterface
|
|
||||||
*/
|
*/
|
||||||
public function cleanup(string $type, PackageInterface $package, string $targetDir, PackageInterface $prevPackage = null): PromiseInterface
|
public function cleanup(string $type, PackageInterface $package, string $targetDir, ?PackageInterface $prevPackage = null): PromiseInterface
|
||||||
{
|
{
|
||||||
$targetDir = $this->normalizeTargetDir($targetDir);
|
$targetDir = $this->normalizeTargetDir($targetDir);
|
||||||
$downloader = $this->getDownloaderForPackage($package);
|
$downloader = $this->getDownloaderForPackage($package);
|
||||||
|
@ -377,8 +363,6 @@ class DownloadManager
|
||||||
* Determines the install preference of a package
|
* Determines the install preference of a package
|
||||||
*
|
*
|
||||||
* @param PackageInterface $package package instance
|
* @param PackageInterface $package package instance
|
||||||
*
|
|
||||||
* @return string
|
|
||||||
*/
|
*/
|
||||||
protected function resolvePackageInstallPreference(PackageInterface $package): string
|
protected function resolvePackageInstallPreference(PackageInterface $package): string
|
||||||
{
|
{
|
||||||
|
@ -400,13 +384,13 @@ class DownloadManager
|
||||||
* @return string[]
|
* @return string[]
|
||||||
* @phpstan-return array<'dist'|'source'>&non-empty-array
|
* @phpstan-return array<'dist'|'source'>&non-empty-array
|
||||||
*/
|
*/
|
||||||
private function getAvailableSources(PackageInterface $package, PackageInterface $prevPackage = null): array
|
private function getAvailableSources(PackageInterface $package, ?PackageInterface $prevPackage = null): array
|
||||||
{
|
{
|
||||||
$sourceType = $package->getSourceType();
|
$sourceType = $package->getSourceType();
|
||||||
$distType = $package->getDistType();
|
$distType = $package->getDistType();
|
||||||
|
|
||||||
// add source before dist by default
|
// add source before dist by default
|
||||||
$sources = array();
|
$sources = [];
|
||||||
if ($sourceType) {
|
if ($sourceType) {
|
||||||
$sources[] = 'source';
|
$sources[] = 'source';
|
||||||
}
|
}
|
||||||
|
@ -445,10 +429,6 @@ class DownloadManager
|
||||||
* Downloaders expect a /path/to/dir without trailing slash
|
* Downloaders expect a /path/to/dir without trailing slash
|
||||||
*
|
*
|
||||||
* 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
|
|
||||||
*/
|
*/
|
||||||
private function normalizeTargetDir(string $dir): string
|
private function normalizeTargetDir(string $dir): string
|
||||||
{
|
{
|
||||||
|
|
|
@ -34,9 +34,8 @@ interface DownloaderInterface
|
||||||
* This should do any network-related tasks to prepare for an upcoming install/update
|
* This should do any network-related tasks to prepare for an upcoming install/update
|
||||||
*
|
*
|
||||||
* @param string $path download path
|
* @param string $path download path
|
||||||
* @return PromiseInterface
|
|
||||||
*/
|
*/
|
||||||
public function download(PackageInterface $package, string $path, PackageInterface $prevPackage = null): PromiseInterface;
|
public function download(PackageInterface $package, string $path, ?PackageInterface $prevPackage = null): PromiseInterface;
|
||||||
|
|
||||||
/**
|
/**
|
||||||
* Do anything that needs to be done between all downloads have been completed and the actual operation is executed
|
* Do anything that needs to be done between all downloads have been completed and the actual operation is executed
|
||||||
|
@ -50,16 +49,14 @@ interface DownloaderInterface
|
||||||
* @param PackageInterface $package package instance
|
* @param PackageInterface $package package instance
|
||||||
* @param string $path download path
|
* @param string $path download path
|
||||||
* @param PackageInterface $prevPackage previous package instance in case of an update
|
* @param PackageInterface $prevPackage previous package instance in case of an update
|
||||||
* @return PromiseInterface
|
|
||||||
*/
|
*/
|
||||||
public function prepare(string $type, PackageInterface $package, string $path, PackageInterface $prevPackage = null): PromiseInterface;
|
public function prepare(string $type, PackageInterface $package, string $path, ?PackageInterface $prevPackage = null): PromiseInterface;
|
||||||
|
|
||||||
/**
|
/**
|
||||||
* Installs specific package into specific folder.
|
* Installs specific package into specific folder.
|
||||||
*
|
*
|
||||||
* @param PackageInterface $package package instance
|
* @param PackageInterface $package package instance
|
||||||
* @param string $path download path
|
* @param string $path download path
|
||||||
* @return PromiseInterface
|
|
||||||
*/
|
*/
|
||||||
public function install(PackageInterface $package, string $path): PromiseInterface;
|
public function install(PackageInterface $package, string $path): PromiseInterface;
|
||||||
|
|
||||||
|
@ -69,7 +66,6 @@ interface DownloaderInterface
|
||||||
* @param PackageInterface $initial initial package
|
* @param PackageInterface $initial initial package
|
||||||
* @param PackageInterface $target updated package
|
* @param PackageInterface $target updated package
|
||||||
* @param string $path download path
|
* @param string $path download path
|
||||||
* @return PromiseInterface
|
|
||||||
*/
|
*/
|
||||||
public function update(PackageInterface $initial, PackageInterface $target, string $path): PromiseInterface;
|
public function update(PackageInterface $initial, PackageInterface $target, string $path): PromiseInterface;
|
||||||
|
|
||||||
|
@ -78,7 +74,6 @@ interface DownloaderInterface
|
||||||
*
|
*
|
||||||
* @param PackageInterface $package package instance
|
* @param PackageInterface $package package instance
|
||||||
* @param string $path download path
|
* @param string $path download path
|
||||||
* @return PromiseInterface
|
|
||||||
*/
|
*/
|
||||||
public function remove(PackageInterface $package, string $path): PromiseInterface;
|
public function remove(PackageInterface $package, string $path): PromiseInterface;
|
||||||
|
|
||||||
|
@ -93,7 +88,6 @@ interface DownloaderInterface
|
||||||
* @param PackageInterface $package package instance
|
* @param PackageInterface $package package instance
|
||||||
* @param string $path download path
|
* @param string $path download path
|
||||||
* @param PackageInterface $prevPackage previous package instance in case of an update
|
* @param PackageInterface $prevPackage previous package instance in case of an update
|
||||||
* @return PromiseInterface
|
|
||||||
*/
|
*/
|
||||||
public function cleanup(string $type, PackageInterface $package, string $path, PackageInterface $prevPackage = null): PromiseInterface;
|
public function cleanup(string $type, PackageInterface $package, string $path, ?PackageInterface $prevPackage = null): PromiseInterface;
|
||||||
}
|
}
|
||||||
|
|
|
@ -63,14 +63,14 @@ class FileDownloader implements DownloaderInterface, ChangeReportInterface
|
||||||
* @private
|
* @private
|
||||||
* @internal
|
* @internal
|
||||||
*/
|
*/
|
||||||
public static $downloadMetadata = array();
|
public static $downloadMetadata = [];
|
||||||
|
|
||||||
/**
|
/**
|
||||||
* @var array<string, string> Map of package name to cache key
|
* @var array<string, string> Map of package name to cache key
|
||||||
*/
|
*/
|
||||||
private $lastCacheWrites = array();
|
private $lastCacheWrites = [];
|
||||||
/** @var array<string, string[]> Map of package name to list of paths */
|
/** @var array<string, string[]> Map of package name to list of paths */
|
||||||
private $additionalCleanupPaths = array();
|
private $additionalCleanupPaths = [];
|
||||||
|
|
||||||
/**
|
/**
|
||||||
* Constructor.
|
* Constructor.
|
||||||
|
@ -82,7 +82,7 @@ class FileDownloader implements DownloaderInterface, ChangeReportInterface
|
||||||
* @param Cache $cache Cache instance
|
* @param Cache $cache Cache instance
|
||||||
* @param Filesystem $filesystem The filesystem
|
* @param Filesystem $filesystem The filesystem
|
||||||
*/
|
*/
|
||||||
public function __construct(IOInterface $io, Config $config, HttpDownloader $httpDownloader, EventDispatcher $eventDispatcher = null, Cache $cache = null, Filesystem $filesystem = null, ProcessExecutor $process = null)
|
public function __construct(IOInterface $io, Config $config, HttpDownloader $httpDownloader, ?EventDispatcher $eventDispatcher = null, ?Cache $cache = null, ?Filesystem $filesystem = null, ?ProcessExecutor $process = null)
|
||||||
{
|
{
|
||||||
$this->io = $io;
|
$this->io = $io;
|
||||||
$this->config = $config;
|
$this->config = $config;
|
||||||
|
@ -108,10 +108,8 @@ class FileDownloader implements DownloaderInterface, ChangeReportInterface
|
||||||
|
|
||||||
/**
|
/**
|
||||||
* @inheritDoc
|
* @inheritDoc
|
||||||
*
|
|
||||||
* @param bool $output
|
|
||||||
*/
|
*/
|
||||||
public function download(PackageInterface $package, string $path, PackageInterface $prevPackage = null, bool $output = true): PromiseInterface
|
public function download(PackageInterface $package, string $path, ?PackageInterface $prevPackage = null, bool $output = true): PromiseInterface
|
||||||
{
|
{
|
||||||
if (!$package->getDistUrl()) {
|
if (!$package->getDistUrl()) {
|
||||||
throw new \InvalidArgumentException('The given package is missing url information');
|
throw new \InvalidArgumentException('The given package is missing url information');
|
||||||
|
@ -126,10 +124,10 @@ class FileDownloader implements DownloaderInterface, ChangeReportInterface
|
||||||
$retries = 3;
|
$retries = 3;
|
||||||
$distUrls = $package->getDistUrls();
|
$distUrls = $package->getDistUrls();
|
||||||
/** @var array<array{base: string, processed: string, cacheKey: string}> $urls */
|
/** @var array<array{base: string, processed: string, cacheKey: string}> $urls */
|
||||||
$urls = array();
|
$urls = [];
|
||||||
foreach ($distUrls as $index => $url) {
|
foreach ($distUrls as $index => $url) {
|
||||||
$processedUrl = $this->processUrl($package, $url);
|
$processedUrl = $this->processUrl($package, $url);
|
||||||
$urls[$index] = array(
|
$urls[$index] = [
|
||||||
'base' => $url,
|
'base' => $url,
|
||||||
'processed' => $processedUrl,
|
'processed' => $processedUrl,
|
||||||
// we use the complete download url here to avoid conflicting entries
|
// we use the complete download url here to avoid conflicting entries
|
||||||
|
@ -137,7 +135,7 @@ class FileDownloader implements DownloaderInterface, ChangeReportInterface
|
||||||
// in a third party repo to pre-populate the cache for the same package in
|
// in a third party repo to pre-populate the cache for the same package in
|
||||||
// packagist for example.
|
// packagist for example.
|
||||||
'cacheKey' => $cacheKeyGenerator($package, $processedUrl),
|
'cacheKey' => $cacheKeyGenerator($package, $processedUrl),
|
||||||
);
|
];
|
||||||
}
|
}
|
||||||
|
|
||||||
$fileName = $this->getFileName($package, $path);
|
$fileName = $this->getFileName($package, $path);
|
||||||
|
@ -252,7 +250,7 @@ class FileDownloader implements DownloaderInterface, ChangeReportInterface
|
||||||
|
|
||||||
if ($e instanceof TransportException) {
|
if ($e instanceof TransportException) {
|
||||||
// if we got an http response with a proper code, then requesting again will probably not help, abort
|
// if we got an http response with a proper code, then requesting again will probably not help, abort
|
||||||
if ((0 !== $e->getCode() && !in_array($e->getCode(), array(500, 502, 503, 504))) || !$retries) {
|
if ((0 !== $e->getCode() && !in_array($e->getCode(), [500, 502, 503, 504])) || !$retries) {
|
||||||
$retries = 0;
|
$retries = 0;
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
|
@ -260,7 +258,7 @@ class FileDownloader implements DownloaderInterface, ChangeReportInterface
|
||||||
// special error code returned when network is being artificially disabled
|
// special error code returned when network is being artificially disabled
|
||||||
if ($e instanceof TransportException && $e->getStatusCode() === 499) {
|
if ($e instanceof TransportException && $e->getStatusCode() === 499) {
|
||||||
$retries = 0;
|
$retries = 0;
|
||||||
$urls = array();
|
$urls = [];
|
||||||
}
|
}
|
||||||
|
|
||||||
if ($retries) {
|
if ($retries) {
|
||||||
|
@ -294,7 +292,7 @@ class FileDownloader implements DownloaderInterface, ChangeReportInterface
|
||||||
/**
|
/**
|
||||||
* @inheritDoc
|
* @inheritDoc
|
||||||
*/
|
*/
|
||||||
public function prepare(string $type, PackageInterface $package, string $path, PackageInterface $prevPackage = null): PromiseInterface
|
public function prepare(string $type, PackageInterface $package, string $path, ?PackageInterface $prevPackage = null): PromiseInterface
|
||||||
{
|
{
|
||||||
return \React\Promise\resolve(null);
|
return \React\Promise\resolve(null);
|
||||||
}
|
}
|
||||||
|
@ -302,18 +300,18 @@ class FileDownloader implements DownloaderInterface, ChangeReportInterface
|
||||||
/**
|
/**
|
||||||
* @inheritDoc
|
* @inheritDoc
|
||||||
*/
|
*/
|
||||||
public function cleanup(string $type, PackageInterface $package, string $path, PackageInterface $prevPackage = null): PromiseInterface
|
public function cleanup(string $type, PackageInterface $package, string $path, ?PackageInterface $prevPackage = null): PromiseInterface
|
||||||
{
|
{
|
||||||
$fileName = $this->getFileName($package, $path);
|
$fileName = $this->getFileName($package, $path);
|
||||||
if (file_exists($fileName)) {
|
if (file_exists($fileName)) {
|
||||||
$this->filesystem->unlink($fileName);
|
$this->filesystem->unlink($fileName);
|
||||||
}
|
}
|
||||||
|
|
||||||
$dirsToCleanUp = array(
|
$dirsToCleanUp = [
|
||||||
$this->config->get('vendor-dir').'/composer/',
|
$this->config->get('vendor-dir').'/composer/',
|
||||||
$this->config->get('vendor-dir'),
|
$this->config->get('vendor-dir'),
|
||||||
$path,
|
$path,
|
||||||
);
|
];
|
||||||
|
|
||||||
if (isset($this->additionalCleanupPaths[$package->getName()])) {
|
if (isset($this->additionalCleanupPaths[$package->getName()])) {
|
||||||
foreach ($this->additionalCleanupPaths[$package->getName()] as $path) {
|
foreach ($this->additionalCleanupPaths[$package->getName()] as $path) {
|
||||||
|
@ -332,8 +330,6 @@ class FileDownloader implements DownloaderInterface, ChangeReportInterface
|
||||||
|
|
||||||
/**
|
/**
|
||||||
* @inheritDoc
|
* @inheritDoc
|
||||||
*
|
|
||||||
* @param bool $output
|
|
||||||
*/
|
*/
|
||||||
public function install(PackageInterface $package, string $path, bool $output = true): PromiseInterface
|
public function install(PackageInterface $package, string $path, bool $output = true): PromiseInterface
|
||||||
{
|
{
|
||||||
|
@ -358,9 +354,6 @@ class FileDownloader implements DownloaderInterface, ChangeReportInterface
|
||||||
return \React\Promise\resolve(null);
|
return \React\Promise\resolve(null);
|
||||||
}
|
}
|
||||||
|
|
||||||
/**
|
|
||||||
* @return void
|
|
||||||
*/
|
|
||||||
protected function clearLastCacheWrite(PackageInterface $package): void
|
protected function clearLastCacheWrite(PackageInterface $package): void
|
||||||
{
|
{
|
||||||
if ($this->cache && isset($this->lastCacheWrites[$package->getName()])) {
|
if ($this->cache && isset($this->lastCacheWrites[$package->getName()])) {
|
||||||
|
@ -369,21 +362,11 @@ class FileDownloader implements DownloaderInterface, ChangeReportInterface
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
|
|
||||||
/**
|
|
||||||
* @param string $path
|
|
||||||
*
|
|
||||||
* @return void
|
|
||||||
*/
|
|
||||||
protected function addCleanupPath(PackageInterface $package, string $path): void
|
protected function addCleanupPath(PackageInterface $package, string $path): void
|
||||||
{
|
{
|
||||||
$this->additionalCleanupPaths[$package->getName()][] = $path;
|
$this->additionalCleanupPaths[$package->getName()][] = $path;
|
||||||
}
|
}
|
||||||
|
|
||||||
/**
|
|
||||||
* @param string $path
|
|
||||||
*
|
|
||||||
* @return void
|
|
||||||
*/
|
|
||||||
protected function removeCleanupPath(PackageInterface $package, string $path): void
|
protected function removeCleanupPath(PackageInterface $package, string $path): void
|
||||||
{
|
{
|
||||||
if (isset($this->additionalCleanupPaths[$package->getName()])) {
|
if (isset($this->additionalCleanupPaths[$package->getName()])) {
|
||||||
|
@ -410,8 +393,6 @@ class FileDownloader implements DownloaderInterface, ChangeReportInterface
|
||||||
|
|
||||||
/**
|
/**
|
||||||
* @inheritDoc
|
* @inheritDoc
|
||||||
*
|
|
||||||
* @param bool $output
|
|
||||||
*/
|
*/
|
||||||
public function remove(PackageInterface $package, string $path, bool $output = true): PromiseInterface
|
public function remove(PackageInterface $package, string $path, bool $output = true): PromiseInterface
|
||||||
{
|
{
|
||||||
|
@ -444,7 +425,6 @@ class FileDownloader implements DownloaderInterface, ChangeReportInterface
|
||||||
*
|
*
|
||||||
* @param PackageInterface $package package instance
|
* @param PackageInterface $package package instance
|
||||||
* @param string $path download path
|
* @param string $path download path
|
||||||
* @return string
|
|
||||||
*/
|
*/
|
||||||
protected function getInstallOperationAppendix(PackageInterface $package, string $path): string
|
protected function getInstallOperationAppendix(PackageInterface $package, string $path): string
|
||||||
{
|
{
|
||||||
|
|
|
@ -19,12 +19,7 @@ namespace Composer\Downloader;
|
||||||
*/
|
*/
|
||||||
class FilesystemException extends \Exception
|
class FilesystemException extends \Exception
|
||||||
{
|
{
|
||||||
/**
|
public function __construct(string $message = '', int $code = 0, ?\Exception $previous = null)
|
||||||
* @param string $message
|
|
||||||
* @param int $code
|
|
||||||
* @param \Exception|null $previous
|
|
||||||
*/
|
|
||||||
public function __construct(string $message = '', int $code = 0, \Exception $previous = null)
|
|
||||||
{
|
{
|
||||||
parent::__construct("Filesystem exception: \n".$message, $code, $previous);
|
parent::__construct("Filesystem exception: \n".$message, $code, $previous);
|
||||||
}
|
}
|
||||||
|
|
|
@ -25,7 +25,7 @@ class FossilDownloader extends VcsDownloader
|
||||||
/**
|
/**
|
||||||
* @inheritDoc
|
* @inheritDoc
|
||||||
*/
|
*/
|
||||||
protected function doDownload(PackageInterface $package, string $path, string $url, PackageInterface $prevPackage = null): PromiseInterface
|
protected function doDownload(PackageInterface $package, string $path, string $url, ?PackageInterface $prevPackage = null): PromiseInterface
|
||||||
{
|
{
|
||||||
return \React\Promise\resolve(null);
|
return \React\Promise\resolve(null);
|
||||||
}
|
}
|
||||||
|
|
|
@ -33,12 +33,12 @@ class GitDownloader extends VcsDownloader implements DvcsDownloaderInterface
|
||||||
* @var bool[]
|
* @var bool[]
|
||||||
* @phpstan-var array<string, bool>
|
* @phpstan-var array<string, bool>
|
||||||
*/
|
*/
|
||||||
private $hasStashedChanges = array();
|
private $hasStashedChanges = [];
|
||||||
/**
|
/**
|
||||||
* @var bool[]
|
* @var bool[]
|
||||||
* @phpstan-var array<string, bool>
|
* @phpstan-var array<string, bool>
|
||||||
*/
|
*/
|
||||||
private $hasDiscardedChanges = array();
|
private $hasDiscardedChanges = [];
|
||||||
/**
|
/**
|
||||||
* @var GitUtil
|
* @var GitUtil
|
||||||
*/
|
*/
|
||||||
|
@ -47,9 +47,9 @@ class GitDownloader extends VcsDownloader implements DvcsDownloaderInterface
|
||||||
* @var array
|
* @var array
|
||||||
* @phpstan-var array<int, array<string, bool>>
|
* @phpstan-var array<int, array<string, bool>>
|
||||||
*/
|
*/
|
||||||
private $cachedPackages = array();
|
private $cachedPackages = [];
|
||||||
|
|
||||||
public function __construct(IOInterface $io, Config $config, ProcessExecutor $process = null, Filesystem $fs = null)
|
public function __construct(IOInterface $io, Config $config, ?ProcessExecutor $process = null, ?Filesystem $fs = null)
|
||||||
{
|
{
|
||||||
parent::__construct($io, $config, $process, $fs);
|
parent::__construct($io, $config, $process, $fs);
|
||||||
$this->gitUtil = new GitUtil($this->io, $this->config, $this->process, $this->filesystem);
|
$this->gitUtil = new GitUtil($this->io, $this->config, $this->process, $this->filesystem);
|
||||||
|
@ -58,7 +58,7 @@ class GitDownloader extends VcsDownloader implements DvcsDownloaderInterface
|
||||||
/**
|
/**
|
||||||
* @inheritDoc
|
* @inheritDoc
|
||||||
*/
|
*/
|
||||||
protected function doDownload(PackageInterface $package, string $path, string $url, PackageInterface $prevPackage = null): PromiseInterface
|
protected function doDownload(PackageInterface $package, string $path, string $url, ?PackageInterface $prevPackage = null): PromiseInterface
|
||||||
{
|
{
|
||||||
GitUtil::cleanEnv();
|
GitUtil::cleanEnv();
|
||||||
|
|
||||||
|
@ -116,13 +116,13 @@ class GitDownloader extends VcsDownloader implements DvcsDownloaderInterface
|
||||||
|
|
||||||
$commandCallable = static function (string $url) use ($path, $command, $cachePath): string {
|
$commandCallable = static function (string $url) use ($path, $command, $cachePath): string {
|
||||||
return str_replace(
|
return str_replace(
|
||||||
array('%url%', '%path%', '%cachePath%', '%sanitizedUrl%'),
|
['%url%', '%path%', '%cachePath%', '%sanitizedUrl%'],
|
||||||
array(
|
[
|
||||||
ProcessExecutor::escape($url),
|
ProcessExecutor::escape($url),
|
||||||
ProcessExecutor::escape($path),
|
ProcessExecutor::escape($path),
|
||||||
ProcessExecutor::escape($cachePath),
|
ProcessExecutor::escape($cachePath),
|
||||||
ProcessExecutor::escape(Preg::replace('{://([^@]+?):(.+?)@}', '://', $url)),
|
ProcessExecutor::escape(Preg::replace('{://([^@]+?):(.+?)@}', '://', $url)),
|
||||||
),
|
],
|
||||||
$command
|
$command
|
||||||
);
|
);
|
||||||
};
|
};
|
||||||
|
@ -174,13 +174,13 @@ class GitDownloader extends VcsDownloader implements DvcsDownloaderInterface
|
||||||
|
|
||||||
$commandCallable = static function ($url) use ($ref, $command, $cachePath): string {
|
$commandCallable = static function ($url) use ($ref, $command, $cachePath): string {
|
||||||
return str_replace(
|
return str_replace(
|
||||||
array('%url%', '%ref%', '%cachePath%', '%sanitizedUrl%'),
|
['%url%', '%ref%', '%cachePath%', '%sanitizedUrl%'],
|
||||||
array(
|
[
|
||||||
ProcessExecutor::escape($url),
|
ProcessExecutor::escape($url),
|
||||||
ProcessExecutor::escape($ref.'^{commit}'),
|
ProcessExecutor::escape($ref.'^{commit}'),
|
||||||
ProcessExecutor::escape($cachePath),
|
ProcessExecutor::escape($cachePath),
|
||||||
ProcessExecutor::escape(Preg::replace('{://([^@]+?):(.+?)@}', '://', $url)),
|
ProcessExecutor::escape(Preg::replace('{://([^@]+?):(.+?)@}', '://', $url)),
|
||||||
),
|
],
|
||||||
$command
|
$command
|
||||||
);
|
);
|
||||||
};
|
};
|
||||||
|
@ -230,9 +230,6 @@ class GitDownloader extends VcsDownloader implements DvcsDownloaderInterface
|
||||||
return strlen($output) > 0 ? $output : null;
|
return strlen($output) > 0 ? $output : null;
|
||||||
}
|
}
|
||||||
|
|
||||||
/**
|
|
||||||
* @return null|string
|
|
||||||
*/
|
|
||||||
public function getUnpushedChanges(PackageInterface $package, string $path): ?string
|
public function getUnpushedChanges(PackageInterface $package, string $path): ?string
|
||||||
{
|
{
|
||||||
GitUtil::cleanEnv();
|
GitUtil::cleanEnv();
|
||||||
|
@ -266,7 +263,7 @@ class GitDownloader extends VcsDownloader implements DvcsDownloaderInterface
|
||||||
|
|
||||||
// do two passes, as if we find anything we want to fetch and then re-try
|
// do two passes, as if we find anything we want to fetch and then re-try
|
||||||
for ($i = 0; $i <= 1; $i++) {
|
for ($i = 0; $i <= 1; $i++) {
|
||||||
$remoteBranches = array();
|
$remoteBranches = [];
|
||||||
|
|
||||||
// try to find matching branch names in remote repos
|
// try to find matching branch names in remote repos
|
||||||
foreach ($candidateBranches as $candidate) {
|
foreach ($candidateBranches as $candidate) {
|
||||||
|
@ -397,12 +394,12 @@ class GitDownloader extends VcsDownloader implements DvcsDownloaderInterface
|
||||||
case '?':
|
case '?':
|
||||||
default:
|
default:
|
||||||
help :
|
help :
|
||||||
$this->io->writeError(array(
|
$this->io->writeError([
|
||||||
' y - discard changes and apply the '.($update ? 'update' : 'uninstall'),
|
' y - discard changes and apply the '.($update ? 'update' : 'uninstall'),
|
||||||
' n - abort the '.($update ? 'update' : 'uninstall').' and let you manually clean things up',
|
' n - abort the '.($update ? 'update' : 'uninstall').' and let you manually clean things up',
|
||||||
' v - view modified files',
|
' v - view modified files',
|
||||||
' d - view local modifications (diff)',
|
' d - view local modifications (diff)',
|
||||||
));
|
]);
|
||||||
if ($update) {
|
if ($update) {
|
||||||
$this->io->writeError(' s - stash changes and try to reapply them after the update');
|
$this->io->writeError(' s - stash changes and try to reapply them after the update');
|
||||||
}
|
}
|
||||||
|
@ -434,9 +431,6 @@ class GitDownloader extends VcsDownloader implements DvcsDownloaderInterface
|
||||||
/**
|
/**
|
||||||
* Updates the given path to the given commit ref
|
* Updates the given path to the given commit ref
|
||||||
*
|
*
|
||||||
* @param string $path
|
|
||||||
* @param string $reference
|
|
||||||
* @param string $prettyVersion
|
|
||||||
* @throws \RuntimeException
|
* @throws \RuntimeException
|
||||||
* @return null|string if a string is returned, it is the commit reference that was checked out if the original could not be found
|
* @return null|string if a string is returned, it is the commit reference that was checked out if the original could not be found
|
||||||
*/
|
*/
|
||||||
|
@ -501,24 +495,12 @@ class GitDownloader extends VcsDownloader implements DvcsDownloaderInterface
|
||||||
throw new \RuntimeException(Url::sanitize('Failed to execute ' . $command . "\n\n" . $this->process->getErrorOutput() . $exceptionExtra));
|
throw new \RuntimeException(Url::sanitize('Failed to execute ' . $command . "\n\n" . $this->process->getErrorOutput() . $exceptionExtra));
|
||||||
}
|
}
|
||||||
|
|
||||||
/**
|
|
||||||
* @param string $path
|
|
||||||
* @param string $url
|
|
||||||
*
|
|
||||||
* @return void
|
|
||||||
*/
|
|
||||||
protected function updateOriginUrl(string $path, string $url): void
|
protected function updateOriginUrl(string $path, string $url): void
|
||||||
{
|
{
|
||||||
$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(string $path, string $url): void
|
protected function setPushUrl(string $path, string $url): void
|
||||||
{
|
{
|
||||||
// set push url for github projects
|
// set push url for github projects
|
||||||
|
@ -549,10 +531,6 @@ class GitDownloader extends VcsDownloader implements DvcsDownloaderInterface
|
||||||
}
|
}
|
||||||
|
|
||||||
/**
|
/**
|
||||||
* @param string $path
|
|
||||||
*
|
|
||||||
* @return PromiseInterface
|
|
||||||
*
|
|
||||||
* @throws \RuntimeException
|
* @throws \RuntimeException
|
||||||
*/
|
*/
|
||||||
protected function discardChanges(string $path): PromiseInterface
|
protected function discardChanges(string $path): PromiseInterface
|
||||||
|
@ -568,10 +546,6 @@ class GitDownloader extends VcsDownloader implements DvcsDownloaderInterface
|
||||||
}
|
}
|
||||||
|
|
||||||
/**
|
/**
|
||||||
* @param string $path
|
|
||||||
*
|
|
||||||
* @return PromiseInterface
|
|
||||||
*
|
|
||||||
* @throws \RuntimeException
|
* @throws \RuntimeException
|
||||||
*/
|
*/
|
||||||
protected function stashChanges(string $path): PromiseInterface
|
protected function stashChanges(string $path): PromiseInterface
|
||||||
|
@ -587,10 +561,6 @@ class GitDownloader extends VcsDownloader implements DvcsDownloaderInterface
|
||||||
}
|
}
|
||||||
|
|
||||||
/**
|
/**
|
||||||
* @param string $path
|
|
||||||
*
|
|
||||||
* @return void
|
|
||||||
*
|
|
||||||
* @throws \RuntimeException
|
* @throws \RuntimeException
|
||||||
*/
|
*/
|
||||||
protected function viewDiff(string $path): void
|
protected function viewDiff(string $path): void
|
||||||
|
@ -603,16 +573,11 @@ class GitDownloader extends VcsDownloader implements DvcsDownloaderInterface
|
||||||
$this->io->writeError($output);
|
$this->io->writeError($output);
|
||||||
}
|
}
|
||||||
|
|
||||||
/**
|
|
||||||
* @param string $path
|
|
||||||
*
|
|
||||||
* @return string
|
|
||||||
*/
|
|
||||||
protected function normalizePath(string $path): string
|
protected function normalizePath(string $path): string
|
||||||
{
|
{
|
||||||
if (Platform::isWindows() && strlen($path) > 0) {
|
if (Platform::isWindows() && strlen($path) > 0) {
|
||||||
$basePath = $path;
|
$basePath = $path;
|
||||||
$removed = array();
|
$removed = [];
|
||||||
|
|
||||||
while (!is_dir($basePath) && $basePath !== '\\') {
|
while (!is_dir($basePath) && $basePath !== '\\') {
|
||||||
array_unshift($removed, basename($basePath));
|
array_unshift($removed, basename($basePath));
|
||||||
|
@ -639,10 +604,6 @@ class GitDownloader extends VcsDownloader implements DvcsDownloaderInterface
|
||||||
return is_dir($path.'/.git');
|
return is_dir($path.'/.git');
|
||||||
}
|
}
|
||||||
|
|
||||||
/**
|
|
||||||
* @param string $reference
|
|
||||||
* @return string
|
|
||||||
*/
|
|
||||||
protected function getShortHash(string $reference): string
|
protected function getShortHash(string $reference): string
|
||||||
{
|
{
|
||||||
if (!$this->io->isVerbose() && Preg::isMatch('{^[0-9a-f]{40}$}', $reference)) {
|
if (!$this->io->isVerbose() && Preg::isMatch('{^[0-9a-f]{40}$}', $reference)) {
|
||||||
|
|
|
@ -54,12 +54,6 @@ class GzipDownloader extends ArchiveDownloader
|
||||||
return \React\Promise\resolve(null);
|
return \React\Promise\resolve(null);
|
||||||
}
|
}
|
||||||
|
|
||||||
/**
|
|
||||||
* @param string $file
|
|
||||||
* @param string $targetFilepath
|
|
||||||
*
|
|
||||||
* @return void
|
|
||||||
*/
|
|
||||||
private function extractUsingExt(string $file, string $targetFilepath): void
|
private function extractUsingExt(string $file, string $targetFilepath): void
|
||||||
{
|
{
|
||||||
$archiveFile = gzopen($file, 'rb');
|
$archiveFile = gzopen($file, 'rb');
|
||||||
|
|
|
@ -25,7 +25,7 @@ class HgDownloader extends VcsDownloader
|
||||||
/**
|
/**
|
||||||
* @inheritDoc
|
* @inheritDoc
|
||||||
*/
|
*/
|
||||||
protected function doDownload(PackageInterface $package, string $path, string $url, PackageInterface $prevPackage = null): PromiseInterface
|
protected function doDownload(PackageInterface $package, string $path, string $url, ?PackageInterface $prevPackage = null): PromiseInterface
|
||||||
{
|
{
|
||||||
if (null === HgUtils::getVersion($this->process)) {
|
if (null === HgUtils::getVersion($this->process)) {
|
||||||
throw new \RuntimeException('hg was not found in your PATH, skipping source download');
|
throw new \RuntimeException('hg was not found in your PATH, skipping source download');
|
||||||
|
|
|
@ -39,7 +39,7 @@ class PathDownloader extends FileDownloader implements VcsCapableDownloaderInter
|
||||||
/**
|
/**
|
||||||
* @inheritDoc
|
* @inheritDoc
|
||||||
*/
|
*/
|
||||||
public function download(PackageInterface $package, string $path, PackageInterface $prevPackage = null, bool $output = true): PromiseInterface
|
public function download(PackageInterface $package, string $path, ?PackageInterface $prevPackage = null, bool $output = true): PromiseInterface
|
||||||
{
|
{
|
||||||
$path = Filesystem::trimTrailingSlash($path);
|
$path = Filesystem::trimTrailingSlash($path);
|
||||||
$url = $package->getDistUrl();
|
$url = $package->getDistUrl();
|
||||||
|
@ -90,9 +90,9 @@ class PathDownloader extends FileDownloader implements VcsCapableDownloaderInter
|
||||||
}
|
}
|
||||||
|
|
||||||
// Get the transport options with default values
|
// Get the transport options with default values
|
||||||
$transportOptions = $package->getTransportOptions() + array('relative' => true);
|
$transportOptions = $package->getTransportOptions() + ['relative' => true];
|
||||||
|
|
||||||
list($currentStrategy, $allowedStrategies) = $this->computeAllowedStrategies($transportOptions);
|
[$currentStrategy, $allowedStrategies] = $this->computeAllowedStrategies($transportOptions);
|
||||||
|
|
||||||
$symfonyFilesystem = new SymfonyFilesystem();
|
$symfonyFilesystem = new SymfonyFilesystem();
|
||||||
$this->filesystem->removeDirectory($path);
|
$this->filesystem->removeDirectory($path);
|
||||||
|
@ -147,7 +147,7 @@ class PathDownloader extends FileDownloader implements VcsCapableDownloaderInter
|
||||||
if ($output) {
|
if ($output) {
|
||||||
$this->io->writeError(sprintf('%sMirroring from %s', $isFallback ? ' ' : '', $url), false);
|
$this->io->writeError(sprintf('%sMirroring from %s', $isFallback ? ' ' : '', $url), false);
|
||||||
}
|
}
|
||||||
$iterator = new ArchivableFilesFinder($realUrl, array());
|
$iterator = new ArchivableFilesFinder($realUrl, []);
|
||||||
$symfonyFilesystem->mirror($realUrl, $path, $iterator);
|
$symfonyFilesystem->mirror($realUrl, $path, $iterator);
|
||||||
}
|
}
|
||||||
|
|
||||||
|
@ -232,7 +232,7 @@ class PathDownloader extends FileDownloader implements VcsCapableDownloaderInter
|
||||||
return ': Source already present';
|
return ': Source already present';
|
||||||
}
|
}
|
||||||
|
|
||||||
list($currentStrategy) = $this->computeAllowedStrategies($package->getTransportOptions());
|
[$currentStrategy] = $this->computeAllowedStrategies($package->getTransportOptions());
|
||||||
|
|
||||||
if ($currentStrategy === self::STRATEGY_SYMLINK) {
|
if ($currentStrategy === self::STRATEGY_SYMLINK) {
|
||||||
if (Platform::isWindows()) {
|
if (Platform::isWindows()) {
|
||||||
|
@ -254,7 +254,7 @@ class PathDownloader extends FileDownloader implements VcsCapableDownloaderInter
|
||||||
{
|
{
|
||||||
// When symlink transport option is null, both symlink and mirror are allowed
|
// When symlink transport option is null, both symlink and mirror are allowed
|
||||||
$currentStrategy = self::STRATEGY_SYMLINK;
|
$currentStrategy = self::STRATEGY_SYMLINK;
|
||||||
$allowedStrategies = array(self::STRATEGY_SYMLINK, self::STRATEGY_MIRROR);
|
$allowedStrategies = [self::STRATEGY_SYMLINK, self::STRATEGY_MIRROR];
|
||||||
|
|
||||||
$mirrorPathRepos = Platform::getEnv('COMPOSER_MIRROR_PATH_REPOS');
|
$mirrorPathRepos = Platform::getEnv('COMPOSER_MIRROR_PATH_REPOS');
|
||||||
if ($mirrorPathRepos) {
|
if ($mirrorPathRepos) {
|
||||||
|
@ -265,10 +265,10 @@ class PathDownloader extends FileDownloader implements VcsCapableDownloaderInter
|
||||||
|
|
||||||
if (true === $symlinkOption) {
|
if (true === $symlinkOption) {
|
||||||
$currentStrategy = self::STRATEGY_SYMLINK;
|
$currentStrategy = self::STRATEGY_SYMLINK;
|
||||||
$allowedStrategies = array(self::STRATEGY_SYMLINK);
|
$allowedStrategies = [self::STRATEGY_SYMLINK];
|
||||||
} elseif (false === $symlinkOption) {
|
} elseif (false === $symlinkOption) {
|
||||||
$currentStrategy = self::STRATEGY_MIRROR;
|
$currentStrategy = self::STRATEGY_MIRROR;
|
||||||
$allowedStrategies = array(self::STRATEGY_MIRROR);
|
$allowedStrategies = [self::STRATEGY_MIRROR];
|
||||||
}
|
}
|
||||||
|
|
||||||
// Check we can use junctions safely if we are on Windows
|
// Check we can use junctions safely if we are on Windows
|
||||||
|
@ -277,7 +277,7 @@ class PathDownloader extends FileDownloader implements VcsCapableDownloaderInter
|
||||||
throw new \RuntimeException('You are on an old Windows / old PHP combo which does not allow Composer to use junctions/symlinks and this path repository has symlink:true in its options so copying is not allowed');
|
throw new \RuntimeException('You are on an old Windows / old PHP combo which does not allow Composer to use junctions/symlinks and this path repository has symlink:true in its options so copying is not allowed');
|
||||||
}
|
}
|
||||||
$currentStrategy = self::STRATEGY_MIRROR;
|
$currentStrategy = self::STRATEGY_MIRROR;
|
||||||
$allowedStrategies = array(self::STRATEGY_MIRROR);
|
$allowedStrategies = [self::STRATEGY_MIRROR];
|
||||||
}
|
}
|
||||||
|
|
||||||
// Check we can use symlink() otherwise
|
// Check we can use symlink() otherwise
|
||||||
|
@ -286,10 +286,10 @@ class PathDownloader extends FileDownloader implements VcsCapableDownloaderInter
|
||||||
throw new \RuntimeException('Your PHP has the symlink() function disabled which does not allow Composer to use symlinks and this path repository has symlink:true in its options so copying is not allowed');
|
throw new \RuntimeException('Your PHP has the symlink() function disabled which does not allow Composer to use symlinks and this path repository has symlink:true in its options so copying is not allowed');
|
||||||
}
|
}
|
||||||
$currentStrategy = self::STRATEGY_MIRROR;
|
$currentStrategy = self::STRATEGY_MIRROR;
|
||||||
$allowedStrategies = array(self::STRATEGY_MIRROR);
|
$allowedStrategies = [self::STRATEGY_MIRROR];
|
||||||
}
|
}
|
||||||
|
|
||||||
return array($currentStrategy, $allowedStrategies);
|
return [$currentStrategy, $allowedStrategies];
|
||||||
}
|
}
|
||||||
|
|
||||||
/**
|
/**
|
||||||
|
@ -302,8 +302,6 @@ class PathDownloader extends FileDownloader implements VcsCapableDownloaderInter
|
||||||
* system rmdir which will preserve target content if given a junction.
|
* system rmdir which will preserve target content if given a junction.
|
||||||
*
|
*
|
||||||
* The PHP bug was fixed in 7.2.16 and 7.3.3 (requires at least Windows 7).
|
* The PHP bug was fixed in 7.2.16 and 7.3.3 (requires at least Windows 7).
|
||||||
*
|
|
||||||
* @return bool
|
|
||||||
*/
|
*/
|
||||||
private function safeJunctions(): bool
|
private function safeJunctions(): bool
|
||||||
{
|
{
|
||||||
|
|
|
@ -28,7 +28,7 @@ class PerforceDownloader extends VcsDownloader
|
||||||
/**
|
/**
|
||||||
* @inheritDoc
|
* @inheritDoc
|
||||||
*/
|
*/
|
||||||
protected function doDownload(PackageInterface $package, string $path, string $url, PackageInterface $prevPackage = null): PromiseInterface
|
protected function doDownload(PackageInterface $package, string $path, string $url, ?PackageInterface $prevPackage = null): PromiseInterface
|
||||||
{
|
{
|
||||||
return \React\Promise\resolve(null);
|
return \React\Promise\resolve(null);
|
||||||
}
|
}
|
||||||
|
@ -53,11 +53,6 @@ class PerforceDownloader extends VcsDownloader
|
||||||
return \React\Promise\resolve(null);
|
return \React\Promise\resolve(null);
|
||||||
}
|
}
|
||||||
|
|
||||||
/**
|
|
||||||
* @param string $ref
|
|
||||||
*
|
|
||||||
* @return string|null
|
|
||||||
*/
|
|
||||||
private function getLabelFromSourceReference(string $ref): ?string
|
private function getLabelFromSourceReference(string $ref): ?string
|
||||||
{
|
{
|
||||||
$pos = strpos($ref, '@');
|
$pos = strpos($ref, '@');
|
||||||
|
@ -68,12 +63,6 @@ class PerforceDownloader extends VcsDownloader
|
||||||
return null;
|
return null;
|
||||||
}
|
}
|
||||||
|
|
||||||
/**
|
|
||||||
* @param string $path
|
|
||||||
* @param string $url
|
|
||||||
*
|
|
||||||
* @return void
|
|
||||||
*/
|
|
||||||
public function initPerforce(PackageInterface $package, string $path, string $url): void
|
public function initPerforce(PackageInterface $package, string $path, string $url): void
|
||||||
{
|
{
|
||||||
if (!empty($this->perforce)) {
|
if (!empty($this->perforce)) {
|
||||||
|
@ -124,9 +113,6 @@ class PerforceDownloader extends VcsDownloader
|
||||||
return $this->perforce->getCommitLogs($fromReference, $toReference);
|
return $this->perforce->getCommitLogs($fromReference, $toReference);
|
||||||
}
|
}
|
||||||
|
|
||||||
/**
|
|
||||||
* @return void
|
|
||||||
*/
|
|
||||||
public function setPerforce(Perforce $perforce): void
|
public function setPerforce(Perforce $perforce): void
|
||||||
{
|
{
|
||||||
$this->perforce = $perforce;
|
$this->perforce = $perforce;
|
||||||
|
|
|
@ -31,7 +31,7 @@ class SvnDownloader extends VcsDownloader
|
||||||
/**
|
/**
|
||||||
* @inheritDoc
|
* @inheritDoc
|
||||||
*/
|
*/
|
||||||
protected function doDownload(PackageInterface $package, string $path, string $url, PackageInterface $prevPackage = null): PromiseInterface
|
protected function doDownload(PackageInterface $package, string $path, string $url, ?PackageInterface $prevPackage = null): PromiseInterface
|
||||||
{
|
{
|
||||||
SvnUtil::cleanEnv();
|
SvnUtil::cleanEnv();
|
||||||
$util = new SvnUtil($url, $this->io, $this->config, $this->process);
|
$util = new SvnUtil($url, $this->io, $this->config, $this->process);
|
||||||
|
@ -112,9 +112,8 @@ class SvnDownloader extends VcsDownloader
|
||||||
* @param string $cwd Working directory
|
* @param string $cwd Working directory
|
||||||
* @param string $path Target for a checkout
|
* @param string $path Target for a checkout
|
||||||
* @throws \RuntimeException
|
* @throws \RuntimeException
|
||||||
* @return string
|
|
||||||
*/
|
*/
|
||||||
protected function execute(PackageInterface $package, string $baseUrl, string $command, string $url, string $cwd = null, string $path = null): string
|
protected function execute(PackageInterface $package, string $baseUrl, string $command, string $url, ?string $cwd = null, ?string $path = null): string
|
||||||
{
|
{
|
||||||
$util = new SvnUtil($baseUrl, $this->io, $this->config, $this->process);
|
$util = new SvnUtil($baseUrl, $this->io, $this->config, $this->process);
|
||||||
$util->setCacheCredentials($this->cacheCredentials);
|
$util->setCacheCredentials($this->cacheCredentials);
|
||||||
|
@ -175,12 +174,12 @@ class SvnDownloader extends VcsDownloader
|
||||||
|
|
||||||
case '?':
|
case '?':
|
||||||
default:
|
default:
|
||||||
$this->io->writeError(array(
|
$this->io->writeError([
|
||||||
' y - discard changes and apply the '.($update ? 'update' : 'uninstall'),
|
' y - discard changes and apply the '.($update ? 'update' : 'uninstall'),
|
||||||
' n - abort the '.($update ? 'update' : 'uninstall').' and let you manually clean things up',
|
' n - abort the '.($update ? 'update' : 'uninstall').' and let you manually clean things up',
|
||||||
' v - view modified files',
|
' v - view modified files',
|
||||||
' ? - print help',
|
' ? - print help',
|
||||||
));
|
]);
|
||||||
break;
|
break;
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
|
@ -231,11 +230,6 @@ 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(string $path): PromiseInterface
|
protected function discardChanges(string $path): PromiseInterface
|
||||||
{
|
{
|
||||||
if (0 !== $this->process->execute('svn revert -R .', $output, $path)) {
|
if (0 !== $this->process->execute('svn revert -R .', $output, $path)) {
|
||||||
|
|
|
@ -24,12 +24,10 @@ class TransportException extends \RuntimeException
|
||||||
/** @var ?int */
|
/** @var ?int */
|
||||||
protected $statusCode;
|
protected $statusCode;
|
||||||
/** @var array<mixed> */
|
/** @var array<mixed> */
|
||||||
protected $responseInfo = array();
|
protected $responseInfo = [];
|
||||||
|
|
||||||
/**
|
/**
|
||||||
* @param array<string> $headers
|
* @param array<string> $headers
|
||||||
*
|
|
||||||
* @return void
|
|
||||||
*/
|
*/
|
||||||
public function setHeaders(array $headers): void
|
public function setHeaders(array $headers): void
|
||||||
{
|
{
|
||||||
|
@ -44,11 +42,6 @@ class TransportException extends \RuntimeException
|
||||||
return $this->headers;
|
return $this->headers;
|
||||||
}
|
}
|
||||||
|
|
||||||
/**
|
|
||||||
* @param null|string $response
|
|
||||||
*
|
|
||||||
* @return void
|
|
||||||
*/
|
|
||||||
public function setResponse(?string $response): void
|
public function setResponse(?string $response): void
|
||||||
{
|
{
|
||||||
$this->response = $response;
|
$this->response = $response;
|
||||||
|
@ -64,8 +57,6 @@ class TransportException extends \RuntimeException
|
||||||
|
|
||||||
/**
|
/**
|
||||||
* @param ?int $statusCode
|
* @param ?int $statusCode
|
||||||
*
|
|
||||||
* @return void
|
|
||||||
*/
|
*/
|
||||||
public function setStatusCode($statusCode): void
|
public function setStatusCode($statusCode): void
|
||||||
{
|
{
|
||||||
|
@ -90,8 +81,6 @@ class TransportException extends \RuntimeException
|
||||||
|
|
||||||
/**
|
/**
|
||||||
* @param array<mixed> $responseInfo
|
* @param array<mixed> $responseInfo
|
||||||
*
|
|
||||||
* @return void
|
|
||||||
*/
|
*/
|
||||||
public function setResponseInfo(array $responseInfo): void
|
public function setResponseInfo(array $responseInfo): void
|
||||||
{
|
{
|
||||||
|
|
|
@ -39,9 +39,9 @@ abstract class VcsDownloader implements DownloaderInterface, ChangeReportInterfa
|
||||||
/** @var Filesystem */
|
/** @var Filesystem */
|
||||||
protected $filesystem;
|
protected $filesystem;
|
||||||
/** @var array<string, true> */
|
/** @var array<string, true> */
|
||||||
protected $hasCleanedChanges = array();
|
protected $hasCleanedChanges = [];
|
||||||
|
|
||||||
public function __construct(IOInterface $io, Config $config, ProcessExecutor $process = null, Filesystem $fs = null)
|
public function __construct(IOInterface $io, Config $config, ?ProcessExecutor $process = null, ?Filesystem $fs = null)
|
||||||
{
|
{
|
||||||
$this->io = $io;
|
$this->io = $io;
|
||||||
$this->config = $config;
|
$this->config = $config;
|
||||||
|
@ -60,7 +60,7 @@ abstract class VcsDownloader implements DownloaderInterface, ChangeReportInterfa
|
||||||
/**
|
/**
|
||||||
* @inheritDoc
|
* @inheritDoc
|
||||||
*/
|
*/
|
||||||
public function download(PackageInterface $package, string $path, PackageInterface $prevPackage = null): PromiseInterface
|
public function download(PackageInterface $package, string $path, ?PackageInterface $prevPackage = null): PromiseInterface
|
||||||
{
|
{
|
||||||
if (!$package->getSourceReference()) {
|
if (!$package->getSourceReference()) {
|
||||||
throw new \InvalidArgumentException('Package '.$package->getPrettyName().' is missing reference information');
|
throw new \InvalidArgumentException('Package '.$package->getPrettyName().' is missing reference information');
|
||||||
|
@ -93,7 +93,7 @@ abstract class VcsDownloader implements DownloaderInterface, ChangeReportInterfa
|
||||||
/**
|
/**
|
||||||
* @inheritDoc
|
* @inheritDoc
|
||||||
*/
|
*/
|
||||||
public function prepare(string $type, PackageInterface $package, string $path, PackageInterface $prevPackage = null): PromiseInterface
|
public function prepare(string $type, PackageInterface $package, string $path, ?PackageInterface $prevPackage = null): PromiseInterface
|
||||||
{
|
{
|
||||||
if ($type === 'update') {
|
if ($type === 'update') {
|
||||||
$this->cleanChanges($prevPackage, $path, true);
|
$this->cleanChanges($prevPackage, $path, true);
|
||||||
|
@ -110,7 +110,7 @@ abstract class VcsDownloader implements DownloaderInterface, ChangeReportInterfa
|
||||||
/**
|
/**
|
||||||
* @inheritDoc
|
* @inheritDoc
|
||||||
*/
|
*/
|
||||||
public function cleanup(string $type, PackageInterface $package, string $path, PackageInterface $prevPackage = null): PromiseInterface
|
public function cleanup(string $type, PackageInterface $package, string $path, ?PackageInterface $prevPackage = null): PromiseInterface
|
||||||
{
|
{
|
||||||
if ($type === 'update' && isset($this->hasCleanedChanges[$prevPackage->getUniqueName()])) {
|
if ($type === 'update' && isset($this->hasCleanedChanges[$prevPackage->getUniqueName()])) {
|
||||||
$this->reapplyChanges($path);
|
$this->reapplyChanges($path);
|
||||||
|
@ -255,12 +255,9 @@ abstract class VcsDownloader implements DownloaderInterface, ChangeReportInterfa
|
||||||
/**
|
/**
|
||||||
* Prompt the user to check if changes should be stashed/removed or the operation aborted
|
* Prompt the user to check if changes should be stashed/removed or the operation aborted
|
||||||
*
|
*
|
||||||
* @param PackageInterface $package
|
|
||||||
* @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
|
||||||
*/
|
*/
|
||||||
|
@ -277,9 +274,7 @@ 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
|
|
||||||
*
|
*
|
||||||
* @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
|
||||||
*/
|
*/
|
||||||
|
@ -294,10 +289,8 @@ abstract class VcsDownloader implements DownloaderInterface, ChangeReportInterfa
|
||||||
* @param string $path download path
|
* @param string $path download path
|
||||||
* @param string $url package url
|
* @param string $url package url
|
||||||
* @param PackageInterface|null $prevPackage previous package (in case of an update)
|
* @param PackageInterface|null $prevPackage previous package (in case of an update)
|
||||||
*
|
|
||||||
* @return PromiseInterface
|
|
||||||
*/
|
*/
|
||||||
abstract protected function doDownload(PackageInterface $package, string $path, string $url, PackageInterface $prevPackage = null): PromiseInterface;
|
abstract protected function doDownload(PackageInterface $package, string $path, string $url, ?PackageInterface $prevPackage = null): PromiseInterface;
|
||||||
|
|
||||||
/**
|
/**
|
||||||
* Downloads specific package into specific folder.
|
* Downloads specific package into specific folder.
|
||||||
|
@ -305,8 +298,6 @@ abstract class VcsDownloader implements DownloaderInterface, ChangeReportInterfa
|
||||||
* @param PackageInterface $package package instance
|
* @param PackageInterface $package package instance
|
||||||
* @param string $path download path
|
* @param string $path download path
|
||||||
* @param string $url package url
|
* @param string $url package url
|
||||||
*
|
|
||||||
* @return PromiseInterface
|
|
||||||
*/
|
*/
|
||||||
abstract protected function doInstall(PackageInterface $package, string $path, string $url): PromiseInterface;
|
abstract protected function doInstall(PackageInterface $package, string $path, string $url): PromiseInterface;
|
||||||
|
|
||||||
|
@ -317,8 +308,6 @@ abstract class VcsDownloader implements DownloaderInterface, ChangeReportInterfa
|
||||||
* @param PackageInterface $target updated package
|
* @param PackageInterface $target updated package
|
||||||
* @param string $path download path
|
* @param string $path download path
|
||||||
* @param string $url package url
|
* @param string $url package url
|
||||||
*
|
|
||||||
* @return PromiseInterface
|
|
||||||
*/
|
*/
|
||||||
abstract protected function doUpdate(PackageInterface $initial, PackageInterface $target, string $path, string $url): PromiseInterface;
|
abstract protected function doUpdate(PackageInterface $initial, PackageInterface $target, string $path, string $url): PromiseInterface;
|
||||||
|
|
||||||
|
@ -328,16 +317,12 @@ abstract class VcsDownloader implements DownloaderInterface, ChangeReportInterfa
|
||||||
* @param string $fromReference the source reference
|
* @param string $fromReference the source reference
|
||||||
* @param string $toReference the target reference
|
* @param string $toReference the target reference
|
||||||
* @param string $path the package path
|
* @param string $path the package path
|
||||||
* @return string
|
|
||||||
*/
|
*/
|
||||||
abstract protected function getCommitLogs(string $fromReference, string $toReference, string $path): string;
|
abstract protected function getCommitLogs(string $fromReference, string $toReference, string $path): string;
|
||||||
|
|
||||||
/**
|
/**
|
||||||
* Checks if VCS metadata repository has been initialized
|
* Checks if VCS metadata repository has been initialized
|
||||||
* repository example: .git|.svn|.hg
|
* repository example: .git|.svn|.hg
|
||||||
*
|
|
||||||
* @param string $path
|
|
||||||
* @return bool
|
|
||||||
*/
|
*/
|
||||||
abstract protected function hasMetadataRepository(string $path): bool;
|
abstract protected function hasMetadataRepository(string $path): bool;
|
||||||
|
|
||||||
|
|
|
@ -40,28 +40,28 @@ class ZipDownloader extends ArchiveDownloader
|
||||||
/**
|
/**
|
||||||
* @inheritDoc
|
* @inheritDoc
|
||||||
*/
|
*/
|
||||||
public function download(PackageInterface $package, string $path, PackageInterface $prevPackage = null, bool $output = true): PromiseInterface
|
public function download(PackageInterface $package, string $path, ?PackageInterface $prevPackage = null, bool $output = true): PromiseInterface
|
||||||
{
|
{
|
||||||
if (null === self::$unzipCommands) {
|
if (null === self::$unzipCommands) {
|
||||||
self::$unzipCommands = array();
|
self::$unzipCommands = [];
|
||||||
$finder = new ExecutableFinder;
|
$finder = new ExecutableFinder;
|
||||||
if (Platform::isWindows() && ($cmd = $finder->find('7z', null, array('C:\Program Files\7-Zip')))) {
|
if (Platform::isWindows() && ($cmd = $finder->find('7z', null, ['C:\Program Files\7-Zip']))) {
|
||||||
self::$unzipCommands[] = array('7z', ProcessExecutor::escape($cmd).' x -bb0 -y %s -o%s');
|
self::$unzipCommands[] = ['7z', ProcessExecutor::escape($cmd).' x -bb0 -y %s -o%s'];
|
||||||
}
|
}
|
||||||
if ($cmd = $finder->find('unzip')) {
|
if ($cmd = $finder->find('unzip')) {
|
||||||
self::$unzipCommands[] = array('unzip', ProcessExecutor::escape($cmd).' -qq %s -d %s');
|
self::$unzipCommands[] = ['unzip', ProcessExecutor::escape($cmd).' -qq %s -d %s'];
|
||||||
}
|
}
|
||||||
if (!Platform::isWindows() && ($cmd = $finder->find('7z'))) { // 7z linux/macOS support is only used if unzip is not present
|
if (!Platform::isWindows() && ($cmd = $finder->find('7z'))) { // 7z linux/macOS support is only used if unzip is not present
|
||||||
self::$unzipCommands[] = array('7z', ProcessExecutor::escape($cmd).' x -bb0 -y %s -o%s');
|
self::$unzipCommands[] = ['7z', ProcessExecutor::escape($cmd).' x -bb0 -y %s -o%s'];
|
||||||
}
|
}
|
||||||
if (!Platform::isWindows() && ($cmd = $finder->find('7zz'))) { // 7zz linux/macOS support is only used if unzip is not present
|
if (!Platform::isWindows() && ($cmd = $finder->find('7zz'))) { // 7zz linux/macOS support is only used if unzip is not present
|
||||||
self::$unzipCommands[] = array('7zz', ProcessExecutor::escape($cmd).' x -bb0 -y %s -o%s');
|
self::$unzipCommands[] = ['7zz', ProcessExecutor::escape($cmd).' x -bb0 -y %s -o%s'];
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
|
|
||||||
$procOpenMissing = false;
|
$procOpenMissing = false;
|
||||||
if (!function_exists('proc_open')) {
|
if (!function_exists('proc_open')) {
|
||||||
self::$unzipCommands = array();
|
self::$unzipCommands = [];
|
||||||
$procOpenMissing = true;
|
$procOpenMissing = true;
|
||||||
}
|
}
|
||||||
|
|
||||||
|
@ -105,7 +105,6 @@ class ZipDownloader extends ArchiveDownloader
|
||||||
*
|
*
|
||||||
* @param string $file File to extract
|
* @param string $file File to extract
|
||||||
* @param string $path Path where to extract file
|
* @param string $path Path where to extract file
|
||||||
* @return PromiseInterface
|
|
||||||
*/
|
*/
|
||||||
private function extractWithSystemUnzip(PackageInterface $package, string $file, string $path): PromiseInterface
|
private function extractWithSystemUnzip(PackageInterface $package, string $file, string $path): PromiseInterface
|
||||||
{
|
{
|
||||||
|
@ -129,7 +128,7 @@ class ZipDownloader extends ArchiveDownloader
|
||||||
}
|
}
|
||||||
|
|
||||||
$executable = $commandSpec[0];
|
$executable = $commandSpec[0];
|
||||||
if (!$warned7ZipLinux && !Platform::isWindows() && in_array($executable, array('7z', '7zz'), true)) {
|
if (!$warned7ZipLinux && !Platform::isWindows() && in_array($executable, ['7z', '7zz'], true)) {
|
||||||
$warned7ZipLinux = true;
|
$warned7ZipLinux = true;
|
||||||
if (0 === $this->process->execute($executable, $output)) {
|
if (0 === $this->process->execute($executable, $output)) {
|
||||||
if (Preg::isMatch('{^\s*7-Zip(?: \[64\])? ([0-9.]+)}', $output, $match) && version_compare($match[1], '21.01', '<')) {
|
if (Preg::isMatch('{^\s*7-Zip(?: \[64\])? ([0-9.]+)}', $output, $match) && version_compare($match[1], '21.01', '<')) {
|
||||||
|
@ -182,7 +181,6 @@ class ZipDownloader extends ArchiveDownloader
|
||||||
*
|
*
|
||||||
* @param string $file File to extract
|
* @param string $file File to extract
|
||||||
* @param string $path Path where to extract file
|
* @param string $path Path where to extract file
|
||||||
* @return PromiseInterface
|
|
||||||
*/
|
*/
|
||||||
private function extractWithZipArchive(PackageInterface $package, string $file, string $path): PromiseInterface
|
private function extractWithZipArchive(PackageInterface $package, string $file, string $path): PromiseInterface
|
||||||
{
|
{
|
||||||
|
@ -222,7 +220,6 @@ class ZipDownloader extends ArchiveDownloader
|
||||||
*
|
*
|
||||||
* @param string $file File to extract
|
* @param string $file File to extract
|
||||||
* @param string $path Path where to extract file
|
* @param string $path Path where to extract file
|
||||||
* @return PromiseInterface
|
|
||||||
*/
|
*/
|
||||||
protected function extract(PackageInterface $package, string $file, string $path): PromiseInterface
|
protected function extract(PackageInterface $package, string $file, string $path): PromiseInterface
|
||||||
{
|
{
|
||||||
|
@ -231,10 +228,6 @@ class ZipDownloader extends ArchiveDownloader
|
||||||
|
|
||||||
/**
|
/**
|
||||||
* Give a meaningful error message to the user.
|
* Give a meaningful error message to the user.
|
||||||
*
|
|
||||||
* @param int $retval
|
|
||||||
* @param string $file
|
|
||||||
* @return string
|
|
||||||
*/
|
*/
|
||||||
protected function getErrorMessage(int $retval, string $file): string
|
protected function getErrorMessage(int $retval, string $file): string
|
||||||
{
|
{
|
||||||
|
|
|
@ -46,7 +46,7 @@ class Event
|
||||||
* @param string[] $args Arguments passed by the user
|
* @param string[] $args Arguments passed by the user
|
||||||
* @param mixed[] $flags Optional flags to pass data not as argument
|
* @param mixed[] $flags Optional flags to pass data not as argument
|
||||||
*/
|
*/
|
||||||
public function __construct(string $name, array $args = array(), array $flags = array())
|
public function __construct(string $name, array $args = [], array $flags = [])
|
||||||
{
|
{
|
||||||
$this->name = $name;
|
$this->name = $name;
|
||||||
$this->args = $args;
|
$this->args = $args;
|
||||||
|
@ -95,8 +95,6 @@ class Event
|
||||||
|
|
||||||
/**
|
/**
|
||||||
* Prevents the event from being passed to further listeners
|
* Prevents the event from being passed to further listeners
|
||||||
*
|
|
||||||
* @return void
|
|
||||||
*/
|
*/
|
||||||
public function stopPropagation(): void
|
public function stopPropagation(): void
|
||||||
{
|
{
|
||||||
|
|
|
@ -54,7 +54,7 @@ class EventDispatcher
|
||||||
/** @var ProcessExecutor */
|
/** @var ProcessExecutor */
|
||||||
protected $process;
|
protected $process;
|
||||||
/** @var array<string, array<int, array<callable|string>>> */
|
/** @var array<string, array<int, array<callable|string>>> */
|
||||||
protected $listeners = array();
|
protected $listeners = [];
|
||||||
/** @var bool */
|
/** @var bool */
|
||||||
protected $runScripts = true;
|
protected $runScripts = true;
|
||||||
/** @var list<string> */
|
/** @var list<string> */
|
||||||
|
@ -67,18 +67,17 @@ class EventDispatcher
|
||||||
* @param IOInterface $io The IOInterface instance
|
* @param IOInterface $io The IOInterface instance
|
||||||
* @param ProcessExecutor $process
|
* @param ProcessExecutor $process
|
||||||
*/
|
*/
|
||||||
public function __construct(PartialComposer $composer, IOInterface $io, ProcessExecutor $process = null)
|
public function __construct(PartialComposer $composer, IOInterface $io, ?ProcessExecutor $process = null)
|
||||||
{
|
{
|
||||||
$this->composer = $composer;
|
$this->composer = $composer;
|
||||||
$this->io = $io;
|
$this->io = $io;
|
||||||
$this->process = $process ?? new ProcessExecutor($io);
|
$this->process = $process ?? new ProcessExecutor($io);
|
||||||
$this->eventStack = array();
|
$this->eventStack = [];
|
||||||
}
|
}
|
||||||
|
|
||||||
/**
|
/**
|
||||||
* Set whether script handlers are active or not
|
* Set whether script handlers are active or not
|
||||||
*
|
*
|
||||||
* @param bool $runScripts
|
|
||||||
* @return $this
|
* @return $this
|
||||||
*/
|
*/
|
||||||
public function setRunScripts(bool $runScripts = true): self
|
public function setRunScripts(bool $runScripts = true): self
|
||||||
|
@ -96,7 +95,7 @@ class EventDispatcher
|
||||||
* @return int return code of the executed script if any, for php scripts a false return
|
* @return int return code of the executed script if any, for php scripts a false return
|
||||||
* value is changed to 1, anything else to 0
|
* value is changed to 1, anything else to 0
|
||||||
*/
|
*/
|
||||||
public function dispatch(?string $eventName, Event $event = null): int
|
public function dispatch(?string $eventName, ?Event $event = null): int
|
||||||
{
|
{
|
||||||
if (null === $event) {
|
if (null === $event) {
|
||||||
if (null === $eventName) {
|
if (null === $eventName) {
|
||||||
|
@ -112,13 +111,12 @@ class EventDispatcher
|
||||||
* Dispatch a script event.
|
* Dispatch a script event.
|
||||||
*
|
*
|
||||||
* @param string $eventName The constant in ScriptEvents
|
* @param string $eventName The constant in ScriptEvents
|
||||||
* @param bool $devMode
|
|
||||||
* @param array<int, mixed> $additionalArgs Arguments passed by the user
|
* @param array<int, mixed> $additionalArgs Arguments passed by the user
|
||||||
* @param array<string, mixed> $flags Optional flags to pass data not as argument
|
* @param array<string, mixed> $flags Optional flags to pass data not as argument
|
||||||
* @return int return code of the executed script if any, for php scripts a false return
|
* @return int return code of the executed script if any, for php scripts a false return
|
||||||
* value is changed to 1, anything else to 0
|
* value is changed to 1, anything else to 0
|
||||||
*/
|
*/
|
||||||
public function dispatchScript(string $eventName, bool $devMode = false, array $additionalArgs = array(), array $flags = array()): int
|
public function dispatchScript(string $eventName, bool $devMode = false, array $additionalArgs = [], array $flags = []): int
|
||||||
{
|
{
|
||||||
assert($this->composer instanceof Composer, new \LogicException('This should only be reached with a fully loaded Composer'));
|
assert($this->composer instanceof Composer, new \LogicException('This should only be reached with a fully loaded Composer'));
|
||||||
|
|
||||||
|
@ -199,7 +197,7 @@ class EventDispatcher
|
||||||
if (is_array($callable) && (is_string($callable[0]) || is_object($callable[0])) && is_string($callable[1])) {
|
if (is_array($callable) && (is_string($callable[0]) || is_object($callable[0])) && is_string($callable[1])) {
|
||||||
$this->io->writeError(sprintf('> %s: %s', $event->getName(), (is_object($callable[0]) ? get_class($callable[0]) : $callable[0]).'->'.$callable[1]), true, IOInterface::VERBOSE);
|
$this->io->writeError(sprintf('> %s: %s', $event->getName(), (is_object($callable[0]) ? get_class($callable[0]) : $callable[0]).'->'.$callable[1]), true, IOInterface::VERBOSE);
|
||||||
}
|
}
|
||||||
$return = false === call_user_func($callable, $event) ? 1 : 0;
|
$return = false === $callable($event) ? 1 : 0;
|
||||||
} elseif ($this->isComposerScript($callable)) {
|
} elseif ($this->isComposerScript($callable)) {
|
||||||
$this->io->writeError(sprintf('> %s: %s', $event->getName(), $callable), true, IOInterface::VERBOSE);
|
$this->io->writeError(sprintf('> %s: %s', $event->getName(), $callable), true, IOInterface::VERBOSE);
|
||||||
|
|
||||||
|
@ -252,7 +250,7 @@ class EventDispatcher
|
||||||
throw $e;
|
throw $e;
|
||||||
}
|
}
|
||||||
} else {
|
} else {
|
||||||
$args = implode(' ', array_map(array('Composer\Util\ProcessExecutor', 'escape'), $event->getArguments()));
|
$args = implode(' ', array_map(['Composer\Util\ProcessExecutor', 'escape'], $event->getArguments()));
|
||||||
|
|
||||||
// @putenv does not receive arguments
|
// @putenv does not receive arguments
|
||||||
if (strpos($callable, '@putenv ') === 0) {
|
if (strpos($callable, '@putenv ') === 0) {
|
||||||
|
@ -283,7 +281,7 @@ class EventDispatcher
|
||||||
if (false === strpos($exec, '=')) {
|
if (false === strpos($exec, '=')) {
|
||||||
Platform::clearEnv(substr($exec, 8));
|
Platform::clearEnv(substr($exec, 8));
|
||||||
} else {
|
} else {
|
||||||
list($var, $value) = explode('=', substr($exec, 8), 2);
|
[$var, $value] = explode('=', substr($exec, 8), 2);
|
||||||
Platform::putEnv($var, $value);
|
Platform::putEnv($var, $value);
|
||||||
}
|
}
|
||||||
|
|
||||||
|
@ -347,11 +345,6 @@ class EventDispatcher
|
||||||
return $returnMax;
|
return $returnMax;
|
||||||
}
|
}
|
||||||
|
|
||||||
/**
|
|
||||||
* @param string $exec
|
|
||||||
*
|
|
||||||
* @return int
|
|
||||||
*/
|
|
||||||
protected function executeTty(string $exec): int
|
protected function executeTty(string $exec): int
|
||||||
{
|
{
|
||||||
if ($this->io->isInteractive()) {
|
if ($this->io->isInteractive()) {
|
||||||
|
@ -361,9 +354,6 @@ class EventDispatcher
|
||||||
return $this->process->execute($exec);
|
return $this->process->execute($exec);
|
||||||
}
|
}
|
||||||
|
|
||||||
/**
|
|
||||||
* @return string
|
|
||||||
*/
|
|
||||||
protected function getPhpExecCommand(): string
|
protected function getPhpExecCommand(): string
|
||||||
{
|
{
|
||||||
$finder = new PhpExecutableFinder();
|
$finder = new PhpExecutableFinder();
|
||||||
|
@ -381,8 +371,6 @@ class EventDispatcher
|
||||||
}
|
}
|
||||||
|
|
||||||
/**
|
/**
|
||||||
* @param string $className
|
|
||||||
* @param string $methodName
|
|
||||||
* @param Event $event Event invoking the PHP callable
|
* @param Event $event Event invoking the PHP callable
|
||||||
*
|
*
|
||||||
* @return mixed
|
* @return mixed
|
||||||
|
@ -404,8 +392,6 @@ class EventDispatcher
|
||||||
* @param string $eventName The event name - typically a constant
|
* @param string $eventName The event name - typically a constant
|
||||||
* @param callable|string $listener A callable expecting an event argument, or a command string to be executed (same as a composer.json "scripts" entry)
|
* @param callable|string $listener A callable expecting an event argument, or a command string to be executed (same as a composer.json "scripts" entry)
|
||||||
* @param int $priority A higher value represents a higher priority
|
* @param int $priority A higher value represents a higher priority
|
||||||
*
|
|
||||||
* @return void
|
|
||||||
*/
|
*/
|
||||||
public function addListener(string $eventName, $listener, int $priority = 0): void
|
public function addListener(string $eventName, $listener, int $priority = 0): void
|
||||||
{
|
{
|
||||||
|
@ -414,8 +400,6 @@ class EventDispatcher
|
||||||
|
|
||||||
/**
|
/**
|
||||||
* @param callable|object $listener A callable or an object instance for which all listeners should be removed
|
* @param callable|object $listener A callable or an object instance for which all listeners should be removed
|
||||||
*
|
|
||||||
* @return void
|
|
||||||
*/
|
*/
|
||||||
public function removeListener($listener): void
|
public function removeListener($listener): void
|
||||||
{
|
{
|
||||||
|
@ -434,21 +418,17 @@ class EventDispatcher
|
||||||
* Adds object methods as listeners for the events in getSubscribedEvents
|
* Adds object methods as listeners for the events in getSubscribedEvents
|
||||||
*
|
*
|
||||||
* @see EventSubscriberInterface
|
* @see EventSubscriberInterface
|
||||||
*
|
|
||||||
* @param EventSubscriberInterface $subscriber
|
|
||||||
*
|
|
||||||
* @return void
|
|
||||||
*/
|
*/
|
||||||
public function addSubscriber(EventSubscriberInterface $subscriber): void
|
public function addSubscriber(EventSubscriberInterface $subscriber): void
|
||||||
{
|
{
|
||||||
foreach ($subscriber->getSubscribedEvents() as $eventName => $params) {
|
foreach ($subscriber->getSubscribedEvents() as $eventName => $params) {
|
||||||
if (is_string($params)) {
|
if (is_string($params)) {
|
||||||
$this->addListener($eventName, array($subscriber, $params));
|
$this->addListener($eventName, [$subscriber, $params]);
|
||||||
} elseif (is_string($params[0])) {
|
} elseif (is_string($params[0])) {
|
||||||
$this->addListener($eventName, array($subscriber, $params[0]), $params[1] ?? 0);
|
$this->addListener($eventName, [$subscriber, $params[0]], $params[1] ?? 0);
|
||||||
} else {
|
} else {
|
||||||
foreach ($params as $listener) {
|
foreach ($params as $listener) {
|
||||||
$this->addListener($eventName, array($subscriber, $listener[0]), $listener[1] ?? 0);
|
$this->addListener($eventName, [$subscriber, $listener[0]], $listener[1] ?? 0);
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
|
@ -457,29 +437,25 @@ class EventDispatcher
|
||||||
/**
|
/**
|
||||||
* Retrieves all listeners for a given event
|
* Retrieves all listeners for a given event
|
||||||
*
|
*
|
||||||
* @param Event $event
|
|
||||||
* @return array<callable|string> All listeners: callables and scripts
|
* @return array<callable|string> All listeners: callables and scripts
|
||||||
*/
|
*/
|
||||||
protected function getListeners(Event $event): array
|
protected function getListeners(Event $event): array
|
||||||
{
|
{
|
||||||
$scriptListeners = $this->runScripts ? $this->getScriptListeners($event) : array();
|
$scriptListeners = $this->runScripts ? $this->getScriptListeners($event) : [];
|
||||||
|
|
||||||
if (!isset($this->listeners[$event->getName()][0])) {
|
if (!isset($this->listeners[$event->getName()][0])) {
|
||||||
$this->listeners[$event->getName()][0] = array();
|
$this->listeners[$event->getName()][0] = [];
|
||||||
}
|
}
|
||||||
krsort($this->listeners[$event->getName()]);
|
krsort($this->listeners[$event->getName()]);
|
||||||
|
|
||||||
$listeners = $this->listeners;
|
$listeners = $this->listeners;
|
||||||
$listeners[$event->getName()][0] = array_merge($listeners[$event->getName()][0], $scriptListeners);
|
$listeners[$event->getName()][0] = array_merge($listeners[$event->getName()][0], $scriptListeners);
|
||||||
|
|
||||||
return call_user_func_array('array_merge', $listeners[$event->getName()]);
|
return array_merge(...$listeners[$event->getName()]);
|
||||||
}
|
}
|
||||||
|
|
||||||
/**
|
/**
|
||||||
* Checks if an event has listeners registered
|
* Checks if an event has listeners registered
|
||||||
*
|
|
||||||
* @param Event $event
|
|
||||||
* @return bool
|
|
||||||
*/
|
*/
|
||||||
public function hasEventListeners(Event $event): bool
|
public function hasEventListeners(Event $event): bool
|
||||||
{
|
{
|
||||||
|
@ -500,7 +476,7 @@ class EventDispatcher
|
||||||
$scripts = $package->getScripts();
|
$scripts = $package->getScripts();
|
||||||
|
|
||||||
if (empty($scripts[$event->getName()])) {
|
if (empty($scripts[$event->getName()])) {
|
||||||
return array();
|
return [];
|
||||||
}
|
}
|
||||||
|
|
||||||
assert($this->composer instanceof Composer, new \LogicException('This should only be reached with a fully loaded Composer'));
|
assert($this->composer instanceof Composer, new \LogicException('This should only be reached with a fully loaded Composer'));
|
||||||
|
@ -525,9 +501,6 @@ class EventDispatcher
|
||||||
|
|
||||||
/**
|
/**
|
||||||
* Checks if string given references a class path and method
|
* Checks if string given references a class path and method
|
||||||
*
|
|
||||||
* @param string $callable
|
|
||||||
* @return bool
|
|
||||||
*/
|
*/
|
||||||
protected function isPhpScript(string $callable): bool
|
protected function isPhpScript(string $callable): bool
|
||||||
{
|
{
|
||||||
|
@ -536,9 +509,6 @@ class EventDispatcher
|
||||||
|
|
||||||
/**
|
/**
|
||||||
* Checks if string given references a composer run-script
|
* Checks if string given references a composer run-script
|
||||||
*
|
|
||||||
* @param string $callable
|
|
||||||
* @return bool
|
|
||||||
*/
|
*/
|
||||||
protected function isComposerScript(string $callable): bool
|
protected function isComposerScript(string $callable): bool
|
||||||
{
|
{
|
||||||
|
@ -548,9 +518,7 @@ class EventDispatcher
|
||||||
/**
|
/**
|
||||||
* Push an event to the stack of active event
|
* Push an event to the stack of active event
|
||||||
*
|
*
|
||||||
* @param Event $event
|
|
||||||
* @throws \RuntimeException
|
* @throws \RuntimeException
|
||||||
* @return int
|
|
||||||
*/
|
*/
|
||||||
protected function pushEvent(Event $event): int
|
protected function pushEvent(Event $event): int
|
||||||
{
|
{
|
||||||
|
@ -564,17 +532,12 @@ class EventDispatcher
|
||||||
|
|
||||||
/**
|
/**
|
||||||
* Pops the active event from the stack
|
* Pops the active event from the stack
|
||||||
*
|
|
||||||
* @return string|null
|
|
||||||
*/
|
*/
|
||||||
protected function popEvent(): ?string
|
protected function popEvent(): ?string
|
||||||
{
|
{
|
||||||
return array_pop($this->eventStack);
|
return array_pop($this->eventStack);
|
||||||
}
|
}
|
||||||
|
|
||||||
/**
|
|
||||||
* @return void
|
|
||||||
*/
|
|
||||||
private function ensureBinDirIsInPath(): void
|
private function ensureBinDirIsInPath(): void
|
||||||
{
|
{
|
||||||
$pathEnv = 'PATH';
|
$pathEnv = 'PATH';
|
||||||
|
|
Some files were not shown because too many files have changed in this diff Show More
Loading…
Reference in New Issue