Skip to content

Commit 3ee7719

Browse files
weaverryanfabpot
authored andcommitted
Merge-powered recipe update system
1 parent e9a1e59 commit 3ee7719

Some content is hidden

Large Commits have some content hidden by default. Use the searchbox below for content that may be hidden.

45 files changed

+4141
-287
lines changed

.php_cs.dist renamed to .php-cs-fixer.dist.php

Lines changed: 1 addition & 1 deletion
Original file line numberDiff line numberDiff line change
@@ -2,7 +2,7 @@
22

33
$finder = PhpCsFixer\Finder::create()->in(__DIR__);
44

5-
return PhpCsFixer\Config::create()
5+
return (new PhpCsFixer\Config())
66
->setFinder($finder)
77
->setRules(array(
88
'@Symfony' => true,

src/Command/InstallRecipesCommand.php

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

1414
use Composer\Command\BaseCommand;
1515
use Composer\DependencyResolver\Operation\InstallOperation;
16-
use Composer\Factory;
1716
use Symfony\Component\Console\Exception\RuntimeException;
1817
use Symfony\Component\Console\Input\InputArgument;
1918
use Symfony\Component\Console\Input\InputInterface;
2019
use Symfony\Component\Console\Input\InputOption;
2120
use Symfony\Component\Console\Output\OutputInterface;
2221
use Symfony\Flex\Event\UpdateEvent;
23-
use Symfony\Flex\Lock;
22+
use Symfony\Flex\Flex;
2423

2524
class InstallRecipesCommand extends BaseCommand
2625
{
26+
/** @var Flex */
2727
private $flex;
2828
private $rootDir;
2929

@@ -55,7 +55,7 @@ protected function execute(InputInterface $input, OutputInterface $output): int
5555
throw new RuntimeException('Cannot run "sync-recipes --force": git not found.');
5656
}
5757

58-
$symfonyLock = new Lock(getenv('SYMFONY_LOCKFILE') ?: str_replace('composer.json', 'symfony.lock', Factory::getComposerFile()));
58+
$symfonyLock = $this->flex->getLock();
5959
$composer = $this->getComposer();
6060
$locker = $composer->getLocker();
6161
$lockData = $locker->getLockData();

src/Command/RecipesCommand.php

Lines changed: 8 additions & 65 deletions
Original file line numberDiff line numberDiff line change
@@ -13,11 +13,11 @@
1313

1414
use Composer\Command\BaseCommand;
1515
use Composer\Downloader\TransportException;
16-
use Composer\Util\HttpDownloader;
1716
use Symfony\Component\Console\Input\InputArgument;
1817
use Symfony\Component\Console\Input\InputInterface;
1918
use Symfony\Component\Console\Input\InputOption;
2019
use Symfony\Component\Console\Output\OutputInterface;
20+
use Symfony\Flex\GithubApi;
2121
use Symfony\Flex\InformationOperation;
2222
use Symfony\Flex\Lock;
2323
use Symfony\Flex\Recipe;
@@ -31,13 +31,13 @@ class RecipesCommand extends BaseCommand
3131
private $flex;
3232

3333
private $symfonyLock;
34-
private $downloader;
34+
private $githubApi;
3535

3636
public function __construct(/* cannot be type-hinted */ $flex, Lock $symfonyLock, $downloader)
3737
{
3838
$this->flex = $flex;
3939
$this->symfonyLock = $symfonyLock;
40-
$this->downloader = $downloader;
40+
$this->githubApi = new GithubApi($downloader);
4141

4242
parent::__construct();
4343
}
@@ -136,7 +136,7 @@ protected function execute(InputInterface $input, OutputInterface $output)
136136
'',
137137
'Run:',
138138
' * <info>composer recipes vendor/package</info> to see details about a recipe.',
139-
' * <info>composer recipes:install vendor/package --force -v</info> to update that recipe.',
139+
' * <info>composer recipes:update vendor/package</info> to update that recipe.',
140140
'',
141141
]));
142142

@@ -171,13 +171,15 @@ private function displayPackageInformation(Recipe $recipe)
171171
$commitDate = null;
172172
if (null !== $lockRef && null !== $lockRepo) {
173173
try {
174-
list($gitSha, $commitDate) = $this->findRecipeCommitDataFromTreeRef(
174+
$recipeCommitData = $this->githubApi->findRecipeCommitDataFromTreeRef(
175175
$recipe->getName(),
176176
$lockRepo,
177177
$lockBranch ?? '',
178178
$lockVersion,
179179
$lockRef
180180
);
181+
$gitSha = $recipeCommitData ? $recipeCommitData['commit'] : null;
182+
$commitDate = $recipeCommitData ? $recipeCommitData['date'] : null;
181183
} catch (TransportException $exception) {
182184
$io->writeError('Error downloading exact git sha for installed recipe.');
183185
}
@@ -232,7 +234,7 @@ private function displayPackageInformation(Recipe $recipe)
232234
$io->write([
233235
'',
234236
'Update this recipe by running:',
235-
sprintf('<info>composer recipes:install %s --force -v</info>', $recipe->getName()),
237+
sprintf('<info>composer recipes:update %s</info>', $recipe->getName()),
236238
]);
237239
}
238240
}
@@ -324,63 +326,4 @@ private function writeTreeLine($line)
324326

325327
$io->write($line);
326328
}
327-
328-
/**
329-
* Attempts to find the original git sha when the recipe was installed.
330-
*/
331-
private function findRecipeCommitDataFromTreeRef(string $package, string $repo, string $branch, string $version, string $lockRef)
332-
{
333-
// only supports public repository placement
334-
if (0 !== strpos($repo, 'github.com')) {
335-
return [null, null];
336-
}
337-
338-
$parts = explode('/', $repo);
339-
if (3 !== \count($parts)) {
340-
return [null, null];
341-
}
342-
343-
$recipePath = sprintf('%s/%s', $package, $version);
344-
$commitsData = $this->requestGitHubApi(sprintf(
345-
'https://api.github.com/repos/%s/%s/commits?path=%s&sha=%s',
346-
$parts[1],
347-
$parts[2],
348-
$recipePath,
349-
$branch
350-
));
351-
352-
foreach ($commitsData as $commitData) {
353-
// go back the commits one-by-one
354-
$treeUrl = $commitData['commit']['tree']['url'].'?recursive=true';
355-
356-
// fetch the full tree, then look for the tree for the package path
357-
$treeData = $this->requestGitHubApi($treeUrl);
358-
foreach ($treeData['tree'] as $treeItem) {
359-
if ($treeItem['path'] !== $recipePath) {
360-
continue;
361-
}
362-
363-
if ($treeItem['sha'] === $lockRef) {
364-
// shorten for brevity
365-
return [
366-
substr($commitData['sha'], 0, 7),
367-
$commitData['commit']['committer']['date'],
368-
];
369-
}
370-
}
371-
}
372-
373-
return [null, null];
374-
}
375-
376-
private function requestGitHubApi(string $path)
377-
{
378-
if ($this->downloader instanceof HttpDownloader) {
379-
$contents = $this->downloader->get($path)->getBody();
380-
} else {
381-
$contents = $this->downloader->getContents('api.github.com', $path, false);
382-
}
383-
384-
return json_decode($contents, true);
385-
}
386329
}

0 commit comments

Comments
 (0)