3 * This file is part of the Composer Merge plugin.
5 * Copyright (C) 2015 Bryan Davis, Wikimedia Foundation, and contributors
7 * This software may be modified and distributed under the terms of the MIT
8 * license. See the LICENSE file for details.
11 namespace Wikimedia\Composer\Merge;
13 use Composer\Package\BasePackage;
14 use Composer\Package\Version\VersionParser;
17 * Adapted from Composer's RootPackageLoader::extractStabilityFlags
18 * @author Bryan Davis <bd808@bd808.com>
24 * @var array Current package name => stability mappings
26 protected $stabilityFlags;
29 * @var int Current default minimum stability
31 protected $minimumStability;
34 * @var string Regex to extract an explict stability flag (eg '@dev')
36 protected $explicitStabilityRe;
40 * @param array $stabilityFlags Current package name => stability mappings
41 * @param int $minimumStability Current default minimum stability
43 public function __construct(
44 array $stabilityFlags = array(),
45 $minimumStability = BasePackage::STABILITY_STABLE
47 $this->stabilityFlags = $stabilityFlags;
48 $this->minimumStability = $this->getStabilityInt($minimumStability);
49 $this->explicitStabilityRe = '/^[^@]*?@(' .
50 implode('|', array_keys(BasePackage::$stabilities)) .
55 * Get the stability value for a given string.
57 * @param string $name Stability name
58 * @return int Stability value
60 protected function getStabilityInt($name)
62 $name = VersionParser::normalizeStability($name);
63 return isset(BasePackage::$stabilities[$name]) ?
64 BasePackage::$stabilities[$name] :
65 BasePackage::STABILITY_STABLE;
69 * Extract and merge stability flags from the given collection of
70 * requires with another collection of stability flags.
72 * @param array $requires New package name => link mappings
73 * @return array Unified package name => stability mappings
75 public function extractAll(array $requires)
79 foreach ($requires as $name => $link) {
80 $name = strtolower($name);
81 $version = $link->getPrettyConstraint();
83 $stability = $this->getExplicitStability($version);
85 if ($stability === null) {
86 $stability = $this->getParsedStability($version);
89 $flags[$name] = max($stability, $this->getCurrentStability($name));
92 // Filter out null stability values
93 return array_filter($flags, function ($v) {
100 * Extract the most unstable explicit stability (eg '@dev') from a version
103 * @param string $version
104 * @return int|null Stability or null if no explict stability found
106 protected function getExplicitStability($version)
109 $constraints = $this->splitConstraints($version);
110 foreach ($constraints as $constraint) {
111 if (preg_match($this->explicitStabilityRe, $constraint, $match)) {
112 $stability = $this->getStabilityInt($match[1]);
113 $found = max($stability, $found);
121 * Split a version specification into a list of version constraints.
123 * @param string $version
126 protected function splitConstraints($version)
129 $orConstraints = preg_split('/\s*\|\|?\s*/', trim($version));
130 foreach ($orConstraints as $constraints) {
131 $andConstraints = preg_split(
132 '/(?<!^|as|[=>< ,]) *(?<!-)[, ](?!-) *(?!,|as|$)/',
135 foreach ($andConstraints as $constraint) {
136 $found[] = $constraint;
144 * Get the stability of a version
146 * @param string $version
147 * @return int|null Stability or null if STABLE or less than minimum
149 protected function getParsedStability($version)
151 // Drop aliasing if used
152 $version = preg_replace('/^([^,\s@]+) as .+$/', '$1', $version);
153 $stability = $this->getStabilityInt(
154 VersionParser::parseStability($version)
157 if ($stability === BasePackage::STABILITY_STABLE ||
158 $this->minimumStability > $stability
160 // Ignore if 'stable' or more stable than the global
170 * Get the current stability of a given package.
172 * @param string $name
173 * @return int|null Stability of null if not set
175 protected function getCurrentStability($name)
177 return isset($this->stabilityFlags[$name]) ?
178 $this->stabilityFlags[$name] : null;
181 // vim:sw=4:ts=4:sts=4:et: