Browse Source

Wrap the package in an aliased package instead of replacing

Jordi Boggiano 13 years ago
parent
commit
f9fc9695e9

+ 16 - 21
src/Composer/Command/InstallCommand.php

@@ -20,10 +20,12 @@ use Composer\DependencyResolver;
 use Composer\DependencyResolver\Pool;
 use Composer\DependencyResolver\Request;
 use Composer\DependencyResolver\Operation;
+use Composer\Package\AliasPackage;
 use Composer\Package\MemoryPackage;
 use Composer\Package\Link;
 use Composer\Package\LinkConstraint\VersionConstraint;
 use Composer\Package\PackageInterface;
+use Composer\Repository\ArrayRepository;
 use Composer\Repository\CompositeRepository;
 use Composer\Repository\PlatformRepository;
 use Composer\Repository\RepositoryInterface;
@@ -103,6 +105,20 @@ EOT
             $installedRepo->addRepository($additionalInstalledRepository);
         }
 
+        // prepare aliased packages
+        $aliasRepo = new ArrayRepository;
+        foreach ($composer->getPackage()->getAliases() as $alias) {
+            foreach ($repoManager->findPackages($alias['package'], $alias['version']) as $package) {
+                $aliasRepo->addPackage(new AliasPackage($package, $alias['replaces']));
+            }
+
+            foreach ($repoManager->getLocalRepository()->findPackages($alias['package'], $alias['version']) as $package) {
+                $repoManager->getLocalRepository()->addPackage(new AliasPackage($package, $alias['replaces']));
+                $repoManager->getLocalRepository()->removePackage($package);
+            }
+        }
+        $repoManager->addRepository($aliasRepo);
+
         // creating repository pool
         $pool = new Pool;
         $pool->addRepository($installedRepo);
@@ -151,27 +167,6 @@ EOT
             }
         }
 
-        // prepare aliased packages
-        foreach ($composer->getPackage()->getAliases() as $alias) {
-            $candidates = array_merge(
-                $repoManager->findPackages($alias['package'], $alias['version']),
-                $repoManager->getLocalRepository()->findPackages($alias['package'], $alias['version'])
-            );
-            foreach ($candidates as $package) {
-                $replaces = $package->getReplaces();
-                foreach ($replaces as $index => $link) {
-                    // link is self.version, but must be replacing also the replaced version
-                    if ('self.version' === $link->getPrettyConstraint()) {
-                        $replaces[] = new Link($link->getSource(), $link->getTarget(), new VersionConstraint('=', $alias['replaces']), 'replaces', $alias['replaces']);
-                    }
-                }
-
-                // add replace of itself
-                $replaces[] = new Link($alias['package'], $alias['package'], new VersionConstraint('=', $alias['replaces']), 'replaces', $alias['replaces']);
-                $package->setReplaces($replaces);
-            }
-        }
-
         // prepare solver
         $installationManager = $composer->getInstallationManager();
         $policy              = new DependencyResolver\DefaultPolicy();

+ 18 - 4
src/Composer/Installer/InstallationManager.php

@@ -123,8 +123,12 @@ class InstallationManager
      */
     public function install(InstallOperation $operation)
     {
-        $installer = $this->getInstaller($operation->getPackage()->getType());
-        $installer->install($operation->getPackage());
+        $package = $operation->getPackage();
+        if ($package instanceof AliasPackage) {
+            $package = $package->getAliasOf();
+        }
+        $installer = $this->getInstaller($package->getType());
+        $installer->install($package);
     }
 
     /**
@@ -135,7 +139,13 @@ class InstallationManager
     public function update(UpdateOperation $operation)
     {
         $initial = $operation->getInitialPackage();
+        if ($initial instanceof AliasPackage) {
+            $initial = $initial->getAliasOf();
+        }
         $target  = $operation->getTargetPackage();
+        if ($target instanceof AliasPackage) {
+            $target = $target->getAliasOf();
+        }
 
         $initialType = $initial->getType();
         $targetType  = $target->getType();
@@ -156,8 +166,12 @@ class InstallationManager
      */
     public function uninstall(UninstallOperation $operation)
     {
-        $installer = $this->getInstaller($operation->getPackage()->getType());
-        $installer->uninstall($operation->getPackage());
+        $package = $operation->getPackage();
+        if ($package instanceof AliasPackage) {
+            $package = $package->getAliasOf();
+        }
+        $installer = $this->getInstaller($package->getType());
+        $installer->uninstall($package);
     }
 
     /**

+ 227 - 0
src/Composer/Package/AliasPackage.php

@@ -0,0 +1,227 @@
+<?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\Package;
+
+use Composer\Package\LinkConstraint\LinkConstraintInterface;
+use Composer\Package\LinkConstraint\VersionConstraint;
+use Composer\Repository\RepositoryInterface;
+use Composer\Repository\PlatformRepository;
+
+/**
+ * @author Jordi Boggiano <j.boggiano@seld.be>
+ */
+class AliasPackage extends BasePackage
+{
+    protected $version;
+    protected $dev;
+    protected $aliasOf;
+
+    protected $requires;
+    protected $conflicts;
+    protected $provides;
+    protected $replaces;
+    protected $recommends;
+    protected $suggests;
+
+    /**
+     * All descendants' constructors should call this parent constructor
+     *
+     * @param PackageInterface $aliasOf The package this package is an alias of
+     * @param string $version The version the alias must report
+     */
+    public function __construct($aliasOf, $version)
+    {
+        parent::__construct($aliasOf->getName());
+
+        $this->version = $version;
+        $this->aliasOf = $aliasOf;
+        $this->dev = 'dev-' === substr($version, 0, 4) || '-dev' === substr($version, -4);
+
+        foreach (self::$supportedLinkTypes as $type => $description) {
+            $links = $aliasOf->{'get'.ucfirst($description)}();
+            $newLinks = array();
+            foreach ($links as $link) {
+                // link is self.version, but must be replacing also the replaced version
+                if ('self.version' === $link->getPrettyConstraint()) {
+                    $newLinks[] = new Link($link->getSource(), $link->getTarget(), new VersionConstraint('=', $this->version), $description, $this->version);
+                }
+            }
+            $this->$description = array_merge($links, $newLinks);
+        }
+    }
+
+    /**
+     * {@inheritDoc}
+     */
+    public function getVersion()
+    {
+        return $this->version;
+    }
+
+    /**
+     * {@inheritDoc}
+     */
+    public function getPrettyVersion()
+    {
+        return $this->version;
+    }
+
+    /**
+     * {@inheritDoc}
+     */
+    public function isDev()
+    {
+        return $this->dev;
+    }
+
+    /**
+     * {@inheritDoc}
+     */
+    function getRequires()
+    {
+        return $this->requires;
+    }
+
+    /**
+     * {@inheritDoc}
+     */
+    function getConflicts()
+    {
+        return $this->conflicts;
+    }
+
+    /**
+     * {@inheritDoc}
+     */
+    function getProvides()
+    {
+        return $this->provides;
+    }
+
+    /**
+     * {@inheritDoc}
+     */
+    function getReplaces()
+    {
+        return $this->replaces;
+    }
+
+    /**
+     * {@inheritDoc}
+     */
+    function getRecommends()
+    {
+        return $this->recommends;
+    }
+
+    /**
+     * {@inheritDoc}
+     */
+    function getSuggests()
+    {
+        return $this->suggests;
+    }
+
+    /***************************************
+     * Wrappers around the aliased package *
+     ***************************************/
+
+    public function getType()
+    {
+        return $this->aliasOf->getType();
+    }
+    public function getTargetDir()
+    {
+        return $this->aliasOf->getTargetDir();
+    }
+    public function getExtra()
+    {
+        return $this->aliasOf->getExtra();
+    }
+    public function setInstallationSource($type)
+    {
+        $this->aliasOf->setInstallationSource($type);
+    }
+    public function getInstallationSource()
+    {
+        return $this->aliasOf->getInstallationSource();
+    }
+    public function getSourceType()
+    {
+        return $this->aliasOf->getSourceType();
+    }
+    public function getSourceUrl()
+    {
+        return $this->aliasOf->getSourceUrl();
+    }
+    public function getSourceReference()
+    {
+        return $this->aliasOf->getSourceReference();
+    }
+    public function getDistType()
+    {
+        return $this->aliasOf->getDistType();
+    }
+    public function getDistUrl()
+    {
+        return $this->aliasOf->getDistUrl();
+    }
+    public function getDistReference()
+    {
+        return $this->aliasOf->getDistReference();
+    }
+    public function getDistSha1Checksum()
+    {
+        return $this->aliasOf->getDistSha1Checksum();
+    }
+    public function getScripts()
+    {
+        return $this->aliasOf->getScripts();
+    }
+    public function getLicense()
+    {
+        return $this->aliasOf->getLicense();
+    }
+    public function getAutoload()
+    {
+        return $this->aliasOf->getAutoload();
+    }
+    public function getRepositories()
+    {
+        return $this->aliasOf->getRepositories();
+    }
+    public function getReleaseDate()
+    {
+        return $this->aliasOf->getReleaseDate();
+    }
+    public function getKeywords()
+    {
+        return $this->aliasOf->getKeywords();
+    }
+    public function getDescription()
+    {
+        return $this->aliasOf->getDescription();
+    }
+    public function getHomepage()
+    {
+        return $this->aliasOf->getHomepage();
+    }
+    public function getAuthors()
+    {
+        return $this->aliasOf->getAuthors();
+    }
+    public function __toString()
+    {
+        return $this->aliasOf->__toString();
+    }
+}

+ 10 - 0
src/Composer/Package/BasePackage.php

@@ -24,8 +24,18 @@ use Composer\Repository\PlatformRepository;
  */
 abstract class BasePackage implements PackageInterface
 {
+    public static $supportedLinkTypes = array(
+        'require'   => 'requires',
+        'conflict'  => 'conflicts',
+        'provide'   => 'provides',
+        'replace'   => 'replaces',
+        'recommend' => 'recommends',
+        'suggest'   => 'suggests',
+    );
+
     protected $name;
     protected $prettyName;
+
     protected $repository;
     protected $id;
 

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

@@ -22,15 +22,6 @@ use Composer\Repository\RepositoryManager;
  */
 class ArrayLoader
 {
-    protected $supportedLinkTypes = array(
-        'require'   => 'requires',
-        'conflict'  => 'conflicts',
-        'provide'   => 'provides',
-        'replace'   => 'replaces',
-        'recommend' => 'recommends',
-        'suggest'   => 'suggests',
-    );
-
     protected $versionParser;
 
     public function __construct(VersionParser $parser = null)
@@ -141,7 +132,7 @@ class ArrayLoader
             $package->setDistSha1Checksum(isset($config['dist']['shasum']) ? $config['dist']['shasum'] : null);
         }
 
-        foreach ($this->supportedLinkTypes as $type => $description) {
+        foreach (Package\BasePackage::$supportedLinkTypes as $type => $description) {
             if (isset($config[$type])) {
                 $method = 'set'.ucfirst($description);
                 $package->{$method}(