2022-02-23 15:58:18 +00:00
|
|
|
<?php declare(strict_types=1);
|
2019-11-06 23:43:19 +00:00
|
|
|
|
2020-11-22 13:48:56 +00:00
|
|
|
/*
|
|
|
|
* This file is part of Composer.
|
|
|
|
*
|
|
|
|
* (c) Nils Adermann <naderman@naderman.de>
|
|
|
|
* Jordi Boggiano <j.boggiano@seld.be>
|
|
|
|
*
|
|
|
|
* For the full copyright and license information, please view the LICENSE
|
|
|
|
* file that was distributed with this source code.
|
|
|
|
*/
|
|
|
|
|
2019-11-06 23:43:19 +00:00
|
|
|
namespace Composer\Test\Util;
|
|
|
|
|
|
|
|
use Composer\Config;
|
|
|
|
use Composer\IO\IOInterface;
|
|
|
|
use Composer\Util\Filesystem;
|
|
|
|
use Composer\Util\Git;
|
2021-08-19 11:00:30 +00:00
|
|
|
use Composer\Test\Mock\ProcessExecutorMock;
|
2020-02-07 03:18:45 +00:00
|
|
|
use Composer\Test\TestCase;
|
2019-11-06 23:43:19 +00:00
|
|
|
|
|
|
|
class GitTest extends TestCase
|
|
|
|
{
|
|
|
|
/** @var Git */
|
|
|
|
private $git;
|
2021-03-09 14:49:40 +00:00
|
|
|
/** @var IOInterface&\PHPUnit\Framework\MockObject\MockObject */
|
2019-11-06 23:43:19 +00:00
|
|
|
private $io;
|
2021-03-09 14:49:40 +00:00
|
|
|
/** @var Config&\PHPUnit\Framework\MockObject\MockObject */
|
2019-11-06 23:43:19 +00:00
|
|
|
private $config;
|
2021-08-19 11:00:30 +00:00
|
|
|
/** @var ProcessExecutorMock */
|
2019-11-06 23:43:19 +00:00
|
|
|
private $process;
|
2021-03-09 14:49:40 +00:00
|
|
|
/** @var Filesystem&\PHPUnit\Framework\MockObject\MockObject */
|
2019-11-06 23:43:19 +00:00
|
|
|
private $fs;
|
|
|
|
|
2021-12-08 16:03:05 +00:00
|
|
|
protected function setUp(): void
|
2019-11-06 23:43:19 +00:00
|
|
|
{
|
|
|
|
$this->io = $this->getMockBuilder('Composer\IO\IOInterface')->getMock();
|
|
|
|
$this->config = $this->getMockBuilder('Composer\Config')->disableOriginalConstructor()->getMock();
|
2021-12-09 16:09:07 +00:00
|
|
|
$this->process = $this->getProcessExecutorMock();
|
2019-11-06 23:43:19 +00:00
|
|
|
$this->fs = $this->getMockBuilder('Composer\Util\Filesystem')->disableOriginalConstructor()->getMock();
|
|
|
|
$this->git = new Git($this->io, $this->config, $this->process, $this->fs);
|
|
|
|
}
|
|
|
|
|
|
|
|
/**
|
|
|
|
* @dataProvider publicGithubNoCredentialsProvider
|
|
|
|
*/
|
2022-02-22 15:47:09 +00:00
|
|
|
public function testRunCommandPublicGitHubRepositoryNotInitialClone(string $protocol, string $expectedUrl): void
|
2019-11-06 23:43:19 +00:00
|
|
|
{
|
2022-02-21 12:42:28 +00:00
|
|
|
$commandCallable = function ($url) use ($expectedUrl): string {
|
2024-05-29 21:12:06 +00:00
|
|
|
self::assertSame($expectedUrl, $url);
|
2019-11-06 23:43:19 +00:00
|
|
|
|
|
|
|
return 'git command';
|
|
|
|
};
|
|
|
|
|
|
|
|
$this->mockConfig($protocol);
|
|
|
|
|
2022-08-17 12:20:07 +00:00
|
|
|
$this->process->expects(['git command'], true);
|
2019-11-06 23:43:19 +00:00
|
|
|
|
|
|
|
$this->git->runCommand($commandCallable, 'https://github.com/acme/repo', null, true);
|
|
|
|
}
|
|
|
|
|
2022-11-24 13:39:08 +00:00
|
|
|
public static function publicGithubNoCredentialsProvider(): array
|
2019-11-06 23:43:19 +00:00
|
|
|
{
|
2022-08-17 12:20:07 +00:00
|
|
|
return [
|
|
|
|
['ssh', 'git@github.com:acme/repo'],
|
|
|
|
['https', 'https://github.com/acme/repo'],
|
|
|
|
];
|
2019-11-06 23:43:19 +00:00
|
|
|
}
|
|
|
|
|
2022-02-18 09:38:54 +00:00
|
|
|
public function testRunCommandPrivateGitHubRepositoryNotInitialCloneNotInteractiveWithoutAuthentication(): void
|
2019-11-06 23:43:19 +00:00
|
|
|
{
|
2021-12-09 19:55:26 +00:00
|
|
|
self::expectException('RuntimeException');
|
2020-09-10 15:21:11 +00:00
|
|
|
|
2022-02-21 12:42:28 +00:00
|
|
|
$commandCallable = function ($url): string {
|
2024-05-29 21:12:06 +00:00
|
|
|
self::assertSame('https://github.com/acme/repo', $url);
|
2019-11-06 23:43:19 +00:00
|
|
|
|
|
|
|
return 'git command';
|
|
|
|
};
|
|
|
|
|
|
|
|
$this->mockConfig('https');
|
|
|
|
|
2022-08-17 12:20:07 +00:00
|
|
|
$this->process->expects([
|
|
|
|
['cmd' => 'git command', 'return' => 1],
|
|
|
|
['cmd' => 'git --version', 'return' => 0],
|
|
|
|
], true);
|
2019-11-06 23:43:19 +00:00
|
|
|
|
|
|
|
$this->git->runCommand($commandCallable, 'https://github.com/acme/repo', null, true);
|
|
|
|
}
|
|
|
|
|
|
|
|
/**
|
|
|
|
* @dataProvider privateGithubWithCredentialsProvider
|
|
|
|
*/
|
2022-02-22 15:47:09 +00:00
|
|
|
public function testRunCommandPrivateGitHubRepositoryNotInitialCloneNotInteractiveWithAuthentication(string $gitUrl, string $protocol, string $gitHubToken, string $expectedUrl, int $expectedFailuresBeforeSuccess): void
|
2019-11-06 23:43:19 +00:00
|
|
|
{
|
2022-08-17 12:20:07 +00:00
|
|
|
$commandCallable = static function ($url) use ($expectedUrl): string {
|
2019-11-06 23:43:19 +00:00
|
|
|
if ($url !== $expectedUrl) {
|
|
|
|
return 'git command failing';
|
|
|
|
}
|
|
|
|
|
|
|
|
return 'git command ok';
|
|
|
|
};
|
|
|
|
|
|
|
|
$this->mockConfig($protocol);
|
|
|
|
|
2022-08-17 12:20:07 +00:00
|
|
|
$expectedCalls = array_fill(0, $expectedFailuresBeforeSuccess, ['cmd' => 'git command failing', 'return' => 1]);
|
|
|
|
$expectedCalls[] = ['cmd' => 'git command ok', 'return' => 0];
|
2021-08-19 11:00:30 +00:00
|
|
|
|
|
|
|
$this->process->expects($expectedCalls, true);
|
2019-11-06 23:43:19 +00:00
|
|
|
|
|
|
|
$this->io
|
|
|
|
->method('isInteractive')
|
|
|
|
->willReturn(false);
|
|
|
|
|
|
|
|
$this->io
|
2020-02-07 06:35:07 +00:00
|
|
|
->expects($this->atLeastOnce())
|
2019-11-06 23:43:19 +00:00
|
|
|
->method('hasAuthentication')
|
|
|
|
->with($this->equalTo('github.com'))
|
|
|
|
->willReturn(true);
|
|
|
|
|
|
|
|
$this->io
|
2020-02-07 06:35:07 +00:00
|
|
|
->expects($this->atLeastOnce())
|
2019-11-06 23:43:19 +00:00
|
|
|
->method('getAuthentication')
|
|
|
|
->with($this->equalTo('github.com'))
|
2022-08-17 12:20:07 +00:00
|
|
|
->willReturn(['username' => 'token', 'password' => $gitHubToken]);
|
2019-11-06 23:43:19 +00:00
|
|
|
|
|
|
|
$this->git->runCommand($commandCallable, $gitUrl, null, true);
|
|
|
|
}
|
|
|
|
|
2022-11-24 13:39:08 +00:00
|
|
|
public static function privateGithubWithCredentialsProvider(): array
|
2019-11-06 23:43:19 +00:00
|
|
|
{
|
2022-08-17 12:20:07 +00:00
|
|
|
return [
|
|
|
|
['git@github.com:acme/repo.git', 'ssh', 'MY_GITHUB_TOKEN', 'https://token:MY_GITHUB_TOKEN@github.com/acme/repo.git', 1],
|
|
|
|
['https://github.com/acme/repo', 'https', 'MY_GITHUB_TOKEN', 'https://token:MY_GITHUB_TOKEN@github.com/acme/repo.git', 2],
|
|
|
|
];
|
2019-11-06 23:43:19 +00:00
|
|
|
}
|
|
|
|
|
2022-02-22 15:47:09 +00:00
|
|
|
private function mockConfig(string $protocol): void
|
2019-11-06 23:43:19 +00:00
|
|
|
{
|
|
|
|
$this->config
|
|
|
|
->method('get')
|
2022-08-17 12:20:07 +00:00
|
|
|
->willReturnMap([
|
|
|
|
['github-domains', 0, ['github.com']],
|
|
|
|
['github-protocols', 0, [$protocol]],
|
|
|
|
]);
|
2019-11-06 23:43:19 +00:00
|
|
|
}
|
|
|
|
}
|