Skip to content

Commit

Permalink
Scaffolder improvements (#902)
Browse files Browse the repository at this point in the history
* Adds an ability to pass command specific parameters to the class declaration.

Improves create:bootloader command
- Adds final for class
- Adds an ability to create domain bootloader with interceptors using `-d` option
- Uses PHP attributes for command definition

* Apply fixes from StyleCI

[ci skip] [skip ci]

* Improves `create:command` command
- Adds `final` for class
- Uses `__invoke` method instead of `perform`
- Uses PHP attributes for command definition
- Uses PHP attributes for console command declaration
- Adds an ability to add arguments and options to generated console command
- Improves command name generation

* chore: removes extra imports

* Improves `create:config` command
- Adds `final` for class
- Uses PHP attributes for command definition

* Brings in order scaffolder commands

* Adds command `create:filter` for filters declaration

* Apply fixes from StyleCI

[ci skip] [skip ci]

* Fixes cs

* Fixes cs

* Fixes tests

* Fixes tests

* Fixes tests

* Fixes tests

* Fixes tests

* Update src/Scaffolder/src/Declaration/CommandDeclaration.php

Co-authored-by: Aleksei Gagarin <[email protected]>

* Update src/Scaffolder/src/Declaration/ConfigDeclaration.php

Co-authored-by: Aleksei Gagarin <[email protected]>

* Fixes rector issues

---------

Co-authored-by: StyleCI Bot <[email protected]>
Co-authored-by: Aleksei Gagarin <[email protected]>
  • Loading branch information
3 people authored Mar 27, 2023
1 parent 5d5b62e commit 577caa8
Show file tree
Hide file tree
Showing 31 changed files with 715 additions and 361 deletions.
2 changes: 1 addition & 1 deletion .github/workflows/main.yml
Original file line number Diff line number Diff line change
Expand Up @@ -115,7 +115,7 @@ jobs:
- name: Static Analysis
run: |
vendor/bin/psalm --no-cache --shepherd --stats --output-format=checkstyle --php-version=${{ matrix.php }}
vendor/bin/rector --dry-run
vendor/bin/rector --dry-run --clear-cache
coding-standards:
Expand Down
10 changes: 10 additions & 0 deletions rector.php
Original file line number Diff line number Diff line change
Expand Up @@ -3,6 +3,7 @@
declare(strict_types=1);

use Rector\Config\RectorConfig;
use Rector\DeadCode\Rector\Property\RemoveUnusedPrivatePropertyRector;
use Rector\DeadCode\Rector\ClassMethod\RemoveUnusedPrivateMethodRector;
use Rector\DeadCode\Rector\If_\RemoveAlwaysTrueIfConditionRector;
use Rector\DeadCode\Rector\Property\RemoveUselessVarTagRector;
Expand All @@ -18,6 +19,15 @@
$config->parallel();
$config->skip([
CountOnNullRector::class,
RemoveUnusedPrivatePropertyRector::class => [
__DIR__ . '/src/Scaffolder/src/Command/BootloaderCommand.php',
__DIR__ . '/src/Scaffolder/src/Command/CommandCommand.php',
__DIR__ . '/src/Scaffolder/src/Command/ConfigCommand.php',
__DIR__ . '/src/Scaffolder/src/Command/ControllerCommand.php',
__DIR__ . '/src/Scaffolder/src/Command/FilterCommand.php',
__DIR__ . '/src/Scaffolder/src/Command/JobHandlerCommand.php',
__DIR__ . '/src/Scaffolder/src/Command/MiddlewareCommand.php',
],
RemoveUnusedPrivateMethodRector::class => [
__DIR__ . '/src/Boot/src/Bootloader/ConfigurationBootloader.php',
__DIR__ . '/src/Broadcasting/src/Bootloader/BroadcastingBootloader.php',
Expand Down
42 changes: 24 additions & 18 deletions src/Scaffolder/src/Bootloader/ScaffolderBootloader.php
Original file line number Diff line number Diff line change
Expand Up @@ -25,7 +25,7 @@ class ScaffolderBootloader extends Bootloader

public function __construct(
private readonly ConfiguratorInterface $config,
private readonly KernelInterface $kernel
private readonly KernelInterface $kernel,
) {
}

Expand All @@ -37,6 +37,7 @@ public function init(ConsoleBootloader $console): void
$console->addCommand(Command\ControllerCommand::class);
$console->addCommand(Command\JobHandlerCommand::class);
$console->addCommand(Command\MiddlewareCommand::class);
$console->addCommand(Command\FilterCommand::class);

try {
$defaultNamespace = (new ReflectionClass($this->kernel))->getNamespaceName();
Expand All @@ -49,58 +50,63 @@ public function init(ConsoleBootloader $console): void
* This is set of comment lines to be applied to every scaffolded file, you can use env() function
* to make it developer specific or set one universal pattern per project.
*/
'header' => [],
'header' => [],

/*
* Base directory for generated classes, class will be automatically localed into sub directory
* using given namespace.
*/
'directory' => directory('app') . 'src/',
'directory' => directory('app') . 'src/',

/*
* Default namespace to be applied for every generated class. By default uses Kernel namespace
*
* Example: 'namespace' => 'MyApplication'
* Controllers: MyApplication\Controllers\SampleController
*/
'namespace' => $defaultNamespace,
'namespace' => $defaultNamespace,

/*
* This is set of default settings to be used for your scaffolding commands.
*/
'declarations' => [
Declaration\BootloaderDeclaration::TYPE => [
'namespace' => 'Bootloader',
'postfix' => 'Bootloader',
'class' => Declaration\BootloaderDeclaration::class,
'postfix' => 'Bootloader',
'class' => Declaration\BootloaderDeclaration::class,
],
Declaration\ConfigDeclaration::TYPE => [
'namespace' => 'Config',
'postfix' => 'Config',
'class' => Declaration\ConfigDeclaration::class,
'options' => [
'postfix' => 'Config',
'class' => Declaration\ConfigDeclaration::class,
'options' => [
'directory' => directory('config'),
],
],
Declaration\ControllerDeclaration::TYPE => [
'namespace' => 'Controller',
'postfix' => 'Controller',
'class' => Declaration\ControllerDeclaration::class,
'postfix' => 'Controller',
'class' => Declaration\ControllerDeclaration::class,
],
Declaration\FilterDeclaration::TYPE => [
'namespace' => 'Filter',
'postfix' => 'Filter',
'class' => Declaration\FilterDeclaration::class,
],
Declaration\MiddlewareDeclaration::TYPE => [
'namespace' => 'Middleware',
'postfix' => '',
'class' => Declaration\MiddlewareDeclaration::class,
'postfix' => '',
'class' => Declaration\MiddlewareDeclaration::class,
],
Declaration\CommandDeclaration::TYPE => [
'namespace' => 'Command',
'postfix' => 'Command',
'class' => Declaration\CommandDeclaration::class,
'postfix' => 'Command',
'class' => Declaration\CommandDeclaration::class,
],
Declaration\JobHandlerDeclaration::TYPE => [
'namespace' => 'Job',
'postfix' => 'Job',
'class' => Declaration\JobHandlerDeclaration::class,
'postfix' => 'Job',
'class' => Declaration\JobHandlerDeclaration::class,
],
],
]);
Expand All @@ -113,7 +119,7 @@ public function addDeclaration(string $name, array $declaration): void
{
$this->config->modify(
ScaffolderConfig::CONFIG,
new Append('declarations', $name, $declaration)
new Append('declarations', $name, $declaration),
);
}
}
4 changes: 2 additions & 2 deletions src/Scaffolder/src/Command/AbstractCommand.php
Original file line number Diff line number Diff line change
Expand Up @@ -31,15 +31,15 @@ public function __construct(
* @param class-string<TClass> $class
* @return TClass
*/
protected function createDeclaration(string $class): DeclarationInterface
protected function createDeclaration(string $class, array $params = []): DeclarationInterface
{
return $this->factory->make(
$class,
[
'name' => (string)$this->argument('name'),
'comment' => $this->getComment(),
'namespace' => $this->getNamespace(),
] + $this->config->declarationOptions($class::TYPE),
] + $params + $this->config->declarationOptions($class::TYPE),
);
}

Expand Down
50 changes: 20 additions & 30 deletions src/Scaffolder/src/Command/BootloaderCommand.php
Original file line number Diff line number Diff line change
Expand Up @@ -4,43 +4,33 @@

namespace Spiral\Scaffolder\Command;

use Spiral\Console\Attribute\Argument;
use Spiral\Console\Attribute\AsCommand;
use Spiral\Console\Attribute\Option;
use Spiral\Console\Attribute\Question;
use Spiral\Scaffolder\Declaration\BootloaderDeclaration;
use Symfony\Component\Console\Input\InputArgument;
use Symfony\Component\Console\Input\InputOption;

#[Question(
question: 'What would you like to name the Bootloader?',
argument: 'name'
)]
#[AsCommand(name: 'create:bootloader', description: 'Create bootloader declaration')]
class BootloaderCommand extends AbstractCommand
{
protected const NAME = 'create:bootloader';
protected const DESCRIPTION = 'Create bootloader declaration';
protected const ARGUMENTS = [
['name', InputArgument::REQUIRED, 'bootloader name'],
];
protected const OPTIONS = [
[
'comment',
'c',
InputOption::VALUE_OPTIONAL,
'Optional comment to add as class header',
],
[
'namespace',
null,
InputOption::VALUE_OPTIONAL,
'Optional, specify a custom namespace',
],
];

/**
* Create bootloader declaration.
*/
#[Argument(description: 'Bootloader name')]
#[Question(question: 'What would you like to name the Bootloader?')]
private string $name;

#[Option(shortcut: 'c', description: 'Optional comment to add as class header')]
private ?string $comment = null;

#[Option(name: 'domain', shortcut: 'd', description: 'Mark as domain bootloader')]
private bool $isDomain = false;

#[Option(description: 'Optional, specify a custom namespace')]
private ?string $namespace = null;

public function perform(): int
{
$declaration = $this->createDeclaration(BootloaderDeclaration::class);
$declaration = $this->createDeclaration(BootloaderDeclaration::class, [
'isDomain' => $this->isDomain,
]);

$this->writeDeclaration($declaration);

Expand Down
78 changes: 38 additions & 40 deletions src/Scaffolder/src/Command/CommandCommand.php
Original file line number Diff line number Diff line change
Expand Up @@ -4,53 +4,51 @@

namespace Spiral\Scaffolder\Command;

use Spiral\Console\Attribute\Argument;
use Spiral\Console\Attribute\AsCommand;
use Spiral\Console\Attribute\Option;
use Spiral\Console\Attribute\Question;
use Spiral\Scaffolder\Declaration\CommandDeclaration;
use Symfony\Component\Console\Input\InputArgument;
use Symfony\Component\Console\Input\InputOption;

#[Question(
question: 'What would you like to name the console Command?',
argument: 'name'
)]
#[AsCommand(name: 'create:command', description: 'Create console command declaration')]
class CommandCommand extends AbstractCommand
{
protected const NAME = 'create:command';
protected const DESCRIPTION = 'Create command declaration';
protected const ARGUMENTS = [
['name', InputArgument::REQUIRED, 'Command name'],
['alias', InputArgument::OPTIONAL, 'Command id/alias'],
];
protected const OPTIONS = [
[
'description',
'd',
InputOption::VALUE_OPTIONAL,
'Command description',
],
[
'comment',
'c',
InputOption::VALUE_OPTIONAL,
'Optional comment to add as class header',
],
[
'namespace',
null,
InputOption::VALUE_OPTIONAL,
'Optional, specify a custom namespace',
],
];

/**
* Create command declaration.
*/
#[Argument(description: 'Command name')]
#[Question(question: 'What would you like to name the console Command?')]
private string $name;

#[Argument(description: 'Command id/alias')]
private ?string $alias = null;

#[Option(shortcut: 'd', description: 'Command description')]
private ?string $description = null;

#[Option(shortcut: 'c', description: 'Optional comment to add as class header')]
private ?string $comment = null;

#[Option(description: 'Optional, specify a custom namespace')]
private ?string $namespace = null;

#[Option(name: 'argument', shortcut: 'a', description: 'Command arguments')]
private array $arguments = [];

#[Option(name: 'option', shortcut: 'o', description: 'Command options')]
private array $options = [];

public function perform(): int
{
$declaration = $this->createDeclaration(CommandDeclaration::class);

$declaration->setAlias((string) ($this->argument('alias') ?? $this->argument('name')));
$declaration->setDescription((string) $this->option('description'));
$declaration = $this->createDeclaration(CommandDeclaration::class, [
'description' => $this->description,
'alias' => $this->alias ?? \strtolower(\preg_replace('/(?<!^)[A-Z]/', ':$0', $this->name)),
]);

foreach ($this->arguments as $argument) {
$declaration->addArgument($argument);
}

foreach ($this->options as $option) {
$declaration->addOption($option);
}

$this->writeDeclaration($declaration);

Expand Down
59 changes: 16 additions & 43 deletions src/Scaffolder/src/Command/ConfigCommand.php
Original file line number Diff line number Diff line change
Expand Up @@ -4,59 +4,32 @@

namespace Spiral\Scaffolder\Command;

use Spiral\Console\Attribute\Argument;
use Spiral\Console\Attribute\AsCommand;
use Spiral\Console\Attribute\Option;
use Spiral\Console\Attribute\Question;
use Spiral\Scaffolder\Declaration\ConfigDeclaration;
use Symfony\Component\Console\Input\InputArgument;
use Symfony\Component\Console\Input\InputOption;

#[Question(
question: 'Please provide the name of the Config class, or the filename of an existing config file',
argument: 'name'
)]
#[AsCommand(name: 'create:config', description: 'Create config declaration')]
class ConfigCommand extends AbstractCommand
{
protected const NAME = 'create:config';
protected const DESCRIPTION = 'Create config declaration';
protected const ARGUMENTS = [
[
'name',
InputArgument::REQUIRED,
'config name, or a config filename if "-r" flag is set ({path/to/configs/directory/}{config/filename}.php)',
],
];
#[Argument(description: 'Сonfig name, or a config filename if "-r" flag is set ({path/to/configs/directory/}{config/filename}.php)')]
#[Question(question: 'Please provide the name of the Config class, or the filename of an existing config file')]
private string $name;

protected const OPTIONS = [
[
'comment',
'c',
InputOption::VALUE_OPTIONAL,
'Optional comment to add as class header',
],
[
'reverse',
'r',
InputOption::VALUE_NONE,
'Create config class based on a given config filename',
],
[
'namespace',
null,
InputOption::VALUE_OPTIONAL,
'Optional, specify a custom namespace',
],
];
#[Option(shortcut: 'r', description: 'Create config class based on a given config filename')]
private bool $reverse = false;

#[Option(shortcut: 'c', description: 'Optional comment to add as class header')]
private ?string $comment = null;

#[Option(description: 'Optional, specify a custom namespace')]
private ?string $namespace = null;

/**
* Create config declaration.
*/
public function perform(): int
{
$declaration = $this->createDeclaration(ConfigDeclaration::class);

$declaration->create(
(bool) $this->option('reverse'),
(string) $this->argument('name')
);
$declaration->create($this->reverse, $this->name);

$this->writeDeclaration($declaration);

Expand Down
Loading

0 comments on commit 577caa8

Please sign in to comment.