diff --git a/src/Composer/Package/Loader/RootPackageLoader.php b/src/Composer/Package/Loader/RootPackageLoader.php index ac3d8f433..536d461ad 100644 --- a/src/Composer/Package/Loader/RootPackageLoader.php +++ b/src/Composer/Package/Loader/RootPackageLoader.php @@ -110,6 +110,11 @@ class RootPackageLoader extends ArrayLoader } } + $defaultBranch = $this->versionGuesser->getDefaultBranchName($cwd ?: getcwd()); + if ($defaultBranch && $config['version'] === 'dev-'.$defaultBranch) { + $config['default-branch'] = true; + } + $realPackage = $package = parent::load($config, $class); if ($realPackage instanceof AliasPackage) { $realPackage = $package->getAliasOf(); diff --git a/src/Composer/Package/Version/VersionGuesser.php b/src/Composer/Package/Version/VersionGuesser.php index d3f78e5c0..8b886fc25 100644 --- a/src/Composer/Package/Version/VersionGuesser.php +++ b/src/Composer/Package/Version/VersionGuesser.php @@ -110,6 +110,35 @@ class VersionGuesser return $versionData; } + /** + * Tries to find name of default branch from VCS info + * + * @param string $path Path to guess into + */ + public function getDefaultBranchName($path) + { + GitUtil::cleanEnv(); + if (0 === $this->process->execute('git remote show origin', $output, $path) || 0 === $this->process->execute('git remote show upstream', $output, $path)) { + if (preg_match('{^ HEAD branch: (.+)$}m', $output, $match)) { + return trim($match[1]); + } + } + + if (is_dir($path.'/.git')) { + return 'master'; + } + + if (is_dir($path.'/.hg')) { + return 'default'; + } + + if (is_dir($path.'/.svn')) { + return 'trunk'; + } + + return null; + } + private function guessGitVersion(array $packageConfig, $path) { GitUtil::cleanEnv(); @@ -155,16 +184,8 @@ class VersionGuesser $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, $defaultBranch); + $result = $this->guessFeatureVersion($packageConfig, $version, $branches, 'git rev-list %candidate%..%branch%', $path); $version = $result['version']; $prettyVersion = $result['pretty_version']; } @@ -231,7 +252,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, 'default'); + $result = $this->guessFeatureVersion($packageConfig, $version, $branches, 'hg log -r "not ancestors(\'%candidate%\') and ancestors(\'%branch%\')" --template "{node}\\n"', $path); $result['commit'] = ''; $result['feature_version'] = $version; $result['feature_pretty_version'] = $version; @@ -240,7 +261,7 @@ class VersionGuesser } } - private function guessFeatureVersion(array $packageConfig, $version, array $branches, $scmCmdline, $path, $defaultBranch) + private function guessFeatureVersion(array $packageConfig, $version, array $branches, $scmCmdline, $path) { $prettyVersion = $version; @@ -262,6 +283,8 @@ class VersionGuesser return array('version' => $version, 'pretty_version' => $prettyVersion); } + $defaultBranch = $this->getDefaultBranchName($path); + foreach ($branches as $candidate) { // do not compare against itself or other feature branches if ($candidate === $branch || !preg_match('{^(' . $nonFeatureBranches . ($defaultBranch ? '|'.preg_quote($defaultBranch) : '').'|master|trunk|default|develop|\d+\..+)$}', $candidate, $match)) { diff --git a/tests/Composer/Test/Package/Loader/RootPackageLoaderTest.php b/tests/Composer/Test/Package/Loader/RootPackageLoaderTest.php index 93cde83f5..e5aebd1d0 100644 --- a/tests/Composer/Test/Package/Loader/RootPackageLoaderTest.php +++ b/tests/Composer/Test/Package/Loader/RootPackageLoaderTest.php @@ -105,6 +105,8 @@ class RootPackageLoaderTest extends TestCase 'pretty_version' => '3.0-dev', 'commit' => 'aabbccddee', )); + $versionGuesser->getDefaultBranchName(Argument::cetera()) + ->willReturn('main'); $config = new Config; $config->merge(array('repositories' => array('packagist' => false))); $loader = new RootPackageLoader($manager->reveal(), $config, null, $versionGuesser->reveal()); @@ -113,6 +115,28 @@ class RootPackageLoaderTest extends TestCase $this->assertEquals('3.0-dev', $package->getPrettyVersion()); } + public function testDefaultBranchIsSetForRootPackageInDefaultBranch() + { + // see #6845 + $manager = $this->prophesize('\\Composer\\Repository\\RepositoryManager'); + $versionGuesser = $this->prophesize('\\Composer\\Package\\Version\\VersionGuesser'); + $versionGuesser->guessVersion(Argument::cetera()) + ->willReturn(array( + 'name' => 'A', + 'version' => 'dev-main', + 'pretty_version' => 'dev-main', + 'commit' => 'aabbccddee', + )); + $versionGuesser->getDefaultBranchName(Argument::cetera()) + ->willReturn('main'); + $config = new Config; + $config->merge(array('repositories' => array('packagist' => false))); + $loader = new RootPackageLoader($manager->reveal(), $config, null, $versionGuesser->reveal()); + $package = $loader->load(array()); + + $this->assertTrue($package->isDefaultBranch()); + } + public function testFeatureBranchPrettyVersion() { if (!function_exists('proc_open')) { @@ -147,6 +171,17 @@ class RootPackageLoaderTest 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: master"; + + return 0; + }) + ; + + $executor + ->expects($this->at(2)) + ->method('execute') ->willReturnCallback(function ($command, &$output) use ($self) { $self->assertEquals('git rev-list master..latest-production', $command); $output = "";