Browse Source

Add support for aliases in streamed repos

Jordi Boggiano 12 years ago
parent
commit
2d4076e9b2

+ 64 - 3
src/Composer/DependencyResolver/Pool.php

@@ -13,6 +13,7 @@
 namespace Composer\DependencyResolver;
 
 use Composer\Package\BasePackage;
+use Composer\Package\AliasPackage;
 use Composer\Package\Version\VersionParser;
 use Composer\Package\Loader\ArrayLoader;
 use Composer\Package\Link;
@@ -64,8 +65,9 @@ class Pool
      * Adds a repository and its packages to this package pool
      *
      * @param RepositoryInterface $repo A package repository
+     * @param array               $aliases
      */
-    public function addRepository(RepositoryInterface $repo)
+    public function addRepository(RepositoryInterface $repo, $aliases = array())
     {
         if ($repo instanceof CompositeRepository) {
             $repos = $repo->getRepositories();
@@ -81,7 +83,8 @@ class Pool
             if ($repo instanceof StreamableRepositoryInterface) {
                 foreach ($repo->getMinimalPackages() as $package) {
                     $name = $package['name'];
-                    $stability = VersionParser::parseStability($package['version']);
+                    $version = $package['version'];
+                    $stability = VersionParser::parseStability($version);
                     if (
                         // always allow exempt repos
                         $exempt
@@ -114,6 +117,35 @@ class Pool
                         foreach (array_keys($names) as $name) {
                             $this->packageByName[$name][] =& $this->packages[$id-2];
                         }
+
+                        // handle root package aliases
+                        if (isset($aliases[$name][$version])) {
+                            $alias = $package;
+                            $alias['version'] = $aliases[$name][$version]['alias_normalized'];
+                            $alias['alias'] = $aliases[$name][$version]['alias'];
+                            $alias['alias_of'] = $package['id'];
+                            $alias['id'] = $id++;
+                            $alias['root_alias'] = true;
+                            $this->packages[] = $alias;
+
+                            foreach (array_keys($names) as $name) {
+                                $this->packageByName[$name][] =& $this->packages[$id-2];
+                            }
+                        }
+
+                        // handle normal package aliases
+                        if (isset($package['alias'])) {
+                            $alias = $package;
+                            $alias['version'] = $package['alias_normalized'];
+                            $alias['alias'] = $package['alias'];
+                            $alias['alias_of'] = $package['id'];
+                            $alias['id'] = $id++;
+                            $this->packages[] = $alias;
+
+                            foreach (array_keys($names) as $name) {
+                                $this->packageByName[$name][] =& $this->packages[$id-2];
+                            }
+                        }
                     }
                 }
             } else {
@@ -137,6 +169,22 @@ class Pool
                         foreach ($package->getNames() as $name) {
                             $this->packageByName[$name][] = $package;
                         }
+
+                        // handle root package aliases
+                        if (isset($aliases[$name][$package->getVersion()])) {
+                            $alias = $aliases[$name][$package->getVersion()];
+                            $package->setAlias($alias['alias_normalized']);
+                            $package->setPrettyAlias($alias['alias']);
+                            $package->getRepository()->addPackage($aliasPackage = new AliasPackage($package, $alias['alias_normalized'], $alias['alias']));
+                            $aliasPackage->setRootPackageAlias(true);
+                            $aliasPackage->setId($id++);
+
+                            $this->packages[] = $aliasPackage;
+
+                            foreach ($aliasPackage->getNames() as $name) {
+                                $this->packageByName[$name][] = $aliasPackage;
+                            }
+                        }
                     }
                 }
             }
@@ -267,7 +315,20 @@ class Pool
     private function ensurePackageIsLoaded($data)
     {
         if (is_array($data)) {
-            $data = $this->packages[$data['id'] - 1] = $data['repo']->loadPackage($data, $data['id']);
+            if (isset($data['alias_of'])) {
+                // TODO move to $repo->loadAliasPackage?
+                $aliasOf = $this->packageById($data['alias_of']);
+                $rootAlias = !empty($data['root_alias']);
+                $package = $this->packages[$data['id'] - 1] = new AliasPackage($aliasOf, $data['version'], $data['alias']);
+                $package->setId($data['id']);
+                $package->setRootPackageAlias($rootAlias);
+
+                return $package;
+            }
+
+            $package = $this->packages[$data['id'] - 1] = $data['repo']->loadPackage($data, $data['id']);
+
+            return $package;
         }
 
         return $data;

+ 9 - 12
src/Composer/Installer.php

@@ -244,9 +244,9 @@ class Installer
 
         // creating repository pool
         $pool = new Pool($minimumStability, $stabilityFlags);
-        $pool->addRepository($installedRepo);
+        $pool->addRepository($installedRepo, $aliases);
         foreach ($this->repositoryManager->getRepositories() as $repository) {
-            $pool->addRepository($repository);
+            $pool->addRepository($repository, $aliases);
         }
 
         // creating requirements request
@@ -276,11 +276,8 @@ class Installer
 
             foreach ($lockedPackages as $package) {
                 $version = $package->getVersion();
-                foreach ($aliases as $alias) {
-                    if ($alias['package'] === $package->getName() && $alias['version'] === $package->getVersion()) {
-                        $version = $alias['alias_normalized'];
-                        break;
-                    }
+                if (isset($aliases[$package->getName()][$version])) {
+                    $version = $aliases[$package->getName()][$version]['alias_normalized'];
                 }
                 $constraint = new VersionConstraint('=', $version);
                 $request->install($package->getName(), $constraint);
@@ -495,11 +492,11 @@ class Installer
             $aliases = $this->package->getAliases();
         }
 
+        $normalizedAliases = array();
+
         foreach ($aliases as $alias) {
-            $packages = array_merge(
-                $platformRepo->findPackages($alias['package'], $alias['version']),
-                $this->repositoryManager->findPackages($alias['package'], $alias['version'])
-            );
+            $normalizedAliases[$alias['package']][$alias['version']] = array('alias' => $alias['alias'], 'alias_normalized' => $alias['alias_normalized']);
+            $packages = $platformRepo->findPackages($alias['package'], $alias['version']);
             foreach ($packages as $package) {
                 $package->setAlias($alias['alias_normalized']);
                 $package->setPrettyAlias($alias['alias']);
@@ -508,7 +505,7 @@ class Installer
             }
         }
 
-        return $aliases;
+        return $normalizedAliases;
     }
 
     private function isUpdateable(PackageInterface $package)

+ 12 - 1
src/Composer/Package/Locker.php

@@ -177,11 +177,22 @@ class Locker
             'hash' => $this->hash,
             'packages' => null,
             'packages-dev' => null,
-            'aliases' => $aliases,
+            'aliases' => array(),
             'minimum-stability' => $minimumStability,
             'stability-flags' => $stabilityFlags,
         );
 
+        foreach ($aliases as $package => $versions) {
+            foreach ($versions as $version => $alias) {
+                $lock['aliases'][] = array(
+                    'alias' => $alias['alias'],
+                    'alias_normalized' => $alias['alias_normalized'],
+                    'version' => $version,
+                    'package' => $package,
+                );
+            }
+        }
+
         $lock['packages'] = $this->lockPackages($packages);
         if (null !== $devPackages) {
             $lock['packages-dev'] = $this->lockPackages($devPackages);

+ 28 - 2
src/Composer/Repository/ComposerRepository.php

@@ -107,6 +107,32 @@ class ComposerRepository extends ArrayRepository implements NotifiableRepository
                 $data['provide'] = $package['provide'];
             }
 
+            // add branch aliases
+            if ('dev-' === substr($package['version'], 0, 4) && isset($package['extra']['branch-alias']) && is_array($package['extra']['branch-alias'])) {
+                foreach ($package['extra']['branch-alias'] as $sourceBranch => $targetBranch) {
+                    // ensure it is an alias to a -dev package
+                    if ('-dev' !== substr($targetBranch, -4)) {
+                        continue;
+                    }
+                    // normalize without -dev and ensure it's a numeric branch that is parseable
+                    $validatedTargetBranch = $versionParser->normalizeBranch(substr($targetBranch, 0, -4));
+                    if ('-dev' !== substr($validatedTargetBranch, -4)) {
+                        continue;
+                    }
+
+                    // ensure that it is the current branch aliasing itself
+                    if (strtolower($package['version']) !== strtolower($sourceBranch)) {
+                        continue;
+                    }
+
+                    $alias = preg_replace('{(\.9{7})+}', '.x', $validatedTargetBranch);
+                    $aliasNormalized = $validatedTargetBranch;
+                    $data['alias'] = $alias;
+                    $data['alias_normalized'] = $aliasNormalized;
+                    break;
+                }
+            }
+
             $this->minimalPackages[] = $data;
         }
 
@@ -115,9 +141,9 @@ class ComposerRepository extends ArrayRepository implements NotifiableRepository
 
     public function loadPackage(array $data, $id)
     {
-        $package = $this->loader->load($data);
+        $package = $this->loader->load($data['raw']);
         $package->setId($id);
-        $package->setRepository($data['repo']);
+        $package->setRepository($this);
 
         return $package;
     }