1
0
Fork 0

Merge branch '1.9'

pull/8458/head
Jordi Boggiano 2019-11-23 12:25:23 +01:00
commit 67e170eaa8
No known key found for this signature in database
GPG Key ID: 7BBD42C429EC80BC
5 changed files with 152 additions and 5 deletions

View File

@ -143,7 +143,7 @@ class GitDriver extends VcsDriver
public function getChangeDate($identifier)
{
$this->process->execute(sprintf(
'git log -1 --format=%%at %s',
'git -c log.showSignature=false log -1 --format=%%at %s',
ProcessExecutor::escape($identifier)
), $output, $this->repoDir);

View File

@ -85,8 +85,10 @@ class Git
}
// failed to checkout, first check git accessibility
if (!$this->io->hasAuthentication($match[1]) && !$this->io->isInteractive()) {
$this->throwException('Failed to clone ' . $url . ' via ' . implode(', ', $protocols) . ' protocols, aborting.' . "\n\n" . implode("\n", $messages), $url);
}
}
// if we have a private github url and the ssh protocol is disabled then we skip it and directly fallback to https
$bypassSshForGitHub = preg_match('{^git@' . self::getGitHubDomainsRegex($this->config) . ':(.+?)\.git$}i', $url) && !in_array('ssh', $protocols, true);
@ -97,7 +99,7 @@ class Git
if ($bypassSshForGitHub || 0 !== $this->process->execute($command, $ignoredOutput, $cwd)) {
// private github repository without ssh key access, try https with auth
if (preg_match('{^git@' . self::getGitHubDomainsRegex($this->config) . ':(.+?)\.git$}i', $url, $match)
|| preg_match('{^(https?)://' . self::getGitHubDomainsRegex($this->config) . '/(.*)}', $url, $match)
|| preg_match('{^https?://' . self::getGitHubDomainsRegex($this->config) . '/(.*)}', $url, $match)
) {
if (!$this->io->hasAuthentication($match[1])) {
$gitHubUtil = new GitHub($this->io, $this->config, $this->process);

View File

@ -155,7 +155,7 @@ class ProcessExecutor
//@see https://bugs.php.net/bug.php?id=43784
//@see https://bugs.php.net/bug.php?id=49446
if ('\\' === DIRECTORY_SEPARATOR) {
if ('' === $argument) {
if ((string) $argument === '') {
return escapeshellarg($argument);
}

View File

@ -734,7 +734,7 @@ composer https://github.com/old/url (push)
$cmd = str_replace('cd ', 'cd /D ', $cmd);
$cmd = str_replace('composerPath', getcwd().'/composerPath', $cmd);
return str_replace('""', '', strtr($cmd, "'", '"'));
return strtr($cmd, "'", '"');
}
return $cmd;

View File

@ -0,0 +1,145 @@
<?php
namespace Composer\Test\Util;
use Composer\Config;
use Composer\IO\IOInterface;
use Composer\Util\Filesystem;
use Composer\Util\Git;
use Composer\Util\ProcessExecutor;
use PHPUnit\Framework\TestCase;
class GitTest extends TestCase
{
/** @var Git */
private $git;
/** @var IOInterface&\PHPUnit_Framework_MockObject_MockObject */
private $io;
/** @var Config&\PHPUnit_Framework_MockObject_MockObject */
private $config;
/** @var ProcessExecutor&\PHPUnit_Framework_MockObject_MockObject */
private $process;
/** @var Filesystem&\PHPUnit_Framework_MockObject_MockObject */
private $fs;
protected function setUp()
{
$this->io = $this->getMockBuilder('Composer\IO\IOInterface')->getMock();
$this->config = $this->getMockBuilder('Composer\Config')->disableOriginalConstructor()->getMock();
$this->process = $this->getMockBuilder('Composer\Util\ProcessExecutor')->disableOriginalConstructor()->getMock();
$this->fs = $this->getMockBuilder('Composer\Util\Filesystem')->disableOriginalConstructor()->getMock();
$this->git = new Git($this->io, $this->config, $this->process, $this->fs);
}
/**
* @dataProvider publicGithubNoCredentialsProvider
*/
public function testRunCommandPublicGitHubRepositoryNotInitialClone($protocol, $expectedUrl)
{
$that = $this;
$commandCallable = function ($url) use ($that, $expectedUrl) {
$that->assertSame($expectedUrl, $url);
return 'git command';
};
$this->mockConfig($protocol);
$this->process
->expects($this->once())
->method('execute')
->with($this->equalTo('git command'))
->willReturn(0);
$this->git->runCommand($commandCallable, 'https://github.com/acme/repo', null, true);
}
public function publicGithubNoCredentialsProvider()
{
return array(
array('ssh', 'git@github.com:acme/repo'),
array('https', 'https://github.com/acme/repo'),
);
}
/**
* @expectedException \RuntimeException
*/
public function testRunCommandPrivateGitHubRepositoryNotInitialCloneNotInteractiveWithoutAuthentication()
{
$that = $this;
$commandCallable = function ($url) use ($that) {
$that->assertSame('https://github.com/acme/repo', $url);
return 'git command';
};
$this->mockConfig('https');
$this->process
->method('execute')
->willReturnMap(array(
array('git command', null, null, 1),
array('git --version', null, null, 0),
));
$this->git->runCommand($commandCallable, 'https://github.com/acme/repo', null, true);
}
/**
* @dataProvider privateGithubWithCredentialsProvider
*/
public function testRunCommandPrivateGitHubRepositoryNotInitialCloneNotInteractiveWithAuthentication($gitUrl, $protocol, $gitHubToken, $expectedUrl)
{
$commandCallable = function ($url) use ($expectedUrl) {
if ($url !== $expectedUrl) {
return 'git command failing';
}
return 'git command ok';
};
$this->mockConfig($protocol);
$this->process
->method('execute')
->willReturnMap(array(
array('git command failing', null, null, 1),
array('git command ok', null, null, 0),
));
$this->io
->method('isInteractive')
->willReturn(false);
$this->io
->method('hasAuthentication')
->with($this->equalTo('github.com'))
->willReturn(true);
$this->io
->method('getAuthentication')
->with($this->equalTo('github.com'))
->willReturn(array('username' => 'token', 'password' => $gitHubToken));
$this->git->runCommand($commandCallable, $gitUrl, null, true);
}
public function privateGithubWithCredentialsProvider()
{
return array(
array('git@github.com:acme/repo.git', 'ssh', 'MY_GITHUB_TOKEN', 'https://token:MY_GITHUB_TOKEN@github.com/acme/repo.git'),
array('https://github.com/acme/repo', 'https', 'MY_GITHUB_TOKEN', 'https://token:MY_GITHUB_TOKEN@github.com/acme/repo.git'),
);
}
private function mockConfig($protocol)
{
$this->config
->method('get')
->willReturnMap(array(
array('github-domains', 0, array('github.com')),
array('github-protocols', 0, array($protocol)),
));
}
}