diff --git a/doc/03-cli.md b/doc/03-cli.md index 0768c1892..d5064c5d9 100644 --- a/doc/03-cli.md +++ b/doc/03-cli.md @@ -140,7 +140,7 @@ php composer.phar update vendor/package vendor/package2 You can also use wildcards to update a bunch of packages at once: ```sh -php composer.phar update vendor/* +php composer.phar update "vendor/*" ``` ### Options diff --git a/src/Composer/Command/ConfigCommand.php b/src/Composer/Command/ConfigCommand.php index 49cb138d8..89ba495cf 100644 --- a/src/Composer/Command/ConfigCommand.php +++ b/src/Composer/Command/ConfigCommand.php @@ -21,6 +21,7 @@ use Symfony\Component\Console\Output\OutputInterface; use Composer\Config; use Composer\Config\JsonConfigSource; use Composer\Factory; +use Composer\IO\IOInterface; use Composer\Json\JsonFile; use Composer\Semver\VersionParser; use Composer\Package\BasePackage; @@ -284,7 +285,7 @@ EOT $value = json_encode($value); } - $this->getIO()->write($value); + $this->getIO()->write($value, true, IOInterface::QUIET); return 0; } @@ -710,9 +711,9 @@ EOT } if (is_string($rawVal) && $rawVal != $value) { - $io->write('[' . $k . $key . '] ' . $rawVal . ' (' . $value . ')'); + $io->write('[' . $k . $key . '] ' . $rawVal . ' (' . $value . ')', true, IOInterface::QUIET); } else { - $io->write('[' . $k . $key . '] ' . $value . ''); + $io->write('[' . $k . $key . '] ' . $value . '', true, IOInterface::QUIET); } } } diff --git a/src/Composer/Command/RequireCommand.php b/src/Composer/Command/RequireCommand.php index 1f29751b9..b347de094 100644 --- a/src/Composer/Command/RequireCommand.php +++ b/src/Composer/Command/RequireCommand.php @@ -195,7 +195,7 @@ EOT $status = $install->run(); if ($status !== 0) { - $this->revertComposerFile(); + $this->revertComposerFile(false); } return $status; @@ -226,7 +226,7 @@ EOT return; } - public function revertComposerFile() + public function revertComposerFile($hardExit = true) { $io = $this->getIO(); @@ -238,6 +238,8 @@ EOT file_put_contents($this->json->getPath(), $this->composerBackup); } - exit(1); + if ($hardExit) { + exit(1); + } } } diff --git a/src/Composer/DependencyResolver/Problem.php b/src/Composer/DependencyResolver/Problem.php index de24b0991..073f64e2d 100644 --- a/src/Composer/DependencyResolver/Problem.php +++ b/src/Composer/DependencyResolver/Problem.php @@ -106,7 +106,7 @@ class Problem $msg = "\n - This package requires ".$job['packageName'].$this->constraintToText($job['constraint']).' but '; - if (defined('HHVM_VERSION')) { + if (defined('HHVM_VERSION') || count($available)) { return $msg . 'your HHVM version does not satisfy that requirement.'; } diff --git a/src/Composer/DependencyResolver/Rule.php b/src/Composer/DependencyResolver/Rule.php index 4760b8964..82c9c499c 100644 --- a/src/Composer/DependencyResolver/Rule.php +++ b/src/Composer/DependencyResolver/Rule.php @@ -175,13 +175,18 @@ abstract class Rule return $text . ' -> your HHVM version does not satisfy that requirement.'; } - if ($targetName === 'hhvm') { - return $text . ' -> you are running this with PHP and not HHVM.'; - } - $packages = $pool->whatProvides($targetName); $package = count($packages) ? current($packages) : phpversion(); + if ($targetName === 'hhvm') { + if ($package instanceof CompletePackage) { + return $text . ' -> your HHVM version ('.$package->getPrettyVersion().') does not satisfy that requirement.'; + } else { + return $text . ' -> you are running this with PHP and not HHVM.'; + } + } + + if (!($package instanceof CompletePackage)) { return $text . ' -> your PHP version ('.phpversion().') does not satisfy that requirement.'; } diff --git a/src/Composer/Installer/BinaryInstaller.php b/src/Composer/Installer/BinaryInstaller.php index a14755bf1..0a7b97149 100644 --- a/src/Composer/Installer/BinaryInstaller.php +++ b/src/Composer/Installer/BinaryInstaller.php @@ -196,9 +196,13 @@ class BinaryInstaller dir=\$(cd "\${0%[/\\\\]*}" > /dev/null; cd $binDir && pwd) -if [ -d /proc/cygdrive ] && [[ \$(which php) == \$(readlink -n /proc/cygdrive)/* ]]; then - # We are in Cygwin using Windows php, so the path must be translated - dir=\$(cygpath -m "\$dir"); +if [ -d /proc/cygdrive ]; then + case \$(which php) in + \$(readlink -n /proc/cygdrive)/*) + # We are in Cygwin using Windows php, so the path must be translated + dir=\$(cygpath -m "\$dir"); + ;; + esac fi "\${dir}/$binFile" "\$@" diff --git a/src/Composer/Package/Dumper/ArrayDumper.php b/src/Composer/Package/Dumper/ArrayDumper.php index 6593143d5..b1e20dbf5 100644 --- a/src/Composer/Package/Dumper/ArrayDumper.php +++ b/src/Composer/Package/Dumper/ArrayDumper.php @@ -48,7 +48,9 @@ class ArrayDumper if ($package->getSourceType()) { $data['source']['type'] = $package->getSourceType(); $data['source']['url'] = $package->getSourceUrl(); - $data['source']['reference'] = $package->getSourceReference(); + if (null !== ($value = $package->getSourceReference())) { + $data['source']['reference'] = $value; + } if ($mirrors = $package->getSourceMirrors()) { $data['source']['mirrors'] = $mirrors; } @@ -57,8 +59,12 @@ class ArrayDumper if ($package->getDistType()) { $data['dist']['type'] = $package->getDistType(); $data['dist']['url'] = $package->getDistUrl(); - $data['dist']['reference'] = $package->getDistReference(); - $data['dist']['shasum'] = $package->getDistSha1Checksum(); + if (null !== ($value = $package->getDistReference())) { + $data['dist']['reference'] = $value; + } + if (null !== ($value = $package->getDistSha1Checksum())) { + $data['dist']['shasum'] = $value; + } if ($mirrors = $package->getDistMirrors()) { $data['dist']['mirrors'] = $mirrors; } diff --git a/src/Composer/Package/Loader/ArrayLoader.php b/src/Composer/Package/Loader/ArrayLoader.php index 303cc3c13..c269afa22 100644 --- a/src/Composer/Package/Loader/ArrayLoader.php +++ b/src/Composer/Package/Loader/ArrayLoader.php @@ -85,7 +85,7 @@ class ArrayLoader implements LoaderInterface } $package->setSourceType($config['source']['type']); $package->setSourceUrl($config['source']['url']); - $package->setSourceReference($config['source']['reference']); + $package->setSourceReference(isset($config['source']['reference']) ? $config['source']['reference'] : null); if (isset($config['source']['mirrors'])) { $package->setSourceMirrors($config['source']['mirrors']); } diff --git a/src/Composer/Repository/PlatformRepository.php b/src/Composer/Repository/PlatformRepository.php index 221f2eb97..50cbb4649 100644 --- a/src/Composer/Repository/PlatformRepository.php +++ b/src/Composer/Repository/PlatformRepository.php @@ -16,15 +16,18 @@ use Composer\Package\CompletePackage; use Composer\Package\PackageInterface; use Composer\Package\Version\VersionParser; use Composer\Plugin\PluginInterface; +use Composer\Util\ProcessExecutor; use Composer\Util\Silencer; +use Composer\Util\Platform; use Composer\XdebugHandler\XdebugHandler; +use Symfony\Component\Process\ExecutableFinder; /** * @author Jordi Boggiano */ class PlatformRepository extends ArrayRepository { - const PLATFORM_PACKAGE_REGEX = '{^(?:php(?:-64bit|-ipv6|-zts|-debug)?|hhvm|(?:ext|lib)-[a-z0-9](?:[_.-]?[a-z0-9]+)*)$}iD'; + const PLATFORM_PACKAGE_REGEX = '{^(?:php(?:-64bit|-ipv6|-zts|-debug)?|hhvm|(?:ext|lib)-[a-z0-9](?:[_.-]?[a-z0-9]+)*|composer-plugin-api)$}iD'; private $versionParser; @@ -37,8 +40,11 @@ class PlatformRepository extends ArrayRepository */ private $overrides = array(); - public function __construct(array $packages = array(), array $overrides = array()) + private $process; + + public function __construct(array $packages = array(), array $overrides = array(), ProcessExecutor $process = null) { + $this->process = $process === null ? (new ProcessExecutor()) : $process; foreach ($overrides as $name => $version) { $this->overrides[strtolower($name)] = array('name' => $name, 'version' => $version); } @@ -220,12 +226,27 @@ class PlatformRepository extends ArrayRepository $this->addPackage($lib); } - if (defined('HHVM_VERSION')) { + $hhvmVersion = defined('HHVM_VERSION') ? HHVM_VERSION : null; + if ($hhvmVersion === null && !Platform::isWindows()) { + $finder = new ExecutableFinder(); + $hhvm = $finder->find('hhvm'); + if ($hhvm !== null) { + $exitCode = $this->process->execute( + ProcessExecutor::escape($hhvm). + ' --php -d hhvm.jit=0 -r "echo HHVM_VERSION;" 2>/dev/null', + $hhvmVersion + ); + if ($exitCode !== 0) { + $hhvmVersion = null; + } + } + } + if ($hhvmVersion) { try { - $prettyVersion = HHVM_VERSION; + $prettyVersion = $hhvmVersion; $version = $this->versionParser->normalize($prettyVersion); } catch (\UnexpectedValueException $e) { - $prettyVersion = preg_replace('#^([^~+-]+).*$#', '$1', HHVM_VERSION); + $prettyVersion = preg_replace('#^([^~+-]+).*$#', '$1', $hhvmVersion); $version = $this->versionParser->normalize($prettyVersion); } diff --git a/tests/Composer/Test/Repository/PlatformRepositoryTest.php b/tests/Composer/Test/Repository/PlatformRepositoryTest.php new file mode 100644 index 000000000..aa51a2fc6 --- /dev/null +++ b/tests/Composer/Test/Repository/PlatformRepositoryTest.php @@ -0,0 +1,70 @@ + + * Jordi Boggiano + * + * For the full copyright and license information, please view the LICENSE + * file that was distributed with this source code. + */ + +namespace Composer\Test\Repository; + +use Composer\Repository\PlatformRepository; +use Composer\Test\TestCase; +use Composer\Util\Platform; +use Symfony\Component\Process\ExecutableFinder; + +class PlatformRepositoryTest extends TestCase { + public function testHHVMVersionWhenExecutingInHHVM() { + if (!defined('HHVM_VERSION_ID')) { + $this->markTestSkipped('Not running with HHVM'); + return; + } + $repository = new PlatformRepository(); + $package = $repository->findPackage('hhvm', '*'); + $this->assertNotNull($package, 'failed to find HHVM package'); + $this->assertSame( + sprintf('%d.%d.%d', + HHVM_VERSION_ID / 10000, + (HHVM_VERSION_ID / 100) % 100, + HHVM_VERSION_ID % 100 + ), + $package->getPrettyVersion() + ); + } + + public function testHHVMVersionWhenExecutingInPHP() { + if (defined('HHVM_VERSION_ID')) { + $this->markTestSkipped('Running with HHVM'); + return; + } + if (PHP_VERSION_ID < 50400) { + $this->markTestSkipped('Test only works on PHP 5.4+'); + return; + } + if (Platform::isWindows()) { + $this->markTestSkipped('Test does not run on Windows'); + return; + } + $finder = new ExecutableFinder(); + $hhvm = $finder->find('hhvm'); + if ($hhvm === null) { + $this->markTestSkipped('HHVM is not installed'); + } + $process = $this->getMockBuilder('Composer\Util\ProcessExecutor')->getMock(); + $process->expects($this->once())->method('execute')->will($this->returnCallback( + function($command, &$out) { + $this->assertContains('HHVM_VERSION', $command); + $out = '4.0.1-dev'; + return 0; + } + )); + $repository = new PlatformRepository(array(), array(), $process); + $package = $repository->findPackage('hhvm', '*'); + $this->assertNotNull($package, 'failed to find HHVM package'); + $this->assertSame('4.0.1.0-dev', $package->getVersion()); + } +}