Browse Source

Merge branch '1.2'

Jordi Boggiano 8 years ago
parent
commit
193d53921b
3 changed files with 95 additions and 47 deletions
  1. 7 1
      CHANGELOG.md
  2. 6 1
      doc/05-repositories.md
  3. 82 45
      src/Composer/Repository/ComposerRepository.php

+ 7 - 1
CHANGELOG.md

@@ -10,6 +10,11 @@
   * Removed `hash` from composer.lock, only `content-hash` is now used which should reduce conflicts
   * Minor fixes and performance improvements
 
+### [1.2.3] - 2016-12-01
+
+  * Fixed bug in HgDriver failing to identify BitBucket repositories
+  * Fixed support for loading partial provider repositories
+
 ### [1.2.2] - 2016-11-03
 
   * Fixed selection of packages based on stability to be independent from package repository order
@@ -453,7 +458,8 @@
 
   * Initial release
 
-[1.3.0-RC]: https://github.com/composer/composer/compare/1.2.2...1.3.0-RC
+[1.3.0-RC]: https://github.com/composer/composer/compare/1.2.3...1.3.0-RC
+[1.2.3]: https://github.com/composer/composer/compare/1.2.2...1.2.3
 [1.2.2]: https://github.com/composer/composer/compare/1.2.1...1.2.2
 [1.2.1]: https://github.com/composer/composer/compare/1.2.0...1.2.1
 [1.2.0]: https://github.com/composer/composer/compare/1.2.0-RC...1.2.0

+ 6 - 1
doc/05-repositories.md

@@ -284,8 +284,13 @@ VCS repository provides `dist`s for them that fetch the packages as zips.
 * **BitBucket:** [bitbucket.org](https://bitbucket.org) (Git and Mercurial)
 
 The VCS driver to be used is detected automatically based on the URL. However,
+<<<<<<< HEAD
 should you need to specify one for whatever reason, you can use `fossil`,
 `git`, `svn` or `hg` as the repository type instead of `vcs`.
+=======
+should you need to specify one for whatever reason, you can use `fossil`, `git`,
+`svn` or `hg` as the repository type instead of `vcs`.
+>>>>>>> 1.2
 
 If you set the `no-api` key to `true` on a github repository it will clone the
 repository as it would with any other git repository instead of using the
@@ -662,7 +667,7 @@ You can disable the default Packagist repository by adding this to your
 {
     "repositories": [
         {
-            "packagist": false
+            "packagist.org": false
         }
     ]
 }

+ 82 - 45
src/Composer/Repository/ComposerRepository.php

@@ -59,6 +59,8 @@ class ComposerRepository extends ArrayRepository implements ConfigurableReposito
     protected $distMirrors;
     private $degradedMode = false;
     private $rootData;
+    private $hasPartialPackages;
+    private $partialPackagesByName;
 
     public function __construct(array $repoConfig, IOInterface $io, Config $config, EventDispatcher $eventDispatcher = null, RemoteFilesystem $rfs = null)
     {
@@ -280,69 +282,84 @@ class ComposerRepository extends ArrayRepository implements ConfigurableReposito
             return $this->providers[$name];
         }
 
-        // skip platform packages, root package and composer-plugin-api
-        if (preg_match(PlatformRepository::PLATFORM_PACKAGE_REGEX, $name) || '__root__' === $name || 'composer-plugin-api' === $name) {
-            return array();
-        }
-
-        if (null === $this->providerListing) {
-            $this->loadProviderListings($this->loadRootServerFile());
+        if ($this->hasPartialPackages && null === $this->partialPackagesByName) {
+            $this->initializePartialPackages();
         }
 
-        $useLastModifiedCheck = false;
-        if ($this->lazyProvidersUrl && !isset($this->providerListing[$name])) {
-            $hash = null;
-            $url = str_replace('%package%', $name, $this->lazyProvidersUrl);
-            $cacheKey = 'provider-'.strtr($name, '/', '$').'.json';
-            $useLastModifiedCheck = true;
-        } elseif ($this->providersUrl) {
-            // package does not exist in this repo
-            if (!isset($this->providerListing[$name])) {
+        if (!$this->hasPartialPackages || !isset($this->partialPackagesByName[$name])) {
+            // skip platform packages, root package and composer-plugin-api
+            if (preg_match(PlatformRepository::PLATFORM_PACKAGE_REGEX, $name) || '__root__' === $name || 'composer-plugin-api' === $name) {
                 return array();
             }
 
-            $hash = $this->providerListing[$name]['sha256'];
-            $url = str_replace(array('%package%', '%hash%'), array($name, $hash), $this->providersUrl);
-            $cacheKey = 'provider-'.strtr($name, '/', '$').'.json';
-        } else {
-            return array();
-        }
+            if (null === $this->providerListing) {
+                $this->loadProviderListings($this->loadRootServerFile());
+            }
 
-        $packages = null;
-        if ($cacheKey) {
-            if (!$useLastModifiedCheck && $hash && $this->cache->sha256($cacheKey) === $hash) {
-                $packages = json_decode($this->cache->read($cacheKey), true);
-            } elseif ($useLastModifiedCheck) {
-                if ($contents = $this->cache->read($cacheKey)) {
-                    $contents = json_decode($contents, true);
-                    if (isset($contents['last-modified'])) {
-                        $response = $this->fetchFileIfLastModified($url, $cacheKey, $contents['last-modified']);
-                        if (true === $response) {
-                            $packages = $contents;
-                        } elseif ($response) {
-                            $packages = $response;
+            $useLastModifiedCheck = false;
+            if ($this->lazyProvidersUrl && !isset($this->providerListing[$name])) {
+                $hash = null;
+                $url = str_replace('%package%', $name, $this->lazyProvidersUrl);
+                $cacheKey = 'provider-'.strtr($name, '/', '$').'.json';
+                $useLastModifiedCheck = true;
+            } elseif ($this->providersUrl) {
+                // package does not exist in this repo
+                if (!isset($this->providerListing[$name])) {
+                    return array();
+                }
+
+                $hash = $this->providerListing[$name]['sha256'];
+                $url = str_replace(array('%package%', '%hash%'), array($name, $hash), $this->providersUrl);
+                $cacheKey = 'provider-'.strtr($name, '/', '$').'.json';
+            } else {
+                return array();
+            }
+
+            $packages = null;
+            if ($cacheKey) {
+                if (!$useLastModifiedCheck && $hash && $this->cache->sha256($cacheKey) === $hash) {
+                    $packages = json_decode($this->cache->read($cacheKey), true);
+                } elseif ($useLastModifiedCheck) {
+                    if ($contents = $this->cache->read($cacheKey)) {
+                        $contents = json_decode($contents, true);
+                        if (isset($contents['last-modified'])) {
+                            $response = $this->fetchFileIfLastModified($url, $cacheKey, $contents['last-modified']);
+                            if (true === $response) {
+                                $packages = $contents;
+                            } elseif ($response) {
+                                $packages = $response;
+                            }
                         }
                     }
                 }
             }
-        }
 
-        if (!$packages) {
-            try {
-                $packages = $this->fetchFile($url, $cacheKey, $hash, $useLastModifiedCheck);
-            } catch (TransportException $e) {
-                // 404s are acceptable for lazy provider repos
-                if ($e->getStatusCode() === 404 && $this->lazyProvidersUrl) {
-                    $packages = array('packages' => array());
-                } else {
-                    throw $e;
+            if (!$packages) {
+                try {
+                    $packages = $this->fetchFile($url, $cacheKey, $hash, $useLastModifiedCheck);
+                } catch (TransportException $e) {
+                    // 404s are acceptable for lazy provider repos
+                    if ($e->getStatusCode() === 404 && $this->lazyProvidersUrl) {
+                        $packages = array('packages' => array());
+                    } else {
+                        throw $e;
+                    }
                 }
             }
+
+            $loadingPartialPackage = false;
+        } else {
+            $packages = array('packages' => array('versions' => $this->partialPackagesByName[$name]));
+            $loadingPartialPackage = true;
         }
 
         $this->providers[$name] = array();
         foreach ($packages['packages'] as $versions) {
             foreach ($versions as $version) {
+                if (!$loadingPartialPackage && $this->hasPartialPackages && isset($this->partialPackagesByName[$version['name']])) {
+                    continue;
+                }
+
                 // avoid loading the same objects twice
                 if (isset($this->providersByUid[$version['uid']])) {
                     // skip if already assigned
@@ -492,6 +509,8 @@ class ComposerRepository extends ArrayRepository implements ConfigurableReposito
         if (!empty($data['providers-lazy-url'])) {
             $this->lazyProvidersUrl = $this->canonicalizeUrl($data['providers-lazy-url']);
             $this->hasProviders = true;
+
+            $this->hasPartialPackages = !empty($data['packages']) && is_array($data['packages']);
         }
 
         if ($this->allowSslDowngrade) {
@@ -754,4 +773,22 @@ class ComposerRepository extends ArrayRepository implements ConfigurableReposito
             }
         }
     }
+
+    /**
+     * This initializes the packages key of a partial packages.json that contain some packages inlined + a providers-lazy-url
+     *
+     * This should only be called once
+     */
+    private function initializePartialPackages()
+    {
+        $rootData = $this->loadRootServerFile();
+
+        $this->partialPackagesByName = array();
+        foreach ($rootData['packages'] as $package => $versions) {
+            $this->partialPackagesByName[strtolower($package)] = $versions;
+        }
+
+        // wipe rootData as it is fully consumed at this point and this saves some memory
+        $this->rootData = true;
+    }
 }