diff --git a/.php_cs.dist b/.php_cs.dist index 9459eed..cd06abc 100644 --- a/.php_cs.dist +++ b/.php_cs.dist @@ -2,7 +2,6 @@ $config = new Amp\CodeStyle\Config(); $config->getFinder() - ->in(__DIR__ . '/examples') ->in(__DIR__ . '/src') ->in(__DIR__ . '/test'); diff --git a/composer.json b/composer.json index b5bd7c0..01ef917 100644 --- a/composer.json +++ b/composer.json @@ -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" } -} \ No newline at end of file +} diff --git a/src/Composer/Traits/Constraint.php b/src/Composer/Traits/Constraint.php index 2c2e08f..743b748 100644 --- a/src/Composer/Traits/Constraint.php +++ b/src/Composer/Traits/Constraint.php @@ -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; } diff --git a/src/Composer/Traits/Repository.php b/src/Composer/Traits/Repository.php index d32a030..8af75fe 100644 --- a/src/Composer/Traits/Repository.php +++ b/src/Composer/Traits/Repository.php @@ -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. * diff --git a/src/Plugin.php b/src/Plugin.php index 17e41d2..1508128 100644 --- a/src/Plugin.php +++ b/src/Plugin.php @@ -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 []; } diff --git a/src/PluginInterface.php b/src/PluginInterface.php index 32e7cdc..b814197 100644 --- a/src/PluginInterface.php +++ b/src/PluginInterface.php @@ -24,7 +24,7 @@ interface PluginInterface * * @psalm-return class-string[]|array, 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[]|array, 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[]|array, array> */ - public static function runWithBefore(): array; + public static function runWithBefore(array $config): array; /** * * @return array Plugin name(s) * * @psalm-return class-string[]|array, 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. * diff --git a/src/Target/Php.php b/src/Target/Php.php index c853172..24ed414 100644 --- a/src/Target/Php.php +++ b/src/Target/Php.php @@ -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. *