phabel/src/Composer/Repository/Repository.php

195 lines
6.3 KiB
PHP
Raw Normal View History

2020-08-13 18:30:12 +02:00
<?php
2020-11-04 10:49:05 +01:00
namespace Phabel\Composer\Repository;
2020-08-13 18:30:12 +02:00
2020-11-04 10:49:05 +01:00
use Composer\Package\AliasPackage;
2020-08-13 18:30:12 +02:00
use Composer\Package\Link;
2020-11-03 22:01:34 +01:00
use Composer\Package\Package;
2020-08-13 18:30:12 +02:00
use Composer\Package\PackageInterface;
2020-11-04 10:49:05 +01:00
use Composer\Repository\PlatformRepository;
2020-11-03 22:01:34 +01:00
use Composer\Repository\RepositoryInterface;
2020-11-04 10:49:05 +01:00
use Composer\Semver\Constraint\Constraint as ConstraintConstraint;
2020-08-13 18:30:12 +02:00
use Composer\Semver\Constraint\ConstraintInterface;
2020-11-04 10:49:05 +01:00
use Composer\Semver\Constraint\MultiConstraint as ConstraintMultiConstraint;
use Phabel\Composer\Constraint\Constraint;
use Phabel\Composer\Constraint\MultiConstraint;
2020-11-03 22:01:34 +01:00
use ReflectionObject;
2020-08-13 18:30:12 +02:00
2020-08-13 21:34:59 +02:00
/**
* @author Daniil Gentili <daniil@daniil.it>
* @license MIT
*/
2020-11-03 22:01:34 +01:00
trait Repository
2020-08-13 18:30:12 +02:00
{
/**
2020-11-03 22:01:34 +01:00
* Previous repository .
2020-08-13 18:30:12 +02:00
*/
2020-11-03 22:01:34 +01:00
protected RepositoryInterface $repository;
2020-08-13 18:30:12 +02:00
/**
2020-11-04 10:49:05 +01:00
* Reflection object.
2020-08-13 18:30:12 +02:00
*/
2020-11-03 22:01:34 +01:00
protected ReflectionObject $reflect;
2020-08-13 18:30:12 +02:00
/**
* Constructor.
*
2020-11-03 22:01:34 +01:00
* @param RepositoryInterface $repository Previous repository
2020-08-13 18:30:12 +02:00
*/
2020-11-03 22:01:34 +01:00
public function __construct(RepositoryInterface $repository)
2020-08-13 18:30:12 +02:00
{
2020-11-03 22:01:34 +01:00
$this->reflect = new ReflectionObject($repository);
2020-08-13 18:30:12 +02:00
$this->repository = $repository;
2020-08-13 21:34:59 +02:00
$this->packages = [];
2020-08-13 18:30:12 +02:00
}
/**
* Checks if specified package registered (installed).
*
* @param PackageInterface $package package instance
*
* @return bool
*/
public function hasPackage(PackageInterface $package): bool
{
return $this->repository->hasPackage($package);
}
/**
* Look for phabel configuration parameters in constraint.
*
* @param string|\Composer\Semver\Constraint\ConstraintInterface|null &$constraint package version or version constraint to match against
*
* @return array
*/
private static function prepareConstraint(&$constraint): array
{
2020-11-04 10:49:05 +01:00
if ($constraint instanceof Constraint || $constraint instanceof MultiConstraint) {
$config = $constraint->getConfig();
$constraint = $constraint->getPrevious();
return $config;
}
/*
2020-08-13 18:30:12 +02:00
if (!$constraint instanceof ConstraintInterface && !\is_string($constraint)) {
return [];
}
$constraint = (string) $constraint;
2020-11-03 22:01:34 +01:00
if (!str_starts_with($constraint, ComposerRepository::CONFIG_PREFIX)) {
2020-08-13 18:30:12 +02:00
return [];
}
2020-11-04 10:49:05 +01:00
[$config, $constraint] = \explode("\0", $constraint, 2);
return \json_decode(\substr($config, 0, \strlen(ComposerRepository::CONFIG_PREFIX)), true) ?: [];*/
2020-08-13 18:30:12 +02:00
}
/**
* Prepare package.
*
* @param PackageInterface $package Package
* @param array $config Configuration inherited from constraint
*
* @return void
*/
private static function preparePackage(PackageInterface $package, array $config): void
{
/**
* Phabel configuration of current package.
* @var array
*/
$myConfig = $package->getExtra()['phabel'] ?? [];
$havePhabel = false;
foreach ($package->getRequires() as $link) {
if ($link->getTarget() === 'phabel/phabel') {
$havePhabel = true;
}
if ($link->getTarget() === 'php') {
$myConfig['target'] = $link->getConstraint();
if ($havePhabel) {
break;
}
}
}
if (!$havePhabel) {
2020-11-04 10:49:05 +01:00
//return;
2020-08-13 18:30:12 +02:00
}
// Config merging logic here...
$links = [];
foreach ($package->getRequires() as $link) {
2020-11-04 10:49:05 +01:00
if (PlatformRepository::isPlatformPackage($link->getTarget())) {
continue;
}
//var_dumP($link->getTarget(), (string) $link->getConstraint());
//$version = ComposerRepository::CONFIG_PREFIX.\json_encode($config)."\0".($link->getConstraint() ?? '');
$constraint = $link->getConstraint();
if ($constraint instanceof ConstraintMultiConstraint) {
$constraint = new MultiConstraint($constraint, $config);
} else {
$constraint = new Constraint($constraint, $config);
}
$links []= new Link($link->getSource(), $link->getTarget(), $constraint, $link->getDescription());
}
if ($package instanceof Package) {
$package->setRequires($links);
} elseif ($package instanceof AliasPackage) {
while (($p = $package->getAliasOf()) instanceof AliasPackage);
$p->setRequires($links);
2020-08-13 18:30:12 +02:00
}
}
/**
* Searches for the first match of a package by name and version.
*
* @param string $name package name
* @param string|\Composer\Semver\Constraint\ConstraintInterface $constraint package version or version constraint to match against
*
* @return PackageInterface|null
*/
2020-11-03 22:01:34 +01:00
public function findPackage($name, $constraint)
2020-08-13 18:30:12 +02:00
{
$config = self::prepareConstraint($constraint);
if (!$package = $this->repository->findPackage($name, $constraint)) {
return null;
}
return self::preparePackage($package, $config);
}
/**
* Searches for all packages matching a name and optionally a version.
*
* @param string $name package name
* @param string|\Composer\Semver\Constraint\ConstraintInterface $constraint package version or version constraint to match against
*
* @return PackageInterface[]
*/
public function findPackages($name, $constraint = null)
{
$config = self::prepareConstraint($constraint);
foreach ($packages = $this->repository->findPackages($name, $constraint) as $package) {
self::preparePackage($package, $config);
}
return $packages;
}
/**
* Returns list of registered packages.
*
* @return PackageInterface[]
*/
public function getPackages()
{
$packages = $this->repository->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);
}
2020-11-04 10:49:05 +01:00
public function getRepoName()
{
return $this->repository->getRepoName();
}
2020-08-13 18:30:12 +02:00
}