Re-use mirror code from the git driver, refs #5384

main
Jordi Boggiano 8 years ago
parent 55e90093a4
commit 4998ee27b3

@ -48,15 +48,10 @@ class GitDownloader extends VcsDownloader implements DvcsDownloaderInterface
$flag = Platform::isWindows() ? '/D ' : '';
// --dissociate option is only available since git 2.3.0-rc0
if (version_compare($this->gitUtil->getVersion(), '2.3.0-rc0', '>=')) {
if (!file_exists($cachePath)) {
$this->io->writeError(sprintf(' Cloning to cache at %s', ProcessExecutor::escape($cachePath)));
$mirrorCommand = 'git clone --mirror %s %s';
$mirrorCommandCallable = function ($url) use ($cachePath, $mirrorCommand) {
return sprintf($mirrorCommand, ProcessExecutor::escape($url), ProcessExecutor::escape($cachePath));
};
$this->gitUtil->runCommand($mirrorCommandCallable, $url, $path, true);
}
$gitVersion = $this->gitUtil->getVersion();
if ($gitVersion && version_compare($gitVersion, '2.3.0-rc0', '>=')) {
$this->io->writeError(sprintf(' Cloning to cache at %s', ProcessExecutor::escape($cachePath)), true, IOInterface::DEBUG);
$this->gitUtil->syncMirror($url, $cachePath);
$cacheOptions = sprintf('--dissociate --reference %s ', ProcessExecutor::escape($cachePath));
}
$command = 'git clone --no-checkout %s %s '.$cacheOptions.'&& cd '.$flag.'%2$s && git remote add composer %1$s && git fetch composer';

@ -58,27 +58,8 @@ class GitDriver extends VcsDriver
}
$gitUtil = new GitUtil($this->io, $this->config, $this->process, $fs);
// update the repo if it is a valid git repository
if (is_dir($this->repoDir) && 0 === $this->process->execute('git rev-parse --git-dir', $output, $this->repoDir) && trim($output) === '.') {
try {
$commandCallable = function ($url) {
return sprintf('git remote set-url origin %s && git remote update --prune origin', ProcessExecutor::escape($url));
};
$gitUtil->runCommand($commandCallable, $this->url, $this->repoDir);
} catch (\Exception $e) {
$this->io->writeError('<error>Failed to update '.$this->url.', package information from this repository may be outdated ('.$e->getMessage().')</error>');
}
} else {
// clean up directory and do a fresh clone into it
$fs->removeDirectory($this->repoDir);
$repoDir = $this->repoDir;
$commandCallable = function ($url) use ($repoDir) {
return sprintf('git clone --mirror %s %s', ProcessExecutor::escape($url), ProcessExecutor::escape($repoDir));
};
$gitUtil->runCommand($commandCallable, $this->url, $this->repoDir, true);
if (!$gitUtil->syncMirror($this->url, $this->repoDir)) {
$this->io->writeError('<error>Failed to update '.$this->url.', package information from this repository may be outdated</error>');
}
$cacheUrl = $this->url;

@ -20,6 +20,8 @@ use Composer\IO\IOInterface;
*/
class Git
{
private static $version;
/** @var IOInterface */
protected $io;
/** @var Config */
@ -198,6 +200,34 @@ class Git
}
}
public function syncMirror($url, $dir)
{
// update the repo if it is a valid git repository
if (is_dir($dir) && 0 === $this->process->execute('git rev-parse --git-dir', $output, $dir) && trim($output) === '.') {
try {
$commandCallable = function ($url) {
return sprintf('git remote set-url origin %s && git remote update --prune origin', ProcessExecutor::escape($url));
};
$this->runCommand($commandCallable, $url, $dir);
} catch (\Exception $e) {
return false;
}
return true;
}
// clean up directory and do a fresh clone into it
$this->filesystem->removeDirectory($dir);
$commandCallable = function ($url) use ($dir) {
return sprintf('git clone --mirror %s %s', ProcessExecutor::escape($url), ProcessExecutor::escape($dir));
};
$this->runCommand($commandCallable, $url, $dir, true);
return true;
}
private function isAuthenticationFailure($url, &$match)
{
if (!preg_match('{(https?://)([^/]+)(.*)$}i', $url, $match)) {
@ -277,16 +307,18 @@ class Git
/**
* Retrieves the current git version.
*
* @return string
* The git version number.
* @return string|null The git version number.
*/
public function getVersion() {
public function getVersion()
{
if (isset(self::$version)) {
return self::$version;
}
if (0 !== $this->process->execute('git --version', $output)) {
throw new \RuntimeException(self::sanitizeUrl('Failed retrieve git version, git was not found, check that it is installed and in your PATH env.' . "\n\n" . $this->process->getErrorOutput()));
return;
}
if (preg_match('/^git version (.*)/', $output, $matches) !== 1) {
throw new \RuntimeException('git --version output seems to have changed, expected "git version x.y.z".');
if (preg_match('/^git version (\d+(?:\.\d+)+)/m', $output, $matches)) {
return self::$version = $matches[1];
}
return $matches[1];
}
}

@ -36,6 +36,11 @@ class GitDownloaderTest extends TestCase
if (is_dir($this->workingDir)) {
$this->fs->removeDirectory($this->workingDir);
}
// reset the static version cache
$refl = new \ReflectionProperty('Composer\Util\Git', 'version');
$refl->setAccessible(true);
$refl->setValue(null, null);
}
protected function setupConfig($config = null) {

Loading…
Cancel
Save