Эх сурвалжийг харах

Merge remote-tracking branch 'mheleniak/prefer_dist' and fix dists

Conflicts:
	src/Composer/Installer.php
	src/Composer/Package/Locker.php
Jordi Boggiano 12 жил өмнө
parent
commit
a9afa8bc1f

+ 2 - 0
src/Composer/Command/InstallCommand.php

@@ -31,6 +31,7 @@ class InstallCommand extends Command
             ->setDescription('Installs the project dependencies from the composer.lock file if present, or falls back on the composer.json.')
             ->setDefinition(array(
                 new InputOption('prefer-source', null, InputOption::VALUE_NONE, 'Forces installation from package sources when possible, including VCS information.'),
+                new InputOption('prefer-dist', null, InputOption::VALUE_NONE, 'Forces installation from package dist even for dev versions.'),
                 new InputOption('dry-run', null, InputOption::VALUE_NONE, 'Outputs the operations but will not execute anything (implicitly enables --verbose).'),
                 new InputOption('dev', null, InputOption::VALUE_NONE, 'Enables installation of dev-require packages.'),
                 new InputOption('no-custom-installers', null, InputOption::VALUE_NONE, 'Disables all custom installers.'),
@@ -60,6 +61,7 @@ EOT
             ->setDryRun($input->getOption('dry-run'))
             ->setVerbose($input->getOption('verbose'))
             ->setPreferSource($input->getOption('prefer-source'))
+            ->setPreferDist($input->getOption('prefer-dist'))
             ->setDevMode($input->getOption('dev'))
             ->setRunScripts(!$input->getOption('no-scripts'))
         ;

+ 2 - 0
src/Composer/Command/UpdateCommand.php

@@ -31,6 +31,7 @@ class UpdateCommand extends Command
             ->setDefinition(array(
                 new InputArgument('packages', InputArgument::IS_ARRAY | InputArgument::OPTIONAL, 'Packages that should be updated, if not provided all packages are.'),
                 new InputOption('prefer-source', null, InputOption::VALUE_NONE, 'Forces installation from package sources when possible, including VCS information.'),
+                new InputOption('prefer-dist', null, InputOption::VALUE_NONE, 'Forces installation from package dist even for dev versions.'),
                 new InputOption('dry-run', null, InputOption::VALUE_NONE, 'Outputs the operations but will not execute anything (implicitly enables --verbose).'),
                 new InputOption('dev', null, InputOption::VALUE_NONE, 'Enables installation of dev-require packages.'),
                 new InputOption('no-custom-installers', null, InputOption::VALUE_NONE, 'Disables all custom installers.'),
@@ -63,6 +64,7 @@ EOT
             ->setDryRun($input->getOption('dry-run'))
             ->setVerbose($input->getOption('verbose'))
             ->setPreferSource($input->getOption('prefer-source'))
+            ->setPreferDist($input->getOption('prefer-dist'))
             ->setDevMode($input->getOption('dev'))
             ->setRunScripts(!$input->getOption('no-scripts'))
             ->setUpdate(true)

+ 16 - 3
src/Composer/Downloader/DownloadManager.php

@@ -23,6 +23,7 @@ use Composer\Util\Filesystem;
  */
 class DownloadManager
 {
+    private $preferDist = false;
     private $preferSource = false;
     private $filesystem;
     private $downloaders  = array();
@@ -51,6 +52,18 @@ class DownloadManager
         return $this;
     }
 
+    /**
+     * Makes downloader prefer dist installation over the source.
+     *
+     * @param bool $preferDist prefer downloading from dist
+     */
+    public function setPreferDist($preferDist)
+    {
+        $this->preferDist = $preferDist;
+
+        return $this;
+    }
+
     /**
      * Sets installer downloader for a specific installation type.
      *
@@ -134,12 +147,12 @@ class DownloadManager
         $sourceType   = $package->getSourceType();
         $distType     = $package->getDistType();
 
-        if (!$package->isDev() && !($preferSource && $sourceType) && $distType) {
+        if ((!$package->isDev() || $this->preferDist) && !($preferSource && $sourceType) && $distType) {
             $package->setInstallationSource('dist');
         } elseif ($sourceType) {
             $package->setInstallationSource('source');
-        } elseif ($package->isDev()) {
-            throw new \InvalidArgumentException('Dev package '.$package.' must have a source specified');
+        } elseif ($package->isDev() && $distType) {
+            throw new \InvalidArgumentException('Dev package '.$package.' should have a source specified because for dev packages dist is used only with --prefer-dist option');
         } else {
             throw new \InvalidArgumentException('Package '.$package.' must have a source or dist specified');
         }

+ 22 - 3
src/Composer/Installer.php

@@ -91,6 +91,7 @@ class Installer
     protected $autoloadGenerator;
 
     protected $preferSource = false;
+    protected $preferDist = false;
     protected $devMode = false;
     protected $dryRun = false;
     protected $verbose = false;
@@ -148,6 +149,9 @@ class Installer
         if ($this->preferSource) {
             $this->downloadManager->setPreferSource(true);
         }
+        if ($this->preferDist) {
+            $this->downloadManager->setPreferDist(true);
+        }
 
         // create installed repo, this contains all local packages + platform packages (php & extensions)
         $installedRootPackage = clone $this->package;
@@ -387,15 +391,17 @@ class Installer
 
             // force update to locked version if it does not match the installed version
             if ($installFromLock) {
-                unset($lockedReference);
                 foreach ($lockedRepository->findPackages($package->getName()) as $lockedPackage) {
                     if (
                         $lockedPackage->isDev()
-                        && $lockedPackage->getSourceReference()
-                        && $lockedPackage->getSourceReference() !== $package->getSourceReference()
+                        && (
+                            ($lockedPackage->getSourceReference() && $lockedPackage->getSourceReference() !== $package->getSourceReference())
+                            || ($lockedPackage->getDistReference() && $lockedPackage->getDistReference() !== $package->getDistReference())
+                        )
                     ) {
                         $newPackage = clone $package;
                         $newPackage->setSourceReference($lockedPackage->getSourceReference());
+                        $newPackage->setDistReference($lockedPackage->getDistReference());
                         $operations[] = new UpdateOperation($package, $newPackage);
 
                         break;
@@ -671,6 +677,19 @@ class Installer
         return $this;
     }
 
+    /**
+     * prefer dist installation
+     *
+     * @param  boolean   $preferDist
+     * @return Installer
+     */
+    public function setPreferDist($preferDist = true)
+    {
+        $this->preferDist = (boolean) $preferDist;
+
+        return $this;
+    }
+
     /**
      * update packages
      *

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

@@ -284,8 +284,9 @@ class Locker
 
             if ($package->isDev()) {
                 if ('git' === $package->getSourceType() && $path = $this->installationManager->getInstallPath($package)) {
+                    $sourceRef = $package->getSourceReference() ?: $package->getDistReference();
                     $process = new ProcessExecutor();
-                    if (0 === $process->execute('git log -n1 --pretty=%ct '.escapeshellarg($package->getSourceReference()), $output, $path)) {
+                    if (0 === $process->execute('git log -n1 --pretty=%ct '.escapeshellarg($sourceRef), $output, $path)) {
                         $spec['time'] = trim($output);
                     }
                 }

+ 46 - 0
tests/Composer/Test/Fixtures/installer/install-dev-using-dist.test

@@ -0,0 +1,46 @@
+--TEST--
+Installs a dev package from lock using dist
+--COMPOSER--
+{
+    "repositories": [
+        {
+            "type": "package",
+            "package": [
+                {
+                    "name": "a/a",
+                    "version": "dev-master",
+                    "version_normalized": "9999999-dev",
+                    "dist": {
+                        "type": "zip",
+                        "url": "http://www.example.com/dist.zip",
+                        "reference": "459720ff3b74ee0c0d159277c6f2f5df89d8a4f6"
+                    }
+                }
+            ]
+        }
+    ],
+    "require": {
+        "a/a": "dev-master"
+    },
+    "minimum-stability": "dev"
+}
+--RUN--
+install --prefer-dist
+--EXPECT-LOCK--
+{
+    "packages": [
+        {
+            "version": "dev-master",
+            "package": "a/a",
+            "source-reference": "459720ff3b74ee0c0d159277c6f2f5df89d8a4f6"
+        }
+    ],
+    "packages-dev": null,
+    "aliases": [],
+    "minimum-stability": "dev",
+    "stability-flags": {
+        "a/a": 20
+    }
+}
+--EXPECT--
+Installing a/a (dev-master)