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 (3)
Affichage de
avec 147 ajouts et 99 suppressions
......@@ -2,5 +2,6 @@
.gitignore export-ignore
.gitattributes export-ignore
/tests/ export-ignore
/plugin.xml export-ignore
/.php-cs-fixer.dist.php export-ignore
/phpunit.xml.dist export-ignore
/phpstan-baseline.neon export-ignore
/phpstan.neon.dist export-ignore
/vendor/
/composer.phar
/composer.lock
.php_cs.cache
/phpunit.xml
/.phpunit.cache
/phpstan.neon
/tmp/
/.php-cs-fixer.cache
/.php-cs-fixer.php
......@@ -14,7 +14,15 @@
},
"require-dev": {
"composer/composer": "^2.8",
"phpunit/phpunit": "^11.4"
"phpunit/phpunit": "^11.4",
"rector/rector": "^2.0",
"spip-league/easy-coding-standard": "^1.1"
},
"repositories": {
"spip": {
"type": "composer",
"url": "https://get.spip.net/composer"
}
},
"autoload": {
"psr-4": {
......@@ -31,5 +39,14 @@
"dev-main": "0.8.x-dev"
},
"class": "SpipLeague\\Composer\\SpipInstallerPlugin"
},
"scripts": {
"analyse": "vendor/bin/phpstan",
"check-cs": "vendor/bin/ecs check --ansi",
"fix-cs": "vendor/bin/ecs check --fix --ansi",
"rector": "vendor/bin/rector process --ansi",
"rector-dry-run": "vendor/bin/rector process --dry-run --ansi",
"test": "phpunit --colors --no-coverage",
"test-coverage": "@php -d xdebug.mode=coverage vendor/bin/phpunit --colors"
}
}
<?php
declare(strict_types=1);
use SpipLeague\EasyCodingStandard\Set\SetList;
use Symplify\EasyCodingStandard\Config\ECSConfig;
return ECSConfig::configure()
->withSets([SetList::SPIP_LEAGUE])
->withPaths([__DIR__ . '/src', __DIR__ . '/tests'])
->withRootFiles()
->withParallel()
;
......@@ -6,4 +6,5 @@ parameters:
phpVersion: 70400
paths:
- src
- tests
level: max
Fichier déplacé
<?php
declare(strict_types=1);
use Rector\CodeQuality\Rector\LogicalAnd\LogicalToBooleanRector;
use Rector\Config\RectorConfig;
use Rector\Php81\Rector\FuncCall\NullToStrictStringFuncCallArgRector;
return RectorConfig::configure()
->withPaths([__DIR__ . '/src', __DIR__ . '/tests'])
->withRootFiles()
->withPhpSets(php74: true)
->withRules([LogicalToBooleanRector::class])
->withSkip([NullToStrictStringFuncCallArgRector::class]);
......@@ -11,31 +11,30 @@ use Symfony\Component\Filesystem\Filesystem as SymfonyFilesystem;
*/
class AssetsClearCache
{
/** @var string[] */
private static array $dirs = [
SpipPaths::DIR_ASSETS_CSS,
SpipPaths::DIR_ASSETS_JS,
];
/**
* @var string[]
*/
private static array $dirs = [SpipPaths::DIR_ASSETS_CSS, SpipPaths::DIR_ASSETS_JS];
/**
* To delete the cache files dedicated for public compiled assets
*
* @param $event
*
* @return void
*/
public static function clearCache(Event $event)
{
$event->getIO()->write('Clearing the assets cache ...');
$vendorDir = $event->getComposer()->getConfig()->get('vendor-dir') . '/';
$event->getIO()
->write('Clearing the assets cache ...');
$vendorDir = $event->getComposer()
->getConfig()
->get('vendor-dir') . '/';
$fs = new Filesystem($event->getComposer()->getLoop()->getProcessExecutor());
$sffs = new SymfonyFilesystem;
$sffs = new SymfonyFilesystem();
foreach (self::$dirs as $dir) {
$fs->emptyDirectory($vendorDir . '../' . SpipPaths::interpolate($dir));
$sffs->chmod($vendorDir . '../' . SpipPaths::interpolate($dir), SpipPaths::CHMOD, SpipPaths::UMASK);
}
$event->getIO()->write('Done.');
$event->getIO()
->write('Done.');
}
}
......@@ -10,12 +10,14 @@ use Symfony\Component\Filesystem\Filesystem;
*/
class BaseDirectories
{
/** @var string[] */
private static array $readOnlyDirs = [
SpipPaths::ETC,
];
/**
* @var string[]
*/
private static array $readOnlyDirs = [SpipPaths::ETC];
/** @var string[] */
/**
* @var string[]
*/
private static array $writeableDirs = [
SpipPaths::VAR,
SpipPaths::TMP,
......@@ -26,46 +28,57 @@ class BaseDirectories
/**
* To create base directories
*
* @param $event
*
* @return void
*/
public static function createBaseDirectories(Event $event, bool $check = false)
{
if ($check) {
$event->getIO()->write('Checking base directories ...');
$event->getIO()
->write('Checking base directories ...');
} else {
$event->getIO()->write('Creating base directories ...');
$event->getIO()
->write('Creating base directories ...');
}
$vendorDir = $event->getComposer()->getConfig()->get('vendor-dir') . '/';
$vendorDir = $event->getComposer()
->getConfig()
->get('vendor-dir') . '/';
$fs = new Filesystem();
foreach (self::$readOnlyDirs as $dir) {
$toCreate = $vendorDir . '../' . SpipPaths::interpolate($dir);
if (!$fs->exists($toCreate)) {
$event->getIO()->write('Creating ' . SpipPaths::interpolate($dir) . ' ...');
$event->getIO()
->write('Creating ' . SpipPaths::interpolate($dir) . ' ...');
$fs->mkdir($toCreate);
} else {
$event->getIO()->write(SpipPaths::interpolate($dir) . ' OK');
$event->getIO()
->write(SpipPaths::interpolate($dir) . ' OK');
}
$event->getIO()->write(\sprintf('Applying chmod %04o on ', SpipPaths::CHMOD & ~0022) . SpipPaths::interpolate($dir) . ' ...');
$event->getIO()
->write(
\sprintf('Applying chmod %04o on ', SpipPaths::CHMOD & ~0022) . SpipPaths::interpolate(
$dir,
) . ' ...',
);
$fs->chmod($toCreate, SpipPaths::CHMOD, SpipPaths::UMASK | 0022);
}
foreach (self::$writeableDirs as $dir) {
$toCreate = $vendorDir . '../' . SpipPaths::interpolate($dir);
if (!$fs->exists($toCreate)) {
$event->getIO()->write('Creating ' . SpipPaths::interpolate($dir) . ' ...');
$event->getIO()
->write('Creating ' . SpipPaths::interpolate($dir) . ' ...');
$fs->mkdir($toCreate);
} else {
$event->getIO()->write(SpipPaths::interpolate($dir) . ' OK');
$event->getIO()
->write(SpipPaths::interpolate($dir) . ' OK');
}
$event->getIO()->write(\sprintf('Applying chmod %04o on ', SpipPaths::CHMOD) . SpipPaths::interpolate($dir) . ' ...');
$event->getIO()
->write(\sprintf('Applying chmod %04o on ', SpipPaths::CHMOD) . SpipPaths::interpolate($dir) . ' ...');
$fs->chmod($toCreate, SpipPaths::CHMOD, SpipPaths::UMASK);
}
$event->getIO()->write('Done.');
$event->getIO()
->write('Done.');
}
}
......@@ -9,7 +9,8 @@ abstract class AbstractSpipCommand extends BaseCommand
protected function getRootDir(): string
{
$composer = $this->requireComposer();
$vendorDir = $composer->getConfig()->get('vendor-dir');
$vendorDir = $composer->getConfig()
->get('vendor-dir');
return \realpath($vendorDir . '/..') ?: '';
}
......
......@@ -13,12 +13,15 @@ use Symfony\Component\Console\Output\OutputInterface;
/**
* @since 0.7.0
*
* @author JamesRezo <jamees@rezo.net>
*/
abstract class AbstractSwitchCommand extends AbstractSpipCommand
{
abstract protected function doSwitch(Analyzer $analyzer, Switcher $switcher, OutputInterface $output, callable $reset): int;
abstract protected function doSwitch(
Analyzer $analyzer,
Switcher $switcher,
OutputInterface $output,
callable $reset,
): int;
protected function execute(InputInterface $input, OutputInterface $output): int
{
......@@ -51,12 +54,15 @@ abstract class AbstractSwitchCommand extends AbstractSpipCommand
if (
$exitCode === AbstractSpipCommand::SUCCESS
) {
$exitCode = $this->getApplication()->doRun(new ArrayInput(['command' => 'update']), $output);
$exitCode = $this->getApplication()
->doRun(new ArrayInput(['command' => 'update']), $output);
if (
$exitCode === AbstractSpipCommand::SUCCESS
&& $this->getApplication()->has('normalize')
&& $this->getApplication()
->has('normalize')
) {
$exitCode = $this->getApplication()->doRun(new ArrayInput(['command' => 'normalize']), $output);
$exitCode = $this->getApplication()
->doRun(new ArrayInput(['command' => 'normalize']), $output);
}
}
......@@ -73,7 +79,7 @@ abstract class AbstractSwitchCommand extends AbstractSpipCommand
} else {
\file_put_contents(
$distributionFile,
\json_encode($distribution, \JSON_PRETTY_PRINT | \JSON_UNESCAPED_SLASHES)
\json_encode($distribution, \JSON_PRETTY_PRINT | \JSON_UNESCAPED_SLASHES),
);
}
}
......
......@@ -66,14 +66,13 @@ class LocalCommand extends AbstractSpipCommand
// create new input without "local" command prefix
$input = new StringInput(Preg::replace('{\bl(?:o(?:c(?:a(?:l)?)?)?)?\b}', '', $input->__toString(), 1));
$this->getApplication()->resetComposer();
$this->getApplication()
->resetComposer();
return $this->getApplication()->run($input, $output);
return $this->getApplication()
->run($input, $output);
}
/**
* @inheritDoc
*/
public function isProxyCommand(): bool
{
return true;
......
......@@ -27,13 +27,14 @@ class ModeDevCommand extends AbstractSpipCommand
{
$composerFile = Factory::getComposerFile();
$composer = $this->tryComposer();
if (\is_null($composer)) {
if ($composer === null) {
return AbstractSpipCommand::FAILURE;
}
$output->writeln('Looking into ' . $composerFile);
if (SpipPaths::LOCAL_COMPOSER == $composerFile) {
$tmp = $composer->getConfig()->get('preferred-install');
if ($composerFile == SpipPaths::LOCAL_COMPOSER) {
$tmp = $composer->getConfig()
->get('preferred-install');
if (is_string($tmp)) {
$tmp = [$tmp];
}
......@@ -42,7 +43,9 @@ class ModeDevCommand extends AbstractSpipCommand
}
if (empty(\array_intersect(['spip/*' => 'source'], $tmp))) {
$output->writeln('<warning>Missing preferred-install in ' . $composerFile . '</warning>');
if (!$this->getIO()->askConfirmation('<info>Adding default preferred-install ?</info> [<comment>Y,n</comment>]?')) {
if (!$this->getIO()->askConfirmation(
'<info>Adding default preferred-install ?</info> [<comment>Y,n</comment>]?',
)) {
$output->writeln('Aborting.');
return AbstractSpipCommand::FAILURE;
}
......@@ -52,7 +55,7 @@ class ModeDevCommand extends AbstractSpipCommand
$json->addConfigSetting('preferred-install', ['spip/*' => 'source']);
$this->resetComposer();
$composer = $this->tryComposer();
if (\is_null($composer)) {
if ($composer === null) {
return AbstractSpipCommand::FAILURE;
}
}
......
......@@ -11,13 +11,11 @@ use Symfony\Component\Console\Output\OutputInterface;
/**
* @since 0.7.0
*
* @author JamesRezo <jamees@rezo.net>
*/
#[AsCommand(
name: 'spip:extensions:switch-back',
description: 'Switch back to a SPIP4-Like installation of extensions',
aliases: ['switch:back', 'back']
aliases: ['switch:back', 'back'],
)]
class SwitchBackCommand extends AbstractSwitchCommand
{
......
......@@ -10,13 +10,11 @@ use Symfony\Component\Console\Output\OutputInterface;
/**
* @since 0.7.0
*
* @author JamesRezo <jamees@rezo.net>
*/
#[AsCommand(
name: 'spip:extensions:switch-forward',
description: 'Switch to a SPIP5-Like installation of extensions',
aliases: ['switch:forward', 'forward']
aliases: ['switch:forward', 'forward'],
)]
class SwitchForwardCommand extends AbstractSwitchCommand
{
......
......@@ -13,16 +13,8 @@ use SpipLeague\Composer\Command\SwitchForwardCommand;
*/
class CommandProvider implements CommandProviderCapability
{
/**
* {@inheritDoc}
*/
public function getCommands()
{
return [
new LocalCommand(),
new ModeDevCommand(),
new SwitchForwardCommand(),
new SwitchBackCommand(),
];
return [new LocalCommand(), new ModeDevCommand(), new SwitchForwardCommand(), new SwitchBackCommand()];
}
}
......@@ -27,10 +27,9 @@ class PreferredInstall
}
$toCheck = array_keys(array_filter(
$this->composer->getConfig()->get('preferred-install'),
function ($install) {
return $install === 'source';
},
$this->composer->getConfig()
->get('preferred-install'),
fn($install) => $install === 'source',
));
// packages to change by mode-dev
......@@ -41,7 +40,8 @@ class PreferredInstall
$template = $extra['spip']['template'] ?? ''; // -> SpipPaths::TEMPLATE/
$privateTemplate = $extra['spip']['private_template'] ?? ''; // -> SpipPaths::PRIVATE_TEMPLATE/
$backOffice = $extra['spip']['back_office'] ?? ''; // -> SpipPaths::BACK_OFFICE/
$vendorDir = $this->composer->getConfig()->get('vendor-dir'); // -> vendor/
$vendorDir = $this->composer->getConfig()
->get('vendor-dir'); // -> vendor/
$rootDir = realpath($vendorDir . '/..');
// -> plugins/ ?
......
......@@ -9,8 +9,6 @@ use SpipLeague\Composer\SpipPaths;
* Déduite du contenu du fichier `./plugins-dist.json`
*
* @since 0.7.0
*
* @author JamesRezo <james@rezo.net>
*/
class Collection implements CollectionInterface
{
......@@ -24,9 +22,10 @@ class Collection implements CollectionInterface
public function __construct(array $distribution, ?string $file = \null)
{
$originalCount = \count($distribution);
$distribution = \array_filter($distribution, function ($specification) {
return $specification instanceof SpecificationInterface && !empty($specification->getPrefix());
});
$distribution = \array_filter(
$distribution,
fn($specification) => $specification instanceof SpecificationInterface && !empty($specification->getPrefix()),
);
$count = \count($distribution);
if ($originalCount != 0 && ($count < 1 || $originalCount != $count)) {
throw new InvalidSpecificationException('A collection must contain at least one valid specification.', 2);
......@@ -40,24 +39,19 @@ class Collection implements CollectionInterface
$this->file = $file;
}
/**
* @throws \RuntimeException on any composer errror
* @throws \LogicException if plugins-dist.json is missing
*/
public static function fromJsonFile(RemoteUrlsInterface $changer, ?string $file = null): self
{
if (\is_null($file)) {
if ($file === null) {
$file = SpipPaths::LOCAL_PLUGINS_DIST;
}
if (!(\file_exists($file) || \file_put_contents($file, '{}'))) {
throw new \LogicException('<error>File "' . $file . '" is missing and can\' be created. Can\'t upgrade/downgrade.</error>');
throw new \LogicException(
'<error>File "' . $file . '" is missing and can\' be created. Can\'t upgrade/downgrade.</error>',
);
}
$pluginsDist = \json_decode(
\file_get_contents($file) ?: '',
\true
);
$pluginsDist = \json_decode(\file_get_contents($file) ?: '', \true);
if (!\is_array($pluginsDist)) {
throw new \LogicException('<error>File "' . $file . '" malformed. Can\'t upgrade/downgrade.</error>');
}
......
......@@ -9,8 +9,6 @@ namespace SpipLeague\Composer\Extensions;
* @extends \Iterator<string,SpecificationInterface>
*
* @since 0.7.0
*
* @author JamesRezo <james@rezo.net>
*/
interface CollectionInterface extends \Countable, \Iterator, \JsonSerializable, \ArrayAccess
{
......
......@@ -6,17 +6,19 @@ namespace SpipLeague\Composer\Extensions;
* Implémentation concrète de \Countable, \Iterator, \JsonSerializable, \ArrayAccess.
*
* @since 0.7.0
*
* @author JamesRezo <james@rezo.net>
*/
trait CollectionTrait
{
protected int $position = 0;
/** @var string[] */
/**
* @var string[]
*/
protected array $keys = [];
/** @var array<string,SpecificationInterface> */
/**
* @var array<string,SpecificationInterface>
*/
protected array $collection = [];
public function count(): int
......@@ -76,7 +78,7 @@ trait CollectionTrait
public function offsetGet(mixed $offset): mixed
{
return isset($this->collection[$offset]) ? $this->collection[$offset] : null;
return $this->collection[$offset] ?? null;
}
public function offsetSet(mixed $offset, mixed $value): void
......@@ -85,7 +87,7 @@ trait CollectionTrait
throw new InvalidSpecificationException('A collection must only contain valid specifications.', 3);
}
if (is_null($offset) || !\is_string($offset)) {
if ($offset === null || !\is_string($offset)) {
$offset = $value->getPrefix();
}
......