Skip to content

Commit 0fc2cd9

Browse files
committed
feature #617 Add support for composer 2 (jderusse, nicolas-grekas)
This PR was merged into the 1.7-dev branch. Discussion ---------- Add support for composer 2 This PR add compatibility with `composer-plugin-api: ^2.0` and fixes #661 Maintaining compatibility with both 1.x and 2.0 was too complex. I think we need to release a version 2.0 of flex compatible with composer 2. - remove `ParallelDownloader` (no more needed with composer 2) - replace `TruncateRepository` by eventListener on `PluginEvents::PRE_POOL_CREATE` note: I didn't change the way commands are added to the application, current plugin's contract expect a class name, while we currently inject command instances (with config and flex itself injected inside) in the application. Commits ------- d790a5c Restore compat with Composer 1 186f05e Add compatibility with composer2
2 parents f850efc + d790a5c commit 0fc2cd9

13 files changed

+488
-68
lines changed

.travis.yml

Lines changed: 6 additions & 1 deletion
Original file line numberDiff line numberDiff line change
@@ -5,7 +5,7 @@ sudo: false
55
matrix:
66
include:
77
- php: 7.1
8-
env: COMPOSER_FLAGS='--prefer-lowest'
8+
env: COMPOSER_FLAGS='--prefer-lowest --prefer-stable'
99
- php: 7.2
1010
- php: 7.3
1111
- php: 7.4
@@ -27,8 +27,13 @@ before_install:
2727
- composer validate
2828

2929
install:
30+
- composer require --no-update composer/composer:^1.0.2
3031
- composer update $COMPOSER_FLAGS
3132

3233
script:
34+
- ./vendor/bin/simple-phpunit
35+
- composer self-update --snapshot
36+
- composer require --no-update composer/composer:^2
37+
- composer update $COMPOSER_FLAGS
3338
- ./vendor/bin/simple-phpunit
3439
- find src/ -name '*.php' | xargs -n1 php -l

composer.json

Lines changed: 4 additions & 4 deletions
Original file line numberDiff line numberDiff line change
@@ -12,13 +12,13 @@
1212
"minimum-stability": "dev",
1313
"require": {
1414
"php": ">=7.1",
15-
"composer-plugin-api": "^1.0"
15+
"composer-plugin-api": "^1.0|^2.0"
1616
},
1717
"require-dev": {
18-
"composer/composer": "^1.0.2",
18+
"composer/composer": "^1.0.2|^2.0",
1919
"symfony/dotenv": "^4.4|^5.0",
2020
"symfony/phpunit-bridge": "^4.4|^5.0",
21-
"symfony/process": "^4.4|^5.0"
21+
"symfony/process": "^3.4|^4.4|^5.0"
2222
},
2323
"autoload": {
2424
"psr-4": {
@@ -27,7 +27,7 @@
2727
},
2828
"extra": {
2929
"branch-alias": {
30-
"dev-master": "1.7-dev"
30+
"dev-master": "1.8-dev"
3131
},
3232
"class": "Symfony\\Flex\\Flex"
3333
}

src/Command/RecipesCommand.php

Lines changed: 7 additions & 3 deletions
Original file line numberDiff line numberDiff line change
@@ -13,12 +13,12 @@
1313

1414
use Composer\Command\BaseCommand;
1515
use Composer\Downloader\TransportException;
16+
use Composer\Util\HttpDownloader;
1617
use Symfony\Component\Console\Input\InputArgument;
1718
use Symfony\Component\Console\Input\InputInterface;
1819
use Symfony\Component\Console\Output\OutputInterface;
1920
use Symfony\Flex\InformationOperation;
2021
use Symfony\Flex\Lock;
21-
use Symfony\Flex\ParallelDownloader;
2222
use Symfony\Flex\Recipe;
2323

2424
/**
@@ -32,7 +32,7 @@ class RecipesCommand extends BaseCommand
3232
private $symfonyLock;
3333
private $downloader;
3434

35-
public function __construct(/* cannot be type-hinted */ $flex, Lock $symfonyLock, ParallelDownloader $downloader)
35+
public function __construct(/* cannot be type-hinted */ $flex, Lock $symfonyLock, $downloader)
3636
{
3737
$this->flex = $flex;
3838
$this->symfonyLock = $symfonyLock;
@@ -354,7 +354,11 @@ private function findRecipeCommitDataFromTreeRef(string $package, string $repo,
354354

355355
private function requestGitHubApi(string $path)
356356
{
357-
$contents = $this->downloader->getContents('api.github.com', $path, false);
357+
if ($this->downloader instanceof HttpDownloader) {
358+
$contents = $this->downloader->get($path)->getBody();
359+
} else {
360+
$contents = $this->downloader->getContents('api.github.com', $path, false);
361+
}
358362

359363
return json_decode($contents, true);
360364
}

src/Command/UnpackCommand.php

Lines changed: 9 additions & 2 deletions
Original file line numberDiff line numberDiff line change
@@ -114,17 +114,24 @@ protected function execute(InputInterface $input, OutputInterface $output)
114114
$lockFile->write($lockData);
115115

116116
// force removal of files under vendor/
117-
$locker = new Locker($io, $lockFile, $composer->getRepositoryManager(), $composer->getInstallationManager(), file_get_contents($json->getPath()));
117+
if (version_compare('2.0.0', PluginInterface::PLUGIN_API_VERSION, '>')) {
118+
$locker = new Locker($io, $lockFile, $composer->getRepositoryManager(), $composer->getInstallationManager(), file_get_contents($json->getPath()));
119+
} else {
120+
$locker = new Locker($io, $lockFile, $composer->getInstallationManager(), file_get_contents($json->getPath()));
121+
}
118122
$composer->setLocker($locker);
119123
$install = Installer::create($io, $composer);
120124
$install
121125
->setDevMode(true)
122126
->setDumpAutoloader(false)
123127
->setRunScripts(false)
124-
->setSkipSuggest(true)
125128
->setIgnorePlatformRequirements(true)
126129
;
127130

131+
if (method_exists($install, 'setSkipSuggest')) {
132+
$install->setSkipSuggest(true);
133+
}
134+
128135
return $install->run();
129136
}
130137
}

src/Downloader.php

Lines changed: 42 additions & 10 deletions
Original file line numberDiff line numberDiff line change
@@ -19,6 +19,8 @@
1919
use Composer\Downloader\TransportException;
2020
use Composer\IO\IOInterface;
2121
use Composer\Json\JsonFile;
22+
use Composer\Util\HttpDownloader;
23+
use function React\Promise\all;
2224

2325
/**
2426
* @author Fabien Potencier <[email protected]>
@@ -39,7 +41,7 @@ class Downloader
3941
private $flexId;
4042
private $enabled = true;
4143

42-
public function __construct(Composer $composer, IoInterface $io, ParallelDownloader $rfs)
44+
public function __construct(Composer $composer, IoInterface $io, $rfs)
4345
{
4446
if (getenv('SYMFONY_CAFILE')) {
4547
$this->caFile = getenv('SYMFONY_CAFILE');
@@ -85,6 +87,10 @@ public function getVersions()
8587
*/
8688
public function getRecipes(array $operations): array
8789
{
90+
if ($this->enabled && self::$DEFAULT_ENDPOINT !== $this->endpoint) {
91+
$this->io->writeError('<warning>Using "'.$this->endpoint.'" as the Symfony endpoint</>');
92+
}
93+
8894
$paths = [];
8995
$chunk = '';
9096
foreach ($operations as $i => $operation) {
@@ -129,16 +135,27 @@ public function getRecipes(array $operations): array
129135
$paths[] = ['/p/'.$chunk];
130136
}
131137

132-
if ($this->enabled && self::$DEFAULT_ENDPOINT !== $this->endpoint) {
133-
$this->io->writeError('<warning>Using "'.$this->endpoint.'" as the Symfony endpoint</>');
134-
}
135-
136-
$bodies = [];
137-
$this->rfs->download($paths, function ($path) use (&$bodies) {
138-
if ($body = $this->get($path, [], false)->getBody()) {
139-
$bodies[] = $body;
138+
if ($this->rfs instanceof HttpDownloader) {
139+
$jobs = [];
140+
foreach ($paths as $path) {
141+
$this->rfs->add($this->endpoint.$path[0]);
140142
}
141-
});
143+
$this->rfs->wait();
144+
$bodies = [];
145+
all($jobs)->then(static function (array $responses) use (&$bodies) {
146+
foreach ($responses as $response) {
147+
$bodies[] = json_decode($response->getBody(), true);
148+
}
149+
}, function (\Exception $e) {
150+
$this->io->writeError('<warning>Failed to download recipes: '.$e->getMessage().'</>');
151+
});
152+
} else {
153+
$this->rfs->download($paths, function ($path) use (&$bodies) {
154+
if ($body = $this->get($path, [], false)->getBody()) {
155+
$bodies[] = $body;
156+
}
157+
});
158+
}
142159

143160
$data = [];
144161
foreach ($bodies as $body) {
@@ -189,6 +206,12 @@ private function fetchFile(string $url, string $cacheKey, array $headers): Respo
189206
$retries = 3;
190207
while ($retries--) {
191208
try {
209+
if ($this->rfs instanceof HttpDownloader) {
210+
$response = $this->rfs->get($url, $options);
211+
212+
return $this->parseJson($response->getBody(), $url, $cacheKey, $response->getHeaders());
213+
}
214+
192215
$json = $this->rfs->getContents($this->endpoint, $url, false, $options);
193216

194217
return $this->parseJson($json, $url, $cacheKey, $this->rfs->getLastHeaders());
@@ -220,6 +243,15 @@ private function fetchFileIfLastModified(string $url, string $cacheKey, string $
220243
$retries = 3;
221244
while ($retries--) {
222245
try {
246+
if ($this->rfs instanceof HttpDownloader) {
247+
$response = $this->rfs->get($url, $options);
248+
if (304 === $response->getStatusCode()) {
249+
return new Response($response->getBody(), $response->getHeaders(), 304);
250+
}
251+
252+
return $this->parseJson($response->getBody(), $url, $cacheKey, $response->getHeaders());
253+
}
254+
223255
$json = $this->rfs->getContents($this->endpoint, $url, false, $options);
224256
if (304 === $this->rfs->findStatusCode($this->rfs->getLastHeaders())) {
225257
return new Response('', $this->rfs->getLastHeaders(), 304);

0 commit comments

Comments
 (0)