1
0
Fork 0

#4828 Using version guesser to pull out the commit has for git repositories. The return value is now an array with version and commit values.

pull/4945/head
Sash 2016-02-22 21:13:39 +00:00
parent 4c0e163977
commit f6899e5c38
4 changed files with 111 additions and 45 deletions

View File

@ -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);

View File

@ -58,18 +58,20 @@ class VersionGuesser
/**
* @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,24 +81,19 @@ 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 (!$version) {
if ($match[1] === '(no branch)' || substr($match[1], 0, 10) === '(detached ') {
$version = 'dev-' . $match[2];
$isFeatureBranch = true;
@ -109,6 +106,11 @@ class VersionGuesser
}
}
if ($match[2]) {
$commit = $match[2];
}
}
if ($branch && !preg_match('{^ *[^/]+/HEAD }', $branch)) {
if (preg_match('{^(?:\* )? *(\S+) *([a-f0-9]+) .*$}', $branch, $match)) {
$branches[] = $match[1];
@ -116,17 +118,28 @@ 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 $version;
}
}
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) {
}
}
return null;
}
private function guessHgVersion(array $packageConfig, $path)
{
// try to fetch current version from hg branch
@ -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' => '');
}
}
@ -218,11 +231,13 @@ class VersionGuesser
$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' => '');
}
}
}
}

View File

@ -129,7 +129,7 @@ class PathRepository extends ArrayRepository implements ConfigurableRepositoryIn
);
if (!isset($package['version'])) {
$package['version'] = $this->versionGuesser->guessVersion($package, $path) ?: 'dev-master';
$package['version'] = $this->versionGuesser->guessVersion($package, $path)['version'] ?: 'dev-master';
}
$output = '';

View File

@ -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,7 +100,7 @@ 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');
$version = $guesser->guessVersion(array(), 'dummy/path')['version'];
$this->assertEquals("dev-$commitHash", $version);
}
@ -89,7 +130,7 @@ 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');
$version = $guesser->guessVersion(array(), 'dummy/path')['version'];
$this->assertEquals("2.0.5.0-alpha2", $version);
}
@ -130,7 +171,7 @@ 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');
$version = $guesser->guessVersion(array(), 'dummy/path')['version'];
$this->assertEquals("dev-foo", $version);
}