1
0
Fork 0
composer/src/Composer/Repository/RepositorySet.php

177 lines
5.5 KiB
PHP
Raw Normal View History

<?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\Repository;
use Composer\DependencyResolver\Pool;
use Composer\DependencyResolver\PoolBuilder;
use Composer\DependencyResolver\Request;
use Composer\Package\BasePackage;
use Composer\Package\Version\VersionParser;
use Composer\Repository\CompositeRepository;
use Composer\Repository\PlatformRepository;
use Composer\Semver\Constraint\ConstraintInterface;
use Composer\Test\DependencyResolver\PoolTest;
/**
* @author Nils Adermann <naderman@naderman.de>
*/
class RepositorySet
{
/** @var array */
private $rootAliases;
/** @var array */
private $rootReferences;
/** @var RepositoryInterface[] */
private $repositories = array();
private $acceptableStabilities;
private $stabilityFlags;
2019-11-23 13:43:22 +00:00
protected $rootRequires;
/** @var Pool */
private $pool;
2019-11-23 13:43:22 +00:00
public function __construct(array $rootAliases = array(), array $rootReferences = array(), $minimumStability = 'stable', array $stabilityFlags = array(), array $rootRequires = array())
{
$this->rootAliases = $rootAliases;
$this->rootReferences = $rootReferences;
$this->acceptableStabilities = array();
foreach (BasePackage::$stabilities as $stability => $value) {
if ($value <= BasePackage::$stabilities[$minimumStability]) {
$this->acceptableStabilities[$stability] = $value;
}
}
$this->stabilityFlags = $stabilityFlags;
2019-11-23 13:43:22 +00:00
$this->rootRequires = $rootRequires;
foreach ($rootRequires as $name => $constraint) {
if (preg_match(PlatformRepository::PLATFORM_PACKAGE_REGEX, $name)) {
2019-11-23 13:43:22 +00:00
unset($this->rootRequires[$name]);
}
}
}
/**
* Adds a repository to this repository set
*
* The first repos added have a higher priority. As soon as a package is found in any
* repository the search for that package ends, and following repos will not be consulted.
*
* @param RepositoryInterface $repo A package repository
*/
public function addRepository(RepositoryInterface $repo)
{
if ($this->pool) {
throw new \RuntimeException("Pool has already been created from this repository set, it cannot be modified anymore.");
}
if ($repo instanceof CompositeRepository) {
$repos = $repo->getRepositories();
} else {
$repos = array($repo);
}
foreach ($repos as $repo) {
$this->repositories[] = $repo;
}
}
public function isPackageAcceptable($name, $stability)
{
foreach ((array) $name as $n) {
// allow if package matches the global stability requirement and has no exception
if (!isset($this->stabilityFlags[$n]) && isset($this->acceptableStabilities[$stability])) {
return true;
}
// allow if package matches the package-specific stability flag
if (isset($this->stabilityFlags[$n]) && BasePackage::$stabilities[$stability] <= $this->stabilityFlags[$n]) {
return true;
}
}
return false;
}
/**
* Find packages providing or matching a name and optionally meeting a constraint in all repositories
*
* Returned in the order of repositories, matching priority
*
* @param string $name
* @param ConstraintInterface|null $constraint
* @param bool $exactMatch
* @return array
*/
public function findPackages($name, ConstraintInterface $constraint = null, $exactMatch = true)
{
$packages = array();
foreach ($this->repositories as $repository) {
$packages[] = $repository->findPackages($name, $constraint) ?: array();
}
$candidates = $packages ? call_user_func_array('array_merge', $packages) : array();
$result = array();
foreach ($candidates as $candidate) {
if ($exactMatch && $candidate->getName() !== $name) {
continue;
}
if ($this->isPackageAcceptable($candidate->getNames(), $candidate->getStability())) {
$result[] = $candidate;
}
}
return $candidates;
}
/**
* Create a pool for dependency resolution from the packages in this repository set.
*
* @return Pool
*/
public function createPool(Request $request)
{
2019-11-23 13:43:22 +00:00
$poolBuilder = new PoolBuilder(array($this, 'isPackageAcceptable'), $this->rootRequires);
return $this->pool = $poolBuilder->buildPool($this->repositories, $this->rootAliases, $this->rootReferences, $request);
}
// TODO unify this with above in some simpler version without "request"?
public function createPoolForPackage($packageName)
{
return $this->createPoolForPackages(array($packageName));
}
public function createPoolForPackages($packageNames)
{
$request = new Request();
foreach ($packageNames as $packageName) {
$request->install($packageName);
}
return $this->createPool($request);
}
/**
* Access the pool object after it has been created, relevant for plugins which need to read info from the pool
* @return Pool
*/
public function getPool()
{
return $this->pool;
}
}