diff --git a/src/Composer/Util/Hg.php b/src/Composer/Util/Hg.php index 0e9f6e58f..c687542e0 100644 --- a/src/Composer/Util/Hg.php +++ b/src/Composer/Util/Hg.php @@ -58,10 +58,20 @@ class Hg } // Try with the authentication information available - if (Preg::isMatch('{^(https?)://((.+)(?:\:(.+))?@)?([^/]+)(/.*)?}mi', $url, $match) && $this->io->hasAuthentication((string) $match[5])) { - $auth = $this->io->getAuthentication((string) $match[5]); - $authenticatedUrl = $match[1] . '://' . rawurlencode($auth['username']) . ':' . rawurlencode($auth['password']) . '@' . $match[5] . $match[6]; - + if ( + Preg::isMatch('{^(?Pssh|https?)://(?:(?P[^:@]+)(?::(?P[^:@]+))?@)?(?P[^/]+)(?P/.*)?}mi', $url, $matches) + && $this->io->hasAuthentication((string) $matches['host']) + ) { + if ($matches['proto'] === 'ssh') { + $user = ''; + if ($matches['user'] !== '' && $matches['user'] !== null) { + $user = rawurlencode($matches['user']) . '@'; + } + $authenticatedUrl = $matches['proto'] . '://' . $user . $matches['host'] . $matches['path']; + } else { + $auth = $this->io->getAuthentication((string) $matches['host']); + $authenticatedUrl = $matches['proto'] . '://' . rawurlencode($auth['username']) . ':' . rawurlencode($auth['password']) . '@' . $matches['host'] . $matches['path']; + } $command = $commandCallable($authenticatedUrl); if (0 === $this->process->execute($command, $ignoredOutput, $cwd)) { @@ -70,10 +80,10 @@ class Hg $error = $this->process->getErrorOutput(); } else { - $error = 'The given URL (' . $url . ') does not match the required format (http(s)://(username:password@)example.com/path-to-repository)'; + $error = 'The given URL (' .$url. ') does not match the required format (ssh|http(s)://(username:password@)example.com/path-to-repository)'; } - $this->throwException('Failed to clone ' . $url . ', ' . "\n\n" . $error, $url); + $this->throwException("Failed to clone $url, \n\n" . $error, $url); } /** @@ -84,7 +94,9 @@ class Hg private function throwException($message, string $url): void { if (null === self::getVersion($this->process)) { - throw new \RuntimeException(Url::sanitize('Failed to clone ' . $url . ', hg was not found, check that it is installed and in your PATH env.' . "\n\n" . $this->process->getErrorOutput())); + throw new \RuntimeException(Url::sanitize( + 'Failed to clone ' . $url . ', hg was not found, check that it is installed and in your PATH env.' . "\n\n" . $this->process->getErrorOutput() + )); } throw new \RuntimeException(Url::sanitize($message));