Skip to content

Commit

Permalink
Merge pull request #24 from kynx/cs-fixer
Browse files Browse the repository at this point in the history
Added --cs-fix option to run phpcbf on changed files
  • Loading branch information
kynx authored Feb 24, 2024
2 parents 3ce2452 + cc818cf commit 0f884d1
Show file tree
Hide file tree
Showing 27 changed files with 1,144 additions and 673 deletions.
2 changes: 1 addition & 1 deletion psalm-baseline.xml
Original file line number Diff line number Diff line change
Expand Up @@ -213,7 +213,7 @@
<code><![CDATA[visitProvider]]></code>
</PossiblyUnusedMethod>
</file>
<file src="test/Writer/FileWriterTest.php">
<file src="test/Writer/NetteCodeGeneratorTest.php">
<PossiblyUnusedMethod>
<code><![CDATA[importTypesProvider]]></code>
<code><![CDATA[writeProvider]]></code>
Expand Down
14 changes: 14 additions & 0 deletions src/CodingStandards/FixerInterface.php
Original file line number Diff line number Diff line change
@@ -0,0 +1,14 @@
<?php

declare(strict_types=1);

namespace Kynx\Laminas\FormShape\CodingStandards;

interface FixerInterface
{
public function getName(): string;

public function addFile(string $path): void;

public function fix(): void;
}
39 changes: 39 additions & 0 deletions src/CodingStandards/PhpCodeSnifferFixer.php
Original file line number Diff line number Diff line change
@@ -0,0 +1,39 @@
<?php

declare(strict_types=1);

namespace Kynx\Laminas\FormShape\CodingStandards;

use Kynx\Laminas\FormShape\CodingStandards\FixerInterface;

use function array_map;
use function basename;
use function escapeshellarg;
use function escapeshellcmd;
use function implode;
use function passthru;

final class PhpCodeSnifferFixer implements FixerInterface
{
private array $paths = [];

public function __construct(private string $phpCbf)
{
}

public function getName(): string
{
return basename($this->phpCbf);
}

public function addFile(string $path): void
{
$this->paths[] = $path;
}

public function fix(): void
{
$paths = array_map(static fn (string $path): string => escapeshellarg($path), $this->paths);
passthru(escapeshellcmd($this->phpCbf) . ' ' . implode(' ', $paths));
}
}
6 changes: 6 additions & 0 deletions src/Command/ProgressListener.php
Original file line number Diff line number Diff line change
Expand Up @@ -4,6 +4,7 @@

namespace Kynx\Laminas\FormShape\Command;

use Kynx\Laminas\FormShape\CodingStandards\FixerInterface;
use Kynx\Laminas\FormShape\Form\ProgressListenerInterface;
use ReflectionClass;
use Symfony\Component\Console\Command\Command;
Expand All @@ -23,6 +24,7 @@ final class ProgressListener implements ProgressListenerInterface
*/
public function __construct(
private readonly StyleInterface $io,
private readonly ?FixerInterface $fixer,
private readonly string $cwd,
private readonly array $paths
) {
Expand All @@ -38,6 +40,10 @@ public function success(ReflectionClass $reflection): void
{
$path = substr($reflection->getFileName(), strlen($this->cwd) + 1);
$this->io->text("Processed $path");

if ($this->fixer !== null) {
$this->fixer->addFile($path);
}
}

public function finally(int $processed): void
Expand Down
30 changes: 25 additions & 5 deletions src/Command/PsalmTypeCommand.php
Original file line number Diff line number Diff line change
Expand Up @@ -4,6 +4,7 @@

namespace Kynx\Laminas\FormShape\Command;

use Kynx\Laminas\FormShape\CodingStandards\FixerInterface;
use Kynx\Laminas\FormShape\Form\FormProcessorInterface;
use Symfony\Component\Console\Command\Command;
use Symfony\Component\Console\Input\InputArgument;
Expand All @@ -16,8 +17,10 @@

final class PsalmTypeCommand extends Command
{
public function __construct(private readonly FormProcessorInterface $formProcessor)
{
public function __construct(
private readonly FormProcessorInterface $formProcessor,
private readonly ?FixerInterface $fixer,
) {
parent::__construct();
}

Expand All @@ -35,16 +38,26 @@ protected function configure(): void
'fieldset-types',
null,
InputOption::VALUE_NEGATABLE,
'Add types to fieldsets',
'Add types to fieldsets (enabled by default)',
true
)
->addOption(
'remove-getdata-return',
null,
InputOption::VALUE_NEGATABLE,
'Remove @return from getData(), if present',
'Remove @return from getData(), if present (disabled by default)',
false
);

if ($this->fixer !== null) {
$name = $this->fixer->getName();
$this->addOption(
'cs-fix',
null,
InputOption::VALUE_NONE,
"Run $name on changed files",
);
}
}

protected function execute(InputInterface $input, OutputInterface $output): int
Expand All @@ -54,11 +67,18 @@ protected function execute(InputInterface $input, OutputInterface $output): int
$processFieldsets = (bool) $input->getOption('fieldset-types');
$removeGetDataReturn = (bool) $input->getOption('remove-getdata-return');

$fix = $this->fixer !== null && $input->getOption('cs-fix');

$io = new SymfonyStyle($input, $output);
$listener = new ProgressListener($io, getcwd(), $paths);
$listener = new ProgressListener($io, $fix ? $this->fixer : null, getcwd(), $paths);

$this->formProcessor->process($paths, $listener, $processFieldsets, $removeGetDataReturn);

if ($fix) {
$io->info("Running " . $this->fixer->getName() . "...");
$this->fixer->fix();
}

return $listener->getStatus();
}
}
30 changes: 29 additions & 1 deletion src/Command/PsalmTypeCommandFactory.php
Original file line number Diff line number Diff line change
Expand Up @@ -4,15 +4,43 @@

namespace Kynx\Laminas\FormShape\Command;

use Composer\InstalledVersions;
use Kynx\Laminas\FormShape\CodingStandards\FixerInterface;
use Kynx\Laminas\FormShape\CodingStandards\PhpCodeSnifferFixer;
use Kynx\Laminas\FormShape\Form\FormProcessor;
use Psr\Container\ContainerInterface;

use function is_executable;
use function sprintf;

final readonly class PsalmTypeCommandFactory
{
public function __invoke(ContainerInterface $container): PsalmTypeCommand
{
return new PsalmTypeCommand(
$container->get(FormProcessor::class)
$container->get(FormProcessor::class),
$this->getFixer()
);
}

private function getFixer(): ?FixerInterface
{
$phpCodeSniffer = null;
foreach (InstalledVersions::getAllRawData() as $installed) {
if (isset($installed['versions']['squizlabs/php_codesniffer'])) {
$phpCodeSniffer = $installed['versions']['squizlabs/php_codesniffer'];
break;
}
}
if ($phpCodeSniffer === null || ! isset($phpCodeSniffer['install_path'])) {
return null;
}

$path = sprintf('%s/bin/phpcbf', $phpCodeSniffer['install_path']);
if (! is_executable($path)) {
return null;
}

return new PhpCodeSnifferFixer($path);
}
}
5 changes: 5 additions & 0 deletions src/ConfigProvider.php
Original file line number Diff line number Diff line change
Expand Up @@ -60,8 +60,11 @@
use Kynx\Laminas\FormShape\Validator\StepVisitor;
use Kynx\Laminas\FormShape\Validator\StringLengthVisitor;
use Kynx\Laminas\FormShape\ValidatorVisitorInterface;
use Kynx\Laminas\FormShape\Writer\CodeGeneratorInterface;
use Kynx\Laminas\FormShape\Writer\FileWriter;
use Kynx\Laminas\FormShape\Writer\FileWriterFactory;
use Kynx\Laminas\FormShape\Writer\NetteCodeGenerator;
use Kynx\Laminas\FormShape\Writer\NetteCodeGeneratorFactory;
use Laminas\ServiceManager\ConfigInterface;
use Psalm\Type\Atomic\TFloat;
use Psalm\Type\Atomic\TInt;
Expand Down Expand Up @@ -212,6 +215,7 @@ private function getDependencyConfig(): array
{
return [
'aliases' => [
CodeGeneratorInterface::class => NetteCodeGenerator::class,
DecoratorInterface::class => PrettyPrinter::class,
FormLocatorInterface::class => FormLocator::class,
InputFilterVisitorInterface::class => InputFilterVisitor::class,
Expand All @@ -225,6 +229,7 @@ private function getDependencyConfig(): array
FileValidatorVisitor::class => FileValidatorVisitorFactory::class,
FormLocator::class => FormLocatorFactory::class,
FormProcessor::class => FormProcessorFactory::class,
NetteCodeGenerator::class => NetteCodeGeneratorFactory::class,
PrettyPrinter::class => PrettyPrinterFactory::class,
PsalmTypeCommand::class => PsalmTypeCommandFactory::class,
FileWriter::class => FileWriterFactory::class,
Expand Down
Original file line number Diff line number Diff line change
Expand Up @@ -11,9 +11,9 @@

use function sprintf;

final class WriterException extends RuntimeException implements ExceptionInterface
final class CodeGeneratorException extends RuntimeException implements ExceptionInterface
{
public static function fileRead(ReflectionClass $reflection, Throwable $throwable): self
public static function cannotParse(ReflectionClass $reflection, Throwable $throwable): self
{
return new self(
sprintf("Could not parse %s: %s", $reflection->getFileName(), $throwable->getMessage()),
Expand Down
23 changes: 23 additions & 0 deletions src/Writer/CodeGeneratorInterface.php
Original file line number Diff line number Diff line change
@@ -0,0 +1,23 @@
<?php

declare(strict_types=1);

namespace Kynx\Laminas\FormShape\Writer;

use Kynx\Laminas\FormShape\InputFilter\ImportType;
use Psalm\Type\Union;
use ReflectionClass;

interface CodeGeneratorInterface
{
/**
* @param array<ImportType> $importTypes
*/
public function generate(
ReflectionClass $reflection,
Union $type,
array $importTypes,
string $contents,
bool $replaceGetDataReturn = false
): GeneratedCode;
}
Loading

0 comments on commit 0f884d1

Please sign in to comment.