Skip to content
Extraits de code Groupes Projets

Comparer les révisions

Les modifications sont affichées comme si la révision source était fusionnée avec la révision cible. En savoir plus sur la comparaison des révisions.

Source

Sélectionner le projet cible
No results found

Cible

Sélectionner le projet cible
  • spip-league/composer-installer
1 résultat
Afficher les modifications
Validations sur la source (2)
Affichage de
avec 208 ajouts et 180 suppressions
...@@ -5,3 +5,4 @@ ...@@ -5,3 +5,4 @@
/.phpunit.cache /.phpunit.cache
/phpstan.neon /phpstan.neon
/tmp/ /tmp/
/build/
stages: stages:
- lint
- check - check
- build
- test - test
default: default:
image: php:latest image:
cache: name: spip/tools:8.2
paths: entrypoint:
- vendor/ - "/bin/ash"
before_script: - "-c"
# Install git
- apt update -yqq
- apt install git libzip-dev -yqq
- docker-php-ext-install zip
# Install composer lint:
- curl -sS https://getcomposer.org/installer | php stage: lint
# Install all project dependencies
- php composer.phar install
# d’abord vérifier rapidement les fichiers
job:check:php:
stage: check
when: on_success when: on_success
only: only:
- main - main
- merge_requests - merge_requests
before_script:
- curl -o /usr/local/bin/parallel-lint -fsL https://github.com/php-parallel-lint/PHP-Parallel-Lint/releases/latest/download/parallel-lint.phar
script: script:
- php /usr/local/bin/parallel-lint --exclude .git --exclude vendor . - make -f /Makefile lint
artifacts:
paths:
- build/phplint.json
expire_in: 2 days
reports:
codequality: build/phplint.json
job:build: phpstan:
stage: build stage: check
when: on_success
only: only:
- main - main
- merge_requests - merge_requests
script: script:
# Security check of dependencies - make -f /Makefile analyze
- php composer.phar audit artifacts:
paths:
- build/phpstan.json
expire_in: 2 days
reports:
codequality: build/phpstan.json
job:test:php-latest: coding_standard:
stage: test stage: check
when: on_success when: on_success
only: only:
- main - main
- merge_requests - merge_requests
before_script:
# pcov pour le code-coverage
- pecl install pcov
- docker-php-ext-enable pcov
script: script:
- php -d memory_limit=-1 -d pcov.enabled=1 -d pcov.directory=. vendor/bin/phpunit --coverage-text --colors=never --coverage-cobertura .phpunit.cache/corbertura/report.xml - make -f /Makefile cs
coverage: /^\s*Lines:\s*\d+.\d+\%/
artifacts: artifacts:
paths: paths:
- .phpunit.cache/html - build/ecs.json
expire_in: 2 days expire_in: 2 days
reports: reports:
coverage_report: codequality: build/ecs.json
coverage_format: cobertura
path: .phpunit.cache/corbertura/report.xml
job:test:php-8.2: outdated:
stage: test stage: check
needs:
- job:test:php-latest
when: on_success when: on_success
only: only:
- main - main
- merge_requests - merge_requests
image: php:8.2
script: script:
- vendor/bin/phpunit --no-coverage - make -f /Makefile outdated
artifacts:
paths:
- build/gl-outdated.json
expire_in: 2 days
reports:
codequality: build/gl-outdated.json
job:test:ecs: audit:
stage: test stage: check
when: on_success when: on_success
only: only:
- main - main
- merge_requests - merge_requests
script: script:
- php -d display_errors=0 vendor/bin/ecs check --output-format=gitlab > ecs-quality-report.json - make -f /Makefile audit
artifacts: artifacts:
paths: paths:
- ecs-quality-report.json - build/gl-audit.json
reports: expire_in: 2 days
codequality: ecs-quality-report.json reports:
codequality: build/gl-audit.json
job:test:phpstan: coverage_report:
stage: test stage: test
when: on_success when: on_success
parallel:
matrix:
- VERSION: ["8.2","8.3","latest"]
image:
name: spip/tools:$VERSION
entrypoint:
- "/bin/ash"
- "-c"
only: only:
- main - main
- merge_requests - merge_requests
script: script:
- php -d memory_limit=-1 vendor/bin/phpstan analyse --error-format gitlab > phpstan-quality-report.json - make -f /Makefile test-coverage
artifacts: artifacts:
paths: paths:
- phpstan-quality-report.json - .phpunit.cache/corbertura/report.xml
reports: expire_in: 2 days
codequality: phpstan-quality-report.json reports:
\ No newline at end of file coverage_report:
coverage_format: cobertura
path: .phpunit.cache/corbertura/report.xml
...@@ -10,6 +10,7 @@ ...@@ -10,6 +10,7 @@
} }
], ],
"require": { "require": {
"php": "^8.2",
"composer-plugin-api": "^2.6" "composer-plugin-api": "^2.6"
}, },
"require-dev": { "require-dev": {
...@@ -35,6 +36,11 @@ ...@@ -35,6 +36,11 @@
"SpipLeague\\Test\\Composer\\": "tests/" "SpipLeague\\Test\\Composer\\": "tests/"
} }
}, },
"config": {
"platform": {
"php": "8.2.27"
}
},
"extra": { "extra": {
"branch-alias": { "branch-alias": {
"dev-main": "0.8.x-dev" "dev-main": "0.8.x-dev"
......
src tests ecs.php rector.php
...@@ -3,7 +3,7 @@ includes: ...@@ -3,7 +3,7 @@ includes:
- vendor/composer/composer/phpstan/rules.neon - vendor/composer/composer/phpstan/rules.neon
parameters: parameters:
phpVersion: 70400 phpVersion: 80200
paths: paths:
- src - src
- tests - tests
......
<?xml version="1.0" encoding="UTF-8"?> <?xml version="1.0" encoding="UTF-8"?>
<phpunit xmlns:xsi="http://www.w3.org/2001/XMLSchema-instance" xsi:noNamespaceSchemaLocation="https://schema.phpunit.de/11.3/phpunit.xsd" bootstrap="vendor/autoload.php" cacheDirectory=".phpunit.cache" executionOrder="depends,defects" requireCoverageMetadata="true" beStrictAboutCoverageMetadata="true" beStrictAboutOutputDuringTests="true" failOnRisky="true" failOnWarning="true"> <phpunit xmlns:xsi="http://www.w3.org/2001/XMLSchema-instance" xsi:noNamespaceSchemaLocation="https://schema.phpunit.de/11.5/phpunit.xsd" bootstrap="vendor/autoload.php" cacheDirectory=".phpunit.cache" executionOrder="depends,defects" requireCoverageMetadata="true" beStrictAboutCoverageMetadata="true" beStrictAboutOutputDuringTests="true" failOnRisky="true" failOnWarning="true">
<testsuites> <testsuites>
<testsuite name="default"> <testsuite name="default">
<directory>tests</directory> <directory>tests</directory>
...@@ -10,6 +10,7 @@ ...@@ -10,6 +10,7 @@
<report> <report>
<html outputDirectory=".phpunit.cache/html"/> <html outputDirectory=".phpunit.cache/html"/>
<text outputFile="php://stdout"/> <text outputFile="php://stdout"/>
<cobertura outputFile=".phpunit.cache/corbertura/report.xml"/>
</report> </report>
</coverage> </coverage>
......
...@@ -19,7 +19,7 @@ class AssetsClearCache ...@@ -19,7 +19,7 @@ class AssetsClearCache
/** /**
* To delete the cache files dedicated for public compiled assets * To delete the cache files dedicated for public compiled assets
*/ */
public static function clearCache(Event $event) public static function clearCache(Event $event): void
{ {
$event->getIO() $event->getIO()
->write('Clearing the assets cache ...'); ->write('Clearing the assets cache ...');
......
...@@ -29,7 +29,7 @@ class BaseDirectories ...@@ -29,7 +29,7 @@ class BaseDirectories
/** /**
* To create base directories * To create base directories
*/ */
public static function createBaseDirectories(Event $event, bool $check = false) public static function createBaseDirectories(Event $event, bool $check = false): void
{ {
if ($check) { if ($check) {
$event->getIO() $event->getIO()
......
...@@ -27,8 +27,8 @@ abstract class AbstractSwitchCommand extends AbstractSpipCommand ...@@ -27,8 +27,8 @@ abstract class AbstractSwitchCommand extends AbstractSpipCommand
{ {
try { try {
$composer = $this->requireComposer(); $composer = $this->requireComposer();
$distribution = Collection::fromJsonFile(Factory::createRemoteUrls($composer)); $distribution = Collection::fromJsonFile();
$analyzer = new Analyzer($distribution, $composer); $analyzer = new Analyzer($distribution, $composer, Factory::createRemoteUrls($composer));
$switcher = new Switcher($distribution, $composer); $switcher = new Switcher($distribution, $composer);
} catch (\Throwable $th) { } catch (\Throwable $th) {
$output->writeln($th->getMessage()); $output->writeln($th->getMessage());
......
...@@ -38,9 +38,9 @@ class ModeDevCommand extends AbstractSpipCommand ...@@ -38,9 +38,9 @@ class ModeDevCommand extends AbstractSpipCommand
if (is_string($tmp)) { if (is_string($tmp)) {
$tmp = [$tmp]; $tmp = [$tmp];
} }
if (!\is_array($tmp)) { // if (!\is_array($tmp)) {
$tmp = []; // $tmp = [];
} // }
if (empty(\array_intersect(['spip/*' => 'source'], $tmp))) { if (empty(\array_intersect(['spip/*' => 'source'], $tmp))) {
$output->writeln('<warning>Missing preferred-install in ' . $composerFile . '</warning>'); $output->writeln('<warning>Missing preferred-install in ' . $composerFile . '</warning>');
if (!$this->getIO()->askConfirmation( if (!$this->getIO()->askConfirmation(
...@@ -69,17 +69,19 @@ class ModeDevCommand extends AbstractSpipCommand ...@@ -69,17 +69,19 @@ class ModeDevCommand extends AbstractSpipCommand
foreach ($toChange as $path) { foreach ($toChange as $path) {
$url = ''; $url = '';
$changer->getProcessor()?->execute($changer->getRemote($path), $url); $changer->getProcessor()?->execute($changer->getRemote($path), $url);
$url = trim($url); $url = is_string($url) ? trim($url) : '';
if ($output->isVerbose()) { if (strlen($url)) {
$output->write('Checking ' . $url . ' in ' . $path . ' ...'); if ($output->isVerbose()) {
} $output->write('Checking ' . $url . ' in ' . $path . ' ...');
$newUrl = $changer->toSsh($url); }
if ($newUrl !== $url) { $newUrl = $changer->toSsh($url);
$output->write(PHP_EOL . 'Converting ' . $url . ' into ' . $newUrl); if ($newUrl !== $url) {
$changer->getProcessor()?->execute($changer->setRemote($path, $newUrl)); $output->write(PHP_EOL . 'Converting ' . $url . ' into ' . $newUrl);
} $changer->getProcessor()?->execute($changer->setRemote($path, $newUrl));
if ($output->isVerbose()) { }
$output->writeln(' OK'); if ($output->isVerbose()) {
$output->writeln(' OK');
}
} }
} }
$output->writeln(PHP_EOL . 'All done.'); $output->writeln(PHP_EOL . 'All done.');
......
...@@ -8,9 +8,6 @@ use SpipLeague\Composer\Command\ModeDevCommand; ...@@ -8,9 +8,6 @@ use SpipLeague\Composer\Command\ModeDevCommand;
use SpipLeague\Composer\Command\SwitchBackCommand; use SpipLeague\Composer\Command\SwitchBackCommand;
use SpipLeague\Composer\Command\SwitchForwardCommand; use SpipLeague\Composer\Command\SwitchForwardCommand;
/**
* @codeCoverageIgnore
*/
class CommandProvider implements CommandProviderCapability class CommandProvider implements CommandProviderCapability
{ {
public function getCommands() public function getCommands()
......
...@@ -26,7 +26,8 @@ class PreferredInstall ...@@ -26,7 +26,8 @@ class PreferredInstall
return []; return [];
} }
$toCheck = array_keys(array_filter( /** @var string[] $toCheck */
$toCheck = \array_keys(\array_filter(
$this->composer->getConfig() $this->composer->getConfig()
->get('preferred-install'), ->get('preferred-install'),
fn($install) => $install === 'source', fn($install) => $install === 'source',
...@@ -42,11 +43,12 @@ class PreferredInstall ...@@ -42,11 +43,12 @@ class PreferredInstall
$backOffice = $extra['spip']['back_office'] ?? ''; // -> SpipPaths::BACK_OFFICE/ $backOffice = $extra['spip']['back_office'] ?? ''; // -> SpipPaths::BACK_OFFICE/
$vendorDir = $this->composer->getConfig() $vendorDir = $this->composer->getConfig()
->get('vendor-dir'); // -> vendor/ ->get('vendor-dir'); // -> vendor/
$rootDir = realpath($vendorDir . '/..'); $rootDir = \realpath($vendorDir . '/..');
// -> plugins/ ? // -> plugins/ ?
$requires = InstalledVersions::getInstalledPackages(); $requires = InstalledVersions::getInstalledPackages();
$toChange = array_reduce($requires, function (array $list, string $packageName) use ( /** @var string[] $toChange */
$toChange = \array_reduce($requires, function (array $list, string $packageName) use (
$toCheck, $toCheck,
$extensions, $extensions,
$template, $template,
......
...@@ -14,12 +14,12 @@ class Collection implements CollectionInterface ...@@ -14,12 +14,12 @@ class Collection implements CollectionInterface
{ {
use CollectionTrait; use CollectionTrait;
private ?string $file; private string $file;
/** /**
* @param SpecificationInterface[] $distribution * @param array<mixed> $distribution
*/ */
public function __construct(array $distribution, ?string $file = \null) public function __construct(array $distribution, string $file)
{ {
$originalCount = \count($distribution); $originalCount = \count($distribution);
$distribution = \array_filter( $distribution = \array_filter(
...@@ -39,12 +39,8 @@ class Collection implements CollectionInterface ...@@ -39,12 +39,8 @@ class Collection implements CollectionInterface
$this->file = $file; $this->file = $file;
} }
public static function fromJsonFile(RemoteUrlsInterface $changer, ?string $file = null): self public static function fromJsonFile(string $file = SpipPaths::LOCAL_PLUGINS_DIST): self
{ {
if ($file === null) {
$file = SpipPaths::LOCAL_PLUGINS_DIST;
}
if (!(\file_exists($file) || \file_put_contents($file, '{}'))) { if (!(\file_exists($file) || \file_put_contents($file, '{}'))) {
throw new \LogicException( throw new \LogicException(
'<error>File "' . $file . '" is missing and can\' be created. Can\'t upgrade/downgrade.</error>', '<error>File "' . $file . '" is missing and can\' be created. Can\'t upgrade/downgrade.</error>',
...@@ -57,17 +53,15 @@ class Collection implements CollectionInterface ...@@ -57,17 +53,15 @@ class Collection implements CollectionInterface
} }
$distribution = []; $distribution = [];
/** @var array<string,array{path:string,source:string,branch?:string,tag?:string}> $pluginsDist */
foreach ($pluginsDist as $prefix => $fromJson) { foreach ($pluginsDist as $prefix => $fromJson) {
$distribution[] = (new Specification($prefix, $fromJson))->setChanger($changer); $distribution[] = new Specification($prefix, $fromJson);
} }
return new self($distribution, $file); return new self($distribution, $file);
} }
/** public function getFile(): string
* @codeCoverageIgnore
*/
public function getFile(): ?string
{ {
return $this->file; return $this->file;
} }
......
...@@ -12,5 +12,5 @@ namespace SpipLeague\Composer\Extensions; ...@@ -12,5 +12,5 @@ namespace SpipLeague\Composer\Extensions;
*/ */
interface CollectionInterface extends \Countable, \Iterator, \JsonSerializable, \ArrayAccess interface CollectionInterface extends \Countable, \Iterator, \JsonSerializable, \ArrayAccess
{ {
public function getFile(): ?string; public function getFile(): string;
} }
<?php <?php
declare(strict_types=1);
namespace SpipLeague\Composer\Extensions; namespace SpipLeague\Composer\Extensions;
/** /**
...@@ -11,85 +13,85 @@ trait CollectionTrait ...@@ -11,85 +13,85 @@ trait CollectionTrait
{ {
protected int $position = 0; protected int $position = 0;
/** /** @var array<string,SpecificationInterface> */
* @var string[] protected array $collection = [];
*/
/** @var string[] */
protected array $keys = []; protected array $keys = [];
/** private function validOffset(mixed $offset): void
* @var array<string,SpecificationInterface> {
*/ if (!(is_string($offset) && strlen($offset) > 0)) {
protected array $collection = []; throw new InvalidCollectionException('wrong offset type. Must be a string.');
}
}
public function count(): int private function validValue(mixed $value): void
{ {
return \count($this->collection); if (!$value instanceof SpecificationInterface) {
throw new InvalidCollectionException('wrong value type. Must be a valid specification.');
}
} }
public function jsonSerialize(): mixed public function count(): int
{ {
return $this->collection; return \count($this->collection);
} }
/**
* @codeCoverageIgnore
*/
public function current(): SpecificationInterface public function current(): SpecificationInterface
{ {
return $this->collection[$this->keys[$this->position]]; return $this->collection[$this->keys[$this->position]];
} }
/** public function key(): string
* @codeCoverageIgnore
*/
public function next(): void
{ {
++$this->position; return $this->keys[$this->position];
} }
/** public function next(): void
* @codeCoverageIgnore
*/
public function valid(): bool
{ {
return isset($this->keys[$this->position]); ++$this->position;
} }
/**
* @codeCoverageIgnore
*/
public function rewind(): void public function rewind(): void
{ {
$this->position = 0; $this->position = 0;
} }
public function valid(): bool
{
return isset($this->keys[$this->position]);
}
/** /**
* @codeCoverageIgnore * @return array<string,SpecificationInterface>
*/ */
public function key(): string public function jsonSerialize(): array
{ {
return $this->keys[$this->position]; return $this->collection;
} }
public function offsetExists(mixed $offset): bool public function offsetExists(mixed $offset): bool
{ {
$this->validOffset($offset);
return isset($this->collection[$offset]); return isset($this->collection[$offset]);
} }
public function offsetGet(mixed $offset): mixed public function offsetGet(mixed $offset): ?SpecificationInterface
{ {
$this->validOffset($offset);
return $this->collection[$offset] ?? null; return $this->collection[$offset] ?? null;
} }
public function offsetSet(mixed $offset, mixed $value): void public function offsetSet(mixed $offset, mixed $value): void
{ {
if (!$value instanceof SpecificationInterface) { $this->validValue($value);
throw new InvalidSpecificationException('A collection must only contain valid specifications.', 3); if (null === $offset) {
}
if ($offset === null || !\is_string($offset)) {
$offset = $value->getPrefix(); $offset = $value->getPrefix();
} }
$this->validOffset($offset);
$this->collection[$offset] = $value; $this->collection[$offset] = $value;
$this->keys = \array_keys($this->collection); $this->keys = \array_keys($this->collection);
...@@ -97,6 +99,8 @@ trait CollectionTrait ...@@ -97,6 +99,8 @@ trait CollectionTrait
public function offsetUnset(mixed $offset): void public function offsetUnset(mixed $offset): void
{ {
$this->validOffset($offset);
unset($this->collection[$offset]); unset($this->collection[$offset]);
$this->keys = \array_keys($this->collection); $this->keys = \array_keys($this->collection);
} }
......
<?php
declare(strict_types=1);
namespace SpipLeague\Composer\Extensions;
/**
* @since 0.8.2
*/
class InvalidCollectionException extends \DomainException
{
}
<?php <?php
declare(strict_types=1);
namespace SpipLeague\Composer\Extensions; namespace SpipLeague\Composer\Extensions;
/** /**
* @since 0.7.0 * @since 0.7.0
*/ */
class InvalidSpecificationException extends \DomainException {} class InvalidSpecificationException extends \DomainException
{
}
<?php <?php
declare(strict_types=1);
namespace SpipLeague\Composer\Extensions; namespace SpipLeague\Composer\Extensions;
use Composer\Composer; use Composer\Composer;
...@@ -16,8 +18,6 @@ use SpipLeague\Composer\SpipPaths; ...@@ -16,8 +18,6 @@ use SpipLeague\Composer\SpipPaths;
*/ */
class Specification implements SpecificationInterface class Specification implements SpecificationInterface
{ {
private string $prefix;
private string $path; private string $path;
private string $source; private string $source;
...@@ -31,14 +31,12 @@ class Specification implements SpecificationInterface ...@@ -31,14 +31,12 @@ class Specification implements SpecificationInterface
*/ */
private static ?array $packages = \null; private static ?array $packages = \null;
protected ?RemoteUrlsInterface $changer = null;
private string $validationError = ''; private string $validationError = '';
/** /**
* @param array{path:string,source:string,branch?:string,tag?:string} $fromJson * @param array{path:string,source:string,branch?:string,tag?:string} $fromJson
*/ */
public function __construct(string $prefix, array $fromJson) public function __construct(private string $prefix, array $fromJson)
{ {
if (!$this->validate($prefix, $fromJson)) { if (!$this->validate($prefix, $fromJson)) {
throw new InvalidSpecificationException($this->validationError, 1); throw new InvalidSpecificationException($this->validationError, 1);
...@@ -62,23 +60,34 @@ class Specification implements SpecificationInterface ...@@ -62,23 +60,34 @@ class Specification implements SpecificationInterface
return false; return false;
} }
if (!(isset($fromJson['path']) && \strlen($fromJson['path']) > 0)) { if (!(isset($fromJson['path']) && \strlen($fromJson['path']) > 0)) {
$this->validationError = 'empty path for "' . $prefix . '" is invalid'; $this->validationError = 'empty path for "'.$prefix.'" is invalid';
return false;
}
if (!(isset($fromJson['source']) && \strlen($fromJson['source']) > 0)) {
$this->validationError = 'empty source for "'.$prefix.'" is invalid';
return false; return false;
} }
if (!(isset($fromJson['source']) && \strlen($fromJson['source']) > 0)) { if (empty($fromJson['branch']) && empty($fromJson['tag'])) {
$this->validationError = 'empty source for "' . $prefix . '" is invalid'; $this->validationError = 'both empty branch and tag for "'.$prefix.'" is invalid';
return false; return false;
} }
$this->validationError = ''; $this->validationError = '';
return true; return true;
} }
public static function unsetPackages(): void
{
self::$packages = \null;
}
/** /**
* Détermine le `prefix` équivalent. * Détermine le `prefix` équivalent.
* *
...@@ -139,32 +148,16 @@ class Specification implements SpecificationInterface ...@@ -139,32 +148,16 @@ class Specification implements SpecificationInterface
throw new InvalidSpecificationException('Package "' . $vendorName . '" is not present.', 4); throw new InvalidSpecificationException('Package "' . $vendorName . '" is not present.', 4);
} }
public function setChanger(RemoteUrlsInterface $changer): self
{
$this->changer = $changer;
return $this;
}
/**
* @codeCoverageIgnore
*/
public function getPrefix(): string public function getPrefix(): string
{ {
return $this->prefix; return $this->prefix;
} }
/**
* @codeCoverageIgnore
*/
public function getSource(): string public function getSource(): string
{ {
return $this->source; return $this->source;
} }
/**
* @codeCoverageIgnore
*/
public function getPath(): string public function getPath(): string
{ {
return $this->path; return $this->path;
...@@ -179,13 +172,9 @@ class Specification implements SpecificationInterface ...@@ -179,13 +172,9 @@ class Specification implements SpecificationInterface
* Limitation: l'extension DOIT être composerisée et être * Limitation: l'extension DOIT être composerisée et être
* distribuée dans un dépôt composer accessible. * distribuée dans un dépôt composer accessible.
*/ */
public function computeVendorName(): string public function computeVendorName(RemoteUrlsInterface $changer): string
{ {
if ($this->changer === null) { $source = $changer->toHttps($this->source);
return '';
}
$source = $this->changer->toHttps($this->source);
$p = parse_url($source); $p = parse_url($source);
$vendorName = $p['path'] ?? ''; $vendorName = $p['path'] ?? '';
...@@ -206,27 +195,29 @@ class Specification implements SpecificationInterface ...@@ -206,27 +195,29 @@ class Specification implements SpecificationInterface
public function computeConstraint(): string public function computeConstraint(): string
{ {
if ($this->tag) { if ($this->tag) {
return '^' . \preg_replace(',^[v|V]?(\d+\.\d+).*$,', '$1', $this->tag); return '^'.\preg_replace(',^[v|V]?(\d+\.\d+).*$,', '$1', $this->tag);
}
if ($this->branch) {
return '^' . $this->branch . '.x-dev';
} }
return ''; return match (\preg_match(',^[\d.]+$,', $this->branch)) {
1 => '^'.$this->branch.'.x-dev',
0, false => 'dev-'.$this->branch,
};
} }
public function jsonSerialize(): mixed /**
* @return array{path:string,source:string,branch?:string,tag?:string}
*/
public function jsonSerialize(): array
{ {
$json = [ $json = [
'path' => $this->getPath(), 'path' => $this->getPath(),
'source' => $this->getSource(), 'source' => $this->getSource(),
]; ];
if (!empty($this->branch)) { if (!empty($this->branch)) {
$json['branch'] = $this->branch; $json['branch'] = $this->branch;
} }
if (!empty($this->tag)) { if (!empty($this->tag)) {
$json['tag'] = $this->tag; $json['tag'] = $this->tag;
} }
return $json; return $json;
......
<?php <?php
declare(strict_types=1);
namespace SpipLeague\Composer\Extensions; namespace SpipLeague\Composer\Extensions;
use SpipLeague\Composer\Git\RemoteUrlsInterface;
/** /**
* Spécifiations d'installation d'un "plugins-dist" en SPIP4.4. * Spécifiations d'installation d'un "plugins-dist" en SPIP4.4.
* *
...@@ -11,12 +15,14 @@ interface SpecificationInterface extends \JsonSerializable ...@@ -11,12 +15,14 @@ interface SpecificationInterface extends \JsonSerializable
{ {
public function getPrefix(): string; public function getPrefix(): string;
public function getSource(): string;
public function getPath(): string; public function getPath(): string;
/** /**
* Détermine le `vendor/name` équivalent. * Détermine le `vendor/name` équivalent.
*/ */
public function computeVendorName(): string; public function computeVendorName(RemoteUrlsInterface $changer): string;
/** /**
* Détermine la `constraint` équivalente. * Détermine la `constraint` équivalente.
......
...@@ -28,7 +28,7 @@ class PluginsClearCache ...@@ -28,7 +28,7 @@ class PluginsClearCache
/** /**
* To delete the cache files dedicated of the activated plugins * To delete the cache files dedicated of the activated plugins
*/ */
public static function clearCache(Event $event) public static function clearCache(Event $event): void
{ {
$event->getIO() $event->getIO()
->write('Clearing the plugins cache ...'); ->write('Clearing the plugins cache ...');
......