diff --git a/src/Composer/Command/InitCommand.php b/src/Composer/Command/InitCommand.php index c62e465c0..449825532 100644 --- a/src/Composer/Command/InitCommand.php +++ b/src/Composer/Command/InitCommand.php @@ -374,6 +374,9 @@ EOT $requirement['version'], $requirement['name'] )); + } else { + // check that the specified version/constraint exists before we proceed + $this->findBestVersionForPackage($input, $requirement['name'], $phpVersion, $preferredStability, $requirement['version']); } $result[] = $requirement['name'] . ' ' . $requirement['version']; @@ -631,13 +634,18 @@ EOT * @throws \InvalidArgumentException * @return string */ - private function findBestVersionForPackage(InputInterface $input, $name, $phpVersion, $preferredStability = 'stable') + private function findBestVersionForPackage(InputInterface $input, $name, $phpVersion, $preferredStability = 'stable', $requiredVersion = null) { // find the latest version allowed in this pool $versionSelector = new VersionSelector($this->getPool($input)); - $package = $versionSelector->findBestCandidate($name, null, $phpVersion, $preferredStability); + $package = $versionSelector->findBestCandidate($name, $requiredVersion, $phpVersion, $preferredStability); if (!$package) { + if ($requiredVersion && $versionSelector->findBestCandidate($name, null, $phpVersion, $preferredStability)) { + throw new \InvalidArgumentException(sprintf( + 'Could not find package %s in a version matching %s', $name, $requiredVersion + )); + } // Check whether the PHP version was the problem if ($phpVersion && $versionSelector->findBestCandidate($name)) { throw new \InvalidArgumentException(sprintf( @@ -655,7 +663,7 @@ EOT } throw new \InvalidArgumentException(sprintf( - 'Could not find package %s at any version for your minimum-stability (%s). Check the package spelling or your minimum-stability', + 'Could not find a matching version of package %s. Check the package spelling, your version constraint and that the package is available in a stability which matches your minimum-stability (%s).', $name, $this->getMinimumStability($input) )); diff --git a/src/Composer/Command/RemoveCommand.php b/src/Composer/Command/RemoveCommand.php index 46dc0b108..200340e9e 100644 --- a/src/Composer/Command/RemoveCommand.php +++ b/src/Composer/Command/RemoveCommand.php @@ -136,19 +136,11 @@ EOT ->setRunScripts(!$input->getOption('no-scripts')) ; - $exception = null; - try { - $status = $install->run(); - } catch (\Exception $exception) { - $status = 1; - } + $status = $install->run(); if ($status !== 0) { $io->writeError("\n".'Removal failed, reverting '.$file.' to its original content.'); file_put_contents($jsonFile->getPath(), $composerBackup); } - if ($exception) { - throw $exception; - } return $status; } diff --git a/src/Composer/Command/RequireCommand.php b/src/Composer/Command/RequireCommand.php index 5c6c14798..0bd7f6993 100644 --- a/src/Composer/Command/RequireCommand.php +++ b/src/Composer/Command/RequireCommand.php @@ -177,12 +177,7 @@ EOT ->setPreferLowest($input->getOption('prefer-lowest')) ; - $exception = null; - try { - $status = $install->run(); - } catch (\Exception $exception) { - $status = 1; - } + $status = $install->run(); if ($status !== 0) { if ($newlyCreated) { $io->writeError("\n".'Installation failed, deleting '.$file.'.'); @@ -192,9 +187,6 @@ EOT file_put_contents($json->getPath(), $composerBackup); } } - if ($exception) { - throw $exception; - } return $status; } diff --git a/src/Composer/DependencyResolver/SolverProblemsException.php b/src/Composer/DependencyResolver/SolverProblemsException.php index 6014012a4..142895697 100644 --- a/src/Composer/DependencyResolver/SolverProblemsException.php +++ b/src/Composer/DependencyResolver/SolverProblemsException.php @@ -43,7 +43,7 @@ class SolverProblemsException extends \RuntimeException } if (strpos($text, 'could not be found') || strpos($text, 'no matching package found')) { - $text .= "\nPotential causes:\n - A typo in the package name\n - The package is not available in a stable-enough version according to your minimum-stability setting\n see for more details.\n\nRead for further common problems."; + $text .= "\nPotential causes:\n - A typo in the package name\n - The package is not available in a stable-enough version according to your minimum-stability setting\n see for more details.\n - It's a private package and you forgot to add a custom repository to find it\n\nRead for further common problems."; } if ($hasExtensionProblems) { diff --git a/src/Composer/Installer.php b/src/Composer/Installer.php index 648212c51..f88f3a70c 100644 --- a/src/Composer/Installer.php +++ b/src/Composer/Installer.php @@ -195,6 +195,9 @@ class Installer } if ($this->runScripts) { + $devMode = (int) $this->devMode; + putenv("COMPOSER_DEV_MODE=$devMode"); + // dispatch pre event $eventName = $this->update ? ScriptEvents::PRE_UPDATE_CMD : ScriptEvents::PRE_INSTALL_CMD; $this->eventDispatcher->dispatchScript($eventName, $this->devMode); @@ -299,15 +302,6 @@ class Installer $this->autoloadGenerator->dump($this->config, $localRepo, $this->package, $this->installationManager, 'composer', $this->optimizeAutoloader); } - if ($this->runScripts) { - $devMode = (int) $this->devMode; - putenv("COMPOSER_DEV_MODE=$devMode"); - - // dispatch post event - $eventName = $this->update ? ScriptEvents::POST_UPDATE_CMD : ScriptEvents::POST_INSTALL_CMD; - $this->eventDispatcher->dispatchScript($eventName, $this->devMode); - } - if ($this->executeOperations) { // force binaries re-generation in case they are missing foreach ($localRepo->getPackages() as $package) { @@ -322,6 +316,12 @@ class Installer } } + if ($this->runScripts) { + // dispatch post event + $eventName = $this->update ? ScriptEvents::POST_UPDATE_CMD : ScriptEvents::POST_INSTALL_CMD; + $this->eventDispatcher->dispatchScript($eventName, $this->devMode); + } + // re-enable GC except on HHVM which triggers a warning here if (!defined('HHVM_VERSION')) { gc_enable(); diff --git a/src/Composer/Util/IniHelper.php b/src/Composer/Util/IniHelper.php index 0dc0529a5..de1065320 100644 --- a/src/Composer/Util/IniHelper.php +++ b/src/Composer/Util/IniHelper.php @@ -33,7 +33,9 @@ class IniHelper */ public static function getAll() { - if ($env = strval(getenv(self::ENV_ORIGINAL))) { + $env = getenv(self::ENV_ORIGINAL); + + if (false !== $env) { return explode(PATH_SEPARATOR, $env); } @@ -47,7 +49,7 @@ class IniHelper } /** - * Describes the location of the loaded php.ini file + * Describes the location of the loaded php.ini file(s) * * @return string */ @@ -56,9 +58,19 @@ class IniHelper $paths = self::getAll(); if (empty($paths[0])) { + array_shift($paths); + } + + $ini = array_shift($paths); + + if (empty($ini)) { return 'A php.ini file does not exist. You will have to create one.'; } - return 'The php.ini used by your command-line PHP is: '.$paths[0]; + if (!empty($paths)) { + return 'Your command-line PHP is using multiple ini files. Run `php --ini` to show them.'; + } + + return 'The php.ini used by your command-line PHP is: '.$ini; } } diff --git a/src/Composer/Util/RemoteFilesystem.php b/src/Composer/Util/RemoteFilesystem.php index 49b1f0c4b..b83639a82 100644 --- a/src/Composer/Util/RemoteFilesystem.php +++ b/src/Composer/Util/RemoteFilesystem.php @@ -224,7 +224,7 @@ class RemoteFilesystem $this->redirects = 1; // The first request counts. // capture username/password from URL if there is one - if (preg_match('{^https?://(.+):(.+)@([^/]+)}i', $fileUrl, $match)) { + if (preg_match('{^https?://([^:/]+):([^@/]+)@([^/]+)}i', $fileUrl, $match)) { $this->io->setAuthentication($originUrl, urldecode($match[1]), urldecode($match[2])); } diff --git a/tests/Composer/Test/DependencyResolver/SolverTest.php b/tests/Composer/Test/DependencyResolver/SolverTest.php index 9067c4abd..989c992f0 100644 --- a/tests/Composer/Test/DependencyResolver/SolverTest.php +++ b/tests/Composer/Test/DependencyResolver/SolverTest.php @@ -710,7 +710,8 @@ class SolverTest extends TestCase $msg .= "Potential causes:\n"; $msg .= " - A typo in the package name\n"; $msg .= " - The package is not available in a stable-enough version according to your minimum-stability setting\n"; - $msg .= " see for more details.\n\n"; + $msg .= " see for more details.\n"; + $msg .= " - It's a private package and you forgot to add a custom repository to find it\n\n"; $msg .= "Read for further common problems."; $this->assertEquals($msg, $e->getMessage()); } diff --git a/tests/Composer/Test/Fixtures/installer/broken-deps-do-not-replace.test b/tests/Composer/Test/Fixtures/installer/broken-deps-do-not-replace.test index fe6b00fff..db4ef23c0 100644 --- a/tests/Composer/Test/Fixtures/installer/broken-deps-do-not-replace.test +++ b/tests/Composer/Test/Fixtures/installer/broken-deps-do-not-replace.test @@ -34,6 +34,7 @@ Potential causes: - A typo in the package name - The package is not available in a stable-enough version according to your minimum-stability setting see for more details. + - It's a private package and you forgot to add a custom repository to find it Read for further common problems. diff --git a/tests/Composer/Test/Fixtures/installer/solver-problems.test b/tests/Composer/Test/Fixtures/installer/solver-problems.test index 605bd3cae..e0359a151 100644 --- a/tests/Composer/Test/Fixtures/installer/solver-problems.test +++ b/tests/Composer/Test/Fixtures/installer/solver-problems.test @@ -55,6 +55,7 @@ Potential causes: - A typo in the package name - The package is not available in a stable-enough version according to your minimum-stability setting see for more details. + - It's a private package and you forgot to add a custom repository to find it Read for further common problems. diff --git a/tests/Composer/Test/Util/IniHelperTest.php b/tests/Composer/Test/Util/IniHelperTest.php index b3a69fd3c..8fa8660c4 100644 --- a/tests/Composer/Test/Util/IniHelperTest.php +++ b/tests/Composer/Test/Util/IniHelperTest.php @@ -21,7 +21,18 @@ class IniHelperTest extends \PHPUnit_Framework_TestCase { public static $envOriginal; - public function testWithLoadedIni() + public function testWithNoIni() + { + $paths = array( + '', + ); + + $this->setEnv($paths); + $this->assertContains('does not exist', IniHelper::getMessage()); + $this->assertEquals($paths, IniHelper::getAll()); + } + + public function testWithLoadedIniOnly() { $paths = array( 'loaded.ini', @@ -32,7 +43,20 @@ class IniHelperTest extends \PHPUnit_Framework_TestCase $this->assertEquals($paths, IniHelper::getAll()); } - public function testWithoutLoadedIni() + public function testWithLoadedIniAndAdditional() + { + $paths = array( + 'loaded.ini', + 'one.ini', + 'two.ini', + ); + + $this->setEnv($paths); + $this->assertContains('multiple ini files', IniHelper::getMessage()); + $this->assertEquals($paths, IniHelper::getAll()); + } + + public function testWithoutLoadedIniAndAdditional() { $paths = array( '', @@ -41,7 +65,7 @@ class IniHelperTest extends \PHPUnit_Framework_TestCase ); $this->setEnv($paths); - $this->assertContains('does not exist', IniHelper::getMessage()); + $this->assertContains('multiple ini files', IniHelper::getMessage()); $this->assertEquals($paths, IniHelper::getAll()); }