Fix support for replacing dist refs in gitlab URLs and add support for gitlab/github enterprise too
parent
ac9c7a50e9
commit
e6114b2ca7
|
@ -101,32 +101,6 @@ abstract class ArchiveDownloader extends FileDownloader
|
|||
return rtrim($path.'/'.md5($path.spl_object_hash($package)).'.'.pathinfo(parse_url($package->getDistUrl(), PHP_URL_PATH), PATHINFO_EXTENSION), '.');
|
||||
}
|
||||
|
||||
/**
|
||||
* {@inheritdoc}
|
||||
*/
|
||||
protected function processUrl(PackageInterface $package, $url)
|
||||
{
|
||||
if ($package->getDistReference() && strpos($url, 'github.com')) {
|
||||
if (preg_match('{^https?://(?:www\.)?github\.com/([^/]+)/([^/]+)/(zip|tar)ball/(.+)$}i', $url, $match)) {
|
||||
// update legacy github archives to API calls with the proper reference
|
||||
$url = 'https://api.github.com/repos/' . $match[1] . '/'. $match[2] . '/' . $match[3] . 'ball/' . $package->getDistReference();
|
||||
} elseif ($package->getDistReference() && preg_match('{^https?://(?:www\.)?github\.com/([^/]+)/([^/]+)/archive/.+\.(zip|tar)(?:\.gz)?$}i', $url, $match)) {
|
||||
// update current github web archives to API calls with the proper reference
|
||||
$url = 'https://api.github.com/repos/' . $match[1] . '/'. $match[2] . '/' . $match[3] . 'ball/' . $package->getDistReference();
|
||||
} elseif ($package->getDistReference() && preg_match('{^https?://api\.github\.com/repos/([^/]+)/([^/]+)/(zip|tar)ball(?:/.+)?$}i', $url, $match)) {
|
||||
// update api archives to the proper reference
|
||||
$url = 'https://api.github.com/repos/' . $match[1] . '/'. $match[2] . '/' . $match[3] . 'ball/' . $package->getDistReference();
|
||||
}
|
||||
} elseif ($package->getDistReference() && strpos($url, 'bitbucket.org')) {
|
||||
if (preg_match('{^https?://(?:www\.)?bitbucket\.org/([^/]+)/([^/]+)/get/(.+)\.(zip|tar\.gz|tar\.bz2)$}i', $url, $match)) {
|
||||
// update Bitbucket archives to the proper reference
|
||||
$url = 'https://bitbucket.org/' . $match[1] . '/'. $match[2] . '/get/' . $package->getDistReference() . '.' . $match[4];
|
||||
}
|
||||
}
|
||||
|
||||
return parent::processUrl($package, $url);
|
||||
}
|
||||
|
||||
/**
|
||||
* Extract file to directory
|
||||
*
|
||||
|
|
|
@ -22,6 +22,7 @@ use Composer\Plugin\PreFileDownloadEvent;
|
|||
use Composer\EventDispatcher\EventDispatcher;
|
||||
use Composer\Util\Filesystem;
|
||||
use Composer\Util\RemoteFilesystem;
|
||||
use Composer\Util\Url as UrlUtil;
|
||||
|
||||
/**
|
||||
* Base downloader for files
|
||||
|
@ -260,6 +261,10 @@ class FileDownloader implements DownloaderInterface
|
|||
throw new \RuntimeException('You must enable the openssl extension to download files via https');
|
||||
}
|
||||
|
||||
if ($package->getDistReference()) {
|
||||
$url = UrlUtil::updateDistReference($this->config, $url, $package->getDistReference());
|
||||
}
|
||||
|
||||
return $url;
|
||||
}
|
||||
|
||||
|
|
|
@ -0,0 +1,56 @@
|
|||
<?php
|
||||
|
||||
/*
|
||||
* 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.
|
||||
*/
|
||||
|
||||
namespace Composer\Util;
|
||||
|
||||
use Composer\Config;
|
||||
use Composer\IO\IOInterface;
|
||||
|
||||
/**
|
||||
* @author Jordi Boggiano <j.boggiano@seld.be>
|
||||
*/
|
||||
class Url
|
||||
{
|
||||
public static function updateDistReference(Config $config, $url, $ref)
|
||||
{
|
||||
$host = parse_url($url, PHP_URL_HOST);
|
||||
|
||||
if ($host === 'api.github.com' || $host === 'github.com' || $host === 'www.github.com') {
|
||||
if (preg_match('{^https?://(?:www\.)?github\.com/([^/]+)/([^/]+)/(zip|tar)ball/(.+)$}i', $url, $match)) {
|
||||
// update legacy github archives to API calls with the proper reference
|
||||
$url = 'https://api.github.com/repos/' . $match[1] . '/'. $match[2] . '/' . $match[3] . 'ball/' . $ref;
|
||||
} elseif (preg_match('{^https?://(?:www\.)?github\.com/([^/]+)/([^/]+)/archive/.+\.(zip|tar)(?:\.gz)?$}i', $url, $match)) {
|
||||
// update current github web archives to API calls with the proper reference
|
||||
$url = 'https://api.github.com/repos/' . $match[1] . '/'. $match[2] . '/' . $match[3] . 'ball/' . $ref;
|
||||
} elseif (preg_match('{^https?://api\.github\.com/repos/([^/]+)/([^/]+)/(zip|tar)ball(?:/.+)?$}i', $url, $match)) {
|
||||
// update api archives to the proper reference
|
||||
$url = 'https://api.github.com/repos/' . $match[1] . '/'. $match[2] . '/' . $match[3] . 'ball/' . $ref;
|
||||
}
|
||||
} elseif ($host === 'bitbucket.org' || $host === 'www.bitbucket.org') {
|
||||
if (preg_match('{^https?://(?:www\.)?bitbucket\.org/([^/]+)/([^/]+)/get/(.+)\.(zip|tar\.gz|tar\.bz2)$}i', $url, $match)) {
|
||||
// update Bitbucket archives to the proper reference
|
||||
$url = 'https://bitbucket.org/' . $match[1] . '/'. $match[2] . '/get/' . $ref . '.' . $match[4];
|
||||
}
|
||||
} elseif ($host === 'gitlab.com' || $host === 'www.gitlab.com') {
|
||||
if (preg_match('{^https?://(?:www\.)?gitlab\.com/api/v[34]/projects/([^/]+)/repository/archive\.(zip|tar\.gz|tar\.bz2|tar)\?sha=.+$}i', $url, $match)) {
|
||||
// update Gitlab archives to the proper reference
|
||||
$url = 'https://gitlab.com/api/v4/projects/' . $match[1] . '/repository/archive.' . $match[2] . '?sha=' . $ref;
|
||||
}
|
||||
} elseif (in_array($host, $config->get('github-domains'), true)) {
|
||||
$url = preg_replace('{(/repos/[^/]+/[^/]+/(zip|tar)ball)(?:/.+)?$}i', '$1/'.$ref, $url);
|
||||
} elseif (in_array($host, $config->get('gitlab-domains'), true)) {
|
||||
$url = preg_replace('{(/api/v[34]/projects/[^/]+/repository/archive\.(?:zip|tar\.gz|tar\.bz2|tar)\?sha=).+$}i', '$1'.$ref, $url);
|
||||
}
|
||||
|
||||
return $url;
|
||||
}
|
||||
}
|
|
@ -0,0 +1,60 @@
|
|||
<?php
|
||||
|
||||
/*
|
||||
* 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.
|
||||
*/
|
||||
|
||||
namespace Composer\Test\Util;
|
||||
|
||||
use Composer\Util\Url;
|
||||
use PHPUnit\Framework\TestCase;
|
||||
use Composer\Config;
|
||||
|
||||
class UrlTest extends TestCase
|
||||
{
|
||||
/**
|
||||
* @dataProvider distRefsProvider
|
||||
*/
|
||||
public function testUpdateDistReference($url, $expectedUrl, $conf = array())
|
||||
{
|
||||
$config = new Config();
|
||||
$config->merge(array('config' => $conf));
|
||||
|
||||
$this->assertSame($expectedUrl, Url::updateDistReference($config, $url, 'newref'));
|
||||
}
|
||||
|
||||
public static function distRefsProvider()
|
||||
{
|
||||
return array(
|
||||
// github
|
||||
array('https://github.com/foo/bar/zipball/abcd', 'https://api.github.com/repos/foo/bar/zipball/newref'),
|
||||
array('https://www.github.com/foo/bar/zipball/abcd', 'https://api.github.com/repos/foo/bar/zipball/newref'),
|
||||
array('https://github.com/foo/bar/archive/abcd.zip', 'https://api.github.com/repos/foo/bar/zipball/newref'),
|
||||
array('https://github.com/foo/bar/archive/abcd.tar.gz', 'https://api.github.com/repos/foo/bar/tarball/newref'),
|
||||
array('https://api.github.com/repos/foo/bar/tarball', 'https://api.github.com/repos/foo/bar/tarball/newref'),
|
||||
array('https://api.github.com/repos/foo/bar/tarball/abcd', 'https://api.github.com/repos/foo/bar/tarball/newref'),
|
||||
|
||||
// github enterprise
|
||||
array('https://mygithub.com/api/v3/repos/foo/bar/tarball/abcd', 'https://mygithub.com/api/v3/repos/foo/bar/tarball/newref', array('github-domains' => array('mygithub.com'))),
|
||||
|
||||
// bitbucket
|
||||
array('https://bitbucket.org/foo/bar/get/abcd.zip', 'https://bitbucket.org/foo/bar/get/newref.zip'),
|
||||
array('https://www.bitbucket.org/foo/bar/get/abcd.tar.bz2', 'https://bitbucket.org/foo/bar/get/newref.tar.bz2'),
|
||||
|
||||
// gitlab
|
||||
array('https://gitlab.com/api/v4/projects/foo%2Fbar/repository/archive.zip?sha=abcd', 'https://gitlab.com/api/v4/projects/foo%2Fbar/repository/archive.zip?sha=newref'),
|
||||
array('https://www.gitlab.com/api/v4/projects/foo%2Fbar/repository/archive.zip?sha=abcd', 'https://gitlab.com/api/v4/projects/foo%2Fbar/repository/archive.zip?sha=newref'),
|
||||
array('https://gitlab.com/api/v3/projects/foo%2Fbar/repository/archive.tar.gz?sha=abcd', 'https://gitlab.com/api/v4/projects/foo%2Fbar/repository/archive.tar.gz?sha=newref'),
|
||||
|
||||
// gitlab enterprise
|
||||
array('https://mygitlab.com/api/v4/projects/foo%2Fbar/repository/archive.tar.gz?sha=abcd', 'https://mygitlab.com/api/v4/projects/foo%2Fbar/repository/archive.tar.gz?sha=newref', array('gitlab-domains' => array('mygitlab.com'))),
|
||||
array('https://mygitlab.com/api/v3/projects/foo%2Fbar/repository/archive.tar.bz2?sha=abcd', 'https://mygitlab.com/api/v3/projects/foo%2Fbar/repository/archive.tar.bz2?sha=newref', array('gitlab-domains' => array('mygitlab.com'))),
|
||||
);
|
||||
}
|
||||
}
|
Loading…
Reference in New Issue