lean-api/src/Cli/CodeGeneration.php

120 lines
7.8 KiB
PHP

<?php
namespace Lean\Api\Cli;
use DI\Attribute\Inject;
use Lean\Lean;
use Lean\Api\Action;
use Mcnd\CLI\{Terminal, OptionValueTypeEnum, OptionStack};
use Notes\CLI\Attribute\{Option, Command};
use Psr\Http\Message\{ServerRequestInterface, ResponseInterface};
#[Command(description: PHP_EOL . <<<CLI
#[color:gray, bg: black]╔═══════════════════════════════════════════════════════════════════╗[#]
#[color:gray, bg: black]║ ║[#]
#[color:gray, bg: black]║ ║[#]
#[color:gray, bg: black]║ ║[#]
#[color:gray, bg: black]║ ║[#]
#[color:gray, bg: black]║ ░▒▓█▓▒░ ░▒▓████████▓▒░░▒▓██████▓▒░░▒▓███████▓▒░ ║[#]
#[color:gray, bg: black]║ ░▒▓█▓▒░ ░▒▓█▓▒░ ░▒▓█▓▒░░▒▓█▓▒░▒▓█▓▒░░▒▓█▓▒░ ║[#]
#[color:gray, bg: black]║ ░▒▓█▓▒░ ░▒▓█▓▒░ ░▒▓█▓▒░░▒▓█▓▒░▒▓█▓▒░░▒▓█▓▒░ ║[#]
#[color:gray, bg: black]║ ░▒▓█▓▒░ ░▒▓██████▓▒░ ░▒▓████████▓▒░▒▓█▓▒░░▒▓█▓▒░ ║[#]
#[color:gray, bg: black]║ ░▒▓█▓▒░ ░▒▓█▓▒░ ░▒▓█▓▒░░▒▓█▓▒░▒▓█▓▒░░▒▓█▓▒░ ║[#]
#[color:gray, bg: black]║ ░▒▓█▓▒░ ░▒▓█▓▒░ ░▒▓█▓▒░░▒▓█▓▒░▒▓█▓▒░░▒▓█▓▒░ ║[#]
#[color:gray, bg: black]║ ░▒▓████████▓▒░▒▓████████▓▒░▒▓█▓▒░░▒▓█▓▒░▒▓█▓▒░░▒▓█▓▒░ ║[#]
#[color:gray, bg: black]║ ║[#]
#[color:gray, bg: black]║ ║[#]
#[color:gray, bg: black]║ A P I ║[#]
#[color:gray, bg: black]║ ║[#]
#[color:gray, bg: black]╚═══════════════════════════════════════════════════════════════════╝[#]
Try #[color:gray, bg: black]'lean api --help'[#] for more information.
CLI
, command: 'lean-api')]
#[Option(switch: ['-h', '--help'], description: "Display help for the given command. When no command is given display help for the list command")]
class CodeGeneration
{
use \Lean\ControllerTrait;
#[Inject]
public Lean $lean;
#[Command(description: "Create an entity and it's related boilerplate", command: "entity:generate")]
#[Option(switch: ['-p', '--application'], description: "Application to target", value: OptionValueTypeEnum::RequiredValue)]
#[Option(switch: ['-n', '--name'], description: "Write generated content into project", value: OptionValueTypeEnum::RequiredValue)]
#[Option(switch: ['-m', '--namespace'], description: "Which PSR-4 namespace should be used", value: OptionValueTypeEnum::OptionalValue)]
#[Option(switch: ['-f', '--form'], description: "Form and context name", value: OptionValueTypeEnum::OptionalValue)]
#[Option(switch: ['-s', '--saveForm'], description: "Include or not a save form", value: OptionValueTypeEnum::OptionalValue)]
#[Option(switch: ['-d', '--deleteForm'], description: "Include or not a delete form", value: OptionValueTypeEnum::OptionalValue)]
#[Option(switch: ['-a', '--api'], description: "Include or not an API controller", value: OptionValueTypeEnum::OptionalValue)]
#[Option(switch: ['-c', '--api-docs'], description: "Include or not an API documentation page", value: OptionValueTypeEnum::OptionalValue)]
#[Option(switch: ['-w', '--web'], description: "Include or not a web controller", value: OptionValueTypeEnum::OptionalValue)]
#[Option(switch: ['-f', '--factory'], description: "Factory file to add to", value: OptionValueTypeEnum::OptionalValue)]
#[Option(switch: ['-w', '--write'], description: "Write generated content into project's folder path",)]
#[Option(switch: ['-o', '--overwrite'], description: "Overwrite every files by default", value: OptionValueTypeEnum::NoValue)]
#[Option(switch: ['-t', '--default-answers'], description: "Auto-accept every default answers", value: OptionValueTypeEnum::NoValue)]
##[Option(switch: ['-p', '--path'], description: "Base project save path", value: OptionValueTypeEnum::OptionalValue)]
public function generate(ServerRequestInterface $request, array $arguments, OptionStack $options, string $rest): ResponseInterface
{
$name = $options->get('name')->value() ?: readline('Entity name : ');
if ( empty($name)) {
throw new \InvalidArgumentException("An entity name must be provided");
}
$applicationList = array_reverse(array_map(fn($e) => $e->name, $this->lean->applications));
$app = $options->get('application')->value() ?? Terminal::proposeListChoice("Select an application : ", $applicationList);
$entityGenerate = new Action\Console\EntityGenerate(
application: $this->lean->getApplication($applicationList[$app]),
name: $name,
overwrite: $options->get('overwrite')->value() ?? false,
default: $options->get('default-answers')->value() ?? false,
);
if ("" === ( $entityGenerate->namespace = $options->get('namespace')->value() ?: "" )) {
$entityGenerate->readNamespace();
}
$entityGenerate->readEntity();
if ($options->get('saveForm')->value() ?? Terminal::proposeListChoice("Add a save form ?", [ true => 'Yes', false => 'No', ])) {
$entityGenerate->readSaveForm();
$hasFactory = true;
}
if ($options->get('deleteForm')->value() ?? Terminal::proposeListChoice("Add a delete form ?", [ true => 'Yes', false => 'No', ])) {
$entityGenerate->readDeleteForm();
$hasFactory = true;
}
if (isset($hasFactory) && (
$options->get('factory')->value() ?? Terminal::proposeListChoice("Add to form factory ?", [ true => 'Yes', false => 'No', ]))
) {
$entityGenerate->readFactory();
}
if ($options->get('web')->value() ?? Terminal::proposeListChoice("Add a Web controller ?", [ true => 'Yes', false => 'No', ])) {
$entityGenerate->readWeb();
}
if ($options->get('api')->value() ?? Terminal::proposeListChoice("Add an API controller ?", [ true => 'Yes', false => 'No', ])) {
$entityGenerate->readApi();
if ($options->get('api-docs')->value() ?? Terminal::proposeListChoice("Provides documentation for this route ?", [ true => 'Yes', false => 'No', ])) {
$entityGenerate->includeDocs = true;
}
}
$entityGenerate->generate();
if ($options->get('write')->value() ?? Terminal::proposeListChoice("Write to disc or output results only ?", [ true => 'Write to disc', false => 'Output results only', ])) {
$entityGenerate->writeToDisc();
}
else {
$entityGenerate->outputResults();
}
return $this->renderCLI($request, "done");
}
}