Ver código fonte

Add parsing and on-the-fly loading of repositories defined in packages

Jordi Boggiano 13 anos atrás
pai
commit
9b24734c9d

+ 1 - 0
src/Composer/Package/Dumper/ArrayDumper.php

@@ -40,6 +40,7 @@ class ArrayDumper
             'recommends',
             'suggests',
             'autoload',
+            'repositories',
         );
 
         $data = array();

+ 16 - 1
src/Composer/Package/Loader/ArrayLoader.php

@@ -13,6 +13,7 @@
 namespace Composer\Package\Loader;
 
 use Composer\Package;
+use Composer\Repository\RepositoryManager;
 
 /**
  * @author Konstantin Kudryashiv <ever.zet@gmail.com>
@@ -30,9 +31,11 @@ class ArrayLoader
     );
 
     protected $versionParser;
+    private $manager;
 
-    public function __construct($parser = null)
+    public function __construct(RepositoryManager $manager, $parser = null)
     {
+        $this->manager = $manager;
         $this->versionParser = $parser;
         if (!$parser) {
             $this->versionParser = new Package\Version\VersionParser;
@@ -50,6 +53,18 @@ class ArrayLoader
             $package->setTargetDir($config['target-dir']);
         }
 
+        if (isset($config['repositories'])) {
+            $repositories = array();
+            foreach ($config['repositories'] as $repo) {
+                if (!$repo) {
+                    continue;
+                }
+                $repository = $this->manager->createRepository(key($repo), current($repo));
+                $this->manager->addRepository($repository);
+            }
+            $package->setRepositories($config['repositories']);
+        }
+
         if (isset($config['extra'])) {
             $package->setExtra($config['extra']);
         }

+ 19 - 0
src/Composer/Package/MemoryPackage.php

@@ -31,6 +31,7 @@ class MemoryPackage extends BasePackage
     protected $distSha1Checksum;
     protected $releaseType;
     protected $version;
+    protected $repositories;
     protected $license;
     protected $extra = array();
 
@@ -233,6 +234,24 @@ class MemoryPackage extends BasePackage
         return $this->distSha1Checksum;
     }
 
+    /**
+     * Set the repositories
+     *
+     * @param string $repositories
+     */
+    public function setRepositories($repositories)
+    {
+        $this->repositories = $repositories;
+    }
+
+    /**
+     * {@inheritDoc}
+     */
+    public function getRepositories()
+    {
+        return $this->repositories;
+    }
+
     /**
      * Set the release type
      *

+ 9 - 0
src/Composer/Package/PackageInterface.php

@@ -228,6 +228,15 @@ interface PackageInterface
      */
     function getAutoload();
 
+    /**
+     * Returns an array of repositories
+     *
+     * {"<type>": {<config key/values>}}
+     *
+     * @return array Repositories
+     */
+    function getRepositories();
+
     /**
      * Stores a reference to the repository that owns the package
      *

+ 12 - 14
src/Composer/Repository/ArrayRepository.php

@@ -22,14 +22,10 @@ use Composer\Package\PackageInterface;
 class ArrayRepository implements RepositoryInterface
 {
     protected $packages;
+    protected $repositoryManager;
 
     /**
-     * Searches for a package by it's name and version (if has one).
-     *
-     * @param   string  $name       package name
-     * @param   string  $version    package version
-     *
-     * @return  PackageInterface|null
+     * {@inheritDoc}
      */
     public function findPackage($name, $version)
     {
@@ -41,11 +37,15 @@ class ArrayRepository implements RepositoryInterface
     }
 
     /**
-     * Checks if specified package in this repository.
-     *
-     * @param   PackageInterface    $package    package instance
-     *
-     * @return  Boolean
+     * {@inheritDoc}
+     */
+    public function setRepositoryManager(RepositoryManager $manager)
+    {
+        $this->repositoryManager = $manager;
+    }
+
+    /**
+     * {@inheritDoc}
      */
     public function hasPackage(PackageInterface $package)
     {
@@ -93,9 +93,7 @@ class ArrayRepository implements RepositoryInterface
     }
 
     /**
-     * Returns all contained packages
-     *
-     * @return array All packages
+     * {@inheritDoc}
      */
     public function getPackages()
     {

+ 1 - 1
src/Composer/Repository/ComposerRepository.php

@@ -51,7 +51,7 @@ class ComposerRepository extends ArrayRepository
     private function createPackages($data)
     {
         foreach ($data['versions'] as $rev) {
-            $loader = new ArrayLoader();
+            $loader = new ArrayLoader($this->repositoryManager);
             $this->addPackage($loader->load($rev));
         }
     }

+ 7 - 0
src/Composer/Repository/RepositoryInterface.php

@@ -47,4 +47,11 @@ interface RepositoryInterface extends \Countable
      * @return  array
      */
     function getPackages();
+
+    /**
+     * Stores the RepositoryManager owning this repository
+     *
+     * @param RepositoryManager $manager
+     */
+    function setRepositoryManager(RepositoryManager $manager);
 }

+ 29 - 6
src/Composer/Repository/RepositoryManager.php

@@ -24,6 +24,15 @@ class RepositoryManager
     private $repositories = array();
     private $repositoryClasses = array();
 
+    /**
+     * Used for lazy loading of packages and their contained repositories
+     *
+     * This is a performance optimization to avoid loading all packages unless they are needed
+     *
+     * @var Boolean
+     */
+    private $initialized;
+
     /**
      * Searches for a package by it's name and version in managed repositories.
      *
@@ -49,24 +58,31 @@ class RepositoryManager
     public function addRepository(RepositoryInterface $repository)
     {
         $this->repositories[] = $repository;
+
+        $repository->setRepositoryManager($this);
+
+        // already initialized, so initialize new repos on the fly
+        if ($this->initialized) {
+            $repository->getPackages();
+        }
     }
 
     /**
-     * Returns repository class for a specific installation type.
-     *
-     * @param   string  $type   installation type
+     * Returns a new repository for a specific installation type.
      *
+     * @param   string $type repository type
+     * @param   string $config repository configuration
      * @return  RepositoryInterface
-     *
      * @throws  InvalidArgumentException     if repository for provided type is not registeterd
      */
-    public function getRepositoryClass($type)
+    public function createRepository($type, $config)
     {
         if (!isset($this->repositoryClasses[$type])) {
             throw new \InvalidArgumentException('Repository type is not registered: '.$type);
         }
 
-        return $this->repositoryClasses[$type];
+        $class = $this->repositoryClasses[$type];
+        return new $class($config);
     }
 
     /**
@@ -87,6 +103,13 @@ class RepositoryManager
      */
     public function getRepositories()
     {
+        if (!$this->initialized) {
+            $this->initialized = true;
+            // warm up repos to be sure all sub-repos are added before we return
+            foreach ($this->repositories as $repository) {
+                $repository->getPackages();
+            }
+        }
         return $this->repositories;
     }