PluginProbe
Media Cloud Sync / trunk
Media Cloud Sync vtrunk
1.4.0 1.3.12 1.3.11 1.3.10 trunk 1.0.0 1.0.1 1.0.2 1.0.3 1.1.0 1.1.1 1.2.0 1.2.10 1.2.11 1.2.12 1.2.13 1.2.2 1.2.3 1.2.4 1.2.5 1.2.6 1.2.7 1.2.8 1.2.9 1.3.0 All 34 releases
media-cloud-sync / includes / sdk / google / composer / InstalledVersions.php

InstalledVersions.php in Media Cloud Sync trunk, at includes/sdk/google/composer/InstalledVersions.php

331 lines 16.7 KB
No matching file
Up and down to move Enter to open Esc to close
Raw Download Zip
1 <?php
2
3 /*
4 * This file is part of Composer.
5 *
6 * (c) Nils Adermann <naderman@naderman.de>
7 * Jordi Boggiano <j.boggiano@seld.be>
8 *
9 * For the full copyright and license information, please view the LICENSE
10 * file that was distributed with this source code.
11 */
12 namespace Dudlewebs\WPMCS\GCP\Composer;
13
14 use Dudlewebs\WPMCS\GCP\Composer\Autoload\ClassLoader;
15 use Dudlewebs\WPMCS\GCP\Composer\Semver\VersionParser;
16 /**
17 * This class is copied in every Composer installed project and available to all
18 *
19 * See also https://getcomposer.org/doc/07-runtime.md#installed-versions
20 *
21 * To require its presence, you can require `composer-runtime-api ^2.0`
22 *
23 * @final
24 */
25 class InstalledVersions
26 {
27 /**
28 * @var mixed[]|null
29 * @psalm-var array{root: array{name: string, pretty_version: string, version: string, reference: string|null, type: string, install_path: string, aliases: string[], dev: bool}, versions: array<string, array{pretty_version?: string, version?: string, reference?: string|null, type?: string, install_path?: string, aliases?: string[], dev_requirement: bool, replaced?: string[], provided?: string[]}>}|array{}|null
30 */
31 private static $installed;
32 /**
33 * @var bool
34 */
35 private static $installedIsLocalDir;
36 /**
37 * @var bool|null
38 */
39 private static $canGetVendors;
40 /**
41 * @var array[]
42 * @psalm-var array<string, array{root: array{name: string, pretty_version: string, version: string, reference: string|null, type: string, install_path: string, aliases: string[], dev: bool}, versions: array<string, array{pretty_version?: string, version?: string, reference?: string|null, type?: string, install_path?: string, aliases?: string[], dev_requirement: bool, replaced?: string[], provided?: string[]}>}>
43 */
44 private static $installedByVendor = array();
45 /**
46 * Returns a list of all package names which are present, either by being installed, replaced or provided
47 *
48 * @return string[]
49 * @psalm-return list<string>
50 */
51 public static function getInstalledPackages()
52 {
53 $packages = array();
54 foreach (self::getInstalled() as $installed) {
55 $packages[] = \array_keys($installed['versions']);
56 }
57 if (1 === \count($packages)) {
58 return $packages[0];
59 }
60 return \array_keys(\array_flip(\call_user_func_array('array_merge', $packages)));
61 }
62 /**
63 * Returns a list of all package names with a specific type e.g. 'library'
64 *
65 * @param string $type
66 * @return string[]
67 * @psalm-return list<string>
68 */
69 public static function getInstalledPackagesByType($type)
70 {
71 $packagesByType = array();
72 foreach (self::getInstalled() as $installed) {
73 foreach ($installed['versions'] as $name => $package) {
74 if (isset($package['type']) && $package['type'] === $type) {
75 $packagesByType[] = $name;
76 }
77 }
78 }
79 return $packagesByType;
80 }
81 /**
82 * Checks whether the given package is installed
83 *
84 * This also returns true if the package name is provided or replaced by another package
85 *
86 * @param string $packageName
87 * @param bool $includeDevRequirements
88 * @return bool
89 */
90 public static function isInstalled($packageName, $includeDevRequirements = \true)
91 {
92 foreach (self::getInstalled() as $installed) {
93 if (isset($installed['versions'][$packageName])) {
94 return $includeDevRequirements || !isset($installed['versions'][$packageName]['dev_requirement']) || $installed['versions'][$packageName]['dev_requirement'] === \false;
95 }
96 }
97 return \false;
98 }
99 /**
100 * Checks whether the given package satisfies a version constraint
101 *
102 * e.g. If you want to know whether version 2.3+ of package foo/bar is installed, you would call:
103 *
104 * Composer\InstalledVersions::satisfies(new VersionParser, 'foo/bar', '^2.3')
105 *
106 * @param VersionParser $parser Install composer/semver to have access to this class and functionality
107 * @param string $packageName
108 * @param string|null $constraint A version constraint to check for, if you pass one you have to make sure composer/semver is required by your package
109 * @return bool
110 */
111 public static function satisfies(VersionParser $parser, $packageName, $constraint)
112 {
113 $constraint = $parser->parseConstraints((string) $constraint);
114 $provided = $parser->parseConstraints(self::getVersionRanges($packageName));
115 return $provided->matches($constraint);
116 }
117 /**
118 * Returns a version constraint representing all the range(s) which are installed for a given package
119 *
120 * It is easier to use this via isInstalled() with the $constraint argument if you need to check
121 * whether a given version of a package is installed, and not just whether it exists
122 *
123 * @param string $packageName
124 * @return string Version constraint usable with composer/semver
125 */
126 public static function getVersionRanges($packageName)
127 {
128 foreach (self::getInstalled() as $installed) {
129 if (!isset($installed['versions'][$packageName])) {
130 continue;
131 }
132 $ranges = array();
133 if (isset($installed['versions'][$packageName]['pretty_version'])) {
134 $ranges[] = $installed['versions'][$packageName]['pretty_version'];
135 }
136 if (\array_key_exists('aliases', $installed['versions'][$packageName])) {
137 $ranges = \array_merge($ranges, $installed['versions'][$packageName]['aliases']);
138 }
139 if (\array_key_exists('replaced', $installed['versions'][$packageName])) {
140 $ranges = \array_merge($ranges, $installed['versions'][$packageName]['replaced']);
141 }
142 if (\array_key_exists('provided', $installed['versions'][$packageName])) {
143 $ranges = \array_merge($ranges, $installed['versions'][$packageName]['provided']);
144 }
145 return \implode(' || ', $ranges);
146 }
147 throw new \OutOfBoundsException('Package "' . $packageName . '" is not installed');
148 }
149 /**
150 * @param string $packageName
151 * @return string|null If the package is being replaced or provided but is not really installed, null will be returned as version, use satisfies or getVersionRanges if you need to know if a given version is present
152 */
153 public static function getVersion($packageName)
154 {
155 foreach (self::getInstalled() as $installed) {
156 if (!isset($installed['versions'][$packageName])) {
157 continue;
158 }
159 if (!isset($installed['versions'][$packageName]['version'])) {
160 return null;
161 }
162 return $installed['versions'][$packageName]['version'];
163 }
164 throw new \OutOfBoundsException('Package "' . $packageName . '" is not installed');
165 }
166 /**
167 * @param string $packageName
168 * @return string|null If the package is being replaced or provided but is not really installed, null will be returned as version, use satisfies or getVersionRanges if you need to know if a given version is present
169 */
170 public static function getPrettyVersion($packageName)
171 {
172 foreach (self::getInstalled() as $installed) {
173 if (!isset($installed['versions'][$packageName])) {
174 continue;
175 }
176 if (!isset($installed['versions'][$packageName]['pretty_version'])) {
177 return null;
178 }
179 return $installed['versions'][$packageName]['pretty_version'];
180 }
181 throw new \OutOfBoundsException('Package "' . $packageName . '" is not installed');
182 }
183 /**
184 * @param string $packageName
185 * @return string|null If the package is being replaced or provided but is not really installed, null will be returned as reference
186 */
187 public static function getReference($packageName)
188 {
189 foreach (self::getInstalled() as $installed) {
190 if (!isset($installed['versions'][$packageName])) {
191 continue;
192 }
193 if (!isset($installed['versions'][$packageName]['reference'])) {
194 return null;
195 }
196 return $installed['versions'][$packageName]['reference'];
197 }
198 throw new \OutOfBoundsException('Package "' . $packageName . '" is not installed');
199 }
200 /**
201 * @param string $packageName
202 * @return string|null If the package is being replaced or provided but is not really installed, null will be returned as install path. Packages of type metapackages also have a null install path.
203 */
204 public static function getInstallPath($packageName)
205 {
206 foreach (self::getInstalled() as $installed) {
207 if (!isset($installed['versions'][$packageName])) {
208 continue;
209 }
210 return isset($installed['versions'][$packageName]['install_path']) ? $installed['versions'][$packageName]['install_path'] : null;
211 }
212 throw new \OutOfBoundsException('Package "' . $packageName . '" is not installed');
213 }
214 /**
215 * @return array
216 * @psalm-return array{name: string, pretty_version: string, version: string, reference: string|null, type: string, install_path: string, aliases: string[], dev: bool}
217 */
218 public static function getRootPackage()
219 {
220 $installed = self::getInstalled();
221 return $installed[0]['root'];
222 }
223 /**
224 * Returns the raw installed.php data for custom implementations
225 *
226 * @deprecated Use getAllRawData() instead which returns all datasets for all autoloaders present in the process. getRawData only returns the first dataset loaded, which may not be what you expect.
227 * @return array[]
228 * @psalm-return array{root: array{name: string, pretty_version: string, version: string, reference: string|null, type: string, install_path: string, aliases: string[], dev: bool}, versions: array<string, array{pretty_version?: string, version?: string, reference?: string|null, type?: string, install_path?: string, aliases?: string[], dev_requirement: bool, replaced?: string[], provided?: string[]}>}
229 */
230 public static function getRawData()
231 {
232 @\trigger_error('getRawData only returns the first dataset loaded, which may not be what you expect. Use getAllRawData() instead which returns all datasets for all autoloaders present in the process.', \E_USER_DEPRECATED);
233 if (null === self::$installed) {
234 // only require the installed.php file if this file is loaded from its dumped location,
235 // and not from its source location in the composer/composer package, see https://github.com/composer/composer/issues/9937
236 if (\substr(__DIR__, -8, 1) !== 'C') {
237 self::$installed = (include __DIR__ . '/installed.php');
238 } else {
239 self::$installed = array();
240 }
241 }
242 return self::$installed;
243 }
244 /**
245 * Returns the raw data of all installed.php which are currently loaded for custom implementations
246 *
247 * @return array[]
248 * @psalm-return list<array{root: array{name: string, pretty_version: string, version: string, reference: string|null, type: string, install_path: string, aliases: string[], dev: bool}, versions: array<string, array{pretty_version?: string, version?: string, reference?: string|null, type?: string, install_path?: string, aliases?: string[], dev_requirement: bool, replaced?: string[], provided?: string[]}>}>
249 */
250 public static function getAllRawData()
251 {
252 return self::getInstalled();
253 }
254 /**
255 * Lets you reload the static array from another file
256 *
257 * This is only useful for complex integrations in which a project needs to use
258 * this class but then also needs to execute another project's autoloader in process,
259 * and wants to ensure both projects have access to their version of installed.php.
260 *
261 * A typical case would be PHPUnit, where it would need to make sure it reads all
262 * the data it needs from this class, then call reload() with
263 * `require $CWD/vendor/composer/installed.php` (or similar) as input to make sure
264 * the project in which it runs can then also use this class safely, without
265 * interference between PHPUnit's dependencies and the project's dependencies.
266 *
267 * @param array[] $data A vendor/composer/installed.php data set
268 * @return void
269 *
270 * @psalm-param array{root: array{name: string, pretty_version: string, version: string, reference: string|null, type: string, install_path: string, aliases: string[], dev: bool}, versions: array<string, array{pretty_version?: string, version?: string, reference?: string|null, type?: string, install_path?: string, aliases?: string[], dev_requirement: bool, replaced?: string[], provided?: string[]}>} $data
271 */
272 public static function reload($data)
273 {
274 self::$installed = $data;
275 self::$installedByVendor = array();
276 // when using reload, we disable the duplicate protection to ensure that self::$installed data is
277 // always returned, but we cannot know whether it comes from the installed.php in __DIR__ or not,
278 // so we have to assume it does not, and that may result in duplicate data being returned when listing
279 // all installed packages for example
280 self::$installedIsLocalDir = \false;
281 }
282 /**
283 * @return array[]
284 * @psalm-return list<array{root: array{name: string, pretty_version: string, version: string, reference: string|null, type: string, install_path: string, aliases: string[], dev: bool}, versions: array<string, array{pretty_version?: string, version?: string, reference?: string|null, type?: string, install_path?: string, aliases?: string[], dev_requirement: bool, replaced?: string[], provided?: string[]}>}>
285 */
286 private static function getInstalled()
287 {
288 if (null === self::$canGetVendors) {
289 self::$canGetVendors = \method_exists('Dudlewebs\\WPMCS\\GCP\\Dudlewebs\\WPMCS\\GCP\\Composer\\Autoload\\ClassLoader', 'getRegisteredLoaders');
290 }
291 $installed = array();
292 $copiedLocalDir = \false;
293 if (self::$canGetVendors) {
294 $selfDir = \strtr(__DIR__, '\\', '/');
295 foreach (ClassLoader::getRegisteredLoaders() as $vendorDir => $loader) {
296 $vendorDir = \strtr($vendorDir, '\\', '/');
297 if (isset(self::$installedByVendor[$vendorDir])) {
298 $installed[] = self::$installedByVendor[$vendorDir];
299 } elseif (\is_file($vendorDir . '/composer/installed.php')) {
300 /** @var array{root: array{name: string, pretty_version: string, version: string, reference: string|null, type: string, install_path: string, aliases: string[], dev: bool}, versions: array<string, array{pretty_version?: string, version?: string, reference?: string|null, type?: string, install_path?: string, aliases?: string[], dev_requirement: bool, replaced?: string[], provided?: string[]}>} $required */
301 $required = (require $vendorDir . '/composer/installed.php');
302 self::$installedByVendor[$vendorDir] = $required;
303 $installed[] = $required;
304 if (self::$installed === null && $vendorDir . '/composer' === $selfDir) {
305 self::$installed = $required;
306 self::$installedIsLocalDir = \true;
307 }
308 }
309 if (self::$installedIsLocalDir && $vendorDir . '/composer' === $selfDir) {
310 $copiedLocalDir = \true;
311 }
312 }
313 }
314 if (null === self::$installed) {
315 // only require the installed.php file if this file is loaded from its dumped location,
316 // and not from its source location in the composer/composer package, see https://github.com/composer/composer/issues/9937
317 if (\substr(__DIR__, -8, 1) !== 'C') {
318 /** @var array{root: array{name: string, pretty_version: string, version: string, reference: string|null, type: string, install_path: string, aliases: string[], dev: bool}, versions: array<string, array{pretty_version?: string, version?: string, reference?: string|null, type?: string, install_path?: string, aliases?: string[], dev_requirement: bool, replaced?: string[], provided?: string[]}>} $required */
319 $required = (require __DIR__ . '/installed.php');
320 self::$installed = $required;
321 } else {
322 self::$installed = array();
323 }
324 }
325 if (self::$installed !== array() && !$copiedLocalDir) {
326 $installed[] = self::$installed;
327 }
328 return $installed;
329 }
330 }
331