1
0
Fork 0

Merge branch 'newrepo'

pull/1241/merge
Jordi Boggiano 2012-10-21 14:18:00 +02:00
commit 573e4b2a7c
10 changed files with 282 additions and 130 deletions

View File

@ -65,4 +65,12 @@ class Cache
return sha1_file($this->root . $file);
}
}
public function sha256($file)
{
$file = preg_replace('{[^a-z0-9.]}i', '-', $file);
if ($this->enabled && file_exists($this->root . $file)) {
return hash_file('sha256', $this->root . $file);
}
}
}

View File

@ -29,12 +29,7 @@ class Decisions implements \Iterator, \Countable
public function __construct($pool)
{
$this->pool = $pool;
if (version_compare(PHP_VERSION, '5.3.4', '>=')) {
$this->decisionMap = new \SplFixedArray($this->pool->getMaxId() + 1);
} else {
$this->decisionMap = array_fill(0, $this->pool->getMaxId() + 1, 0);
}
$this->decisionMap = array();
}
public function decide($literal, $level, $why)
@ -51,8 +46,8 @@ class Decisions implements \Iterator, \Countable
$packageId = abs($literal);
return (
$literal > 0 && $this->decisionMap[$packageId] > 0 ||
$literal < 0 && $this->decisionMap[$packageId] < 0
$literal > 0 && isset($this->decisionMap[$packageId]) && $this->decisionMap[$packageId] > 0 ||
$literal < 0 && isset($this->decisionMap[$packageId]) && $this->decisionMap[$packageId] < 0
);
}
@ -61,29 +56,36 @@ class Decisions implements \Iterator, \Countable
$packageId = abs($literal);
return (
($this->decisionMap[$packageId] > 0 && $literal < 0) ||
($this->decisionMap[$packageId] < 0 && $literal > 0)
(isset($this->decisionMap[$packageId]) && $this->decisionMap[$packageId] > 0 && $literal < 0) ||
(isset($this->decisionMap[$packageId]) && $this->decisionMap[$packageId] < 0 && $literal > 0)
);
}
public function decided($literalOrPackageId)
{
return $this->decisionMap[abs($literalOrPackageId)] != 0;
return !empty($this->decisionMap[abs($literalOrPackageId)]);
}
public function undecided($literalOrPackageId)
{
return $this->decisionMap[abs($literalOrPackageId)] == 0;
return empty($this->decisionMap[abs($literalOrPackageId)]);
}
public function decidedInstall($literalOrPackageId)
{
return $this->decisionMap[abs($literalOrPackageId)] > 0;
$packageId = abs($literalOrPackageId);
return isset($this->decisionMap[$packageId]) && $this->decisionMap[$packageId] > 0;
}
public function decisionLevel($literalOrPackageId)
{
return abs($this->decisionMap[abs($literalOrPackageId)]);
$packageId = abs($literalOrPackageId);
if (isset($this->decisionMap[$packageId])) {
return abs($this->decisionMap[$packageId]);
}
return 0;
}
public function decisionRule($literalOrPackageId)
@ -179,7 +181,7 @@ class Decisions implements \Iterator, \Countable
{
$packageId = abs($literal);
$previousDecision = $this->decisionMap[$packageId];
$previousDecision = isset($this->decisionMap[$packageId]) ? $this->decisionMap[$packageId] : null;
if ($previousDecision != 0) {
$literalString = $this->pool->literalToString($literal);
$package = $this->pool->literalToPackage($literal);

View File

@ -20,6 +20,7 @@ use Composer\Package\LinkConstraint\LinkConstraintInterface;
use Composer\Package\LinkConstraint\VersionConstraint;
use Composer\Repository\RepositoryInterface;
use Composer\Repository\CompositeRepository;
use Composer\Repository\ComposerRepository;
use Composer\Repository\InstalledRepositoryInterface;
use Composer\Repository\StreamableRepositoryInterface;
use Composer\Repository\PlatformRepository;
@ -39,11 +40,14 @@ class Pool
const MATCH_REPLACE = 3;
protected $repositories = array();
protected $composerRepos = array();
protected $packages = array();
protected $packageByName = array();
protected $acceptableStabilities;
protected $stabilityFlags;
protected $versionParser;
protected $providerCache = array();
protected $id = 1;
public function __construct($minimumStability = 'stable', array $stabilityFlags = array())
{
@ -72,18 +76,21 @@ class Pool
$repos = array($repo);
}
$id = count($this->packages) + 1;
foreach ($repos as $repo) {
$this->repositories[] = $repo;
$exempt = $repo instanceof PlatformRepository || $repo instanceof InstalledRepositoryInterface;
if ($repo instanceof StreamableRepositoryInterface) {
if ($repo instanceof ComposerRepository && $repo->hasProviders()) {
$this->composerRepos[] = $repo;
$repo->resetPackageIds();
} elseif ($repo instanceof StreamableRepositoryInterface) {
foreach ($repo->getMinimalPackages() as $package) {
$name = $package['name'];
$version = $package['version'];
$stability = VersionParser::parseStability($version);
if ($exempt || $this->isPackageAcceptable($name, $stability)) {
$package['id'] = $id++;
$package['id'] = $this->id++;
$this->packages[] = $package;
// collect names
@ -102,7 +109,7 @@ class Pool
}
foreach (array_keys($names) as $provided) {
$this->packageByName[$provided][] =& $this->packages[$id-2];
$this->packageByName[$provided][] =& $this->packages[$this->id - 2];
}
// handle root package aliases
@ -119,12 +126,12 @@ class Pool
$alias['version'] = $rootAliasData['alias_normalized'];
$alias['alias'] = $rootAliasData['alias'];
$alias['alias_of'] = $package['id'];
$alias['id'] = $id++;
$alias['id'] = $this->id++;
$alias['root_alias'] = true;
$this->packages[] = $alias;
foreach (array_keys($names) as $name) {
$this->packageByName[$name][] =& $this->packages[$id-2];
$this->packageByName[$name][] =& $this->packages[$this->id - 2];
}
}
@ -135,11 +142,11 @@ class Pool
$alias['version'] = $package['alias_normalized'];
$alias['alias'] = $package['alias'];
$alias['alias_of'] = $package['id'];
$alias['id'] = $id++;
$alias['id'] = $this->id++;
$this->packages[] = $alias;
foreach (array_keys($names) as $name) {
$this->packageByName[$name][] =& $this->packages[$id-2];
$this->packageByName[$name][] =& $this->packages[$this->id - 2];
}
}
}
@ -149,7 +156,7 @@ class Pool
$name = $package->getName();
$stability = $package->getStability();
if ($exempt || $this->isPackageAcceptable($name, $stability)) {
$package->setId($id++);
$package->setId($this->id++);
$this->packages[] = $package;
foreach ($package->getNames() as $name) {
@ -163,7 +170,7 @@ class Pool
$package->setPrettyAlias($alias['alias']);
$package->getRepository()->addPackage($aliasPackage = new AliasPackage($package, $alias['alias_normalized'], $alias['alias']));
$aliasPackage->setRootPackageAlias(true);
$aliasPackage->setId($id++);
$aliasPackage->setId($this->id++);
$this->packages[] = $aliasPackage;
@ -201,16 +208,6 @@ class Pool
return $this->packages[$id - 1];
}
/**
* Retrieves the highest id assigned to a package in this pool
*
* @return int Highest package id
*/
public function getMaxId()
{
return count($this->packages);
}
/**
* Searches all packages providing the given package name and match the constraint
*
@ -221,11 +218,33 @@ class Pool
*/
public function whatProvides($name, LinkConstraintInterface $constraint = null)
{
if (!isset($this->packageByName[$name])) {
return array();
if (isset($this->providerCache[$name][(string) $constraint])) {
return $this->providerCache[$name][(string) $constraint];
}
$candidates = $this->packageByName[$name];
return $this->providerCache[$name][(string) $constraint] = $this->computeWhatProvides($name, $constraint);
}
/**
* @see whatProvides
*/
private function computeWhatProvides($name, $constraint)
{
$candidates = array();
foreach ($this->composerRepos as $repo) {
foreach ($repo->whatProvides($this, $name) as $candidate) {
$candidates[] = $candidate;
if ($candidate->getId() < 1) {
$candidate->setId($this->id++);
$this->packages[$this->id - 2] = $candidate;
}
}
}
if (isset($this->packageByName[$name])) {
$candidates = array_merge($candidates, $this->packageByName[$name]);
}
if (null === $constraint) {
foreach ($candidates as $key => $candidate) {
@ -298,7 +317,7 @@ class Pool
return $prefix.' '.$package->getPrettyString();
}
private function isPackageAcceptable($name, $stability)
public function isPackageAcceptable($name, $stability)
{
// allow if package matches the global stability requirement and has no exception
if (!isset($this->stabilityFlags[$name]) && isset($this->acceptableStabilities[$stability])) {
@ -368,16 +387,12 @@ class Pool
$replaces = $candidate->getReplaces();
}
foreach ($provides as $link) {
if ($link->getTarget() === $name && $constraint->matches($link->getConstraint())) {
return self::MATCH_PROVIDE;
}
if (isset($provides[$name]) && $constraint->matches($provides[$name]->getConstraint())) {
return self::MATCH_PROVIDE;
}
foreach ($replaces as $link) {
if ($link->getTarget() === $name && $constraint->matches($link->getConstraint())) {
return self::MATCH_REPLACE;
}
if (isset($replaces[$name]) && $constraint->matches($replaces[$name]->getConstraint())) {
return self::MATCH_REPLACE;
}
return self::MATCH_NONE;

View File

@ -53,7 +53,8 @@ class Solver
{
$decisionStart = count($this->decisions) - 1;
for ($ruleIndex = 0; $ruleIndex < count($this->rules); $ruleIndex++) {
$rulesCount = count($this->rules);
for ($ruleIndex = 0; $ruleIndex < $rulesCount; $ruleIndex++) {
$rule = $this->rules->ruleById($ruleIndex);
if (!$rule->isAssertion() || $rule->isDisabled()) {

View File

@ -85,7 +85,7 @@ class JsonFile
$json = file_get_contents($this->path);
}
} catch (TransportException $e) {
throw new \RuntimeException($e->getMessage());
throw new \RuntimeException($e->getMessage(), 0, $e);
} catch (\Exception $e) {
throw new \RuntimeException('Could not read '.$this->path."\n\n".$e->getMessage());
}

View File

@ -189,7 +189,7 @@ class VersionParser
} else {
$parsedConstraint = $this->parseConstraints($constraint);
}
$res[] = new Link($source, $target, $parsedConstraint, $description, $constraint);
$res[strtolower($target)] = new Link($source, $target, $parsedConstraint, $description, $constraint);
}
return $res;

View File

@ -14,12 +14,15 @@ namespace Composer\Repository;
use Composer\Package\Loader\ArrayLoader;
use Composer\Package\PackageInterface;
use Composer\Package\AliasPackage;
use Composer\Package\Version\VersionParser;
use Composer\DependencyResolver\Pool;
use Composer\Json\JsonFile;
use Composer\Cache;
use Composer\Config;
use Composer\IO\IOInterface;
use Composer\Util\RemoteFilesystem;
use Composer\Downloader\TransportException;
/**
* @author Jordi Boggiano <j.boggiano@seld.be>
@ -29,13 +32,19 @@ class ComposerRepository extends ArrayRepository implements NotifiableRepository
protected $config;
protected $options;
protected $url;
protected $baseUrl;
protected $io;
protected $cache;
protected $notifyUrl;
protected $hasProviders = false;
protected $providerListing;
protected $providers = array();
protected $providersByUid = array();
protected $loader;
private $rawData;
private $minimalPackages;
private $degradedMode = false;
private $rootData;
public function __construct(array $repoConfig, IOInterface $io, Config $config)
{
@ -60,6 +69,7 @@ class ComposerRepository extends ArrayRepository implements NotifiableRepository
$this->config = $config;
$this->options = $repoConfig['options'];
$this->url = $repoConfig['url'];
$this->baseUrl = rtrim(preg_replace('{^(.*)(?:/packages.json)?(?:[?#].*)?$}', '$1', $this->url), '/');
$this->io = $io;
$this->cache = new Cache($io, $config->get('home').'/cache/'.preg_replace('{[^a-z0-9.]}i', '-', $this->url));
$this->loader = new ArrayLoader();
@ -182,6 +192,90 @@ class ComposerRepository extends ArrayRepository implements NotifiableRepository
return $aliasPackage;
}
public function hasProviders()
{
$this->loadRootServerFile();
return $this->hasProviders;
}
public function resetPackageIds()
{
foreach ($this->providersByUid as $package) {
$package->setId(-1);
}
}
public function whatProvides(Pool $pool, $name)
{
// skip platform packages
if ($name === 'php' || in_array(substr($name, 0, 4), array('ext-', 'lib-'), true) || $name === '__root__') {
return array();
}
if (isset($this->providers[$name])) {
return $this->providers[$name];
}
if (null === $this->providerListing) {
$this->loadProviderListings($this->loadRootServerFile());
}
$url = 'p/'.$name.'.json';
// package does not exist in this repo
if (!isset($this->providerListing[$url])) {
return array();
}
if ($this->cache->sha256($url) === $this->providerListing[$url]['sha256']) {
$packages = json_decode($this->cache->read($url), true);
} else {
$packages = $this->fetchFile($url, null, $this->providerListing[$url]['sha256']);
}
$this->providers[$name] = array();
foreach ($packages['packages'] as $versions) {
foreach ($versions as $version) {
// avoid loading the same objects twice
if (isset($this->providersByUid[$version['uid']])) {
// skip if already assigned
if (!isset($this->providers[$name][$version['uid']])) {
// expand alias in two packages
if ($this->providersByUid[$version['uid']] instanceof AliasPackage) {
$this->providers[$name][$version['uid']] = $this->providersByUid[$version['uid']]->getAliasOf();
$this->providers[$name][$version['uid'].'-alias'] = $this->providersByUid[$version['uid']];
} else {
$this->providers[$name][$version['uid']] = $this->providersByUid[$version['uid']];
}
}
} else {
if (!$pool->isPackageAcceptable($version['name'], VersionParser::parseStability($version['version']))) {
continue;
}
// load acceptable packages in the providers
$package = $this->createPackage($version, 'Composer\Package\Package');
$package->setRepository($this);
$this->providers[$name][$version['uid']] = $package;
$this->providersByUid[$version['uid']] = $package;
if ($package->getAlias()) {
$alias = $this->createAliasPackage($package);
$alias->setRepository($this);
$this->providers[$name][$version['uid'].'-alias'] = $alias;
// override provider with its alias so it can be expanded in the if block above
$this->providersByUid[$version['uid']] = $alias;
}
}
}
}
return $this->providers[$name];
}
/**
* {@inheritDoc}
*/
@ -196,8 +290,12 @@ class ComposerRepository extends ArrayRepository implements NotifiableRepository
}
}
protected function loadDataFromServer()
protected function loadRootServerFile()
{
if (null !== $this->rootData) {
return $this->rootData;
}
if (!extension_loaded('openssl') && 'https' === substr($this->url, 0, 5)) {
throw new \RuntimeException('You must enable the openssl extension in your php.ini to load information from '.$this->url);
}
@ -220,9 +318,42 @@ class ComposerRepository extends ArrayRepository implements NotifiableRepository
}
}
if (!empty($data['providers']) || !empty($data['providers-includes'])) {
$this->hasProviders = true;
}
return $this->rootData = $data;
}
protected function loadDataFromServer()
{
$data = $this->loadRootServerFile();
return $this->loadIncludes($data);
}
protected function loadProviderListings($data)
{
if (isset($data['providers'])) {
if (!is_array($this->providerListing)) {
$this->providerListing = array();
}
$this->providerListing = array_merge($this->providerListing, $data['providers']);
}
if (isset($data['providers-includes'])) {
foreach ($data['providers-includes'] as $include => $metadata) {
if ($this->cache->sha256($include) === $metadata['sha256']) {
$includedData = json_decode($this->cache->read($include), true);
} else {
$includedData = $this->fetchFile($include, null, $metadata['sha256']);
}
$this->loadProviderListings($includedData);
}
}
}
protected function loadIncludes($data)
{
$packages = array();
@ -269,11 +400,11 @@ class ComposerRepository extends ArrayRepository implements NotifiableRepository
}
}
protected function fetchFile($filename, $cacheKey = null)
protected function fetchFile($filename, $cacheKey = null, $sha256 = null)
{
if (!$cacheKey) {
$cacheKey = $filename;
$filename = $this->url.'/'.$filename;
$filename = $this->baseUrl.'/'.$filename;
}
$retries = 3;
@ -281,7 +412,11 @@ class ComposerRepository extends ArrayRepository implements NotifiableRepository
try {
$json = new JsonFile($filename, new RemoteFilesystem($this->io, $this->options));
$data = $json->read();
$this->cache->write($cacheKey, json_encode($data));
$encoded = json_encode($data);
if ($sha256 && $sha256 !== hash('sha256', $encoded)) {
throw new \UnexpectedValueException('The contents of '.$filename.' do not match its signature, this may be due to a temporary glitch or a man-in-the-middle attack, aborting for safety. Please try running Composer again.');
}
$this->cache->write($cacheKey, $encoded);
break;
} catch (\Exception $e) {

View File

@ -129,20 +129,4 @@ class PoolTest extends TestCase
$this->assertEquals(array(), $pool->whatProvides('foo'));
}
public function testGetMaxId()
{
$pool = new Pool;
$repository = new ArrayRepository;
$firstPackage = $this->getPackage('foo', '1');
$secondPackage = $this->getPackage('foo1', '1');
$this->assertEquals(0, $pool->getMaxId());
$repository->addPackage($firstPackage);
$repository->addPackage($secondPackage);
$pool->addRepository($repository);
$this->assertEquals(2, $pool->getMaxId());
}
}

View File

@ -19,6 +19,7 @@ use Composer\DependencyResolver\Solver;
use Composer\DependencyResolver\SolverProblemsException;
use Composer\Package\Link;
use Composer\Test\TestCase;
use Composer\Package\LinkConstraint\MultiConstraint;
class SolverTest extends TestCase
{
@ -103,7 +104,7 @@ class SolverTest extends TestCase
$this->repo->addPackage($packageB = $this->getPackage('B', '1.0'));
$this->repo->addPackage($newPackageB = $this->getPackage('B', '1.1'));
$packageA->setRequires(array(new Link('A', 'B', $this->getVersionConstraint('<', '1.1'), 'requires')));
$packageA->setRequires(array('b' => new Link('A', 'B', $this->getVersionConstraint('<', '1.1'), 'requires')));
$this->reposComplete();
@ -124,9 +125,11 @@ class SolverTest extends TestCase
$this->repo->addPackage($newPackageB13 = $this->getPackage('B', '1.3'));
$packageA->setRequires(array(
new Link('A', 'B', $this->getVersionConstraint('<=', '1.3'), 'requires'),
new Link('A', 'B', $this->getVersionConstraint('<>', '1.3'), 'requires'),
new Link('A', 'B', $this->getVersionConstraint('!=', '1.2'), 'requires'),
'b' => new Link('A', 'B', new MultiConstraint(array(
$this->getVersionConstraint('<=', '1.3'),
$this->getVersionConstraint('<>', '1.3'),
$this->getVersionConstraint('!=', '1.2'),
)), 'requires'),
));
$this->reposComplete();
@ -146,11 +149,11 @@ class SolverTest extends TestCase
$this->repo->addPackage($packageC = $this->getPackage('C', '1.0'));
$packageB->setRequires(array(
new Link('B', 'A', $this->getVersionConstraint('>=', '1.0'), 'requires'),
new Link('B', 'C', $this->getVersionConstraint('>=', '1.0'), 'requires'),
'a' => new Link('B', 'A', $this->getVersionConstraint('>=', '1.0'), 'requires'),
'c' => new Link('B', 'C', $this->getVersionConstraint('>=', '1.0'), 'requires'),
));
$packageC->setRequires(array(
new Link('C', 'A', $this->getVersionConstraint('>=', '1.0'), 'requires'),
'a' => new Link('C', 'A', $this->getVersionConstraint('>=', '1.0'), 'requires'),
));
$this->reposComplete();
@ -216,7 +219,7 @@ class SolverTest extends TestCase
$this->repo->addPackage($newPackageB = $this->getPackage('B', '1.1'));
$this->reposComplete();
$packageA->setRequires(array(new Link('A', 'B', $this->getVersionConstraint('>=', '1.0.0.0'), 'requires')));
$packageA->setRequires(array('b' => new Link('A', 'B', $this->getVersionConstraint('>=', '1.0.0.0'), 'requires')));
$this->request->install('A', $this->getVersionConstraint('=', '1.0.0.0'));
$this->request->install('B', $this->getVersionConstraint('=', '1.1.0.0'));
@ -249,8 +252,8 @@ class SolverTest extends TestCase
$this->repo->addPackage($newPackageA = $this->getPackage('A', '1.1'));
$this->repo->addPackage($newPackageB = $this->getPackage('B', '1.1'));
$packageA->setRequires(array(new Link('A', 'B', null, 'requires')));
$newPackageA->setRequires(array(new Link('A', 'B', null, 'requires')));
$packageA->setRequires(array('b' => new Link('A', 'B', null, 'requires')));
$newPackageA->setRequires(array('b' => new Link('A', 'B', null, 'requires')));
$this->reposComplete();
@ -361,7 +364,7 @@ class SolverTest extends TestCase
$this->repo->addPackage($newPackageB = $this->getPackage('B', '1.1'));
$this->repo->addPackage($packageC = $this->getPackage('C', '1.1'));
$this->repo->addPackage($this->getPackage('D', '1.0'));
$packageA->setRequires(array(new Link('A', 'B', $this->getVersionConstraint('<', '1.1'), 'requires')));
$packageA->setRequires(array('b' => new Link('A', 'B', $this->getVersionConstraint('<', '1.1'), 'requires')));
$this->reposComplete();
@ -384,8 +387,8 @@ class SolverTest extends TestCase
$this->repo->addPackage($middlePackageB = $this->getPackage('B', '1.0'));
$this->repo->addPackage($newPackageB = $this->getPackage('B', '1.1'));
$this->repo->addPackage($oldPackageB = $this->getPackage('B', '0.9'));
$packageA->setRequires(array(new Link('A', 'B', $this->getVersionConstraint('<', '1.1'), 'requires')));
$packageA->setConflicts(array(new Link('A', 'B', $this->getVersionConstraint('<', '1.0'), 'conflicts')));
$packageA->setRequires(array('b' => new Link('A', 'B', $this->getVersionConstraint('<', '1.1'), 'requires')));
$packageA->setConflicts(array('b' => new Link('A', 'B', $this->getVersionConstraint('<', '1.0'), 'conflicts')));
$this->reposComplete();
@ -401,7 +404,7 @@ class SolverTest extends TestCase
{
$this->repoInstalled->addPackage($packageA = $this->getPackage('A', '1.0'));
$this->repo->addPackage($packageB = $this->getPackage('B', '1.0'));
$packageB->setReplaces(array(new Link('B', 'A', null)));
$packageB->setReplaces(array('a' => new Link('B', 'A', null)));
$this->reposComplete();
@ -430,8 +433,8 @@ class SolverTest extends TestCase
{
$this->repo->addPackage($packageA = $this->getPackage('A', '1.0'));
$this->repo->addPackage($packageQ = $this->getPackage('Q', '1.0'));
$packageA->setRequires(array(new Link('A', 'B', $this->getVersionConstraint('>=', '1.0'), 'requires')));
$packageQ->setProvides(array(new Link('Q', 'B', $this->getVersionConstraint('=', '1.0'), 'provides')));
$packageA->setRequires(array('b' => new Link('A', 'B', $this->getVersionConstraint('>=', '1.0'), 'requires')));
$packageQ->setProvides(array('b' => new Link('Q', 'B', $this->getVersionConstraint('=', '1.0'), 'provides')));
$this->reposComplete();
@ -448,8 +451,8 @@ class SolverTest extends TestCase
$this->repo->addPackage($packageA = $this->getPackage('A', '1.0'));
$this->repo->addPackage($packageQ = $this->getPackage('Q', '1.0'));
$this->repo->addPackage($packageB = $this->getPackage('B', '1.0'));
$packageA->setRequires(array(new Link('A', 'B', $this->getVersionConstraint('>=', '1.0'), 'requires')));
$packageQ->setReplaces(array(new Link('Q', 'B', $this->getVersionConstraint('>=', '1.0'), 'replaces')));
$packageA->setRequires(array('b' => new Link('A', 'B', $this->getVersionConstraint('>=', '1.0'), 'requires')));
$packageQ->setReplaces(array('b' => new Link('Q', 'B', $this->getVersionConstraint('>=', '1.0'), 'replaces')));
$this->reposComplete();
@ -465,8 +468,8 @@ class SolverTest extends TestCase
{
$this->repo->addPackage($packageA = $this->getPackage('A', '1.0'));
$this->repo->addPackage($packageQ = $this->getPackage('Q', '1.0'));
$packageA->setRequires(array(new Link('A', 'B', $this->getVersionConstraint('>=', '1.0'), 'requires')));
$packageQ->setReplaces(array(new Link('Q', 'B', $this->getVersionConstraint('>=', '1.0'), 'replaces')));
$packageA->setRequires(array('b' => new Link('A', 'B', $this->getVersionConstraint('>=', '1.0'), 'requires')));
$packageQ->setReplaces(array('b' => new Link('Q', 'B', $this->getVersionConstraint('>=', '1.0'), 'replaces')));
$this->reposComplete();
@ -483,8 +486,8 @@ class SolverTest extends TestCase
$this->repo->addPackage($packageA = $this->getPackage('A', '1.0'));
$this->repo->addPackage($packageQ = $this->getPackage('Q', '1.0'));
$this->repo->addPackage($packageB = $this->getPackage('B', '1.0'));
$packageA->setRequires(array(new Link('A', 'B', $this->getVersionConstraint('>=', '1.0'), 'requires')));
$packageQ->setReplaces(array(new Link('Q', 'B', $this->getVersionConstraint('>=', '1.0'), 'replaces')));
$packageA->setRequires(array('b' => new Link('A', 'B', $this->getVersionConstraint('>=', '1.0'), 'requires')));
$packageQ->setReplaces(array('b' => new Link('Q', 'B', $this->getVersionConstraint('>=', '1.0'), 'replaces')));
$this->reposComplete();
@ -501,24 +504,28 @@ class SolverTest extends TestCase
{
$this->repo->addPackage($packageX = $this->getPackage('X', '1.0'));
$packageX->setRequires(array(
new Link('X', 'A', $this->getVersionConstraint('>=', '2.0.0.0'), 'requires'),
new Link('X', 'B', $this->getVersionConstraint('>=', '2.0.0.0'), 'requires')));
'a' => new Link('X', 'A', $this->getVersionConstraint('>=', '2.0.0.0'), 'requires'),
'b' => new Link('X', 'B', $this->getVersionConstraint('>=', '2.0.0.0'), 'requires')
));
$this->repo->addPackage($packageA = $this->getPackage('A', '2.0.0'));
$this->repo->addPackage($newPackageA = $this->getPackage('A', '2.1.0'));
$this->repo->addPackage($newPackageB = $this->getPackage('B', '2.1.0'));
$packageA->setRequires(array(new Link('A', 'B', $this->getVersionConstraint('>=', '2.0.0.0'), 'requires')));
$packageA->setRequires(array('b' => new Link('A', 'B', $this->getVersionConstraint('>=', '2.0.0.0'), 'requires')));
// new package A depends on version of package B that does not exist
// => new package A is not installable
$newPackageA->setRequires(array(new Link('A', 'B', $this->getVersionConstraint('>=', '2.2.0.0'), 'requires')));
$newPackageA->setRequires(array('b' => new Link('A', 'B', $this->getVersionConstraint('>=', '2.2.0.0'), 'requires')));
// add a package S replacing both A and B, so that S and B or S and A cannot be simultaneously installed
// but an alternative option for A and B both exists
// this creates a more difficult so solve conflict
$this->repo->addPackage($packageS = $this->getPackage('S', '2.0.0'));
$packageS->setReplaces(array(new Link('S', 'A', $this->getVersionConstraint('>=', '2.0.0.0'), 'replaces'), new Link('S', 'B', $this->getVersionConstraint('>=', '2.0.0.0'), 'replaces')));
$packageS->setReplaces(array(
'a' => new Link('S', 'A', $this->getVersionConstraint('>=', '2.0.0.0'), 'replaces'),
'b' => new Link('S', 'B', $this->getVersionConstraint('>=', '2.0.0.0'), 'replaces')
));
$this->reposComplete();
@ -536,8 +543,8 @@ class SolverTest extends TestCase
$this->repo->addPackage($packageA = $this->getPackage('A', '1.0'));
$this->repo->addPackage($packageB1 = $this->getPackage('B', '0.9'));
$this->repo->addPackage($packageB2 = $this->getPackage('B', '1.1'));
$packageA->setRequires(array(new Link('A', 'B', $this->getVersionConstraint('>=', '1.0'), 'requires')));
$packageB2->setRequires(array(new Link('B', 'A', $this->getVersionConstraint('>=', '1.0'), 'requires')));
$packageA->setRequires(array('b' => new Link('A', 'B', $this->getVersionConstraint('>=', '1.0'), 'requires')));
$packageB2->setRequires(array('a' => new Link('B', 'A', $this->getVersionConstraint('>=', '1.0'), 'requires')));
$this->reposComplete();
@ -555,13 +562,13 @@ class SolverTest extends TestCase
$this->repo->addPackage($packageB = $this->getPackage('B', '1.0'));
$this->repo->addPackage($packageC = $this->getPackage('C', '1.0'));
$this->repo->addPackage($packageD = $this->getPackage('D', '1.0'));
$packageA->setRequires(array(new Link('A', 'B', $this->getVersionConstraint('>=', '1.0'), 'requires')));
$packageB->setRequires(array(new Link('B', 'Virtual', $this->getVersionConstraint('>=', '1.0'), 'requires')));
$packageC->setProvides(array(new Link('C', 'Virtual', $this->getVersionConstraint('==', '1.0'), 'provides')));
$packageD->setProvides(array(new Link('D', 'Virtual', $this->getVersionConstraint('==', '1.0'), 'provides')));
$packageA->setRequires(array('b' => new Link('A', 'B', $this->getVersionConstraint('>=', '1.0'), 'requires')));
$packageB->setRequires(array('virtual' => new Link('B', 'Virtual', $this->getVersionConstraint('>=', '1.0'), 'requires')));
$packageC->setProvides(array('virtual' => new Link('C', 'Virtual', $this->getVersionConstraint('==', '1.0'), 'provides')));
$packageD->setProvides(array('virtual' => new Link('D', 'Virtual', $this->getVersionConstraint('==', '1.0'), 'provides')));
$packageC->setRequires(array(new Link('C', 'A', $this->getVersionConstraint('==', '1.0'), 'requires')));
$packageD->setRequires(array(new Link('D', 'A', $this->getVersionConstraint('==', '1.0'), 'requires')));
$packageC->setRequires(array('a' => new Link('C', 'A', $this->getVersionConstraint('==', '1.0'), 'requires')));
$packageD->setRequires(array('a' => new Link('D', 'A', $this->getVersionConstraint('==', '1.0'), 'requires')));
$this->reposComplete();
@ -586,18 +593,18 @@ class SolverTest extends TestCase
$this->repo->addPackage($packageD2 = $this->getPackage('D', '1.1'));
$packageA->setRequires(array(
new Link('A', 'B', $this->getVersionConstraint('>=', '1.0'), 'requires'),
new Link('A', 'C', $this->getVersionConstraint('>=', '1.0'), 'requires'),
'b' => new Link('A', 'B', $this->getVersionConstraint('>=', '1.0'), 'requires'),
'c' => new Link('A', 'C', $this->getVersionConstraint('>=', '1.0'), 'requires'),
));
$packageD->setReplaces(array(
new Link('D', 'B', $this->getVersionConstraint('>=', '1.0'), 'replaces'),
new Link('D', 'C', $this->getVersionConstraint('>=', '1.0'), 'replaces'),
'b' => new Link('D', 'B', $this->getVersionConstraint('>=', '1.0'), 'replaces'),
'c' => new Link('D', 'C', $this->getVersionConstraint('>=', '1.0'), 'replaces'),
));
$packageD2->setReplaces(array(
new Link('D', 'B', $this->getVersionConstraint('>=', '1.0'), 'replaces'),
new Link('D', 'C', $this->getVersionConstraint('>=', '1.0'), 'replaces'),
'b' => new Link('D', 'B', $this->getVersionConstraint('>=', '1.0'), 'replaces'),
'c' => new Link('D', 'C', $this->getVersionConstraint('>=', '1.0'), 'replaces'),
));
$this->reposComplete();
@ -621,19 +628,19 @@ class SolverTest extends TestCase
$this->repo->addPackage($packageD = $this->getPackage('D', '2.0.9'));
$packageC->setRequires(array(
new Link('C', 'A', $this->getVersionConstraint('>=', '2.0'), 'requires'),
new Link('C', 'D', $this->getVersionConstraint('>=', '2.0'), 'requires'),
'a' => new Link('C', 'A', $this->getVersionConstraint('>=', '2.0'), 'requires'),
'd' => new Link('C', 'D', $this->getVersionConstraint('>=', '2.0'), 'requires'),
));
$packageD->setRequires(array(
new Link('D', 'A', $this->getVersionConstraint('>=', '2.1'), 'requires'),
new Link('D', 'B', $this->getVersionConstraint('>=', '2.0-dev'), 'requires'),
'a' => new Link('D', 'A', $this->getVersionConstraint('>=', '2.1'), 'requires'),
'b' => new Link('D', 'B', $this->getVersionConstraint('>=', '2.0-dev'), 'requires'),
));
$packageB1->setRequires(array(new Link('B', 'A', $this->getVersionConstraint('==', '2.1.0.0-dev'), 'requires')));
$packageB2->setRequires(array(new Link('B', 'A', $this->getVersionConstraint('==', '2.1.0.0-dev'), 'requires')));
$packageB1->setRequires(array('a' => new Link('B', 'A', $this->getVersionConstraint('==', '2.1.0.0-dev'), 'requires')));
$packageB2->setRequires(array('a' => new Link('B', 'A', $this->getVersionConstraint('==', '2.1.0.0-dev'), 'requires')));
$packageB2->setReplaces(array(new Link('B', 'D', $this->getVersionConstraint('==', '2.0.9.0'), 'replaces')));
$packageB2->setReplaces(array('d' => new Link('B', 'D', $this->getVersionConstraint('==', '2.0.9.0'), 'replaces')));
$this->reposComplete();
@ -650,7 +657,7 @@ class SolverTest extends TestCase
$this->repo->addPackage($packageB = $this->getPackage('B', '1.0'));;
$packageA->setConflicts(array(
new Link('A', 'B', $this->getVersionConstraint('>=', '1.0'), 'conflicts'),
'b' => new Link('A', 'B', $this->getVersionConstraint('>=', '1.0'), 'conflicts'),
));
$this->reposComplete();
@ -680,7 +687,7 @@ class SolverTest extends TestCase
$this->repo->addPackage($packageB = $this->getPackage('B', '1.0'));
$packageA->setRequires(array(
new Link('A', 'B', $this->getVersionConstraint('>=', '2.0'), 'requires'),
'b' => new Link('A', 'B', $this->getVersionConstraint('>=', '2.0'), 'requires'),
));
$this->reposComplete();
@ -717,16 +724,16 @@ class SolverTest extends TestCase
$this->repo->addPackage($packageD = $this->getPackage('D', '1.0'));
$packageA->setRequires(array(
new Link('A', 'B', $this->getVersionConstraint('>=', '1.0'), 'requires'),
'b' => new Link('A', 'B', $this->getVersionConstraint('>=', '1.0'), 'requires'),
));
$packageB->setRequires(array(
new Link('B', 'C', $this->getVersionConstraint('>=', '1.0'), 'requires'),
'c' => new Link('B', 'C', $this->getVersionConstraint('>=', '1.0'), 'requires'),
));
$packageC->setRequires(array(
new Link('C', 'D', $this->getVersionConstraint('>=', '1.0'), 'requires'),
'd' => new Link('C', 'D', $this->getVersionConstraint('>=', '1.0'), 'requires'),
));
$packageD->setRequires(array(
new Link('D', 'B', $this->getVersionConstraint('<', '1.0'), 'requires'),
'b' => new Link('D', 'B', $this->getVersionConstraint('<', '1.0'), 'requires'),
));
$this->reposComplete();
@ -761,11 +768,11 @@ class SolverTest extends TestCase
$this->repo->addPackage($packageTwigBridge = $this->getPackage('symfony/twig-bridge', '2.0'));
$packageTwigBridge->setRequires(array(
new Link('symfony/twig-bridge', 'twig/twig', $this->getVersionConstraint('<', '2.0'), 'requires'),
'twig/twig' => new Link('symfony/twig-bridge', 'twig/twig', $this->getVersionConstraint('<', '2.0'), 'requires'),
));
$packageSymfony->setReplaces(array(
new Link('symfony/symfony', 'symfony/twig-bridge', $this->getVersionConstraint('==', '2.0'), 'replaces'),
'symfony/twig-bridge' => new Link('symfony/symfony', 'symfony/twig-bridge', $this->getVersionConstraint('==', '2.0'), 'replaces'),
));
$this->reposComplete();
@ -786,10 +793,10 @@ class SolverTest extends TestCase
$this->repo->addPackage($packageA2 = $this->getPackage('A', '2.0'));
$packageA2->setRequires(array(
new Link('A', 'B', $this->getVersionConstraint('==', '2.0'), 'requires', '== 2.0'),
'b' => new Link('A', 'B', $this->getVersionConstraint('==', '2.0'), 'requires', '== 2.0'),
));
$packageB->setRequires(array(
new Link('B', 'A', $this->getVersionConstraint('>=', '2.0'), 'requires'),
'a' => new Link('B', 'A', $this->getVersionConstraint('>=', '2.0'), 'requires'),
));
$this->repo->addPackage($packageA2Alias = $this->getAliasPackage($packageA2, '1.1'));
@ -811,7 +818,7 @@ class SolverTest extends TestCase
$this->repo->addPackage($packageB = $this->getPackage('B', '1.0'));
$packageB->setRequires(array(
new Link('B', 'A', $this->getVersionConstraint('<', '2.0'), 'requires'),
'a' => new Link('B', 'A', $this->getVersionConstraint('<', '2.0'), 'requires'),
));
$this->repo->addPackage($packageAAlias = $this->getAliasPackage($packageA, '1.1'));

View File

@ -34,7 +34,7 @@ class ArrayLoaderTest extends \PHPUnit_Framework_TestCase
$package = $this->loader->load($config);
$replaces = $package->getReplaces();
$this->assertEquals('== 1.2.3.4', (string) $replaces[0]->getConstraint());
$this->assertEquals('== 1.2.3.4', (string) $replaces['foo']->getConstraint());
}
public function testTypeDefault()