diff --git a/src/Composer/Package/Loader/RootPackageLoader.php b/src/Composer/Package/Loader/RootPackageLoader.php
index 8d44d0e03..fa96acaaa 100644
--- a/src/Composer/Package/Loader/RootPackageLoader.php
+++ b/src/Composer/Package/Loader/RootPackageLoader.php
@@ -71,8 +71,11 @@ class RootPackageLoader extends ArrayLoader
// override with env var if available
if (getenv('COMPOSER_ROOT_VERSION')) {
$version = getenv('COMPOSER_ROOT_VERSION');
+ $commit = null;
} else {
- $version = $this->versionGuesser->guessVersion($config, $cwd ?: getcwd());
+ $versionData = $this->versionGuesser->guessVersion($config, $cwd ?: getcwd());
+ $version = $versionData['version'];
+ $commit = $versionData['commit'];
}
if (!$version) {
@@ -81,6 +84,13 @@ class RootPackageLoader extends ArrayLoader
}
$config['version'] = $version;
+ if($commit){
+ $config['source'] = array(
+ 'type' => '',
+ 'url' => '',
+ 'reference' => $commit
+ );
+ }
}
$realPackage = $package = parent::load($config, $class);
diff --git a/src/Composer/Package/Version/VersionGuesser.php b/src/Composer/Package/Version/VersionGuesser.php
index b11bb9bc1..42642feee 100644
--- a/src/Composer/Package/Version/VersionGuesser.php
+++ b/src/Composer/Package/Version/VersionGuesser.php
@@ -56,20 +56,22 @@ class VersionGuesser
}
/**
- * @param array $packageConfig
- * @param string $path Path to guess into
+ * @param array $packageConfig
+ * @param string $path Path to guess into
+ *
+ * @return array versionData, 'version' and 'commit' keys
*/
public function guessVersion(array $packageConfig, $path)
{
if (function_exists('proc_open')) {
- $version = $this->guessGitVersion($packageConfig, $path);
- if (null !== $version) {
- return $version;
+ $versionData = $this->guessGitVersion($packageConfig, $path);
+ if (null !== $versionData) {
+ return $versionData;
}
- $version = $this->guessHgVersion($packageConfig, $path);
- if (null !== $version) {
- return $version;
+ $versionData = $this->guessHgVersion($packageConfig, $path);
+ if (null !== $versionData) {
+ return $versionData;
}
return $this->guessSvnVersion($packageConfig, $path);
@@ -79,34 +81,34 @@ class VersionGuesser
private function guessGitVersion(array $packageConfig, $path)
{
GitUtil::cleanEnv();
-
- // try to fetch current version from git tags
- if (0 === $this->process->execute('git describe --exact-match --tags', $output, $path)) {
- try {
- return $this->versionParser->normalize(trim($output));
- } catch (\Exception $e) {
- }
- }
+ $version = null;
+ $commit = null;
+ $version = $this->versionFromGitTags($path);
// try to fetch current version from git branch
if (0 === $this->process->execute('git branch --no-color --no-abbrev -v', $output, $path)) {
$branches = array();
$isFeatureBranch = false;
- $version = null;
// find current branch and collect all branch names
foreach ($this->process->splitLines($output) as $branch) {
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;
- } else {
- $version = $this->versionParser->normalizeBranch($match[1]);
- $isFeatureBranch = 0 === strpos($version, 'dev-');
- if ('9999999-dev' === $version) {
- $version = 'dev-'.$match[1];
+ if (!$version) {
+ if ($match[1] === '(no branch)' || substr($match[1], 0, 10) === '(detached ') {
+ $version = 'dev-' . $match[2];
+ $isFeatureBranch = true;
+ } else {
+ $version = $this->versionParser->normalizeBranch($match[1]);
+ $isFeatureBranch = 0 === strpos($version, 'dev-');
+ if ('9999999-dev' === $version) {
+ $version = 'dev-' . $match[1];
+ }
}
}
+
+ if ($match[2]) {
+ $commit = $match[2];
+ }
}
if ($branch && !preg_match('{^ *[^/]+/HEAD }', $branch)) {
@@ -116,15 +118,26 @@ class VersionGuesser
}
}
- if (!$isFeatureBranch) {
- return $version;
+ if ($isFeatureBranch) {
+ // try to find the best (nearest) version branch to assume this feature's version
+ $version = $this->guessFeatureVersion($packageConfig, $version, $branches, 'git rev-list %candidate%..%branch%', $path);
+ }
+ }
+
+ return array('version' => $version, 'commit' => $commit);
+ }
+
+ private function versionFromGitTags($path)
+ {
+ // try to fetch current version from git tags
+ if (0 === $this->process->execute('git describe --exact-match --tags', $output, $path)) {
+ try {
+ return $this->versionParser->normalize(trim($output));
+ } catch (\Exception $e) {
}
- // try to find the best (nearest) version branch to assume this feature's version
- $version = $this->guessFeatureVersion($packageConfig, $version, $branches, 'git rev-list %candidate%..%branch%', $path);
-
- return $version;
}
+ return null;
}
private function guessHgVersion(array $packageConfig, $path)
@@ -136,7 +149,7 @@ class VersionGuesser
$isFeatureBranch = 0 === strpos($version, 'dev-');
if ('9999999-dev' === $version) {
- $version = 'dev-'.$branch;
+ $version = 'dev-' . $branch;
}
if (!$isFeatureBranch) {
@@ -150,7 +163,7 @@ class VersionGuesser
// try to find the best (nearest) version branch to assume this feature's version
$version = $this->guessFeatureVersion($packageConfig, $version, $branches, 'hg log -r "not ancestors(\'%candidate%\') and ancestors(\'%branch%\')" --template "{node}\\n"', $path);
- return $version;
+ return array('version' => $version, 'commit' => '');
}
}
@@ -189,7 +202,7 @@ class VersionGuesser
$length = strlen($output);
$version = $this->versionParser->normalizeBranch($candidate);
if ('9999999-dev' === $version) {
- $version = 'dev-'.$match[1];
+ $version = 'dev-' . $match[1];
}
}
}
@@ -208,21 +221,23 @@ class VersionGuesser
$branchesPath = isset($packageConfig['branches-path']) ? preg_quote($packageConfig['branches-path'], '#') : 'branches';
$tagsPath = isset($packageConfig['tags-path']) ? preg_quote($packageConfig['tags-path'], '#') : 'tags';
- $urlPattern = '#.*/('.$trunkPath.'|('.$branchesPath.'|'. $tagsPath .')/(.*))#';
+ $urlPattern = '#.*/(' . $trunkPath . '|(' . $branchesPath . '|' . $tagsPath . ')/(.*))#';
if (preg_match($urlPattern, $output, $matches)) {
if (isset($matches[2]) && ($branchesPath === $matches[2] || $tagsPath === $matches[2])) {
// we are in a branches path
$version = $this->versionParser->normalizeBranch($matches[3]);
if ('9999999-dev' === $version) {
- $version = 'dev-'.$matches[3];
+ $version = 'dev-' . $matches[3];
}
- return $version;
+ return array('version' => $version, 'commit' => '');
}
- return $this->versionParser->normalize(trim($matches[1]));
+ $version = $this->versionParser->normalize(trim($matches[1]));
+ return array('version' => $version, 'commit' => '');
}
}
}
+
}
diff --git a/src/Composer/Repository/PathRepository.php b/src/Composer/Repository/PathRepository.php
index 60c90ff74..ff1eeb544 100644
--- a/src/Composer/Repository/PathRepository.php
+++ b/src/Composer/Repository/PathRepository.php
@@ -142,7 +142,8 @@ class PathRepository extends ArrayRepository implements ConfigurableRepositoryIn
$package['transport-options'] = $this->options;
if (!isset($package['version'])) {
- $package['version'] = $this->versionGuesser->guessVersion($package, $path) ?: 'dev-master';
+ $versionData = $this->versionGuesser->guessVersion($package, $path);
+ $package['version'] = $versionData['version'] ?: 'dev-master';
}
$output = '';
diff --git a/tests/Composer/Test/Package/Version/VersionGuesserTest.php b/tests/Composer/Test/Package/Version/VersionGuesserTest.php
index 84da8d2e9..55beac6b2 100644
--- a/tests/Composer/Test/Package/Version/VersionGuesserTest.php
+++ b/tests/Composer/Test/Package/Version/VersionGuesserTest.php
@@ -25,6 +25,47 @@ class VersionGuesserTest extends \PHPUnit_Framework_TestCase
}
}
+ public function testGuessVersionReturnsData()
+ {
+ $commitHash = '03a15d220da53c52eddd5f32ffca64a7b3801bea';
+ $anotherCommitHash = '03a15d220da53c52eddd5f32ffca64a7b3801bea';
+
+ $executor = $this->getMockBuilder('\\Composer\\Util\\ProcessExecutor')
+ ->setMethods(array('execute'))
+ ->disableArgumentCloning()
+ ->disableOriginalConstructor()
+ ->getMock()
+ ;
+
+ $executor
+ ->expects($this->at(0))
+ ->method('execute')
+ ->with('git describe --exact-match --tags')
+ ->willReturn(1)
+ ;
+
+ $self = $this;
+
+ $executor
+ ->expects($this->at(1))
+ ->method('execute')
+ ->willReturnCallback(function ($command, &$output) use ($self, $commitHash, $anotherCommitHash) {
+ $self->assertEquals('git branch --no-color --no-abbrev -v', $command);
+ $output = "* master $commitHash Commit message\n(no branch) $anotherCommitHash Commit message\n";
+
+ return 0;
+ })
+ ;
+
+ $config = new Config;
+ $config->merge(array('repositories' => array('packagist' => false)));
+ $guesser = new VersionGuesser($config, $executor, new VersionParser());
+ $versionArray = $guesser->guessVersion(array(), 'dummy/path');
+
+ $this->assertEquals("dev-master", $versionArray['version']);
+ $this->assertEquals($commitHash, $versionArray['commit']);
+ }
+
public function testDetachedHeadBecomesDevHash()
{
$commitHash = '03a15d220da53c52eddd5f32ffca64a7b3801bea';
@@ -59,9 +100,9 @@ class VersionGuesserTest extends \PHPUnit_Framework_TestCase
$config = new Config;
$config->merge(array('repositories' => array('packagist' => false)));
$guesser = new VersionGuesser($config, $executor, new VersionParser());
- $version = $guesser->guessVersion(array(), 'dummy/path');
+ $versionData = $guesser->guessVersion(array(), 'dummy/path');
- $this->assertEquals("dev-$commitHash", $version);
+ $this->assertEquals("dev-$commitHash", $versionData['version']);
}
public function testTagBecomesVersion()
@@ -89,9 +130,9 @@ class VersionGuesserTest extends \PHPUnit_Framework_TestCase
$config = new Config;
$config->merge(array('repositories' => array('packagist' => false)));
$guesser = new VersionGuesser($config, $executor, new VersionParser());
- $version = $guesser->guessVersion(array(), 'dummy/path');
+ $versionData = $guesser->guessVersion(array(), 'dummy/path');
- $this->assertEquals("2.0.5.0-alpha2", $version);
+ $this->assertEquals("2.0.5.0-alpha2", $versionData['version']);
}
public function testInvalidTagBecomesVersion()
@@ -130,8 +171,8 @@ class VersionGuesserTest extends \PHPUnit_Framework_TestCase
$config = new Config;
$config->merge(array('repositories' => array('packagist' => false)));
$guesser = new VersionGuesser($config, $executor, new VersionParser());
- $version = $guesser->guessVersion(array(), 'dummy/path');
+ $versionData = $guesser->guessVersion(array(), 'dummy/path');
- $this->assertEquals("dev-foo", $version);
+ $this->assertEquals("dev-foo", $versionData['version']);
}
}