diff --git a/.travis.yml b/.travis.yml index fa96bc75b..6b0409547 100644 --- a/.travis.yml +++ b/.travis.yml @@ -5,6 +5,7 @@ php: - 5.3 - 5.4 - 5.5 + - 5.6 - hhvm - 5.6 diff --git a/doc/articles/aliases.md b/doc/articles/aliases.md index 26a9c46ab..9e8f3da89 100644 --- a/doc/articles/aliases.md +++ b/doc/articles/aliases.md @@ -7,7 +7,7 @@ ## Why aliases? When you are using a VCS repository, you will only get comparable versions for -branches that look like versions, such as `2.0`. For your `master` branch, you +branches that look like versions, such as `2.0` or `2.0.x`. For your `master` branch, you will get a `dev-master` version. For your `bugfix` branch, you will get a `dev-bugfix` version. diff --git a/doc/articles/troubleshooting.md b/doc/articles/troubleshooting.md index 2fc7bb487..fc9faa8d5 100644 --- a/doc/articles/troubleshooting.md +++ b/doc/articles/troubleshooting.md @@ -118,3 +118,22 @@ your GitHub account and to solve this issue you need to: 2. Add it to the configuration running `composer config -g github-oauth.github.com ` Now Composer should install/update without asking for authentication. + +## proc_open(): fork failed errors +If composer shows proc_open() fork failed on some commands: + + PHP Fatal error: Uncaught exception 'ErrorException' with message 'proc_open(): fork failed - Cannot allocate memory' in phar + +This could be happening because the VPS runs out of memory and has no Swap space enabled. + + [root@my_tiny_vps htdocs]# free -m + total used free shared buffers cached + Mem: 2048 357 1690 0 0 237 + -/+ buffers/cache: 119 1928 + Swap: 0 0 0 + +To enable the swap you can use for example: + + /bin/dd if=/dev/zero of=/var/swap.1 bs=1M count=1024 + /sbin/mkswap /var/swap.1 + /sbin/swapon /var/swap.1 diff --git a/src/Composer/Installer.php b/src/Composer/Installer.php index e1dbd496f..4e4502dfe 100644 --- a/src/Composer/Installer.php +++ b/src/Composer/Installer.php @@ -105,6 +105,11 @@ class Installer protected $verbose = false; protected $update = false; protected $runScripts = true; + /** + * Array of package names/globs flagged for update + * + * @var array|null + */ protected $updateWhitelist = null; protected $whitelistDependencies = false; @@ -785,9 +790,8 @@ class Installer } foreach ($this->updateWhitelist as $whiteListedPattern => $void) { - $cleanedWhiteListedPattern = str_replace('\\*', '.*', preg_quote($whiteListedPattern)); - - if (preg_match("{^".$cleanedWhiteListedPattern."$}i", $package->getName())) { + $patternRegexp = $this->packageNameToRegexp($whiteListedPattern); + if (preg_match($patternRegexp, $package->getName())) { return true; } } @@ -795,6 +799,19 @@ class Installer return false; } + /** + * Build a regexp from a package name, expanding * globs as required + * + * @param string $whiteListedPattern + * @return string + */ + private function packageNameToRegexp($whiteListedPattern) + { + $cleanedWhiteListedPattern = str_replace('\\*', '.*', preg_quote($whiteListedPattern)); + + return "{^" . $cleanedWhiteListedPattern . "$}i"; + } + private function extractPlatformRequirements($links) { $platformReqs = array(); @@ -844,11 +861,27 @@ class Installer $seen = array(); + $rootRequiredPackageNames = array_keys($rootRequires); + foreach ($this->updateWhitelist as $packageName => $void) { $packageQueue = new \SplQueue; $depPackages = $pool->whatProvides($packageName); - if (count($depPackages) == 0 && !in_array($packageName, $requiredPackageNames) && !in_array($packageName, array('nothing', 'lock'))) { + + $nameMatchesRequiredPackage = in_array($packageName, $requiredPackageNames, true); + + // check if the name is a glob pattern that did not match directly + if (!$nameMatchesRequiredPackage) { + $whitelistPatternRegexp = $this->packageNameToRegexp($packageName); + foreach ($rootRequiredPackageNames as $rootRequiredPackageName) { + if (preg_match($whitelistPatternRegexp, $rootRequiredPackageName)) { + $nameMatchesRequiredPackage = true; + break; + } + } + } + + if (count($depPackages) == 0 && !$nameMatchesRequiredPackage && !in_array($packageName, array('nothing', 'lock'))) { $this->io->write('Package "' . $packageName . '" listed for update is not installed. Ignoring.'); } diff --git a/src/Composer/Package/Loader/RootPackageLoader.php b/src/Composer/Package/Loader/RootPackageLoader.php index 2dc4e220d..f177f8eab 100644 --- a/src/Composer/Package/Loader/RootPackageLoader.php +++ b/src/Composer/Package/Loader/RootPackageLoader.php @@ -210,7 +210,7 @@ class RootPackageLoader extends ArrayLoader // find current branch and collect all branch names foreach ($this->process->splitLines($output) as $branch) { - if ($branch && preg_match('{^(?:\* ) *(\(no branch\)|\(detached from [a-f0-9]+\)|\S+) *([a-f0-9]+) .*$}', $branch, $match)) { + if ($branch && preg_match('{^(?:\* ) *(\(no branch\)|\(detached from \S+\)|\S+) *([a-f0-9]+) .*$}', $branch, $match)) { if ($match[1] === '(no branch)' || substr($match[1], 0, 10) === '(detached ') { $version = 'dev-'.$match[2]; $isFeatureBranch = true;