Add make:enum console command

This commit is contained in:
Jérémy Munsch 2021-09-12 19:21:54 +02:00
parent 03bac5ba89
commit 163eeabcd1
No known key found for this signature in database
GPG key ID: 677E1F9F80C16560
3 changed files with 189 additions and 0 deletions

View file

@ -0,0 +1,16 @@
<?php
namespace App\Enums;
use Kwaadpepper\Enum\BaseEnumRoutable;
/**
* This is an enumeration class,
* the following methods are its possible values
*
* ##VALUES
*/
class TemplateEnum extends BaseEnumRoutable
{
// ##OVERRIDE
}

165
src/Console/CreateEnum.php Normal file
View file

@ -0,0 +1,165 @@
<?php
namespace Kwaadpepper\Enum\Console;
use Illuminate\Console\Command;
use Illuminate\Support\Facades\File;
class CreateEnum extends Command
{
protected $signature = 'make:enum';
protected $description = 'Create a new enum class';
// phpcs:ignore Generic.Metrics.CyclomaticComplexity.TooHigh
public function handle()
{
$validate = false;
$info = [
'name' => false,
'definition' => [],
'labels' => [],
'values' => []
];
$this->info('Enumeration Generator.');
do {
do {
$name = ucfirst($this->ask('Which name should have the enum class ? (use PascalCase, ex: UserRole)'));
if (\strlen($name) <= 1 or \preg_match('/^[a-zA-Z_\x80-\xff][a-zA-Z0-9_\x80-\xff]*$/', $name) !== 1) {
$this->question('You shall provide a valid class name.');
if (!$this->confirm('Do you want to continue ?')) {
return -1;
}
}
if (File::exists(\app_path("Enums/$name.php"))) {
$this->question("$name.php already exists.");
if (!$this->confirm('Do you want to continue ?')) {
return -1;
}
} else {
$info['name'] = $name;
}
} while ($info['name'] === false);
do {
// phpcs:ignore Generic.Files.LineLength.TooLong
$values = \trim($this->ask('Write down definitions separated with pipes (|), ex: admin|editor|user|guest'));
$info['definition'] = (\strlen($values) > 1 and \strpos($values, '|') !== 0) ?
explode('|', $values) : [];
if (empty($info['definition'])) {
$this->question('You have to provide a definition for your enum.');
if (!$this->confirm('Do you want to continue ?')) {
return -1;
}
}
} while (empty($info['definition']));
if ($this->confirm('Do you want to add custom values to your enum ?')) {
// phpcs:ignore Generic.Files.LineLength.TooLong
$values = $this->ask('Write down your values separated with pipes (|), ex: 0|1|2|3, or \'value1\'|\'value2\'|\'value3\'');
$info['values'] = explode('|', $values);
}
if ($this->confirm('Do you want to add custom labels to your enum ?')) {
// phpcs:ignore Generic.Files.LineLength.TooLong
$values = $this->ask('Write down your labels separated with pipes (|), ex: When off|When on|When blinking');
$info['labels'] = explode('|', str_replace('\'', '\\\'', $values));
}
$this->info('You have selected the followings :');
$print = [];
foreach ($info['definition'] as $k => $definition) {
$print[] = [
$definition => [
'label' => $info['labels'][$k] ?? $definition,
'value' => $info['values'][$k] ?? $definition,
]
];
}
$this->info(\json_encode($print, \JSON_PRETTY_PRINT | \JSON_NUMERIC_CHECK));
if ($this->confirm('Do you want to use these parameters ?', true)) {
$validate = true;
} elseif (!$this->confirm('Do you want to continue ?')) {
return -1;
}
} while (!$validate);
if (!File::exists(\app_path('Enums'))) {
$this->info('Creating Enums directory');
File::makeDirectory(\app_path('Enums'));
}
$this->info('Generating enum');
$templateEnum = File::get(__DIR__ . '/../../resources/templates/TemplateEnum.php');
$this->replaceClassName($templateEnum, $info);
$this->replaceDefinition($templateEnum, $info);
$this->insertLabelsAndValues($templateEnum, $info);
File::put(\app_path("Enums/$name.php"), $templateEnum);
$this->info(\sprintf('File generated %s', \app_path("Enums/$name.php")));
}
private function replaceClassName(string &$templateEnum, array $info): void
{
$targetDefinition = "class TemplateEnum";
$replaceDefinition = "class {$info['name']}";
$templateEnum = str_replace($targetDefinition, $replaceDefinition, $templateEnum);
}
private function replaceDefinition(string &$templateEnum, array $info): void
{
$targetDefinition = " * ##VALUES\n";
$replaceDefinition = '';
foreach ($info['definition'] as $definition) {
$replaceDefinition .= " * @method static self $definition()\n";
}
$replaceDefinition .= " *\n";
$templateEnum = str_replace($targetDefinition, $replaceDefinition, $templateEnum);
}
private function insertLabelsAndValues(string &$templateEnum, array $info): void
{
$targetDefinition = " // ##OVERRIDE\n";
$replaceDefinition = '';
$templateValues = 'public static function values()';
$templateLabels = 'public static function labels()';
if (count($info['values'])) {
$replaceDefinition = " $templateValues\n {\n return [\n";
foreach ($info['definition'] as $k => $definition) {
$replaceDefinition .= sprintf(
" '%s' => %s,\n",
$definition,
$info['values'][$k] ?? $definition
);
}
$replaceDefinition = rtrim($replaceDefinition, ',');
$replaceDefinition .= " ];\n }\n";
}
if (count($info['labels'])) {
$replaceDefinition .= "\n $templateLabels\n {\n return [\n";
foreach ($info['definition'] as $k => $definition) {
$replaceDefinition .= sprintf(
" '%s' => '%s',\n",
$definition,
$info['labels'][$k] ?? $definition
);
}
$replaceDefinition = rtrim($replaceDefinition, ',');
$replaceDefinition .= " ];\n }\n";
}
$templateEnum = str_replace($targetDefinition, $replaceDefinition, $templateEnum);
}
}

View file

@ -3,6 +3,7 @@
namespace Kwaadpepper\Enum;
use Illuminate\Support\ServiceProvider;
use Kwaadpepper\Enum\Console\CreateEnum;
class EnumServiceProvider extends ServiceProvider
{
@ -18,5 +19,12 @@ class EnumServiceProvider extends ServiceProvider
$this->publishes([
__DIR__ . '/../resources/lang' => resource_path('lang/vendor/enum'),
]);
// Register the command if we are using the application via the CLI
if ($this->app->runningInConsole()) {
$this->commands([
CreateEnum::class,
]);
}
}
}