diff --git a/src/Composer/Package/Version/VersionGuesser.php b/src/Composer/Package/Version/VersionGuesser.php index 1c2f99247..eaeca6dc5 100644 --- a/src/Composer/Package/Version/VersionGuesser.php +++ b/src/Composer/Package/Version/VersionGuesser.php @@ -137,7 +137,7 @@ class VersionGuesser } else { $version = $this->versionParser->normalizeBranch($match[1]); $prettyVersion = 'dev-' . $match[1]; - $isFeatureBranch = 0 === strpos($version, 'dev-'); + $isFeatureBranch = $this->isFeatureBranch($packageConfig, $match[1]); } if ($match[2]) { @@ -245,19 +245,18 @@ class VersionGuesser $branch = preg_replace('{^dev-}', '', $version); $length = PHP_INT_MAX; - $nonFeatureBranches = ''; - if (!empty($packageConfig['non-feature-branches'])) { - $nonFeatureBranches = implode('|', $packageConfig['non-feature-branches']); - } - // return directly, if branch is configured to be non-feature branch - if (preg_match('{^(' . $nonFeatureBranches . ')$}', $branch)) { + if (!$this->isFeatureBranch($packageConfig, $branch)) { return array('version' => $version, 'pretty_version' => $prettyVersion); } + // sort numeric branches below named ones, to make sure if the branch has the same distance from main and 1.10 and 1.9 for example, main is picked + // and sort using natural sort so that 1.10 will appear before 1.9 + rsort($branches, SORT_NATURAL); + foreach ($branches as $candidate) { // do not compare against itself or other feature branches - if ($candidate === $branch || !preg_match('{^(' . $nonFeatureBranches . '|master|main|latest|next|current|support|tip|trunk|default|develop|\d+\..+)$}', $candidate, $match)) { + if ($candidate === $branch || $this->isFeatureBranch($packageConfig, $candidate)) { continue; } @@ -269,7 +268,7 @@ class VersionGuesser if (strlen($output) < $length) { $length = strlen($output); $version = $this->versionParser->normalizeBranch($candidate); - $prettyVersion = 'dev-' . $match[1]; + $prettyVersion = 'dev-' . $candidate; } } } @@ -277,6 +276,16 @@ class VersionGuesser return array('version' => $version, 'pretty_version' => $prettyVersion); } + private function isFeatureBranch(array $packageConfig, $branchName) + { + $nonFeatureBranches = ''; + if (!empty($packageConfig['non-feature-branches'])) { + $nonFeatureBranches = implode('|', $packageConfig['non-feature-branches']); + } + + return !preg_match('{^(' . $nonFeatureBranches . '|master|main|latest|next|current|support|tip|trunk|default|develop|\d+\..+)$}', $branchName, $match); + } + private function guessFossilVersion(array $packageConfig, $path) { $version = null; diff --git a/tests/Composer/Test/Package/Version/VersionGuesserTest.php b/tests/Composer/Test/Package/Version/VersionGuesserTest.php index cedd697ce..2d6209673 100644 --- a/tests/Composer/Test/Package/Version/VersionGuesserTest.php +++ b/tests/Composer/Test/Package/Version/VersionGuesserTest.php @@ -189,7 +189,7 @@ class VersionGuesserTest extends TestCase ->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"; + $output = " arbitrary $commitHash Commit message\n* feature $anotherCommitHash Another message\n"; return 0; }) @@ -199,7 +199,7 @@ class VersionGuesserTest extends TestCase ->expects($this->at(1)) ->method('execute') ->willReturnCallback(function ($command, &$output, $path) use ($self, $anotherCommitHash) { - $self->assertEquals('git rev-list arbitrary..current', $command); + $self->assertEquals('git rev-list arbitrary..feature', $command); $output = "$anotherCommitHash\n"; return 0; @@ -213,8 +213,8 @@ class VersionGuesserTest extends TestCase $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']); + $this->assertEquals("dev-feature", $versionArray['feature_version']); + $this->assertEquals("dev-feature", $versionArray['feature_pretty_version']); } public function testGuessVersionReadsAndRespectsNonFeatureBranchesConfigurationForArbitraryNamingRegex() @@ -236,7 +236,7 @@ class VersionGuesserTest extends TestCase ->method('execute') ->willReturnCallback(function ($command, &$output) use ($self, $commitHash, $anotherCommitHash) { $self->assertEquals('git branch --no-color --no-abbrev -v', $command); - $output = " latest-testing $commitHash Commit message\n* current $anotherCommitHash Another message\n"; + $output = " latest-testing $commitHash Commit message\n* feature $anotherCommitHash Another message\n"; return 0; }) @@ -245,7 +245,7 @@ class VersionGuesserTest extends TestCase ->expects($this->at(1)) ->method('execute') ->willReturnCallback(function ($command, &$output, $path) use ($self, $anotherCommitHash) { - $self->assertEquals('git rev-list latest-testing..current', $command); + $self->assertEquals('git rev-list latest-testing..feature', $command); $output = "$anotherCommitHash\n"; return 0; @@ -259,8 +259,8 @@ class VersionGuesserTest extends TestCase $this->assertEquals("dev-latest-testing", $versionArray['version']); $this->assertEquals($anotherCommitHash, $versionArray['commit']); - $this->assertEquals("dev-current", $versionArray['feature_version']); - $this->assertEquals("dev-current", $versionArray['feature_pretty_version']); + $this->assertEquals("dev-feature", $versionArray['feature_version']); + $this->assertEquals("dev-feature", $versionArray['feature_pretty_version']); } public function testGuessVersionReadsAndRespectsNonFeatureBranchesConfigurationForArbitraryNamingWhenOnNonFeatureBranch()