Continue work on composer injector

This commit is contained in:
Daniil Gentili 2020-11-04 16:54:36 +01:00
parent 5418c27788
commit 7cea5c8b26
Signed by: danog
GPG Key ID: 8C1BE3B34B230CA7
7 changed files with 88 additions and 77 deletions

View File

@ -2,7 +2,6 @@
$config = new Amp\CodeStyle\Config();
$config->getFinder()
->in(__DIR__ . '/examples')
->in(__DIR__ . '/src')
->in(__DIR__ . '/test');

View File

@ -4,7 +4,7 @@
"type": "composer-plugin",
"require": {
"nikic/php-parser": "^4.7",
"composer-plugin-api": "^1|^2"
"composer-plugin-api": "^2"
},
"require-dev": {
"phpunit/phpunit": "^7 | ^8 | ^9",
@ -35,4 +35,4 @@
"cs-fix": "php-cs-fixer fix -v --diff",
"test": "@php -dzend.assertions=1 -dassert.exception=1 ./vendor/bin/phpunit --coverage-text"
}
}
}

View File

@ -5,12 +5,12 @@ namespace Phabel\Composer\Traits;
trait Constraint
{
/**
* Config.
* Phabel config.
*/
private array $config;
/**
* Get config.
* Get phabel config.
*
* @return array
*/
@ -20,15 +20,15 @@ trait Constraint
}
/**
* Set config.
* Set phabel config.
*
* @param array $config Config.
* @param array $config Phabel config
*
* @return self
*/
public function setConfig(array $config): self
public function setConfig($config): self
{
$this->config = $config;
$this->config = is_string($config) ? json_decode($config, true) : $config;
return $this;
}

View File

@ -11,6 +11,7 @@ use Composer\Semver\Constraint\Constraint as ComposerConstraint;
use Composer\Semver\Constraint\ConstraintInterface;
use Composer\Semver\Constraint\MultiConstraint;
use Phabel\Composer\PhabelConstraintInterface;
use Phabel\Target\Php;
use Phabel\Tools;
/**
@ -44,47 +45,12 @@ trait Repository
return $packages;
}
/**
* Look for phabel configuration parameters in constraint.
*
* @param \Composer\Semver\Constraint\ConstraintInterface $constraint package version or version constraint to match against
*
* @return ?array
*/
public static function extractConfig(&$constraint): ?array
{
$config = null;
if ($constraint instanceof PhabelConstraintInterface) {
$config = $constraint->getConfig();
} elseif ($constraint instanceof ComposerConstraint) {
$version = $constraint->getVersion();
if (str_starts_with($version, 'phabel')) {
[$version, $config] = \explode("\0", \substr($version, 6));
$config = \json_decode($config, true);
$constraint = new ComposerConstraint($constraint->getOperator(), $version);
}
} elseif ($constraint instanceof MultiConstraint) {
$constraints = $constraint->getConstraints() ;
foreach ($constraints as &$cur) {
$config = self::trickleMergeConfig($config, self::extractConfig($cur));
}
$constraint = new MultiConstraint($constraints, $constraint->isConjunctive());
}
return $config;
/*
if (!$constraint instanceof ConstraintInterface && !\is_string($constraint)) {
return [];
}
$constraint = (string) $constraint;
if (!str_starts_with($constraint, ComposerRepository::CONFIG_PREFIX)) {
return [];
}
[$config, $constraint] = \explode("\0", $constraint, 2);
return \json_decode(\substr($config, 0, \strlen(ComposerRepository::CONFIG_PREFIX)), true) ?: [];*/
}
private static function trickleMergeConfig(?array $prev, ?array $new): ?array
{
return $new;
if ($prev === null || empty($prev)) {
return $new;
}
return $prev;
}
/**
* Prepare package.
@ -107,7 +73,7 @@ trait Repository
$havePhabel = true;
}
if ($link->getTarget() === 'php') {
$myConfig['target'] = $link->getConstraint();
$myConfig['target'] = Php::normalizeVersion($link->getConstraint()->getLowerBound()->getVersion());
if ($havePhabel) {
break;
}
@ -118,14 +84,11 @@ trait Repository
return;
}
\var_dump("Applying ".$package->getName());
// Config merging logic here...
if ($config === null || empty($config)) {
$config = $myConfig;
}
self::processRequires($package, $config);
$config = self::trickleMergeConfig($config, $myConfig);
self::processRequires($package, \json_encode($config));
}
private static function processRequires(PackageInterface $package, array $config)
private static function processRequires(PackageInterface $package, string $config)
{
$links = [];
foreach ($package->getRequires() as $link) {
@ -133,20 +96,10 @@ trait Repository
continue;
}
//var_dumP($link->getTarget(), (string) $link->getConstraint());
$constraint = $link->getConstraint();
if ($constraint instanceof ComposerConstraint) {
$version = $constraint-
}
if ($constraint instanceof PhabelConstraintInterface) {
$constraint = clone $constraint;
} else {
$constraint = Tools::cloneWithTrait($constraint, Constraint::class, PhabelConstraintInterface::class);
}
$constraint->setConfig($config);
$links []= new Link(
$link->getSource(),
$link->getTarget(),
$constraint,
self::injectConfig($link->getConstraint(), $config),
$link->getDescription(),
$link->getPrettyConstraint()
);
@ -159,8 +112,59 @@ trait Repository
}
}
private static function injectConstraint
/**
* Inject config into constraint.
*
* @param ConstraintInterface $constraint
* @param string $config
* @return ConstraintInterface
*/
private static function injectConfig(ConstraintInterface $constraint, string $config): ConstraintInterface
{
if ($constraint instanceof ComposerConstraint) {
$version = $constraint->getVersion();
$version = "phabel$version\0$config";
return new ComposerConstraint($constraint->getOperator(), $version);
} elseif ($constraint instanceof MultiConstraint) {
$constraints = $constraint->getConstraints();
foreach ($constraints as &$cur) {
$cur = self::injectConfig($cur, $config);
}
return new MultiConstraint($constraints, $constraint->isConjunctive());
}
return $constraint;
}
/**
* Look for phabel configuration parameters in constraint.
*
* @param \Composer\Semver\Constraint\ConstraintInterface $constraint package version or version constraint to match against
*
* @return ?array
*/
public static function extractConfig(ConstraintInterface &$constraint): ?array
{
$config = null;
if ($constraint instanceof ComposerConstraint) {
$version = $constraint->getVersion();
if (str_starts_with($version, 'phabel')) {
[$version, $config] = \explode("\0", \substr($version, 6));
$config = \json_decode($config, true);
if ($config === false) {
$config = null;
}
$constraint = new ComposerConstraint($constraint->getOperator(), $version);
}
} elseif ($constraint instanceof MultiConstraint) {
$constraints = $constraint->getConstraints() ;
foreach ($constraints as &$cur) {
$config = self::trickleMergeConfig($config, self::extractConfig($cur));
}
$constraint = new MultiConstraint($constraints, $constraint->isConjunctive());
}
return $config;
}
/**
* Searches for the first match of a package by name and version.
*

View File

@ -119,35 +119,35 @@ abstract class Plugin extends Tools implements PluginInterface
/**
* {@inheritDoc}
*/
public static function composerRequires(): array
public static function composerRequires(array $config): array
{
return [];
}
/**
* {@inheritDoc}
*/
public static function runAfter(): array
public static function runAfter(array $config): array
{
return [];
}
/**
* {@inheritDoc}
*/
public static function runBefore(): array
public static function runBefore(array $config): array
{
return [];
}
/**
* {@inheritDoc}
*/
public static function runWithBefore(): array
public static function runWithBefore(array $config): array
{
return [];
}
/**
* {@inheritDoc}
*/
public static function runWithAfter(): array
public static function runWithAfter(array $config): array
{
return [];
}

View File

@ -24,7 +24,7 @@ interface PluginInterface
*
* @psalm-return class-string<PluginInterface>[]|array<class-string<PluginInterface>, array>
*/
public static function runAfter(): array;
public static function runAfter(array $config): array;
/**
* Specify which plugins should run before this plugin.
*
@ -32,7 +32,7 @@ interface PluginInterface
*
* @psalm-return class-string<PluginInterface>[]|array<class-string<PluginInterface>, array>
*/
public static function runBefore(): array;
public static function runBefore(array $config): array;
/**
* Specify which plugins does this plugin extend.
*
@ -44,21 +44,21 @@ interface PluginInterface
*
* @psalm-return class-string<PluginInterface>[]|array<class-string<PluginInterface>, array>
*/
public static function runWithBefore(): array;
public static function runWithBefore(array $config): array;
/**
*
* @return array Plugin name(s)
*
* @psalm-return class-string<PluginInterface>[]|array<class-string<PluginInterface>, array>
*/
public static function runWithAfter(): array;
public static function runWithAfter(array $config): array;
/**
* Specify a list of composer dependencies.
*
* @return array
*/
public static function composerRequires(): array;
public static function composerRequires(array $config): array;
/**
* Set configuration array.
*

View File

@ -29,6 +29,14 @@ class Php extends Plugin
* Default target.
*/
private const DEFAULT_TARGET = '70';
public static function normalizeVersion(string $target): string
{
if (\preg_match(":^\D*(\d+\.\d+)\..*:", $target, $matches)) {
$target = $matches[1];
}
$target = \str_replace('.', '', $target);
return in_array($target, self::VERSIONS) ? $target : self::DEFAULT_TARGET;
}
/**
* Get PHP version range to target.
*