From 6a3d3fec57a41dd49102c2ab589320d6ccb552dd Mon Sep 17 00:00:00 2001 From: Daniil Gentili Date: Wed, 4 Nov 2020 12:00:16 +0100 Subject: [PATCH] Improve composer API --- src/Composer/Constraint/MultiConstraint.php | 2 +- src/Composer/Plugin.php | 65 +++++++------- src/Composer/Repository/ArrayRepository.php | 43 ---------- .../Repository/ComposerRepository.php | 85 ------------------- .../Repository/ConfigurableRepository.php | 31 ------- src/Composer/Repository/Repository.php | 58 ++++--------- src/Context.php | 2 +- src/PluginGraph/GraphInternal.php | 2 +- src/Target/Php.php | 13 +-- src/Traverser.php | 1 - 10 files changed, 55 insertions(+), 247 deletions(-) delete mode 100644 src/Composer/Repository/ArrayRepository.php delete mode 100644 src/Composer/Repository/ComposerRepository.php delete mode 100644 src/Composer/Repository/ConfigurableRepository.php diff --git a/src/Composer/Constraint/MultiConstraint.php b/src/Composer/Constraint/MultiConstraint.php index 8e392bc..12a5899 100644 --- a/src/Composer/Constraint/MultiConstraint.php +++ b/src/Composer/Constraint/MultiConstraint.php @@ -43,7 +43,7 @@ class MultiConstraint extends ComposerMultiConstraint * Tries to optimize the constraints as much as possible, meaning * reducing/collapsing congruent constraints etc. * Does not necessarily return a MultiConstraint instance if - * things can be reduced to a simple constraint + * things can be reduced to a simple constraint. * * @param ConstraintInterface[] $constraints A set of constraints * @param bool $conjunctive Whether the constraints should be treated as conjunctive or disjunctive diff --git a/src/Composer/Plugin.php b/src/Composer/Plugin.php index 7fa6610..bdc1dc6 100644 --- a/src/Composer/Plugin.php +++ b/src/Composer/Plugin.php @@ -9,13 +9,8 @@ use Composer\Installer\PackageEvent; use Composer\Installer\PackageEvents; use Composer\IO\IOInterface; use Composer\Plugin\PluginInterface; -use Composer\Repository\ArrayRepository as ComposerArrayRepository; -use Composer\Repository\ComposerRepository as ComposerComposerRepository; -use Composer\Repository\ConfigurableRepository as ComposerConfigurableRepository; -use Phabel\Composer\Repository\ArrayRepository; -use Phabel\Composer\Repository\ComposerRepository; -use Phabel\Composer\Repository\ConfigurableRepository; use Phabel\Composer\Repository\Repository; +use ReflectionClass; use ReflectionObject; /** @@ -44,37 +39,35 @@ class Plugin implements PluginInterface, EventSubscriberInterface $reflect->setAccessible(true); $reflect->setValue($repoManager, []); foreach ($repos as $repo) { - if ($repo instanceof ComposerComposerRepository) { - $repo = new ComposerRepository($repo); - } else { - $traits = []; - foreach ([ - ComposerArrayRepository::class => ArrayRepository::class, - ComposerConfigurableRepository::class => ConfigurableRepository::class, - ] as $class => $trait) { - if ($repo instanceof $class) { - $traits []= $trait; - } - } - \sort($traits); - if ($traits === [ArrayRepository::class]) { - $repo = new class($repo) extends ComposerArrayRepository { - use Repository; - use ArrayRepository; - }; - } elseif ($traits === [ConfigurableRepository::class]) { - $repo = new class($repo) extends ComposerRepository { - use Repository; - use ConfigurableRepository; - }; - } else { - $repo = new class($repo) extends ComposerArrayRepository { - use Repository; - use ArrayRepository; - use ConfigurableRepository; - }; - } + $traits = [Repository::class]; + $traitsStr = ''; + foreach ($traits as $trait) { + $traitsStr .= "use \\$trait;\n"; } + $reflect = new ReflectionClass($repo); + + $extend = "extends \\".\get_class($repo); + $eval = "\$newRepo = new class $extend { + $traitsStr + + public function __construct() {} + };"; + eval($eval); + + $reflectNew = new ReflectionClass($newRepo); + $reflectNew = $reflectNew->getParentClass(); + + do { + foreach ($reflect->getProperties() as $prop) { + $propNew = $reflectNew->getProperty($prop->getName()); + $propNew->setAccessible(true); + $prop->setAccessible(true); + $propNew->setValue($newRepo, $prop->getValue($repo)); + } + $reflectNew = $reflectNew->getParentClass(); + } while ($reflect = $reflect->getParentClass()); + $repo = $newRepo; + $repoManager->prependRepository($repo); } \var_dump(\array_map('get_class', $repoManager->getRepositories())); diff --git a/src/Composer/Repository/ArrayRepository.php b/src/Composer/Repository/ArrayRepository.php deleted file mode 100644 index ee864d9..0000000 --- a/src/Composer/Repository/ArrayRepository.php +++ /dev/null @@ -1,43 +0,0 @@ - - * @license MIT - * - * @property ComposerArrayRepository $repository - */ -trait ArrayRepository -{ - public function addPackage(PackageInterface $package) - { - $this->repository->addPackage($package); - } - - public function getProviders($packageName) - { - return $this->repository->getProviders($packageName); - } - public function loadPackages(array $packageNameMap, array $acceptableStabilities, array $stabilityFlags, array $alreadyLoaded = array()) - { - $packages = $this->repository->loadPackages($packageNameMap, $acceptableStabilities, $stabilityFlags, $alreadyLoaded); - foreach ($packages['packages'] as &$package) { - self::preparePackage($package, []); - } - return $packages; - } - public function getPackageNames($packageFilter = null) - { - return $this->getPackageNames($packageFilter); - } -} \ No newline at end of file diff --git a/src/Composer/Repository/ComposerRepository.php b/src/Composer/Repository/ComposerRepository.php deleted file mode 100644 index ce7d8f9..0000000 --- a/src/Composer/Repository/ComposerRepository.php +++ /dev/null @@ -1,85 +0,0 @@ - - * @license MIT - * - * @property ComposerComposerRepository $repository - */ -class ComposerRepository extends ComposerComposerRepository -{ - use Repository; - use ArrayRepository; - use ConfigurableRepository; - /** - * Configuration prefix. - */ - const CONFIG_PREFIX = 'phabel-config'; - - /** - * @param Pool $pool - * @param string $name package name - * @param bool $bypassFilters If set to true, this bypasses the stability filtering, and forces a recompute without cache - * @return array|mixed - */ - /* - public function whatProvides(Pool $pool, $name, $bypassFilters = false) - { - $whatProvides = $this->reflect->getMethod('whatProvides')->invokeArgs($this->repository, [$pool, $name, $bypassFilters]); - foreach ($whatProvides as $package => &$versions) { - foreach ($versions as &$version) { - if (!isset($version['require']['phabel/phabel'])) { - continue; - } - $config = $version['extra']['phabel'] ?? []; - if (!isset($config['target']) && isset($version['require']['php'])) { - $config['target'] = $version['require']['php']; - } - foreach ($version['require'] as $package => &$version) { - $version = self::CONFIG_PREFIX.\json_encode($config)."\n".$version; - } - } - } - return $whatProvides; - }*/ - - - public function getProviderNames() - { - return $this->repository->getProviderNames(); - } - - public function hasProviders() - { - return $this->repository->hasProviders(); - } - public function resetPackageIds() - { - return $this->repository->resetPackageIds(); - } - - public function createPackages(array $packages, $class = 'Composer\Package\CompletePackage') - { - return $this->repository->createPackages($packages, $class); - } - - /** - * TODO v3 should make this private once we can drop PHP 5.3 support - * - * @param string $name package name (must be lowercased already) - * @private - */ - public function isVersionAcceptable($constraint, $name, $versionData, array $acceptableStabilities = null, array $stabilityFlags = null) - { - self::prepareConstraint($constraint); - return $this->isVersionAcceptable($constraint, $name, $versionData, $acceptableStabilities, $stabilityFlags); - } -} diff --git a/src/Composer/Repository/ConfigurableRepository.php b/src/Composer/Repository/ConfigurableRepository.php deleted file mode 100644 index 9f6d4db..0000000 --- a/src/Composer/Repository/ConfigurableRepository.php +++ /dev/null @@ -1,31 +0,0 @@ - - * @license MIT - * - * @property ConfigurableRepositoryInterface $repository - */ -trait ConfigurableRepository -{ - /** - * Get repository configuration. - * - * @return mixed - */ - public function getRepoConfig() - { - return $this->repository->getRepoConfig(); - } -} \ No newline at end of file diff --git a/src/Composer/Repository/Repository.php b/src/Composer/Repository/Repository.php index cd7eb4c..4739306 100644 --- a/src/Composer/Repository/Repository.php +++ b/src/Composer/Repository/Repository.php @@ -7,13 +7,10 @@ use Composer\Package\Link; use Composer\Package\Package; use Composer\Package\PackageInterface; use Composer\Repository\PlatformRepository; -use Composer\Repository\RepositoryInterface; -use Composer\Semver\Constraint\Constraint as ConstraintConstraint; use Composer\Semver\Constraint\ConstraintInterface; use Composer\Semver\Constraint\MultiConstraint as ConstraintMultiConstraint; use Phabel\Composer\Constraint\Constraint; use Phabel\Composer\Constraint\MultiConstraint; -use ReflectionObject; /** * @author Daniil Gentili @@ -22,34 +19,23 @@ use ReflectionObject; trait Repository { /** - * Previous repository . - */ - protected RepositoryInterface $repository; - /** - * Reflection object. - */ - protected ReflectionObject $reflect; - /** - * Constructor. + * TODO v3 should make this private once we can drop PHP 5.3 support. * - * @param RepositoryInterface $repository Previous repository + * @param string $name package name (must be lowercased already) + * @private */ - public function __construct(RepositoryInterface $repository) + public function isVersionAcceptable($constraint, $name, $versionData, array $acceptableStabilities = null, array $stabilityFlags = null) { - $this->reflect = new ReflectionObject($repository); - $this->repository = $repository; - $this->packages = []; + self::prepareConstraint($constraint); + return parent::isVersionAcceptable($constraint, $name, $versionData, $acceptableStabilities, $stabilityFlags); } - /** - * Checks if specified package registered (installed). - * - * @param PackageInterface $package package instance - * - * @return bool - */ - public function hasPackage(PackageInterface $package): bool + public function loadPackages(array $packageNameMap, array $acceptableStabilities, array $stabilityFlags, array $alreadyLoaded = []) { - return $this->repository->hasPackage($package); + $packages = parent::loadPackages($packageNameMap, $acceptableStabilities, $stabilityFlags, $alreadyLoaded); + foreach ($packages['packages'] as &$package) { + self::preparePackage($package, []); + } + return $packages; } /** @@ -66,6 +52,7 @@ trait Repository $constraint = $constraint->getPrevious(); return $config; } + return []; /* if (!$constraint instanceof ConstraintInterface && !\is_string($constraint)) { return []; @@ -142,7 +129,7 @@ trait Repository public function findPackage($name, $constraint) { $config = self::prepareConstraint($constraint); - if (!$package = $this->repository->findPackage($name, $constraint)) { + if (!$package = parent::findPackage($name, $constraint)) { return null; } return self::preparePackage($package, $config); @@ -159,7 +146,7 @@ trait Repository public function findPackages($name, $constraint = null) { $config = self::prepareConstraint($constraint); - foreach ($packages = $this->repository->findPackages($name, $constraint) as $package) { + foreach ($packages = parent::findPackages($name, $constraint) as $package) { self::preparePackage($package, $config); } return $packages; @@ -172,23 +159,10 @@ trait Repository */ public function getPackages() { - $packages = $this->repository->getPackages(); + $packages = parent::getPackages(); foreach ($packages as $package) { self::preparePackage($package, []); } return $packages; } - - /** - * {@inheritDoc} - */ - public function search($query, $mode = 0, $type = null) - { - return $this->repository->search($query, $mode, $type); - } - - public function getRepoName() - { - return $this->repository->getRepoName(); - } } diff --git a/src/Context.php b/src/Context.php index 75e0946..d4485af 100644 --- a/src/Context.php +++ b/src/Context.php @@ -308,7 +308,7 @@ class Context } /** - * Gets name context + * Gets name context. * * @return NameContext */ diff --git a/src/PluginGraph/GraphInternal.php b/src/PluginGraph/GraphInternal.php index fcba23c..6108960 100644 --- a/src/PluginGraph/GraphInternal.php +++ b/src/PluginGraph/GraphInternal.php @@ -62,7 +62,7 @@ class GraphInternal * @param PackageContext $ctx Package context * * @psalm-param class-string $plugin Plugin to add - * + * * @return Node[] */ public function addPlugin(string $plugin, array $config, PackageContext $ctx): array diff --git a/src/Target/Php.php b/src/Target/Php.php index ef4bb0f..28a3d04 100644 --- a/src/Target/Php.php +++ b/src/Target/Php.php @@ -3,7 +3,6 @@ namespace Phabel\Target; use Phabel\Plugin; -use Phabel\Target\Php55\YieldDetector; /** * Makes changes necessary to polyfill syntaxes of various PHP versions. @@ -39,10 +38,10 @@ class Php extends Plugin private static function getRange(array $config): array { $target = $config['target'] ?? PHP_MAJOR_VERSION.PHP_MINOR_VERSION; - if (preg_match(":^\D*(\d+\.\d+)\..*:", $config['target'], $matches)) { + if (\preg_match(":^\D*(\d+\.\d+)\..*:", $config['target'], $matches)) { $target = $matches[1]; } - $key = \array_search(str_replace('.', '', $target), self::VERSIONS); + $key = \array_search(\str_replace('.', '', $target), self::VERSIONS); return \array_slice( self::VERSIONS, $key === false ? self::DEFAULT_TARGET : $key @@ -59,9 +58,11 @@ class Php extends Plugin { $classes = []; foreach (self::getRange($config) as $version) { - foreach (scandir(__DIR__."/Php$version") as $file) { - if (substr($file, -4) !== '.php') continue; - $class = basename($version, '.php'); + foreach (\scandir(__DIR__."/Php$version") as $file) { + if (\substr($file, -4) !== '.php') { + continue; + } + $class = \basename($version, '.php'); $classes[$class] = $config[$class] ?? []; } } diff --git a/src/Traverser.php b/src/Traverser.php index 6113056..87fdbe6 100644 --- a/src/Traverser.php +++ b/src/Traverser.php @@ -3,7 +3,6 @@ namespace Phabel; use PhpParser\Node; -use PhpParser\NodeTraverser; use PhpParser\Parser; use PhpParser\ParserFactory; use SplQueue;