diff --git a/src/Composer/Package/Version/VersionGuesser.php b/src/Composer/Package/Version/VersionGuesser.php index b42fb6274..d3f78e5c0 100644 --- a/src/Composer/Package/Version/VersionGuesser.php +++ b/src/Composer/Package/Version/VersionGuesser.php @@ -154,8 +154,17 @@ class VersionGuesser if ($isFeatureBranch) { $featureVersion = $version; $featurePrettyVersion = $prettyVersion; + + // try to find name of default branch from git info + $defaultBranch = null; + if (0 === $this->process->execute('git remote show origin', $output) || 0 === $this->process->execute('git remote show upstream', $output)) { + if (preg_match('{^ HEAD branch: (.+)$}m', $output, $match)) { + $defaultBranch = trim($match[1]); + } + } + // try to find the best (nearest) version branch to assume this feature's version - $result = $this->guessFeatureVersion($packageConfig, $version, $branches, 'git rev-list %candidate%..%branch%', $path); + $result = $this->guessFeatureVersion($packageConfig, $version, $branches, 'git rev-list %candidate%..%branch%', $path, $defaultBranch); $version = $result['version']; $prettyVersion = $result['pretty_version']; } @@ -222,7 +231,7 @@ class VersionGuesser $branches = array_keys($driver->getBranches()); // try to find the best (nearest) version branch to assume this feature's version - $result = $this->guessFeatureVersion($packageConfig, $version, $branches, 'hg log -r "not ancestors(\'%candidate%\') and ancestors(\'%branch%\')" --template "{node}\\n"', $path); + $result = $this->guessFeatureVersion($packageConfig, $version, $branches, 'hg log -r "not ancestors(\'%candidate%\') and ancestors(\'%branch%\')" --template "{node}\\n"', $path, 'default'); $result['commit'] = ''; $result['feature_version'] = $version; $result['feature_pretty_version'] = $version; @@ -231,7 +240,7 @@ class VersionGuesser } } - private function guessFeatureVersion(array $packageConfig, $version, array $branches, $scmCmdline, $path) + private function guessFeatureVersion(array $packageConfig, $version, array $branches, $scmCmdline, $path, $defaultBranch) { $prettyVersion = $version; @@ -248,14 +257,14 @@ class VersionGuesser $nonFeatureBranches = implode('|', $packageConfig['non-feature-branches']); } - foreach ($branches as $candidate) { - // return directly, if branch is configured to be non-feature branch - if ($candidate === $branch && preg_match('{^(' . $nonFeatureBranches . ')$}', $candidate)) { - break; - } + // return directly, if branch is configured to be non-feature branch + if (preg_match('{^(' . $nonFeatureBranches . ')$}', $branch)) { + return array('version' => $version, 'pretty_version' => $prettyVersion); + } + foreach ($branches as $candidate) { // do not compare against itself or other feature branches - if ($candidate === $branch || !preg_match('{^(' . $nonFeatureBranches . '|master|trunk|default|develop|\d+\..+)$}', $candidate, $match)) { + if ($candidate === $branch || !preg_match('{^(' . $nonFeatureBranches . ($defaultBranch ? '|'.preg_quote($defaultBranch) : '').'|master|trunk|default|develop|\d+\..+)$}', $candidate, $match)) { continue; } diff --git a/tests/Composer/Test/Package/Version/VersionGuesserTest.php b/tests/Composer/Test/Package/Version/VersionGuesserTest.php index 29619ea45..0b7486afd 100644 --- a/tests/Composer/Test/Package/Version/VersionGuesserTest.php +++ b/tests/Composer/Test/Package/Version/VersionGuesserTest.php @@ -135,6 +135,64 @@ class VersionGuesserTest extends TestCase $this->assertEquals($commitHash, $versionArray['commit']); } + public function testGuessVersionReadsAndRespectsDefaultBranchAsNonFeatureBranch() + { + $commitHash = '03a15d220da53c52eddd5f32ffca64a7b3801bea'; + $anotherCommitHash = '13a15d220da53c52eddd5f32ffca64a7b3801bea'; + + $executor = $this->getMockBuilder('\\Composer\\Util\\ProcessExecutor') + ->setMethods(array('execute')) + ->disableArgumentCloning() + ->disableOriginalConstructor() + ->getMock() + ; + + $self = $this; + + $executor + ->expects($this->at(0)) + ->method('execute') + ->willReturnCallback(function ($command, &$output) use ($self, $commitHash, $anotherCommitHash) { + $self->assertEquals('git branch --no-color --no-abbrev -v', $command); + $output = " arbitrary $commitHash Commit message\n* current $anotherCommitHash Another message\n"; + + return 0; + }) + ; + + $executor + ->expects($this->at(1)) + ->method('execute') + ->willReturnCallback(function ($command, &$output) use ($self) { + $self->assertEquals('git remote show origin', $command); + $output = " HEAD branch: arbitrary\r\n"; + + return 0; + }) + ; + + $executor + ->expects($this->at(2)) + ->method('execute') + ->willReturnCallback(function ($command, &$output, $path) use ($self, $anotherCommitHash) { + $self->assertEquals('git rev-list arbitrary..current', $command); + $output = "$anotherCommitHash\n"; + + return 0; + }) + ; + + $config = new Config; + $config->merge(array('repositories' => array('packagist' => false))); + $guesser = new VersionGuesser($config, $executor, new VersionParser()); + $versionArray = $guesser->guessVersion(array('version' => 'self.version'), 'dummy/path'); + + $this->assertEquals("dev-arbitrary", $versionArray['version']); + $this->assertEquals($anotherCommitHash, $versionArray['commit']); + $this->assertEquals("dev-current", $versionArray['feature_version']); + $this->assertEquals("dev-current", $versionArray['feature_pretty_version']); + } + public function testGuessVersionReadsAndRespectsNonFeatureBranchesConfigurationForArbitraryNaming() { $commitHash = '03a15d220da53c52eddd5f32ffca64a7b3801bea'; @@ -163,6 +221,17 @@ class VersionGuesserTest extends TestCase $executor ->expects($this->at(1)) ->method('execute') + ->willReturnCallback(function ($command, &$output) use ($self) { + $self->assertEquals('git remote show origin', $command); + $output = " HEAD branch: foo\r\n"; + + return 0; + }) + ; + + $executor + ->expects($this->at(2)) + ->method('execute') ->willReturnCallback(function ($command, &$output, $path) use ($self, $anotherCommitHash) { $self->assertEquals('git rev-list arbitrary..current', $command); $output = "$anotherCommitHash\n"; @@ -206,10 +275,19 @@ class VersionGuesserTest extends TestCase return 0; }) ; - $executor ->expects($this->at(1)) ->method('execute') + ->willReturnCallback(function ($command, &$output) use ($self) { + $self->assertEquals('git remote show origin', $command); + $output = " HEAD branch: foo\r\n"; + + return 0; + }) + ; + $executor + ->expects($this->at(2)) + ->method('execute') ->willReturnCallback(function ($command, &$output, $path) use ($self, $anotherCommitHash) { $self->assertEquals('git rev-list latest-testing..current', $command); $output = "$anotherCommitHash\n"; @@ -378,10 +456,19 @@ class VersionGuesserTest extends TestCase return 0; }) ; - $executor ->expects($this->at(1)) ->method('execute') + ->willReturnCallback(function ($command, &$output) use ($self) { + $self->assertEquals('git remote show origin', $command); + $output = " HEAD branch: foo\r\n"; + + return 0; + }) + ; + $executor + ->expects($this->at(2)) + ->method('execute') ->willReturnCallback(function ($command, &$output) use ($self) { $self->assertEquals('git describe --exact-match --tags', $command); $output = "v2.0.5-alpha2"; @@ -419,10 +506,19 @@ class VersionGuesserTest extends TestCase return 0; }) ; - $executor ->expects($this->at(1)) ->method('execute') + ->willReturnCallback(function ($command, &$output) use ($self) { + $self->assertEquals('git remote show origin', $command); + $output = " HEAD branch: foo\r\n"; + + return 0; + }) + ; + $executor + ->expects($this->at(2)) + ->method('execute') ->willReturnCallback(function ($command, &$output) use ($self) { $self->assertEquals('git describe --exact-match --tags', $command); $output = '1.0.0';