diff --git a/doc/04-schema.md b/doc/04-schema.md
index 96d89289b..5f2ecca67 100644
--- a/doc/04-schema.md
+++ b/doc/04-schema.md
@@ -200,22 +200,10 @@ An example:
Optional, but highly recommended.
-### Package links (require, require-dev, conflict, replace, provide)
+### Package links
-Each of these takes an object which maps package names to version constraints.
-
-* **require:** Packages required by this package.
-* **require-dev:** Packages required for developing this package, or running
- tests, etc. They are installed if install or update is ran with `--dev`.
-* **conflict:** Mark this version of this package as conflicting with other
- packages.
-* **replace:** Packages that can be replaced by this package. This is useful
- for large repositories with subtree splits. It allows the main package to
- replace all of it's child packages.
-* **provide:** List of other packages that are provided by this package. This
- is mostly useful for common interfaces. A package could depend on some virtual
- `logger` package, any library that provides this logger, would simply list it
- in `provide`.
+All of the following take an object which maps package names to
+[version constraints](01-basic-usage.md#package-versions).
Example:
@@ -225,7 +213,59 @@ Example:
}
}
-Optional.
+All links are optional fields.
+
+`require` and `require-dev` additionally support stability flags (root-only).
+These allow you to further restrict or expand the stability of a package beyond
+the scope of the [minimum-stability](#minimum-stability) setting. You can apply
+them to a constraint, or just apply them to an empty constraint if you want to
+allow unstable packages of a dependency's dependency for example.
+
+Example:
+
+ {
+ "require": {
+ "monolog/monolog": "1.0.*@beta"
+ "acme/foo": "@dev"
+ }
+ }
+
+#### require
+
+Lists packages required by this package. The package will not be installed
+unless those requirements can be met.
+
+#### require-dev
+
+Lists packages required for developing this package, or running
+tests, etc. They are installed if install or update is ran with `--dev`.
+
+#### conflict
+
+Lists packages that conflict with this version of this package. They
+will not be allowed to be installed together with your package.
+
+#### replace
+
+Lists packages that are replaced by this package.
+
+This is useful for packages that contain sub-packages, for example the main
+symfony/symfony package contains all the Symfony Components which are also
+available as individual packages. If you require the main package it will
+automatically fulfill any requirement of one of the individual components,
+since it replaces them.
+
+Caution is advised when using replace however, for the sub-package example
+above you should typically only replace using `self.version` as a version
+constraint, to make sure the main package only replaces the sub-packages of
+that exact version, and not any other version, which would be incorrect.
+
+#### provide
+
+List of other packages that are provided by this package. This is mostly
+useful for common interfaces. A package could depend on some virtual
+`logger` package, any library that implements this logger interface would
+simply list it in `provide`.
### suggest
@@ -340,6 +380,19 @@ To do that, `autoload` and `target-dir` are defined as follows:
Optional.
+### minimum-stability (root-only)
+
+This defines the default behavior for filtering packages by stability. This
+defaults to `dev` but in the future will be switched to `stable`. As such if
+you rely on a default of `dev` you should specify it in your file to avoid
+surprises.
+
+All versions of each package is checked for stability, and those that are less
+stable than the `minimum-stability` setting will be ignored when resolving
+your project dependencies. Specific changes to the stability requirements of
+a given package can be done in `require` or `require-dev` (see
+[package links](#package-links)).
+
### repositories (root-only)
Custom package repositories to use.
diff --git a/res/composer-schema.json b/res/composer-schema.json
index f1f7ed1f9..35377faff 100644
--- a/res/composer-schema.json
+++ b/res/composer-schema.json
@@ -143,6 +143,10 @@
"description": "A set of additional repositories where packages can be found.",
"additionalProperties": true
},
+ "minimum-stability": {
+ "type": ["string"],
+ "description": "The minimum stability the packages must have to be install-able. Possible values are: dev, alpha, beta, RC, stable."
+ },
"bin": {
"type": ["array"],
"description": "A set of files that should be treated as binaries and symlinked into bin-dir (from config).",
diff --git a/src/Composer/DependencyResolver/Pool.php b/src/Composer/DependencyResolver/Pool.php
index 24ef5427a..2b8dec0ad 100644
--- a/src/Composer/DependencyResolver/Pool.php
+++ b/src/Composer/DependencyResolver/Pool.php
@@ -12,19 +12,39 @@
namespace Composer\DependencyResolver;
+use Composer\Package\BasePackage;
use Composer\Package\LinkConstraint\LinkConstraintInterface;
use Composer\Repository\RepositoryInterface;
+use Composer\Repository\CompositeRepository;
+use Composer\Repository\InstalledRepositoryInterface;
+use Composer\Repository\PlatformRepository;
/**
* A package pool contains repositories that provide packages.
*
* @author Nils Adermann
+ * @author Jordi Boggiano
*/
class Pool
{
protected $repositories = array();
protected $packages = array();
protected $packageByName = array();
+ protected $acceptableStabilities;
+ protected $stabilityFlags;
+
+ // TODO BC change to stable end of june?
+ public function __construct($minimumStability = 'dev', array $stabilityFlags = array())
+ {
+ $stabilities = BasePackage::$stabilities;
+ $this->acceptableStabilities = array();
+ foreach (BasePackage::$stabilities as $stability => $value) {
+ if ($value <= BasePackage::$stabilities[$minimumStability]) {
+ $this->acceptableStabilities[$stability] = $value;
+ }
+ }
+ $this->stabilityFlags = $stabilityFlags;
+ }
/**
* Adds a repository and its packages to this package pool
@@ -33,14 +53,38 @@ class Pool
*/
public function addRepository(RepositoryInterface $repo)
{
- $this->repositories[] = $repo;
+ if ($repo instanceof CompositeRepository) {
+ $repos = $repo->getRepositories();
+ } else {
+ $repos = array($repo);
+ }
- foreach ($repo->getPackages() as $package) {
- $package->setId(count($this->packages) + 1);
- $this->packages[] = $package;
+ $id = count($this->packages) + 1;
+ foreach ($repos as $repo) {
+ $this->repositories[] = $repo;
- foreach ($package->getNames() as $name) {
- $this->packageByName[$name][] = $package;
+ $exempt = $repo instanceof PlatformRepository || $repo instanceof InstalledRepositoryInterface;
+ foreach ($repo->getPackages() as $package) {
+ $name = $package->getName();
+ $stability = $package->getStability();
+ if (
+ // always allow exempt repos
+ $exempt
+ // allow if package matches the global stability requirement and has no exception
+ || (!isset($this->stabilityFlags[$name])
+ && isset($this->acceptableStabilities[$stability]))
+ // allow if package matches the package-specific stability flag
+ || (isset($this->stabilityFlags[$name])
+ && BasePackage::$stabilities[$stability] <= $this->stabilityFlags[$name]
+ )
+ ) {
+ $package->setId($id++);
+ $this->packages[] = $package;
+
+ foreach ($package->getNames() as $name) {
+ $this->packageByName[$name][] = $package;
+ }
+ }
}
}
}
diff --git a/src/Composer/Installer.php b/src/Composer/Installer.php
index 2f7a3b137..0eed0050a 100644
--- a/src/Composer/Installer.php
+++ b/src/Composer/Installer.php
@@ -29,6 +29,7 @@ use Composer\Package\Locker;
use Composer\Package\PackageInterface;
use Composer\Repository\ArrayRepository;
use Composer\Repository\CompositeRepository;
+use Composer\Repository\InstalledArrayRepository;
use Composer\Repository\PlatformRepository;
use Composer\Repository\RepositoryInterface;
use Composer\Repository\RepositoryManager;
@@ -139,7 +140,7 @@ class Installer
$repos = array_merge(
$this->repositoryManager->getLocalRepositories(),
array(
- new ArrayRepository(array($this->package)),
+ new InstalledArrayRepository(array($this->package)),
new PlatformRepository(),
)
);
@@ -179,7 +180,9 @@ class Installer
$updatedLock = $this->locker->setLockData(
$this->repositoryManager->getLocalRepository()->getPackages(),
$this->devMode ? $this->repositoryManager->getLocalDevRepository()->getPackages() : null,
- $aliases
+ $aliases,
+ $this->package->getMinimumStability(),
+ $this->package->getStabilityFlags()
);
if ($updatedLock) {
$this->io->write('Writing lock file');
@@ -201,13 +204,18 @@ class Installer
protected function doInstall($localRepo, $installedRepo, $aliases, $devMode = false)
{
+ $minimumStability = $this->package->getMinimumStability();
+ $stabilityFlags = $this->package->getStabilityFlags();
+
// initialize locker to create aliased packages
if (!$this->update && $this->locker->isLocked($devMode)) {
$lockedPackages = $this->locker->getLockedPackages($devMode);
+ $minimumStability = $this->locker->getMinimumStability();
+ $stabilityFlags = $this->locker->getStabilityFlags();
}
// creating repository pool
- $pool = new Pool;
+ $pool = new Pool($minimumStability, $stabilityFlags);
$pool->addRepository($installedRepo);
foreach ($this->repositoryManager->getRepositories() as $repository) {
$pool->addRepository($repository);
diff --git a/src/Composer/Package/AliasPackage.php b/src/Composer/Package/AliasPackage.php
index 6670b93e5..6835226d8 100644
--- a/src/Composer/Package/AliasPackage.php
+++ b/src/Composer/Package/AliasPackage.php
@@ -28,6 +28,7 @@ class AliasPackage extends BasePackage
protected $dev;
protected $aliasOf;
protected $rootPackageAlias = false;
+ protected $stability;
protected $requires;
protected $conflicts;
@@ -50,7 +51,8 @@ class AliasPackage extends BasePackage
$this->version = $version;
$this->prettyVersion = $prettyVersion;
$this->aliasOf = $aliasOf;
- $this->dev = VersionParser::isDev($version);
+ $this->stability = VersionParser::parseStability($version);
+ $this->dev = $this->stability === 'dev';
// replace self.version dependencies
foreach (array('requires', 'devRequires') as $type) {
@@ -91,6 +93,14 @@ class AliasPackage extends BasePackage
return $this->version;
}
+ /**
+ * {@inheritDoc}
+ */
+ public function getStability()
+ {
+ return $this->stability;
+ }
+
/**
* {@inheritDoc}
*/
diff --git a/src/Composer/Package/BasePackage.php b/src/Composer/Package/BasePackage.php
index 171c5ee08..299c9b17c 100644
--- a/src/Composer/Package/BasePackage.php
+++ b/src/Composer/Package/BasePackage.php
@@ -32,6 +32,20 @@ abstract class BasePackage implements PackageInterface
'require-dev' => array('description' => 'requires (for development)', 'method' => 'devRequires'),
);
+ const STABILITY_STABLE = 0;
+ const STABILITY_RC = 5;
+ const STABILITY_BETA = 10;
+ const STABILITY_ALPHA = 15;
+ const STABILITY_DEV = 20;
+
+ public static $stabilities = array(
+ 'stable' => self::STABILITY_STABLE,
+ 'RC' => self::STABILITY_RC,
+ 'beta' => self::STABILITY_BETA,
+ 'alpha' => self::STABILITY_ALPHA,
+ 'dev' => self::STABILITY_DEV,
+ );
+
protected $name;
protected $prettyName;
diff --git a/src/Composer/Package/Loader/RootPackageLoader.php b/src/Composer/Package/Loader/RootPackageLoader.php
index 496463222..1742b5632 100644
--- a/src/Composer/Package/Loader/RootPackageLoader.php
+++ b/src/Composer/Package/Loader/RootPackageLoader.php
@@ -12,6 +12,7 @@
namespace Composer\Package\Loader;
+use Composer\Package\BasePackage;
use Composer\Package\Version\VersionParser;
use Composer\Repository\RepositoryManager;
use Composer\Util\ProcessExecutor;
@@ -60,20 +61,22 @@ class RootPackageLoader extends ArrayLoader
$package = parent::load($config);
+ $aliases = array();
+ $stabilityFlags = array();
if (isset($config['require'])) {
- $aliases = array();
- foreach ($config['require'] as $reqName => $reqVersion) {
- if (preg_match('{^([^,\s]+) +as +([^,\s]+)$}', $reqVersion, $match)) {
- $aliases[] = array(
- 'package' => strtolower($reqName),
- 'version' => $this->versionParser->normalize($match[1]),
- 'alias' => $match[2],
- 'alias_normalized' => $this->versionParser->normalize($match[2]),
- );
- }
- }
+ $aliases = $this->extractAliases($config['require'], $aliases);
+ $stabilityFlags = $this->extractStabilityFlags($config['require'], $stabilityFlags);
+ }
+ if (isset($config['require-dev'])) {
+ $aliases = $this->extractAliases($config['require-dev'], $aliases);
+ $stabilityFlags = $this->extractStabilityFlags($config['require-dev'], $stabilityFlags);
+ }
- $package->setAliases($aliases);
+ $package->setAliases($aliases);
+ $package->setStabilityFlags($stabilityFlags);
+
+ if (isset($config['minimum-stability'])) {
+ $package->setMinimumStability(VersionParser::normalizeStability($config['minimum-stability']));
}
if (isset($config['repositories'])) {
@@ -95,4 +98,51 @@ class RootPackageLoader extends ArrayLoader
return $package;
}
+
+ private function extractAliases(array $requires, array $aliases)
+ {
+ foreach ($requires as $reqName => $reqVersion) {
+ if (preg_match('{^([^,\s]+) +as +([^,\s]+)$}', $reqVersion, $match)) {
+ $aliases[] = array(
+ 'package' => strtolower($reqName),
+ 'version' => $this->versionParser->normalize($match[1]),
+ 'alias' => $match[2],
+ 'alias_normalized' => $this->versionParser->normalize($match[2]),
+ );
+ }
+ }
+
+ return $aliases;
+ }
+
+ private function extractStabilityFlags(array $requires, array $stabilityFlags)
+ {
+ $stabilities = BasePackage::$stabilities;
+ foreach ($requires as $reqName => $reqVersion) {
+ // parse explicit stability flags
+ if (preg_match('{^[^,\s]*?@('.implode('|', array_keys($stabilities)).')$}i', $reqVersion, $match)) {
+ $name = strtolower($reqName);
+ $stability = $stabilities[VersionParser::normalizeStability($match[1])];
+
+ if (isset($stabilityFlags[$name]) && $stabilityFlags[$name] > $stability) {
+ continue;
+ }
+ $stabilityFlags[$name] = $stability;
+
+ continue;
+ }
+
+ // infer flags for requirements that have an explicit -dev or -beta version specified for example
+ if (preg_match('{^[^,\s@]+$}', $reqVersion) && 'stable' !== ($stabilityName = VersionParser::parseStability($reqVersion))) {
+ $name = strtolower($reqName);
+ $stability = $stabilities[$stabilityName];
+ if (isset($stabilityFlags[$name]) && $stabilityFlags[$name] > $stability) {
+ continue;
+ }
+ $stabilityFlags[$name] = $stability;
+ }
+ }
+
+ return $stabilityFlags;
+ }
}
diff --git a/src/Composer/Package/Locker.php b/src/Composer/Package/Locker.php
index 7f6b738f6..d7502bfdb 100644
--- a/src/Composer/Package/Locker.php
+++ b/src/Composer/Package/Locker.php
@@ -82,10 +82,10 @@ class Locker
*/
public function getLockedPackages($dev = false)
{
- $lockList = $this->getLockData();
+ $lockData = $this->getLockData();
$packages = array();
- $lockedPackages = $dev ? $lockList['packages-dev'] : $lockList['packages'];
+ $lockedPackages = $dev ? $lockData['packages-dev'] : $lockData['packages'];
$repo = $dev ? $this->repositoryManager->getLocalDevRepository() : $this->repositoryManager->getLocalRepository();
foreach ($lockedPackages as $info) {
@@ -128,22 +128,38 @@ class Locker
return $packages;
}
+ public function getMinimumStability()
+ {
+ $lockData = $this->getLockData();
+
+ // TODO BC change dev to stable end of june?
+ return isset($lockData['minimum-stability']) ? $lockData['minimum-stability'] : 'dev';
+ }
+
+ public function getStabilityFlags()
+ {
+ $lockData = $this->getLockData();
+
+ return isset($lockData['stability-flags']) ? $lockData['stability-flags'] : array();
+ }
+
public function getAliases()
{
- $lockList = $this->getLockData();
- return isset($lockList['aliases']) ? $lockList['aliases'] : array();
+ $lockData = $this->getLockData();
+
+ return isset($lockData['aliases']) ? $lockData['aliases'] : array();
}
public function getLockData()
{
- if (!$this->lockFile->exists()) {
- throw new \LogicException('No lockfile found. Unable to read locked packages');
- }
-
if (null !== $this->lockDataCache) {
return $this->lockDataCache;
}
+ if (!$this->lockFile->exists()) {
+ throw new \LogicException('No lockfile found. Unable to read locked packages');
+ }
+
return $this->lockDataCache = $this->lockFile->read();
}
@@ -156,13 +172,15 @@ class Locker
*
* @return Boolean
*/
- public function setLockData(array $packages, $devPackages, array $aliases)
+ public function setLockData(array $packages, $devPackages, array $aliases, $minimumStability, array $stabilityFlags)
{
$lock = array(
'hash' => $this->hash,
'packages' => null,
'packages-dev' => null,
'aliases' => $aliases,
+ 'minimum-stability' => $minimumStability,
+ 'stability-flags' => $stabilityFlags,
);
$lock['packages'] = $this->lockPackages($packages);
diff --git a/src/Composer/Package/MemoryPackage.php b/src/Composer/Package/MemoryPackage.php
index 147f94ed7..dcb973a5b 100644
--- a/src/Composer/Package/MemoryPackage.php
+++ b/src/Composer/Package/MemoryPackage.php
@@ -48,6 +48,10 @@ class MemoryPackage extends BasePackage
protected $prettyAlias;
protected $dev;
+ // TODO BC change dev to stable end of june?
+ protected $minimumStability = 'dev';
+ protected $stabilityFlags = array();
+
protected $requires = array();
protected $conflicts = array();
protected $provides = array();
@@ -71,7 +75,8 @@ class MemoryPackage extends BasePackage
$this->version = $version;
$this->prettyVersion = $prettyVersion;
- $this->dev = VersionParser::isDev($version);
+ $this->stability = VersionParser::parseStability($version);
+ $this->dev = $this->stability === 'dev';
}
/**
@@ -98,6 +103,14 @@ class MemoryPackage extends BasePackage
return $this->type ?: 'library';
}
+ /**
+ * {@inheritDoc}
+ */
+ public function getStability()
+ {
+ return $this->stability;
+ }
+
/**
* @param string $targetDir
*/
@@ -588,6 +601,42 @@ class MemoryPackage extends BasePackage
return $this->homepage;
}
+ /**
+ * Set the minimumStability
+ *
+ * @param string $minimumStability
+ */
+ public function setMinimumStability($minimumStability)
+ {
+ $this->minimumStability = $minimumStability;
+ }
+
+ /**
+ * {@inheritDoc}
+ */
+ public function getMinimumStability()
+ {
+ return $this->minimumStability;
+ }
+
+ /**
+ * Set the stabilityFlags
+ *
+ * @param array $stabilityFlags
+ */
+ public function setStabilityFlags(array $stabilityFlags)
+ {
+ $this->stabilityFlags = $stabilityFlags;
+ }
+
+ /**
+ * {@inheritDoc}
+ */
+ public function getStabilityFlags()
+ {
+ return $this->stabilityFlags;
+ }
+
/**
* Set the autoload mapping
*
diff --git a/src/Composer/Package/PackageInterface.php b/src/Composer/Package/PackageInterface.php
index 5b8d2ddb2..43a07d28b 100644
--- a/src/Composer/Package/PackageInterface.php
+++ b/src/Composer/Package/PackageInterface.php
@@ -180,6 +180,13 @@ interface PackageInterface
*/
function getPrettyVersion();
+ /**
+ * Returns the stability of this package: one of (dev, alpha, beta, RC, stable)
+ *
+ * @return string
+ */
+ function getStability();
+
/**
* Returns the package license, e.g. MIT, BSD, GPL
*
diff --git a/src/Composer/Package/Version/VersionParser.php b/src/Composer/Package/Version/VersionParser.php
index 57d0596cc..eedd5f3ae 100644
--- a/src/Composer/Package/Version/VersionParser.php
+++ b/src/Composer/Package/Version/VersionParser.php
@@ -12,6 +12,7 @@
namespace Composer\Package\Version;
+use Composer\Package\BasePackage;
use Composer\Package\LinkConstraint\MultiConstraint;
use Composer\Package\LinkConstraint\VersionConstraint;
@@ -22,17 +23,37 @@ use Composer\Package\LinkConstraint\VersionConstraint;
*/
class VersionParser
{
- private $modifierRegex = '[.-]?(?:(beta|RC|alpha|patch|pl|p)(?:[.-]?(\d+))?)?([.-]?dev)?';
+ private static $modifierRegex = '[.-]?(?:(beta|RC|alpha|patch|pl|p)(?:[.-]?(\d+))?)?([.-]?dev)?';
/**
- * Checks if a version is dev or not
+ * Returns the stability of a version
*
* @param string $version
- * @return Boolean
+ * @return string
*/
- static public function isDev($version)
+ static public function parseStability($version)
{
- return 'dev-' === substr($version, 0, 4) || '-dev' === substr($version, -4);
+ if ('dev-' === substr($version, 0, 4) || '-dev' === substr($version, -4)) {
+ return 'dev';
+ }
+
+ preg_match('{'.self::$modifierRegex.'$}', $version, $match);
+ if (!empty($match[3])) {
+ return 'dev';
+ }
+
+ if (!empty($match[1]) && ($match[1] === 'beta' || $match[1] === 'alpha' || $match[1] === 'RC')) {
+ return $match[1];
+ }
+
+ return 'stable';
+ }
+
+ static public function normalizeStability($stability)
+ {
+ $stability = strtolower($stability);
+
+ return $stability === 'rc' ? 'RC' : $stability;
}
/**
@@ -60,13 +81,13 @@ class VersionParser
}
// match classical versioning
- if (preg_match('{^v?(\d{1,3})(\.\d+)?(\.\d+)?(\.\d+)?'.$this->modifierRegex.'$}i', $version, $matches)) {
+ if (preg_match('{^v?(\d{1,3})(\.\d+)?(\.\d+)?(\.\d+)?'.self::$modifierRegex.'$}i', $version, $matches)) {
$version = $matches[1]
.(!empty($matches[2]) ? $matches[2] : '.0')
.(!empty($matches[3]) ? $matches[3] : '.0')
.(!empty($matches[4]) ? $matches[4] : '.0');
$index = 5;
- } elseif (preg_match('{^v?(\d{4}(?:[.:-]?\d{2}){1,6}(?:[.:-]?\d{1,3})?)'.$this->modifierRegex.'$}i', $version, $matches)) { // match date-based versioning
+ } elseif (preg_match('{^v?(\d{4}(?:[.:-]?\d{2}){1,6}(?:[.:-]?\d{1,3})?)'.self::$modifierRegex.'$}i', $version, $matches)) { // match date-based versioning
$version = preg_replace('{\D}', '-', $matches[1]);
$index = 2;
}
@@ -130,6 +151,10 @@ class VersionParser
*/
public function parseConstraints($constraints)
{
+ if (preg_match('{^([^,\s]*?)@('.implode('|', array_keys(BasePackage::$stabilities)).')$}i', $constraints, $match)) {
+ $constraints = empty($match[1]) ? '*' : $match[1];
+ }
+
$constraints = preg_split('{\s*,\s*}', trim($constraints));
if (count($constraints) > 1) {
diff --git a/src/Composer/Repository/CompositeRepository.php b/src/Composer/Repository/CompositeRepository.php
index e000d97e8..82b7e9b45 100644
--- a/src/Composer/Repository/CompositeRepository.php
+++ b/src/Composer/Repository/CompositeRepository.php
@@ -36,6 +36,16 @@ class CompositeRepository implements RepositoryInterface
$this->repositories = $repositories;
}
+ /**
+ * Returns all the wrapped repositories
+ *
+ * @return array
+ */
+ public function getRepositories()
+ {
+ return $this->repositories;
+ }
+
/**
* {@inheritdoc}
*/
diff --git a/src/Composer/Repository/InstalledArrayRepository.php b/src/Composer/Repository/InstalledArrayRepository.php
new file mode 100644
index 000000000..151d00190
--- /dev/null
+++ b/src/Composer/Repository/InstalledArrayRepository.php
@@ -0,0 +1,42 @@
+
+ * Jordi Boggiano
+ *
+ * For the full copyright and license information, please view the LICENSE
+ * file that was distributed with this source code.
+ */
+
+namespace Composer\Repository;
+
+use Composer\Json\JsonFile;
+use Composer\Package\PackageInterface;
+use Composer\Package\Loader\ArrayLoader;
+use Composer\Package\Dumper\ArrayDumper;
+
+/**
+ * Installed array repository.
+ *
+ * This is used for serving the RootPackage inside an in-memory InstalledRepository
+ *
+ * @author Jordi Boggiano
+ */
+class InstalledArrayRepository extends ArrayRepository implements InstalledRepositoryInterface
+{
+ /**
+ * {@inheritDoc}
+ */
+ public function write()
+ {
+ }
+
+ /**
+ * {@inheritDoc}
+ */
+ public function reload()
+ {
+ }
+}
diff --git a/tests/Composer/Test/DependencyResolver/PoolTest.php b/tests/Composer/Test/DependencyResolver/PoolTest.php
index c98570534..7c6618582 100644
--- a/tests/Composer/Test/DependencyResolver/PoolTest.php
+++ b/tests/Composer/Test/DependencyResolver/PoolTest.php
@@ -14,6 +14,7 @@ namespace Composer\Test\DependencyResolver;
use Composer\DependencyResolver\Pool;
use Composer\Repository\ArrayRepository;
+use Composer\Package\BasePackage;
use Composer\Test\TestCase;
class PoolTest extends TestCase
@@ -31,6 +32,22 @@ class PoolTest extends TestCase
$this->assertEquals(array($package), $pool->whatProvides('foo'));
}
+ public function testPoolIgnoresIrrelevantPackages()
+ {
+ $pool = new Pool('stable', array('bar' => BasePackage::STABILITY_BETA));
+ $repo = new ArrayRepository;
+ $repo->addPackage($package = $this->getPackage('bar', '1'));
+ $repo->addPackage($betaPackage = $this->getPackage('bar', '1-beta'));
+ $repo->addPackage($alphaPackage = $this->getPackage('bar', '1-alpha'));
+ $repo->addPackage($package2 = $this->getPackage('foo', '1'));
+ $repo->addPackage($rcPackage2 = $this->getPackage('foo', '1rc'));
+
+ $pool->addRepository($repo);
+
+ $this->assertEquals(array($package, $betaPackage), $pool->whatProvides('bar'));
+ $this->assertEquals(array($package2), $pool->whatProvides('foo'));
+ }
+
/**
* @expectedException \RuntimeException
*/
diff --git a/tests/Composer/Test/Package/LockerTest.php b/tests/Composer/Test/Package/LockerTest.php
index 729da4b93..a67beb277 100644
--- a/tests/Composer/Test/Package/LockerTest.php
+++ b/tests/Composer/Test/Package/LockerTest.php
@@ -157,9 +157,11 @@ class LockerTest extends \PHPUnit_Framework_TestCase
),
'packages-dev' => array(),
'aliases' => array(),
+ 'minimum-stability' => 'dev',
+ 'stability-flags' => array(),
));
- $locker->setLockData(array($package1, $package2), array(), array());
+ $locker->setLockData(array($package1, $package2), array(), array(), 'dev', array());
}
public function testLockBadPackages()
@@ -177,7 +179,7 @@ class LockerTest extends \PHPUnit_Framework_TestCase
$this->setExpectedException('LogicException');
- $locker->setLockData(array($package1), array(), array());
+ $locker->setLockData(array($package1), array(), array(), 'dev', array());
}
public function testIsFresh()
diff --git a/tests/Composer/Test/Package/Version/VersionParserTest.php b/tests/Composer/Test/Package/Version/VersionParserTest.php
index fa123e7dc..0be1b7269 100644
--- a/tests/Composer/Test/Package/Version/VersionParserTest.php
+++ b/tests/Composer/Test/Package/Version/VersionParserTest.php
@@ -106,6 +106,12 @@ class VersionParserTest extends \PHPUnit_Framework_TestCase
);
}
+ public function testParseConstraintsIgnoresStabilityFlag()
+ {
+ $parser = new VersionParser;
+ $this->assertSame((string) new VersionConstraint('=', '1.0.0.0'), (string) $parser->parseConstraints('1.0@dev'));
+ }
+
/**
* @dataProvider simpleConstraints
*/
@@ -195,21 +201,25 @@ class VersionParserTest extends \PHPUnit_Framework_TestCase
}
/**
- * @dataProvider dataIsDev
+ * @dataProvider stabilityProvider
*/
- public function testIsDev($expected, $version)
+ public function testParseStability($expected, $version)
{
- $this->assertSame($expected, VersionParser::isDev($version));
+ $this->assertSame($expected, VersionParser::parseStability($version));
}
- public function dataIsDev()
+ public function stabilityProvider()
{
return array(
- array(false, '1.0'),
- array(false, 'v2.0.*'),
- array(false, '3.0dev'),
- array(true, 'dev-master'),
- array(true, '3.1.2-dev'),
+ array('stable', '1.0'),
+ array('dev', 'v2.0.x-dev'),
+ array('RC', '3.0-RC2'),
+ array('dev', 'dev-master'),
+ array('dev', '3.1.2-dev'),
+ array('stable', '3.1.2-pl2'),
+ array('stable', '3.1.2-patch'),
+ array('alpha', '3.1.2-alpha5'),
+ array('beta', '3.1.2-beta'),
);
}
}