From aa0ff14be51ab2a4803d14f13f625cac992b8375 Mon Sep 17 00:00:00 2001 From: Mateusz Heleniak Date: Fri, 31 Aug 2012 22:25:17 +0200 Subject: [PATCH 1/4] added --prefer-dist option --- src/Composer/Command/InstallCommand.php | 2 ++ src/Composer/Command/UpdateCommand.php | 2 ++ src/Composer/Downloader/DownloadManager.php | 19 ++++++++++++++++--- src/Composer/Installer.php | 17 +++++++++++++++++ 4 files changed, 37 insertions(+), 3 deletions(-) diff --git a/src/Composer/Command/InstallCommand.php b/src/Composer/Command/InstallCommand.php index 7039cfd10..a8e2fb568 100644 --- a/src/Composer/Command/InstallCommand.php +++ b/src/Composer/Command/InstallCommand.php @@ -31,6 +31,7 @@ class InstallCommand extends Command ->setDescription('Parses the composer.json file and downloads the needed dependencies.') ->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.'), @@ -59,6 +60,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')) ; diff --git a/src/Composer/Command/UpdateCommand.php b/src/Composer/Command/UpdateCommand.php index 9a5d4a7aa..86bf3e710 100644 --- a/src/Composer/Command/UpdateCommand.php +++ b/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) diff --git a/src/Composer/Downloader/DownloadManager.php b/src/Composer/Downloader/DownloadManager.php index 4b4bf3ec4..d88220db4 100644 --- a/src/Composer/Downloader/DownloadManager.php +++ b/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'); } diff --git a/src/Composer/Installer.php b/src/Composer/Installer.php index d14662518..a75a59bb9 100644 --- a/src/Composer/Installer.php +++ b/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; @@ -679,6 +683,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 * From 6489487245c2ca7b001031b783c72abb209cdc2f Mon Sep 17 00:00:00 2001 From: Mateusz Heleniak Date: Fri, 31 Aug 2012 23:27:36 +0200 Subject: [PATCH 2/4] compare references when using dists --- src/Composer/Installer.php | 7 ++++++- src/Composer/Package/Locker.php | 2 +- 2 files changed, 7 insertions(+), 2 deletions(-) diff --git a/src/Composer/Installer.php b/src/Composer/Installer.php index a75a59bb9..5de297f99 100644 --- a/src/Composer/Installer.php +++ b/src/Composer/Installer.php @@ -388,7 +388,12 @@ class Installer break; } } - if (isset($lockedReference) && $lockedReference !== $package->getSourceReference()) { + $sourceReference = $package->getSourceReference() ?: $package->getDistReference(); + if (isset($lockedReference) && $lockedReference !== $sourceReference) { + if (!$package->getSourceType() && $package->getDistType()) { + throw new \RuntimeException(sprintf('Dist reference (%s) does not match locked reference (%s)', $sourceReference, $lockedReference)); + } + // changing the source ref to update to will be handled in the operations loop below $operations[] = new UpdateOperation($package, clone $package); } diff --git a/src/Composer/Package/Locker.php b/src/Composer/Package/Locker.php index 9b3d2cd25..967af370e 100644 --- a/src/Composer/Package/Locker.php +++ b/src/Composer/Package/Locker.php @@ -232,7 +232,7 @@ class Locker $spec = array('package' => $name, 'version' => $version); if ($package->isDev() && !$alias) { - $spec['source-reference'] = $package->getSourceReference(); + $spec['source-reference'] = $package->getSourceReference() ?: $package->getDistReference(); if ('git' === $package->getSourceType() && $path = $this->installationManager->getInstallPath($package)) { $process = new ProcessExecutor(); if (0 === $process->execute('git log -n1 --pretty=%ct '.escapeshellarg($package->getSourceReference()), $output, $path)) { From be736c745eed6617ba61ad69cd3e7c2b2592408c Mon Sep 17 00:00:00 2001 From: Mateusz Heleniak Date: Fri, 31 Aug 2012 23:32:28 +0200 Subject: [PATCH 3/4] better exception message --- src/Composer/Installer.php | 2 +- 1 file changed, 1 insertion(+), 1 deletion(-) diff --git a/src/Composer/Installer.php b/src/Composer/Installer.php index 5de297f99..e61e3ee97 100644 --- a/src/Composer/Installer.php +++ b/src/Composer/Installer.php @@ -391,7 +391,7 @@ class Installer $sourceReference = $package->getSourceReference() ?: $package->getDistReference(); if (isset($lockedReference) && $lockedReference !== $sourceReference) { if (!$package->getSourceType() && $package->getDistType()) { - throw new \RuntimeException(sprintf('Dist reference (%s) does not match locked reference (%s)', $sourceReference, $lockedReference)); + throw new \RuntimeException(sprintf('Cannot install "%s" - dist reference ("%s") does not match locked reference ("%s")', $package->getName(), $sourceReference, $lockedReference)); } // changing the source ref to update to will be handled in the operations loop below From d0829adfee7be7c3b618820c4e12038b7bb12680 Mon Sep 17 00:00:00 2001 From: Mateusz Heleniak Date: Sat, 1 Sep 2012 00:30:48 +0200 Subject: [PATCH 4/4] added test case --- .../installer/install-dev-using-dist.test | 46 +++++++++++++++++++ 1 file changed, 46 insertions(+) create mode 100644 tests/Composer/Test/Fixtures/installer/install-dev-using-dist.test diff --git a/tests/Composer/Test/Fixtures/installer/install-dev-using-dist.test b/tests/Composer/Test/Fixtures/installer/install-dev-using-dist.test new file mode 100644 index 000000000..8517152a2 --- /dev/null +++ b/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)