[ Index ] |
PHP Cross Reference of phpBB-3.3.14-deutsch |
[Summary view] [Print] [Text view]
1 <?php 2 3 declare(strict_types=1); 4 5 namespace PackageVersions; 6 7 use Composer\Composer; 8 use Composer\Config; 9 use Composer\EventDispatcher\EventSubscriberInterface; 10 use Composer\IO\IOInterface; 11 use Composer\Package\AliasPackage; 12 use Composer\Package\Locker; 13 use Composer\Package\PackageInterface; 14 use Composer\Package\RootPackageInterface; 15 use Composer\Plugin\PluginInterface; 16 use Composer\Script\Event; 17 use Composer\Script\ScriptEvents; 18 use Generator; 19 use RuntimeException; 20 21 use function array_key_exists; 22 use function array_merge; 23 use function chmod; 24 use function dirname; 25 use function file_exists; 26 use function file_put_contents; 27 use function is_writable; 28 use function iterator_to_array; 29 use function rename; 30 use function sprintf; 31 use function uniqid; 32 use function var_export; 33 34 final class Installer implements PluginInterface, EventSubscriberInterface 35 { 36 private static $generatedClassTemplate = <<<'PHP' 37 <?php 38 39 declare(strict_types=1); 40 41 namespace PackageVersions; 42 43 use Composer\InstalledVersions; 44 use OutOfBoundsException; 45 46 class_exists(InstalledVersions::class); 47 48 /** 49 * This class is generated by composer/package-versions-deprecated, specifically by 50 * @see \PackageVersions\Installer 51 * 52 * This file is overwritten at every run of `composer install` or `composer update`. 53 * 54 * @deprecated in favor of the Composer\InstalledVersions class provided by Composer 2. Require composer-runtime-api:^2 to ensure it is present. 55 */ 56 %s 57 { 58 /** 59 * @deprecated please use {@see self::rootPackageName()} instead. 60 * This constant will be removed in version 2.0.0. 61 */ 62 const ROOT_PACKAGE_NAME = '%s'; 63 64 /** 65 * Array of all available composer packages. 66 * Dont read this array from your calling code, but use the \PackageVersions\Versions::getVersion() method instead. 67 * 68 * @var array<string, string> 69 * @internal 70 */ 71 const VERSIONS = %s; 72 73 private function __construct() 74 { 75 } 76 77 /** 78 * @psalm-pure 79 * 80 * @psalm-suppress ImpureMethodCall we know that {@see InstalledVersions} interaction does not 81 * cause any side effects here. 82 */ 83 public static function rootPackageName() : string 84 { 85 if (!self::composer2ApiUsable()) { 86 return self::ROOT_PACKAGE_NAME; 87 } 88 89 return InstalledVersions::getRootPackage()['name']; 90 } 91 92 /** 93 * @throws OutOfBoundsException If a version cannot be located. 94 * 95 * @psalm-param key-of<self::VERSIONS> $packageName 96 * @psalm-pure 97 * 98 * @psalm-suppress ImpureMethodCall we know that {@see InstalledVersions} interaction does not 99 * cause any side effects here. 100 */ 101 public static function getVersion(string $packageName): string 102 { 103 if (self::composer2ApiUsable()) { 104 return InstalledVersions::getPrettyVersion($packageName) 105 . '@' . InstalledVersions::getReference($packageName); 106 } 107 108 if (isset(self::VERSIONS[$packageName])) { 109 return self::VERSIONS[$packageName]; 110 } 111 112 throw new OutOfBoundsException( 113 'Required package "' . $packageName . '" is not installed: check your ./vendor/composer/installed.json and/or ./composer.lock files' 114 ); 115 } 116 117 private static function composer2ApiUsable(): bool 118 { 119 if (!class_exists(InstalledVersions::class, false)) { 120 return false; 121 } 122 123 if (method_exists(InstalledVersions::class, 'getAllRawData')) { 124 $rawData = InstalledVersions::getAllRawData(); 125 if (count($rawData) === 1 && count($rawData[0]) === 0) { 126 return false; 127 } 128 } else { 129 $rawData = InstalledVersions::getRawData(); 130 if ($rawData === null || $rawData === []) { 131 return false; 132 } 133 } 134 135 return true; 136 } 137 } 138 139 PHP; 140 141 public function activate(Composer $composer, IOInterface $io) 142 { 143 // Nothing to do here, as all features are provided through event listeners 144 } 145 146 public function deactivate(Composer $composer, IOInterface $io) 147 { 148 // Nothing to do here, as all features are provided through event listeners 149 } 150 151 public function uninstall(Composer $composer, IOInterface $io) 152 { 153 // Nothing to do here, as all features are provided through event listeners 154 } 155 156 /** 157 * {@inheritDoc} 158 */ 159 public static function getSubscribedEvents(): array 160 { 161 return [ScriptEvents::POST_AUTOLOAD_DUMP => 'dumpVersionsClass']; 162 } 163 164 /** 165 * @throws RuntimeException 166 */ 167 public static function dumpVersionsClass(Event $composerEvent) 168 { 169 $composer = $composerEvent->getComposer(); 170 $rootPackage = $composer->getPackage(); 171 $versions = iterator_to_array(self::getVersions($composer->getLocker(), $rootPackage)); 172 173 if (! array_key_exists('composer/package-versions-deprecated', $versions)) { 174 //plugin must be globally installed - we only want to generate versions for projects which specifically 175 //require composer/package-versions-deprecated 176 return; 177 } 178 179 $versionClass = self::generateVersionsClass($rootPackage->getName(), $versions); 180 181 self::writeVersionClassToFile($versionClass, $composer, $composerEvent->getIO()); 182 } 183 184 /** 185 * @param string[] $versions 186 */ 187 private static function generateVersionsClass(string $rootPackageName, array $versions): string 188 { 189 return sprintf( 190 self::$generatedClassTemplate, 191 'fin' . 'al ' . 'cla' . 'ss ' . 'Versions', // note: workaround for regex-based code parsers :-( 192 $rootPackageName, 193 var_export($versions, true) 194 ); 195 } 196 197 /** 198 * @throws RuntimeException 199 */ 200 private static function writeVersionClassToFile(string $versionClassSource, Composer $composer, IOInterface $io) 201 { 202 $installPath = self::locateRootPackageInstallPath($composer->getConfig(), $composer->getPackage()) 203 . '/src/PackageVersions/Versions.php'; 204 205 $installDir = dirname($installPath); 206 if (! file_exists($installDir)) { 207 $io->write('<info>composer/package-versions-deprecated:</info> Package not found (probably scheduled for removal); generation of version class skipped.'); 208 209 return; 210 } 211 212 if (! is_writable($installDir)) { 213 $io->write( 214 sprintf( 215 '<info>composer/package-versions-deprecated:</info> %s is not writable; generation of version class skipped.', 216 $installDir 217 ) 218 ); 219 220 return; 221 } 222 223 $io->write('<info>composer/package-versions-deprecated:</info> Generating version class...'); 224 225 $installPathTmp = $installPath . '_' . uniqid('tmp', true); 226 file_put_contents($installPathTmp, $versionClassSource); 227 chmod($installPathTmp, 0664); 228 rename($installPathTmp, $installPath); 229 230 $io->write('<info>composer/package-versions-deprecated:</info> ...done generating version class'); 231 } 232 233 /** 234 * @throws RuntimeException 235 */ 236 private static function locateRootPackageInstallPath( 237 Config $composerConfig, 238 RootPackageInterface $rootPackage 239 ): string { 240 if (self::getRootPackageAlias($rootPackage)->getName() === 'composer/package-versions-deprecated') { 241 return dirname($composerConfig->get('vendor-dir')); 242 } 243 244 return $composerConfig->get('vendor-dir') . '/composer/package-versions-deprecated'; 245 } 246 247 private static function getRootPackageAlias(RootPackageInterface $rootPackage): PackageInterface 248 { 249 $package = $rootPackage; 250 251 while ($package instanceof AliasPackage) { 252 $package = $package->getAliasOf(); 253 } 254 255 return $package; 256 } 257 258 /** 259 * @return Generator&string[] 260 * 261 * @psalm-return Generator<string, string> 262 */ 263 private static function getVersions(Locker $locker, RootPackageInterface $rootPackage): Generator 264 { 265 $lockData = $locker->getLockData(); 266 267 $lockData['packages-dev'] = $lockData['packages-dev'] ?? []; 268 269 $packages = $lockData['packages']; 270 if (getenv('COMPOSER_DEV_MODE') !== '0') { 271 $packages = array_merge($packages, $lockData['packages-dev']); 272 } 273 foreach ($packages as $package) { 274 yield $package['name'] => $package['version'] . '@' . ( 275 $package['source']['reference'] ?? $package['dist']['reference'] ?? '' 276 ); 277 } 278 279 foreach ($rootPackage->getReplaces() as $replace) { 280 $version = $replace->getPrettyConstraint(); 281 if ($version === 'self.version') { 282 $version = $rootPackage->getPrettyVersion(); 283 } 284 285 yield $replace->getTarget() => $version . '@' . $rootPackage->getSourceReference(); 286 } 287 288 yield $rootPackage->getName() => $rootPackage->getPrettyVersion() . '@' . $rootPackage->getSourceReference(); 289 } 290 }
title
Description
Body
title
Description
Body
title
Description
Body
title
Body
Generated: Mon Nov 25 19:05:08 2024 | Cross-referenced by PHPXref 0.7.1 |