diff --git a/src/Composer/ArrayRepository.php b/src/Composer/ArrayRepository.php new file mode 100644 index 0000000..300c1d2 --- /dev/null +++ b/src/Composer/ArrayRepository.php @@ -0,0 +1,27 @@ + + * @license MIT + * + * @property ComposerArrayRepository $repository + */ +trait ArrayRepository +{ + + public function addPackage(PackageInterface $package) + { + $this->repository->addPackage($package); + } +} \ No newline at end of file diff --git a/src/Composer/ComposerRepository.php b/src/Composer/ComposerRepository.php new file mode 100644 index 0000000..f988e24 --- /dev/null +++ b/src/Composer/ComposerRepository.php @@ -0,0 +1,67 @@ + + * @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(); + } +} diff --git a/src/Composer/ConfigurableRepository.php b/src/Composer/ConfigurableRepository.php new file mode 100644 index 0000000..3a0150c --- /dev/null +++ b/src/Composer/ConfigurableRepository.php @@ -0,0 +1,31 @@ + + * @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/Plugin.php b/src/Composer/Plugin.php index e80f036..4981c25 100644 --- a/src/Composer/Plugin.php +++ b/src/Composer/Plugin.php @@ -10,6 +10,11 @@ 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\ConfigurableRepository as ComposerConfigurableRepository; +use Composer\Repository\ComposerRepository as ComposerComposerRepository; +use Composer\Repository\RepositoryInterface; +use ReflectionObject; /** * @author Daniil Gentili @@ -33,7 +38,44 @@ class Plugin implements PluginInterface, EventSubscriberInterface { $repoManager = $composer->getRepositoryManager(); $repos = $repoManager->getRepositories(); - $repoManager->prependRepository(new Repository($repos[0])); + $reflect = (new ReflectionObject($repoManager))->getProperty('repositories'); + $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; + }; + } else if ($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; + }; + } + } + $repoManager->prependRepository($repo); + } + var_dump(array_map('get_class', $repoManager->getRepositories())); $this->io = $io; } @@ -69,8 +111,6 @@ class Plugin implements PluginInterface, EventSubscriberInterface public static function getSubscribedEvents() { return [ - InstallerEvents::PRE_DEPENDENCIES_SOLVING => - ['onDependencySolve', 100000], PackageEvents::POST_PACKAGE_INSTALL => ['onInstall', 100000], ]; @@ -78,7 +118,6 @@ class Plugin implements PluginInterface, EventSubscriberInterface public function onInstall(PackageEvent $event): void { - \var_dumP($event); } /** @@ -90,6 +129,5 @@ class Plugin implements PluginInterface, EventSubscriberInterface */ public function onDependencySolve(InstallerEvent $event): void { - \var_dump($event); } } diff --git a/src/Composer/Repository.php b/src/Composer/Repository.php index acfeea5..73f8229 100644 --- a/src/Composer/Repository.php +++ b/src/Composer/Repository.php @@ -2,59 +2,39 @@ namespace Phabel\Composer; -use Composer\DependencyResolver\Pool; use Composer\Package\Link; +use Composer\Package\Package; use Composer\Package\PackageInterface; -use Composer\Repository\ComposerRepository; +use Composer\Repository\RepositoryInterface; use Composer\Semver\Constraint\Constraint; use Composer\Semver\Constraint\ConstraintInterface; +use ReflectionObject; /** * @author Daniil Gentili * @license MIT */ -class Repository extends ComposerRepository +trait Repository { - /** - * Configuration prefix. - */ - private const CONFIG_PREFIX = 'phabel-config'; /** * Previous repository . */ - private ComposerRepository $repository; + protected RepositoryInterface $repository; + /** + * Reflection object + */ + protected ReflectionObject $reflect; /** * Constructor. * - * @param RepositoryInterface[] $repositories Previous repositories + * @param RepositoryInterface $repository Previous repository */ - public function __construct(ComposerRepository $repository) + public function __construct(RepositoryInterface $repository) { + $this->reflect = new ReflectionObject($repository); $this->repository = $repository; $this->packages = []; } - - /** - * Get repository configuration. - * - * @return mixed - */ - public function getRepoConfig() - { - return $this->repository->getRepoConfig(); - } - /** - * Set root aliases. - * - * @param array $rootAliases Root aliases - * - * @return void - */ - public function setRootAliases(array $rootAliases): void - { - $this->repository->setRootAliases($rootAliases); - } - /** * Checks if specified package registered (installed). * @@ -80,11 +60,11 @@ class Repository extends ComposerRepository return []; } $constraint = (string) $constraint; - if (!str_starts_with($constraint, self::CONFIG_PREFIX)) { + if (!str_starts_with($constraint, ComposerRepository::CONFIG_PREFIX)) { return []; } [$config, $constraint] = \explode("\n", $constraint, 2); - return \json_decode(\substr($config, 0, \strlen(self::CONFIG_PREFIX)), true) ?: []; + return \json_decode(\substr($config, 0, \strlen(ComposerRepository::CONFIG_PREFIX)), true) ?: []; } /** * Prepare package. @@ -119,7 +99,7 @@ class Repository extends ComposerRepository // Config merging logic here... $links = []; foreach ($package->getRequires() as $link) { - $version = self::CONFIG_PREFIX.\json_encode($config)."\n".($link->getConstraint() ?? ''); + $version = ComposerRepository::CONFIG_PREFIX.\json_encode($config)."\n".($link->getConstraint() ?? ''); $links []= new Link($link->getSource(), $link->getTarget(), new Constraint('>=', $version), $link->getDescription()); } $package->setRequires($links); @@ -133,7 +113,7 @@ class Repository extends ComposerRepository * * @return PackageInterface|null */ - public function findPackage(string $name, $constraint): ?PackageInterface + public function findPackage($name, $constraint) { $config = self::prepareConstraint($constraint); if (!$package = $this->repository->findPackage($name, $constraint)) { @@ -180,47 +160,4 @@ class Repository extends ComposerRepository { return $this->repository->search($query, $mode, $type); } - - public function getProviderNames() - { - return $this->repository->getProviderNames(); - } - - public function hasProviders() - { - return $this->repository->hasProviders(); - } - public function resetPackageIds() - { - return $this->repository->resetPackageIds(); - } - public function addPackage(PackageInterface $package) - { - $this->repository->addPackage($package); - } - /** - * @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->repository->whatProvides($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; - } }