Merge branch '2.2' into main

main
Jordi Boggiano 2 years ago
commit dce63fdf4f
No known key found for this signature in database
GPG Key ID: 7BBD42C429EC80BC

@ -42,6 +42,14 @@
* Fixed symlink creation in linux VM guest filesystems to be recognized by Windows (#10592)
* Performance improvement in pool optimization step (#10585)
### [2.2.11] 2022-04-01
* Added missing config.bitbucket-oauth in composer-schema.json
* Added --2.2 flag to `self-update` to pin the Composer version to the 2.2 LTS range (#10682)
* Updated semver, jsonlint deps for minor fixes
* Fixed generation of autoload crashing if a package has a broken path (#10688)
* Removed dev-master=>dev-main alias from #10372 as it does not work when reloading from lock file and extracting dev deps (#10651)
### [2.2.10] 2022-03-29
* Fixed Bitbucket authorization detection due to API changes (#10657)
@ -1461,6 +1469,7 @@
[2.3.0]: https://github.com/composer/composer/compare/2.3.0-RC2...2.3.0
[2.3.0-RC2]: https://github.com/composer/composer/compare/2.3.0-RC1...2.3.0-RC2
[2.3.0-RC1]: https://github.com/composer/composer/compare/2.2.9...2.3.0-RC1
[2.2.11]: https://github.com/composer/composer/compare/2.2.10...2.2.11
[2.2.10]: https://github.com/composer/composer/compare/2.2.9...2.2.10
[2.2.9]: https://github.com/composer/composer/compare/2.2.8...2.2.9
[2.2.8]: https://github.com/composer/composer/compare/2.2.7...2.2.8

12
composer.lock generated

@ -224,16 +224,16 @@
},
{
"name": "composer/semver",
"version": "3.3.1",
"version": "3.3.2",
"source": {
"type": "git",
"url": "https://github.com/composer/semver.git",
"reference": "5d8e574bb0e69188786b8ef77d43341222a41a71"
"reference": "3953f23262f2bff1919fc82183ad9acb13ff62c9"
},
"dist": {
"type": "zip",
"url": "https://api.github.com/repos/composer/semver/zipball/5d8e574bb0e69188786b8ef77d43341222a41a71",
"reference": "5d8e574bb0e69188786b8ef77d43341222a41a71",
"url": "https://api.github.com/repos/composer/semver/zipball/3953f23262f2bff1919fc82183ad9acb13ff62c9",
"reference": "3953f23262f2bff1919fc82183ad9acb13ff62c9",
"shasum": ""
},
"require": {
@ -285,7 +285,7 @@
"support": {
"irc": "irc://irc.freenode.org/composer",
"issues": "https://github.com/composer/semver/issues",
"source": "https://github.com/composer/semver/tree/3.3.1"
"source": "https://github.com/composer/semver/tree/3.3.2"
},
"funding": [
{
@ -301,7 +301,7 @@
"type": "tidelift"
}
],
"time": "2022-03-16T11:22:07+00:00"
"time": "2022-04-01T19:23:25+00:00"
},
{
"name": "composer/spdx-licenses",

@ -162,6 +162,7 @@ class AutoloadGenerator
* @param string $suffix
* @return int
* @throws \Seld\JsonLint\ParsingException
* @throws \RuntimeException
*/
public function dump(Config $config, InstalledRepositoryInterface $localRepo, RootPackageInterface $rootPackage, InstallationManager $installationManager, string $targetDir, bool $scanPsrPackages = false, string $suffix = '')
{
@ -1240,6 +1241,9 @@ INITIALIZER;
}
$resolvedPath = realpath($installPath . '/' . $updir);
if (false === $resolvedPath) {
continue;
}
$autoloads[] = preg_quote(strtr($resolvedPath, '\\', '/')) . '/' . $path . '($|/)';
continue;
}

@ -59,6 +59,7 @@ class SelfUpdateCommand extends BaseCommand
new InputOption('snapshot', null, InputOption::VALUE_NONE, 'Force an update to the snapshot channel'),
new InputOption('1', null, InputOption::VALUE_NONE, 'Force an update to the stable channel, but only use 1.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('set-channel-only', null, InputOption::VALUE_NONE, 'Only store the channel as the default one and then exit'),
))
->setHelp(
@ -181,8 +182,12 @@ EOT
}
}
if ($requestedChannel && is_numeric($requestedChannel) && strpos($latestStable['version'], $requestedChannel) !== 0) {
$io->writeError('<warning>Warning: You forced the install of '.$latestVersion.' via --'.$requestedChannel.', but '.$latestStable['version'].' is the latest stable version. Updating to it via composer self-update --stable is recommended.</warning>');
$effectiveChannel = $requestedChannel === null ? $versionsUtil->getChannel() : $requestedChannel;
if (is_numeric($effectiveChannel) && strpos($latestStable['version'], $effectiveChannel) !== 0) {
$io->writeError('<warning>Warning: You forced the install of '.$latestVersion.' via --'.$effectiveChannel.', but '.$latestStable['version'].' is the latest stable version. Updating to it via composer self-update --stable is recommended.</warning>');
}
if (isset($latest['eol'])) {
$io->writeError('<warning>Warning: Version '.$latestVersion.' is EOL / End of Life. '.$latestStable['version'].' is the latest stable version. Updating to it via composer self-update --stable is recommended.</warning>');
}
if (Preg::isMatch('{^[0-9a-f]{40}$}', $updateVersion) && $updateVersion !== $latestVersion) {

@ -12,6 +12,7 @@
namespace Composer\SelfUpdate;
use Composer\Pcre\Preg;
use Composer\Util\HttpDownloader;
use Composer\Config;
@ -21,7 +22,7 @@ use Composer\Config;
class Versions
{
/** @var string[] */
public static $channels = array('stable', 'preview', 'snapshot', '1', '2');
public static $channels = array('stable', 'preview', 'snapshot', '1', '2', '2.2');
/** @var HttpDownloader */
private $httpDownloader;
@ -29,8 +30,8 @@ class Versions
private $config;
/** @var string */
private $channel;
/** @var array<string, array<int, array{path: string, version: string, min-php: int}>> */
private $versionsData;
/** @var array<string, array<int, array{path: string, version: string, min-php: int, eol?: true}>>|null */
private $versionsData = null;
public function __construct(Config $config, HttpDownloader $httpDownloader)
{
@ -50,7 +51,7 @@ class Versions
$channelFile = $this->config->get('home').'/update-channel';
if (file_exists($channelFile)) {
$channel = trim(file_get_contents($channelFile));
if (in_array($channel, array('stable', 'preview', 'snapshot'), true)) {
if (in_array($channel, array('stable', 'preview', 'snapshot', '2.2'), true)) {
return $this->channel = $channel;
}
}
@ -71,13 +72,14 @@ class Versions
$channelFile = $this->config->get('home').'/update-channel';
$this->channel = $channel;
file_put_contents($channelFile, (is_numeric($channel) ? 'stable' : $channel).PHP_EOL);
// rewrite '2' and '1' channels to stable for future self-updates, but LTS ones like '2.2' remain pinned
file_put_contents($channelFile, (Preg::isMatch('{^\d+$}D', $channel) ? 'stable' : $channel).PHP_EOL);
}
/**
* @param string|null $channel
*
* @return array{path: string, version: string, min-php: int}
* @return array{path: string, version: string, min-php: int, eol?: true}
*/
public function getLatest(?string $channel = null): array
{
@ -93,11 +95,11 @@ class Versions
}
/**
* @return array<string, array<int, array{path: string, version: string, min-php: int}>>
* @return array<string, array<int, array{path: string, version: string, min-php: int, eol?: true}>>
*/
private function getVersionsData(): array
{
if (!$this->versionsData) {
if (null === $this->versionsData) {
if ($this->config->get('disable-tls') === true) {
$protocol = 'http';
} else {

@ -14,6 +14,7 @@ namespace Composer\Test\Autoload;
use Composer\Autoload\AutoloadGenerator;
use Composer\Filter\PlatformRequirementFilter\PlatformRequirementFilterFactory;
use Composer\Package\CompletePackage;
use Composer\Package\Link;
use Composer\Package\Version\VersionParser;
use Composer\Semver\Constraint\Constraint;
@ -772,8 +773,8 @@ EOF;
include $this->vendorDir.'/composer/autoload_classmap.php'
);
$this->assertAutoloadFiles('classmap5', $this->vendorDir.'/composer', 'classmap');
$this->assertStringNotContainsString('$loader->setClassMapAuthoritative(true);', file_get_contents($this->vendorDir.'/composer/autoload_real.php'));
$this->assertStringNotContainsString('$loader->setApcuPrefix(', file_get_contents($this->vendorDir.'/composer/autoload_real.php'));
$this->assertStringNotContainsString('$loader->setClassMapAuthoritative(true);', (string) file_get_contents($this->vendorDir.'/composer/autoload_real.php'));
$this->assertStringNotContainsString('$loader->setApcuPrefix(', (string) file_get_contents($this->vendorDir.'/composer/autoload_real.php'));
}
public function testClassMapAutoloadingAuthoritativeAndApcu(): void
@ -821,8 +822,8 @@ EOF;
);
$this->assertAutoloadFiles('classmap8', $this->vendorDir.'/composer', 'classmap');
$this->assertStringContainsString('$loader->setClassMapAuthoritative(true);', file_get_contents($this->vendorDir.'/composer/autoload_real.php'));
$this->assertStringContainsString('$loader->setApcuPrefix(', file_get_contents($this->vendorDir.'/composer/autoload_real.php'));
$this->assertStringContainsString('$loader->setClassMapAuthoritative(true);', (string) file_get_contents($this->vendorDir.'/composer/autoload_real.php'));
$this->assertStringContainsString('$loader->setApcuPrefix(', (string) file_get_contents($this->vendorDir.'/composer/autoload_real.php'));
}
public function testClassMapAutoloadingAuthoritativeAndApcuPrefix(): void
@ -870,8 +871,8 @@ EOF;
);
$this->assertAutoloadFiles('classmap8', $this->vendorDir.'/composer', 'classmap');
$this->assertStringContainsString('$loader->setClassMapAuthoritative(true);', file_get_contents($this->vendorDir.'/composer/autoload_real.php'));
$this->assertStringContainsString('$loader->setApcuPrefix(\'custom\\\'Prefix\');', file_get_contents($this->vendorDir.'/composer/autoload_real.php'));
$this->assertStringContainsString('$loader->setClassMapAuthoritative(true);', (string) file_get_contents($this->vendorDir.'/composer/autoload_real.php'));
$this->assertStringContainsString('$loader->setApcuPrefix(\'custom\\\'Prefix\');', (string) file_get_contents($this->vendorDir.'/composer/autoload_real.php'));
}
public function testFilesAutoloadGeneration(): void
@ -1433,8 +1434,8 @@ EOF;
$this->assertStringEqualsFile($vendorDir.'/composer/autoload_namespaces.php', $expectedNamespace);
$this->assertStringEqualsFile($vendorDir.'/composer/autoload_psr4.php', $expectedPsr4);
$this->assertStringEqualsFile($vendorDir.'/composer/autoload_classmap.php', $expectedClassmap);
$this->assertStringContainsString("\$vendorDir . '/b/b/bootstrap.php',\n", file_get_contents($vendorDir.'/composer/autoload_files.php'));
$this->assertStringContainsString("\$baseDir . '/test.php',\n", file_get_contents($vendorDir.'/composer/autoload_files.php'));
$this->assertStringContainsString("\$vendorDir . '/b/b/bootstrap.php',\n", (string) file_get_contents($vendorDir.'/composer/autoload_files.php'));
$this->assertStringContainsString("\$baseDir . '/test.php',\n", (string) file_get_contents($vendorDir.'/composer/autoload_files.php'));
}
public function testUpLevelRelativePaths(): void
@ -1518,7 +1519,85 @@ EOF;
$this->assertStringEqualsFile($this->vendorDir.'/composer/autoload_namespaces.php', $expectedNamespace);
$this->assertStringEqualsFile($this->vendorDir.'/composer/autoload_psr4.php', $expectedPsr4);
$this->assertStringEqualsFile($this->vendorDir.'/composer/autoload_classmap.php', $expectedClassmap);
$this->assertStringContainsString("\$baseDir . '/../test.php',\n", file_get_contents($this->vendorDir.'/composer/autoload_files.php'));
$this->assertStringContainsString("\$baseDir . '/../test.php',\n", (string) file_get_contents($this->vendorDir.'/composer/autoload_files.php'));
}
public function testAutoloadRulesInPackageThatDoesNotExistOnDisk(): void
{
$package = new RootPackage('root/a', '1.0', '1.0');
$package->setRequires(array(
'dep/a' => new Link('root/a', 'dep/a', new MatchAllConstraint(), 'requires'),
));
$dep = new CompletePackage('dep/a', '1.0', '1.0');
$this->repository->expects($this->any())
->method('getCanonicalPackages')
->will($this->returnValue(array($dep)));
$dep->setAutoload(array(
'psr-0' => array('Foo' => './src'),
));
$this->generator->dump($this->config, $this->repository, $package, $this->im, 'composer', true, '_19');
$expectedNamespace = <<<'EOF'
<?php
// autoload_namespaces.php @generated by Composer
$vendorDir = dirname(__DIR__);
$baseDir = dirname($vendorDir);
return array(
'Foo' => array($vendorDir . '/dep/a/src'),
);
EOF;
$this->assertStringEqualsFile($this->vendorDir.'/composer/autoload_namespaces.php', $expectedNamespace);
$dep->setAutoload(array(
'psr-4' => array('Acme\Foo\\' => './src-psr4'),
));
$this->generator->dump($this->config, $this->repository, $package, $this->im, 'composer', true, '_19');
$expectedPsr4 = <<<'EOF'
<?php
// autoload_psr4.php @generated by Composer
$vendorDir = dirname(__DIR__);
$baseDir = dirname($vendorDir);
return array(
'Acme\\Foo\\' => array($vendorDir . '/dep/a/src-psr4'),
);
EOF;
$this->assertStringEqualsFile($this->vendorDir.'/composer/autoload_psr4.php', $expectedPsr4);
$dep->setAutoload(array(
'classmap' => array('classmap'),
));
try {
$this->generator->dump($this->config, $this->repository, $package, $this->im, 'composer', true, '_19');
} catch (\RuntimeException $e) {
$this->assertSame('Could not scan for classes inside "'.$this->vendorDir.'/dep/a/classmap" which does not appear to be a file nor a folder', $e->getMessage());
}
$dep->setAutoload(array(
'files' => array('./test.php'),
));
$this->generator->dump($this->config, $this->repository, $package, $this->im, 'composer', true, '_19');
$this->assertStringContainsString("\$vendorDir . '/dep/a/test.php',\n", (string) file_get_contents($this->vendorDir.'/composer/autoload_files.php'));
$package->setAutoload(array(
'exclude-from-classmap' => array('../excludedroot', 'root/excl'),
));
$dep->setAutoload(array(
'exclude-from-classmap' => array('../../excluded', 'foo/bar'),
));
$map = $this->generator->buildPackageMap($this->im, $package, array($dep));
$parsed = $this->generator->parseAutoloads($map, $package);
$this->assertSame(array(preg_quote(dirname($this->workingDir)).'/excludedroot($|/)', preg_quote($this->workingDir).'/root/excl($|/)'), $parsed['exclude-from-classmap']);
}
public function testEmptyPaths(): void
@ -1736,10 +1815,10 @@ EOF;
if (null === $expectedFixture) {
$this->assertFalse(file_exists($this->vendorDir . '/composer/platform_check.php'));
$this->assertStringNotContainsString("require __DIR__ . '/platform_check.php';", file_get_contents($this->vendorDir.'/composer/autoload_real.php'));
$this->assertStringNotContainsString("require __DIR__ . '/platform_check.php';", (string) file_get_contents($this->vendorDir.'/composer/autoload_real.php'));
} else {
$this->assertFileContentEquals(__DIR__ . '/Fixtures/platform/' . $expectedFixture . '.php', $this->vendorDir . '/composer/platform_check.php');
$this->assertStringContainsString("require __DIR__ . '/platform_check.php';", file_get_contents($this->vendorDir.'/composer/autoload_real.php'));
$this->assertStringContainsString("require __DIR__ . '/platform_check.php';", (string) file_get_contents($this->vendorDir.'/composer/autoload_real.php'));
}
}

Loading…
Cancel
Save