From 5f2eefb49b3658b50293481b643dc4346670fa3c Mon Sep 17 00:00:00 2001 From: Stephan Vock Date: Wed, 10 Oct 2018 14:09:42 +0200 Subject: [PATCH] Vcs Repository: add option to cache/reuse entire versions --- src/Composer/Repository/VcsRepository.php | 67 ++++++++++++++++--- .../Repository/VersionCacheInterface.php | 23 +++++++ 2 files changed, 80 insertions(+), 10 deletions(-) create mode 100644 src/Composer/Repository/VersionCacheInterface.php diff --git a/src/Composer/Repository/VcsRepository.php b/src/Composer/Repository/VcsRepository.php index 57639cdea..785b8534b 100644 --- a/src/Composer/Repository/VcsRepository.php +++ b/src/Composer/Repository/VcsRepository.php @@ -41,8 +41,10 @@ class VcsRepository extends ArrayRepository implements ConfigurableRepositoryInt private $drivers; /** @var VcsDriverInterface */ private $driver; + /** @var VersionCacheInterface */ + private $versionCache; - public function __construct(array $repoConfig, IOInterface $io, Config $config, EventDispatcher $dispatcher = null, array $drivers = null) + public function __construct(array $repoConfig, IOInterface $io, Config $config, EventDispatcher $dispatcher = null, array $drivers = null, VersionCacheInterface $versionCache = null) { parent::__construct(); $this->drivers = $drivers ?: array( @@ -64,6 +66,7 @@ class VcsRepository extends ArrayRepository implements ConfigurableRepositoryInt $this->verbose = $io->isVeryVerbose(); $this->config = $config; $this->repoConfig = $repoConfig; + $this->versionCache = $versionCache; } public function getRepoConfig() @@ -152,6 +155,13 @@ class VcsRepository extends ArrayRepository implements ConfigurableRepositoryInt // strip the release- prefix from tags if present $tag = str_replace('release-', '', $tag); + $cachedPackage = $this->getCachedPackageVersion($tag, $identifier, $verbose); + if ($cachedPackage) { + $this->addPackage($cachedPackage); + + continue; + } + if (!$parsedTag = $this->validateTag($tag)) { if ($verbose) { $this->io->writeError('Skipped tag '.$tag.', invalid tag name'); @@ -235,6 +245,21 @@ class VcsRepository extends ArrayRepository implements ConfigurableRepositoryInt continue; } + // make sure branch packages have a dev flag + if ('dev-' === substr($parsedBranch, 0, 4) || '9999999-dev' === $parsedBranch) { + $version = 'dev-' . $branch; + } else { + $prefix = substr($branch, 0, 1) === 'v' ? 'v' : ''; + $version = $prefix . preg_replace('{(\.9{7})+}', '.x', $parsedBranch); + } + + $cachedPackage = $this->getCachedPackageVersion($version, $identifier, $verbose); + if ($cachedPackage) { + $this->addPackage($cachedPackage); + + continue; + } + try { if (!$data = $driver->getComposerInformation($identifier)) { if ($verbose) { @@ -244,17 +269,9 @@ class VcsRepository extends ArrayRepository implements ConfigurableRepositoryInt } // branches are always auto-versioned, read value from branch name - $data['version'] = $branch; + $data['version'] = $version; $data['version_normalized'] = $parsedBranch; - // make sure branch packages have a dev flag - if ('dev-' === substr($parsedBranch, 0, 4) || '9999999-dev' === $parsedBranch) { - $data['version'] = 'dev-' . $data['version']; - } else { - $prefix = substr($branch, 0, 1) === 'v' ? 'v' : ''; - $data['version'] = $prefix . preg_replace('{(\.9{7})+}', '.x', $parsedBranch); - } - if ($verbose) { $this->io->writeError('Importing branch '.$branch.' ('.$data['version'].')'); } @@ -325,4 +342,34 @@ class VcsRepository extends ArrayRepository implements ConfigurableRepositoryInt return false; } + + private function getCachedPackageVersion($version, $identifier, $verbose) + { + if (!$this->versionCache) { + return; + } + + $cachedPackage = $this->versionCache->getVersionPackage($version, $identifier); + if ($cachedPackage) { + $msg = 'Found cached composer.json of ' . ($this->packageName ?: $this->url) . ' (' . $version . ')'; + if ($verbose) { + $this->io->writeError($msg); + } else { + $this->io->overwriteError($msg, false); + } + + if ($existingPackage = $this->findPackage($cachedPackage['name'], $cachedPackage['version_normalized'])) { + if ($verbose) { + $this->io->writeError('Skipped cached version '.$version.', it conflicts with an another tag ('.$existingPackage->getPrettyVersion().') as both resolve to '.$cachedPackage['version_normalized'].' internally'); + } + $cachedPackage = null; + } + } + + if ($cachedPackage) { + return $this->loader->load($cachedPackage); + } + + return null; + } } diff --git a/src/Composer/Repository/VersionCacheInterface.php b/src/Composer/Repository/VersionCacheInterface.php new file mode 100644 index 000000000..db5934b59 --- /dev/null +++ b/src/Composer/Repository/VersionCacheInterface.php @@ -0,0 +1,23 @@ + + * Jordi Boggiano + * + * For the full copyright and license information, please view the LICENSE + * file that was distributed with this source code. + */ + +namespace Composer\Repository; + +interface VersionCacheInterface +{ + /** + * @param string $version + * @param string $identifier + * @return array Package version data + */ + public function getVersionPackage($version, $identifier); +}