Chris@0
|
1 <?php
|
Chris@0
|
2 /**
|
Chris@0
|
3 * This file is part of the Composer Merge plugin.
|
Chris@0
|
4 *
|
Chris@0
|
5 * Copyright (C) 2015 Bryan Davis, Wikimedia Foundation, and contributors
|
Chris@0
|
6 *
|
Chris@0
|
7 * This software may be modified and distributed under the terms of the MIT
|
Chris@0
|
8 * license. See the LICENSE file for details.
|
Chris@0
|
9 */
|
Chris@0
|
10
|
Chris@0
|
11 namespace Wikimedia\Composer\Merge;
|
Chris@0
|
12
|
Chris@0
|
13 use Composer\Package\BasePackage;
|
Chris@0
|
14 use Composer\Package\Version\VersionParser;
|
Chris@0
|
15
|
Chris@0
|
16 /**
|
Chris@0
|
17 * Adapted from Composer's RootPackageLoader::extractStabilityFlags
|
Chris@0
|
18 * @author Bryan Davis <bd808@bd808.com>
|
Chris@0
|
19 */
|
Chris@0
|
20 class StabilityFlags
|
Chris@0
|
21 {
|
Chris@0
|
22
|
Chris@0
|
23 /**
|
Chris@0
|
24 * @var array Current package name => stability mappings
|
Chris@0
|
25 */
|
Chris@0
|
26 protected $stabilityFlags;
|
Chris@0
|
27
|
Chris@0
|
28 /**
|
Chris@0
|
29 * @var int Current default minimum stability
|
Chris@0
|
30 */
|
Chris@0
|
31 protected $minimumStability;
|
Chris@0
|
32
|
Chris@0
|
33 /**
|
Chris@0
|
34 * @var string Regex to extract an explict stability flag (eg '@dev')
|
Chris@0
|
35 */
|
Chris@0
|
36 protected $explicitStabilityRe;
|
Chris@0
|
37
|
Chris@0
|
38
|
Chris@0
|
39 /**
|
Chris@0
|
40 * @param array $stabilityFlags Current package name => stability mappings
|
Chris@0
|
41 * @param int $minimumStability Current default minimum stability
|
Chris@0
|
42 */
|
Chris@0
|
43 public function __construct(
|
Chris@0
|
44 array $stabilityFlags = array(),
|
Chris@0
|
45 $minimumStability = BasePackage::STABILITY_STABLE
|
Chris@0
|
46 ) {
|
Chris@0
|
47 $this->stabilityFlags = $stabilityFlags;
|
Chris@0
|
48 $this->minimumStability = $this->getStabilityInt($minimumStability);
|
Chris@0
|
49 $this->explicitStabilityRe = '/^[^@]*?@(' .
|
Chris@0
|
50 implode('|', array_keys(BasePackage::$stabilities)) .
|
Chris@0
|
51 ')$/i';
|
Chris@0
|
52 }
|
Chris@0
|
53
|
Chris@0
|
54 /**
|
Chris@0
|
55 * Get the stability value for a given string.
|
Chris@0
|
56 *
|
Chris@0
|
57 * @param string $name Stability name
|
Chris@0
|
58 * @return int Stability value
|
Chris@0
|
59 */
|
Chris@0
|
60 protected function getStabilityInt($name)
|
Chris@0
|
61 {
|
Chris@0
|
62 $name = VersionParser::normalizeStability($name);
|
Chris@0
|
63 return isset(BasePackage::$stabilities[$name]) ?
|
Chris@0
|
64 BasePackage::$stabilities[$name] :
|
Chris@0
|
65 BasePackage::STABILITY_STABLE;
|
Chris@0
|
66 }
|
Chris@0
|
67
|
Chris@0
|
68 /**
|
Chris@0
|
69 * Extract and merge stability flags from the given collection of
|
Chris@0
|
70 * requires with another collection of stability flags.
|
Chris@0
|
71 *
|
Chris@0
|
72 * @param array $requires New package name => link mappings
|
Chris@0
|
73 * @return array Unified package name => stability mappings
|
Chris@0
|
74 */
|
Chris@0
|
75 public function extractAll(array $requires)
|
Chris@0
|
76 {
|
Chris@0
|
77 $flags = array();
|
Chris@0
|
78
|
Chris@0
|
79 foreach ($requires as $name => $link) {
|
Chris@0
|
80 $name = strtolower($name);
|
Chris@0
|
81 $version = $link->getPrettyConstraint();
|
Chris@0
|
82
|
Chris@0
|
83 $stability = $this->getExplicitStability($version);
|
Chris@0
|
84
|
Chris@0
|
85 if ($stability === null) {
|
Chris@0
|
86 $stability = $this->getParsedStability($version);
|
Chris@0
|
87 }
|
Chris@0
|
88
|
Chris@0
|
89 $flags[$name] = max($stability, $this->getCurrentStability($name));
|
Chris@0
|
90 }
|
Chris@0
|
91
|
Chris@0
|
92 // Filter out null stability values
|
Chris@0
|
93 return array_filter($flags, function ($v) {
|
Chris@0
|
94 return $v !== null;
|
Chris@0
|
95 });
|
Chris@0
|
96 }
|
Chris@0
|
97
|
Chris@0
|
98
|
Chris@0
|
99 /**
|
Chris@0
|
100 * Extract the most unstable explicit stability (eg '@dev') from a version
|
Chris@0
|
101 * specification.
|
Chris@0
|
102 *
|
Chris@0
|
103 * @param string $version
|
Chris@0
|
104 * @return int|null Stability or null if no explict stability found
|
Chris@0
|
105 */
|
Chris@0
|
106 protected function getExplicitStability($version)
|
Chris@0
|
107 {
|
Chris@0
|
108 $found = null;
|
Chris@0
|
109 $constraints = $this->splitConstraints($version);
|
Chris@0
|
110 foreach ($constraints as $constraint) {
|
Chris@0
|
111 if (preg_match($this->explicitStabilityRe, $constraint, $match)) {
|
Chris@0
|
112 $stability = $this->getStabilityInt($match[1]);
|
Chris@0
|
113 $found = max($stability, $found);
|
Chris@0
|
114 }
|
Chris@0
|
115 }
|
Chris@0
|
116 return $found;
|
Chris@0
|
117 }
|
Chris@0
|
118
|
Chris@0
|
119
|
Chris@0
|
120 /**
|
Chris@0
|
121 * Split a version specification into a list of version constraints.
|
Chris@0
|
122 *
|
Chris@0
|
123 * @param string $version
|
Chris@0
|
124 * @return array
|
Chris@0
|
125 */
|
Chris@0
|
126 protected function splitConstraints($version)
|
Chris@0
|
127 {
|
Chris@0
|
128 $found = array();
|
Chris@0
|
129 $orConstraints = preg_split('/\s*\|\|?\s*/', trim($version));
|
Chris@0
|
130 foreach ($orConstraints as $constraints) {
|
Chris@0
|
131 $andConstraints = preg_split(
|
Chris@0
|
132 '/(?<!^|as|[=>< ,]) *(?<!-)[, ](?!-) *(?!,|as|$)/',
|
Chris@0
|
133 $constraints
|
Chris@0
|
134 );
|
Chris@0
|
135 foreach ($andConstraints as $constraint) {
|
Chris@0
|
136 $found[] = $constraint;
|
Chris@0
|
137 }
|
Chris@0
|
138 }
|
Chris@0
|
139 return $found;
|
Chris@0
|
140 }
|
Chris@0
|
141
|
Chris@0
|
142
|
Chris@0
|
143 /**
|
Chris@0
|
144 * Get the stability of a version
|
Chris@0
|
145 *
|
Chris@0
|
146 * @param string $version
|
Chris@0
|
147 * @return int|null Stability or null if STABLE or less than minimum
|
Chris@0
|
148 */
|
Chris@0
|
149 protected function getParsedStability($version)
|
Chris@0
|
150 {
|
Chris@0
|
151 // Drop aliasing if used
|
Chris@0
|
152 $version = preg_replace('/^([^,\s@]+) as .+$/', '$1', $version);
|
Chris@0
|
153 $stability = $this->getStabilityInt(
|
Chris@0
|
154 VersionParser::parseStability($version)
|
Chris@0
|
155 );
|
Chris@0
|
156
|
Chris@0
|
157 if ($stability === BasePackage::STABILITY_STABLE ||
|
Chris@0
|
158 $this->minimumStability > $stability
|
Chris@0
|
159 ) {
|
Chris@0
|
160 // Ignore if 'stable' or more stable than the global
|
Chris@0
|
161 // minimum
|
Chris@0
|
162 $stability = null;
|
Chris@0
|
163 }
|
Chris@0
|
164
|
Chris@0
|
165 return $stability;
|
Chris@0
|
166 }
|
Chris@0
|
167
|
Chris@0
|
168
|
Chris@0
|
169 /**
|
Chris@0
|
170 * Get the current stability of a given package.
|
Chris@0
|
171 *
|
Chris@0
|
172 * @param string $name
|
Chris@0
|
173 * @return int|null Stability of null if not set
|
Chris@0
|
174 */
|
Chris@0
|
175 protected function getCurrentStability($name)
|
Chris@0
|
176 {
|
Chris@0
|
177 return isset($this->stabilityFlags[$name]) ?
|
Chris@0
|
178 $this->stabilityFlags[$name] : null;
|
Chris@0
|
179 }
|
Chris@0
|
180 }
|
Chris@0
|
181 // vim:sw=4:ts=4:sts=4:et:
|