Browse Source

Vcs Repository: add option to cache/reuse entire versions

Stephan Vock 6 years ago
parent
commit
5f2eefb49b

+ 57 - 10
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('<warning>Skipped tag '.$tag.', invalid tag name</warning>');
@@ -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 <info>' . ($this->packageName ?: $this->url) . '</info> (<comment>' . $version . '</comment>)';
+            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('<warning>Skipped cached version '.$version.', it conflicts with an another tag ('.$existingPackage->getPrettyVersion().') as both resolve to '.$cachedPackage['version_normalized'].' internally</warning>');
+                }
+                $cachedPackage = null;
+            }
+        }
+
+        if ($cachedPackage) {
+            return $this->loader->load($cachedPackage);
+        }
+
+        return null;
+    }
 }

+ 23 - 0
src/Composer/Repository/VersionCacheInterface.php

@@ -0,0 +1,23 @@
+<?php
+
+/*
+ * This file is part of Composer.
+ *
+ * (c) Nils Adermann <naderman@naderman.de>
+ *     Jordi Boggiano <j.boggiano@seld.be>
+ *
+ * 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);
+}