Skip to content

Commit

Permalink
Merge-powered recipe update system
Browse files Browse the repository at this point in the history
  • Loading branch information
weaverryan authored and fabpot committed Jan 19, 2022
1 parent e9a1e59 commit 3ee7719
Show file tree
Hide file tree
Showing 45 changed files with 4,141 additions and 287 deletions.
2 changes: 1 addition & 1 deletion .php_cs.dist → .php-cs-fixer.dist.php
Original file line number Diff line number Diff line change
Expand Up @@ -2,7 +2,7 @@

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

return PhpCsFixer\Config::create()
return (new PhpCsFixer\Config())
->setFinder($finder)
->setRules(array(
'@Symfony' => true,
Expand Down
6 changes: 3 additions & 3 deletions src/Command/InstallRecipesCommand.php
Original file line number Diff line number Diff line change
Expand Up @@ -13,17 +13,17 @@

use Composer\Command\BaseCommand;
use Composer\DependencyResolver\Operation\InstallOperation;
use Composer\Factory;
use Symfony\Component\Console\Exception\RuntimeException;
use Symfony\Component\Console\Input\InputArgument;
use Symfony\Component\Console\Input\InputInterface;
use Symfony\Component\Console\Input\InputOption;
use Symfony\Component\Console\Output\OutputInterface;
use Symfony\Flex\Event\UpdateEvent;
use Symfony\Flex\Lock;
use Symfony\Flex\Flex;

class InstallRecipesCommand extends BaseCommand
{
/** @var Flex */
private $flex;
private $rootDir;

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

$symfonyLock = new Lock(getenv('SYMFONY_LOCKFILE') ?: str_replace('composer.json', 'symfony.lock', Factory::getComposerFile()));
$symfonyLock = $this->flex->getLock();
$composer = $this->getComposer();
$locker = $composer->getLocker();
$lockData = $locker->getLockData();
Expand Down
73 changes: 8 additions & 65 deletions src/Command/RecipesCommand.php
Original file line number Diff line number Diff line change
Expand Up @@ -13,11 +13,11 @@

use Composer\Command\BaseCommand;
use Composer\Downloader\TransportException;
use Composer\Util\HttpDownloader;
use Symfony\Component\Console\Input\InputArgument;
use Symfony\Component\Console\Input\InputInterface;
use Symfony\Component\Console\Input\InputOption;
use Symfony\Component\Console\Output\OutputInterface;
use Symfony\Flex\GithubApi;
use Symfony\Flex\InformationOperation;
use Symfony\Flex\Lock;
use Symfony\Flex\Recipe;
Expand All @@ -31,13 +31,13 @@ class RecipesCommand extends BaseCommand
private $flex;

private $symfonyLock;
private $downloader;
private $githubApi;

public function __construct(/* cannot be type-hinted */ $flex, Lock $symfonyLock, $downloader)
{
$this->flex = $flex;
$this->symfonyLock = $symfonyLock;
$this->downloader = $downloader;
$this->githubApi = new GithubApi($downloader);

parent::__construct();
}
Expand Down Expand Up @@ -136,7 +136,7 @@ protected function execute(InputInterface $input, OutputInterface $output)
'',
'Run:',
' * <info>composer recipes vendor/package</info> to see details about a recipe.',
' * <info>composer recipes:install vendor/package --force -v</info> to update that recipe.',
' * <info>composer recipes:update vendor/package</info> to update that recipe.',
'',
]));

Expand Down Expand Up @@ -171,13 +171,15 @@ private function displayPackageInformation(Recipe $recipe)
$commitDate = null;
if (null !== $lockRef && null !== $lockRepo) {
try {
list($gitSha, $commitDate) = $this->findRecipeCommitDataFromTreeRef(
$recipeCommitData = $this->githubApi->findRecipeCommitDataFromTreeRef(
$recipe->getName(),
$lockRepo,
$lockBranch ?? '',
$lockVersion,
$lockRef
);
$gitSha = $recipeCommitData ? $recipeCommitData['commit'] : null;
$commitDate = $recipeCommitData ? $recipeCommitData['date'] : null;
} catch (TransportException $exception) {
$io->writeError('Error downloading exact git sha for installed recipe.');
}
Expand Down Expand Up @@ -232,7 +234,7 @@ private function displayPackageInformation(Recipe $recipe)
$io->write([
'',
'Update this recipe by running:',
sprintf('<info>composer recipes:install %s --force -v</info>', $recipe->getName()),
sprintf('<info>composer recipes:update %s</info>', $recipe->getName()),
]);
}
}
Expand Down Expand Up @@ -324,63 +326,4 @@ private function writeTreeLine($line)

$io->write($line);
}

/**
* Attempts to find the original git sha when the recipe was installed.
*/
private function findRecipeCommitDataFromTreeRef(string $package, string $repo, string $branch, string $version, string $lockRef)
{
// only supports public repository placement
if (0 !== strpos($repo, 'github.com')) {
return [null, null];
}

$parts = explode('/', $repo);
if (3 !== \count($parts)) {
return [null, null];
}

$recipePath = sprintf('%s/%s', $package, $version);
$commitsData = $this->requestGitHubApi(sprintf(
'https://api.github.com/repos/%s/%s/commits?path=%s&sha=%s',
$parts[1],
$parts[2],
$recipePath,
$branch
));

foreach ($commitsData as $commitData) {
// go back the commits one-by-one
$treeUrl = $commitData['commit']['tree']['url'].'?recursive=true';

// fetch the full tree, then look for the tree for the package path
$treeData = $this->requestGitHubApi($treeUrl);
foreach ($treeData['tree'] as $treeItem) {
if ($treeItem['path'] !== $recipePath) {
continue;
}

if ($treeItem['sha'] === $lockRef) {
// shorten for brevity
return [
substr($commitData['sha'], 0, 7),
$commitData['commit']['committer']['date'],
];
}
}
}

return [null, null];
}

private function requestGitHubApi(string $path)
{
if ($this->downloader instanceof HttpDownloader) {
$contents = $this->downloader->get($path)->getBody();
} else {
$contents = $this->downloader->getContents('api.github.com', $path, false);
}

return json_decode($contents, true);
}
}
Loading

0 comments on commit 3ee7719

Please sign in to comment.