diff --git a/src/Composer/Command/StatusCommand.php b/src/Composer/Command/StatusCommand.php index 780f70031..5d90b3105 100644 --- a/src/Composer/Command/StatusCommand.php +++ b/src/Composer/Command/StatusCommand.php @@ -92,7 +92,7 @@ EOT $vcsVersionChanges = []; $parser = new VersionParser; - $guesser = new VersionGuesser($composer->getConfig(), $composer->getLoop()->getProcessExecutor() ?? new ProcessExecutor($io), $parser); + $guesser = new VersionGuesser($composer->getConfig(), $composer->getLoop()->getProcessExecutor() ?? new ProcessExecutor($io), $parser, $io); $dumper = new ArrayDumper; // list packages diff --git a/src/Composer/Downloader/PathDownloader.php b/src/Composer/Downloader/PathDownloader.php index 8997f561e..f71ea2568 100644 --- a/src/Composer/Downloader/PathDownloader.php +++ b/src/Composer/Downloader/PathDownloader.php @@ -224,7 +224,7 @@ class PathDownloader extends FileDownloader implements VcsCapableDownloaderInter { $path = Filesystem::trimTrailingSlash($path); $parser = new VersionParser; - $guesser = new VersionGuesser($this->config, $this->process, $parser); + $guesser = new VersionGuesser($this->config, $this->process, $parser, $this->io); $dumper = new ArrayDumper; $packageConfig = $dumper->dump($package); diff --git a/src/Composer/Downloader/VcsDownloader.php b/src/Composer/Downloader/VcsDownloader.php index a1c5979d5..626bcb5c5 100644 --- a/src/Composer/Downloader/VcsDownloader.php +++ b/src/Composer/Downloader/VcsDownloader.php @@ -241,7 +241,7 @@ abstract class VcsDownloader implements DownloaderInterface, ChangeReportInterfa public function getVcsReference(PackageInterface $package, string $path): ?string { $parser = new VersionParser; - $guesser = new VersionGuesser($this->config, $this->process, $parser); + $guesser = new VersionGuesser($this->config, $this->process, $parser, $this->io); $dumper = new ArrayDumper; $packageConfig = $dumper->dump($package); diff --git a/src/Composer/Factory.php b/src/Composer/Factory.php index 3d6d58318..4389c487e 100644 --- a/src/Composer/Factory.php +++ b/src/Composer/Factory.php @@ -384,7 +384,7 @@ class Factory // load package $parser = new VersionParser; - $guesser = new VersionGuesser($config, $process, $parser); + $guesser = new VersionGuesser($config, $process, $parser, $io); $loader = $this->loadRootPackage($rm, $config, $parser, $guesser, $io); $package = $loader->load($localConfig, 'Composer\Package\RootPackage', $cwd); $composer->setPackage($package); diff --git a/src/Composer/Package/Loader/RootPackageLoader.php b/src/Composer/Package/Loader/RootPackageLoader.php index 81cb375fc..50807e506 100644 --- a/src/Composer/Package/Loader/RootPackageLoader.php +++ b/src/Composer/Package/Loader/RootPackageLoader.php @@ -60,7 +60,7 @@ class RootPackageLoader extends ArrayLoader $this->manager = $manager; $this->config = $config; - $this->versionGuesser = $versionGuesser ?: new VersionGuesser($config, new ProcessExecutor($io), $this->versionParser); + $this->versionGuesser = $versionGuesser ?: new VersionGuesser($config, new ProcessExecutor($io), $this->versionParser, $io); $this->io = $io; } diff --git a/src/Composer/Package/Version/VersionGuesser.php b/src/Composer/Package/Version/VersionGuesser.php index bfc16d524..8a0fe9c14 100644 --- a/src/Composer/Package/Version/VersionGuesser.php +++ b/src/Composer/Package/Version/VersionGuesser.php @@ -13,6 +13,7 @@ namespace Composer\Package\Version; use Composer\Config; +use Composer\IO\IOInterface; use Composer\Pcre\Preg; use Composer\Repository\Vcs\HgDriver; use Composer\IO\NullIO; @@ -50,11 +51,17 @@ class VersionGuesser */ private $versionParser; - public function __construct(Config $config, ProcessExecutor $process, SemverVersionParser $versionParser) + /** + * @var IOInterface|null + */ + private $io; + + public function __construct(Config $config, ProcessExecutor $process, SemverVersionParser $versionParser, ?IOInterface $io = null) { $this->config = $config; $this->process = $process; $this->versionParser = $versionParser; + $this->io = $io; } /** @@ -178,6 +185,7 @@ class VersionGuesser $prettyVersion = $result['pretty_version']; } } + GitUtil::checkForRepoOwnershipError($this->process->getErrorOutput(), $path, $this->io); if (!$version || $isDetached) { $result = $this->versionFromGitTags($path); diff --git a/src/Composer/Repository/PathRepository.php b/src/Composer/Repository/PathRepository.php index 1d9e4e7e0..4e99bd415 100644 --- a/src/Composer/Repository/PathRepository.php +++ b/src/Composer/Repository/PathRepository.php @@ -116,7 +116,7 @@ class PathRepository extends ArrayRepository implements ConfigurableRepositoryIn $this->loader = new ArrayLoader(null, true); $this->url = Platform::expandPath($repoConfig['url']); $this->process = $process ?? new ProcessExecutor($io); - $this->versionGuesser = new VersionGuesser($config, $this->process, new VersionParser()); + $this->versionGuesser = new VersionGuesser($config, $this->process, new VersionParser(), $io); $this->repoConfig = $repoConfig; $this->options = $repoConfig['options'] ?? []; if (!isset($this->options['relative'])) { diff --git a/src/Composer/Repository/Vcs/GitDriver.php b/src/Composer/Repository/Vcs/GitDriver.php index f3f7a91a6..57bc9b2ef 100644 --- a/src/Composer/Repository/Vcs/GitDriver.php +++ b/src/Composer/Repository/Vcs/GitDriver.php @@ -236,6 +236,7 @@ class GitDriver extends VcsDriver if ($process->execute('git tag', $output, $url) === 0) { return true; } + GitUtil::checkForRepoOwnershipError($process->getErrorOutput(), $url); } if (!$deep) { diff --git a/src/Composer/Util/Git.php b/src/Composer/Util/Git.php index 58df0ad57..f3369c8aa 100644 --- a/src/Composer/Util/Git.php +++ b/src/Composer/Util/Git.php @@ -43,6 +43,20 @@ class Git $this->filesystem = $fs; } + /** + * @param IOInterface|null $io If present, a warning is output there instead of throwing, so pass this in only for cases where this is a soft failure + */ + public static function checkForRepoOwnershipError(string $output, string $path, ?IOInterface $io = null): void + { + if (str_contains($output, 'fatal: detected dubious ownership')) { + $msg = 'The repository at "' . $path . '" does not have the correct ownership and git refuses to use it:' . PHP_EOL . PHP_EOL . $output; + if ($io === null) { + throw new \RuntimeException($msg); + } + $io->writeError(''.$msg.''); + } + } + public function setHttpDownloader(HttpDownloader $httpDownloader): void { $this->httpDownloader = $httpDownloader; @@ -317,6 +331,7 @@ class Git return true; } + self::checkForRepoOwnershipError($this->process->getErrorOutput(), $dir); // clean up directory and do a fresh clone into it $this->filesystem->removeDirectory($dir); @@ -384,6 +399,7 @@ class Git return true; } } + self::checkForRepoOwnershipError($this->process->getErrorOutput(), $dir); return false; }