1
0
Fork 0

Merge branch '1.2'

pull/5918/merge
Jordi Boggiano 2016-12-01 00:00:32 +01:00
commit 193d53921b
3 changed files with 95 additions and 47 deletions

View File

@ -10,6 +10,11 @@
* Removed `hash` from composer.lock, only `content-hash` is now used which should reduce conflicts * Removed `hash` from composer.lock, only `content-hash` is now used which should reduce conflicts
* Minor fixes and performance improvements * Minor fixes and performance improvements
### [1.2.3] - 2016-12-01
* Fixed bug in HgDriver failing to identify BitBucket repositories
* Fixed support for loading partial provider repositories
### [1.2.2] - 2016-11-03 ### [1.2.2] - 2016-11-03
* Fixed selection of packages based on stability to be independent from package repository order * Fixed selection of packages based on stability to be independent from package repository order
@ -453,7 +458,8 @@
* Initial release * Initial release
[1.3.0-RC]: https://github.com/composer/composer/compare/1.2.2...1.3.0-RC [1.3.0-RC]: https://github.com/composer/composer/compare/1.2.3...1.3.0-RC
[1.2.3]: https://github.com/composer/composer/compare/1.2.2...1.2.3
[1.2.2]: https://github.com/composer/composer/compare/1.2.1...1.2.2 [1.2.2]: https://github.com/composer/composer/compare/1.2.1...1.2.2
[1.2.1]: https://github.com/composer/composer/compare/1.2.0...1.2.1 [1.2.1]: https://github.com/composer/composer/compare/1.2.0...1.2.1
[1.2.0]: https://github.com/composer/composer/compare/1.2.0-RC...1.2.0 [1.2.0]: https://github.com/composer/composer/compare/1.2.0-RC...1.2.0

View File

@ -284,8 +284,13 @@ VCS repository provides `dist`s for them that fetch the packages as zips.
* **BitBucket:** [bitbucket.org](https://bitbucket.org) (Git and Mercurial) * **BitBucket:** [bitbucket.org](https://bitbucket.org) (Git and Mercurial)
The VCS driver to be used is detected automatically based on the URL. However, The VCS driver to be used is detected automatically based on the URL. However,
<<<<<<< HEAD
should you need to specify one for whatever reason, you can use `fossil`, should you need to specify one for whatever reason, you can use `fossil`,
`git`, `svn` or `hg` as the repository type instead of `vcs`. `git`, `svn` or `hg` as the repository type instead of `vcs`.
=======
should you need to specify one for whatever reason, you can use `fossil`, `git`,
`svn` or `hg` as the repository type instead of `vcs`.
>>>>>>> 1.2
If you set the `no-api` key to `true` on a github repository it will clone the If you set the `no-api` key to `true` on a github repository it will clone the
repository as it would with any other git repository instead of using the repository as it would with any other git repository instead of using the
@ -662,7 +667,7 @@ You can disable the default Packagist repository by adding this to your
{ {
"repositories": [ "repositories": [
{ {
"packagist": false "packagist.org": false
} }
] ]
} }

View File

@ -59,6 +59,8 @@ class ComposerRepository extends ArrayRepository implements ConfigurableReposito
protected $distMirrors; protected $distMirrors;
private $degradedMode = false; private $degradedMode = false;
private $rootData; private $rootData;
private $hasPartialPackages;
private $partialPackagesByName;
public function __construct(array $repoConfig, IOInterface $io, Config $config, EventDispatcher $eventDispatcher = null, RemoteFilesystem $rfs = null) public function __construct(array $repoConfig, IOInterface $io, Config $config, EventDispatcher $eventDispatcher = null, RemoteFilesystem $rfs = null)
{ {
@ -280,69 +282,84 @@ class ComposerRepository extends ArrayRepository implements ConfigurableReposito
return $this->providers[$name]; return $this->providers[$name];
} }
// skip platform packages, root package and composer-plugin-api if ($this->hasPartialPackages && null === $this->partialPackagesByName) {
if (preg_match(PlatformRepository::PLATFORM_PACKAGE_REGEX, $name) || '__root__' === $name || 'composer-plugin-api' === $name) { $this->initializePartialPackages();
return array();
} }
if (null === $this->providerListing) { if (!$this->hasPartialPackages || !isset($this->partialPackagesByName[$name])) {
$this->loadProviderListings($this->loadRootServerFile()); // skip platform packages, root package and composer-plugin-api
} if (preg_match(PlatformRepository::PLATFORM_PACKAGE_REGEX, $name) || '__root__' === $name || 'composer-plugin-api' === $name) {
$useLastModifiedCheck = false;
if ($this->lazyProvidersUrl && !isset($this->providerListing[$name])) {
$hash = null;
$url = str_replace('%package%', $name, $this->lazyProvidersUrl);
$cacheKey = 'provider-'.strtr($name, '/', '$').'.json';
$useLastModifiedCheck = true;
} elseif ($this->providersUrl) {
// package does not exist in this repo
if (!isset($this->providerListing[$name])) {
return array(); return array();
} }
$hash = $this->providerListing[$name]['sha256']; if (null === $this->providerListing) {
$url = str_replace(array('%package%', '%hash%'), array($name, $hash), $this->providersUrl); $this->loadProviderListings($this->loadRootServerFile());
$cacheKey = 'provider-'.strtr($name, '/', '$').'.json'; }
} else {
return array();
}
$packages = null; $useLastModifiedCheck = false;
if ($cacheKey) { if ($this->lazyProvidersUrl && !isset($this->providerListing[$name])) {
if (!$useLastModifiedCheck && $hash && $this->cache->sha256($cacheKey) === $hash) { $hash = null;
$packages = json_decode($this->cache->read($cacheKey), true); $url = str_replace('%package%', $name, $this->lazyProvidersUrl);
} elseif ($useLastModifiedCheck) { $cacheKey = 'provider-'.strtr($name, '/', '$').'.json';
if ($contents = $this->cache->read($cacheKey)) { $useLastModifiedCheck = true;
$contents = json_decode($contents, true); } elseif ($this->providersUrl) {
if (isset($contents['last-modified'])) { // package does not exist in this repo
$response = $this->fetchFileIfLastModified($url, $cacheKey, $contents['last-modified']); if (!isset($this->providerListing[$name])) {
if (true === $response) { return array();
$packages = $contents; }
} elseif ($response) {
$packages = $response; $hash = $this->providerListing[$name]['sha256'];
$url = str_replace(array('%package%', '%hash%'), array($name, $hash), $this->providersUrl);
$cacheKey = 'provider-'.strtr($name, '/', '$').'.json';
} else {
return array();
}
$packages = null;
if ($cacheKey) {
if (!$useLastModifiedCheck && $hash && $this->cache->sha256($cacheKey) === $hash) {
$packages = json_decode($this->cache->read($cacheKey), true);
} elseif ($useLastModifiedCheck) {
if ($contents = $this->cache->read($cacheKey)) {
$contents = json_decode($contents, true);
if (isset($contents['last-modified'])) {
$response = $this->fetchFileIfLastModified($url, $cacheKey, $contents['last-modified']);
if (true === $response) {
$packages = $contents;
} elseif ($response) {
$packages = $response;
}
} }
} }
} }
} }
}
if (!$packages) { if (!$packages) {
try { try {
$packages = $this->fetchFile($url, $cacheKey, $hash, $useLastModifiedCheck); $packages = $this->fetchFile($url, $cacheKey, $hash, $useLastModifiedCheck);
} catch (TransportException $e) { } catch (TransportException $e) {
// 404s are acceptable for lazy provider repos // 404s are acceptable for lazy provider repos
if ($e->getStatusCode() === 404 && $this->lazyProvidersUrl) { if ($e->getStatusCode() === 404 && $this->lazyProvidersUrl) {
$packages = array('packages' => array()); $packages = array('packages' => array());
} else { } else {
throw $e; throw $e;
}
} }
} }
$loadingPartialPackage = false;
} else {
$packages = array('packages' => array('versions' => $this->partialPackagesByName[$name]));
$loadingPartialPackage = true;
} }
$this->providers[$name] = array(); $this->providers[$name] = array();
foreach ($packages['packages'] as $versions) { foreach ($packages['packages'] as $versions) {
foreach ($versions as $version) { foreach ($versions as $version) {
if (!$loadingPartialPackage && $this->hasPartialPackages && isset($this->partialPackagesByName[$version['name']])) {
continue;
}
// avoid loading the same objects twice // avoid loading the same objects twice
if (isset($this->providersByUid[$version['uid']])) { if (isset($this->providersByUid[$version['uid']])) {
// skip if already assigned // skip if already assigned
@ -492,6 +509,8 @@ class ComposerRepository extends ArrayRepository implements ConfigurableReposito
if (!empty($data['providers-lazy-url'])) { if (!empty($data['providers-lazy-url'])) {
$this->lazyProvidersUrl = $this->canonicalizeUrl($data['providers-lazy-url']); $this->lazyProvidersUrl = $this->canonicalizeUrl($data['providers-lazy-url']);
$this->hasProviders = true; $this->hasProviders = true;
$this->hasPartialPackages = !empty($data['packages']) && is_array($data['packages']);
} }
if ($this->allowSslDowngrade) { if ($this->allowSslDowngrade) {
@ -754,4 +773,22 @@ class ComposerRepository extends ArrayRepository implements ConfigurableReposito
} }
} }
} }
/**
* This initializes the packages key of a partial packages.json that contain some packages inlined + a providers-lazy-url
*
* This should only be called once
*/
private function initializePartialPackages()
{
$rootData = $this->loadRootServerFile();
$this->partialPackagesByName = array();
foreach ($rootData['packages'] as $package => $versions) {
$this->partialPackagesByName[strtolower($package)] = $versions;
}
// wipe rootData as it is fully consumed at this point and this saves some memory
$this->rootData = true;
}
} }