diff --git a/doc/06-config.md b/doc/06-config.md index 7f6d492a5..ad350e850 100644 --- a/doc/06-config.md +++ b/doc/06-config.md @@ -86,6 +86,11 @@ of their API. Composer may prompt for credentials when needed, but these can als manually set. Read more on how to get an OAuth token for GitHub and cli syntax [here](articles/authentication-for-private-packages.md#github-oauth). +## gitlab-domains + +Defaults to `["gitlab.com"]`. A list of domains of GitLab servers. +This is used if you use the `gitlab` repository type. + ## gitlab-oauth A list of domain names and oauth keys. For example using `{"gitlab.com": @@ -109,6 +114,16 @@ gitlab.com the domain names must be also specified with the `api` or `read_api` scope. Further info can also be found [here](articles/authentication-for-private-packages.md#gitlab-token) +## gitlab-protocol + +A protocol to force use of when creating a repository URL for the `source` +value of the package metadata. One of `git` or `http`. (`https` is treated +as a synonym for `http`.) Helpful when working with projects referencing +private repositories which will later be cloned in GitLab CI jobs with a +[GitLab CI job token](https://docs.gitlab.com/ee/user/project/new_ci_build_permissions_model.html#dependent-repositories) +using HTTP basic auth. By default, Composer will generate a git-over-SSH +URL for private repositories and HTTP(S) only for public. + ## disable-tls Defaults to `false`. If set to true all HTTPS URLs will be tried with HTTP @@ -283,11 +298,6 @@ used for GitHub Enterprise setups. Defaults to `true`. If `false`, the OAuth tokens created to access the github API will have a date instead of the machine hostname. -## gitlab-domains - -Defaults to `["gitlab.com"]`. A list of domains of GitLab servers. -This is used if you use the `gitlab` repository type. - ## use-github-api Defaults to `true`. Similar to the `no-api` key on a specific repository, diff --git a/src/Composer/Config.php b/src/Composer/Config.php index 07fa81db2..49ac45435 100644 --- a/src/Composer/Config.php +++ b/src/Composer/Config.php @@ -31,6 +31,7 @@ class Config 'preferred-install' => 'dist', 'notify-on-install' => true, 'github-protocols' => array('https', 'ssh', 'git'), + 'gitlab-protocol' => null, 'vendor-dir' => 'vendor', 'bin-dir' => '{$vendor-dir}/bin', 'cache-dir' => '{$home}/cache', diff --git a/src/Composer/Repository/Vcs/GitLabDriver.php b/src/Composer/Repository/Vcs/GitLabDriver.php index a3d4a18f6..9ed413b11 100644 --- a/src/Composer/Repository/Vcs/GitLabDriver.php +++ b/src/Composer/Repository/Vcs/GitLabDriver.php @@ -60,6 +60,13 @@ class GitLabDriver extends VcsDriver */ protected $gitDriver = null; + /** + * Protocol to force use of for repository URLs. + * + * @var string One of ssh, http + */ + protected $protocol; + /** * Defaults to true unless we can make sure it is public * @@ -97,6 +104,14 @@ class GitLabDriver extends VcsDriver ; $this->originUrl = self::determineOrigin($configuredDomains, $guessedDomain, $urlParts, $match['port']); + if ($protocol = $this->config->get('gitlab-protocol')) { + // https treated as a synonym for http. + if (!in_array($protocol, array('git', 'http', 'https'))) { + throw new \RuntimeException('gitlab-protocol must be one of git, http.'); + } + $this->protocol = $protocol === 'git' ? 'ssh' : 'http'; + } + if (false !== strpos($this->originUrl, ':') || false !== strpos($this->originUrl, '/')) { $this->hasNonstandardOrigin = true; } @@ -210,6 +225,9 @@ class GitLabDriver extends VcsDriver */ public function getRepositoryUrl() { + if ($this->protocol) { + return $this->project["{$this->protocol}_url_to_repo"]; + } return $this->isPrivate ? $this->project['ssh_url_to_repo'] : $this->project['http_url_to_repo']; } @@ -360,7 +378,7 @@ class GitLabDriver extends VcsDriver if (isset($this->project['visibility'])) { $this->isPrivate = $this->project['visibility'] !== 'public'; } else { - // client is not authendicated, therefore repository has to be public + // client is not authenticated, therefore repository has to be public $this->isPrivate = false; } } diff --git a/tests/Composer/Test/Repository/Vcs/GitLabDriverTest.php b/tests/Composer/Test/Repository/Vcs/GitLabDriverTest.php index 0fd2fa956..883231489 100644 --- a/tests/Composer/Test/Repository/Vcs/GitLabDriverTest.php +++ b/tests/Composer/Test/Repository/Vcs/GitLabDriverTest.php @@ -561,6 +561,38 @@ JSON; $driver->initialize(); } + public function testProtocolOverrideRepositoryUrlGeneration() + { + // @link http://doc.gitlab.com/ce/api/projects.html#get-single-project + $projectData = <<mockResponse($apiUrl, array(), $projectData) + ->shouldBeCalledTimes(1) + ; + + $config = clone $this->config; + $config->merge(array('config' => array('gitlab-protocol' => 'http'))); + $driver = new GitLabDriver(array('url' => $url), $this->io->reveal(), $config, $this->httpDownloader->reveal(), $this->process->reveal()); + $driver->initialize(); + $this->assertEquals('https://gitlab.com/mygroup/myproject.git', $driver->getRepositoryUrl(), 'Repository URL matches config request for http not git'); + } + private function mockResponse($url, $options, $return) { return $this->httpDownloader