From f2b77a3fbdfe1fe0d089eb294789f0c5089a9072 Mon Sep 17 00:00:00 2001 From: Egoist Date: Sun, 10 Jul 2022 18:49:30 +0300 Subject: [PATCH] Add generic make commands --- composer.json | 2 +- resources/stubs/command/Command.php.stub | 4 +- resources/stubs/command/Controller.php.stub | 2 +- resources/stubs/command/Service.php.stub | 5 ++ src/Command/Make/DefaultController.php | 12 +++++ src/Services/PackagerService.php | 56 +++++++++++++++++++++ src/Supports/PackagerSupport.php | 46 ++++++++++------- 7 files changed, 104 insertions(+), 23 deletions(-) diff --git a/composer.json b/composer.json index abb2c93..e5574e4 100644 --- a/composer.json +++ b/composer.json @@ -1,7 +1,7 @@ { "name": "laravel-ready/packager", "description": "Minicli Application Template", - "version": "1.1.0", + "version": "1.2.0", "license": "MIT", "homepage": "https://github.com/minicli/application", "keywords": ["cli","command-line", "template"], diff --git a/resources/stubs/command/Command.php.stub b/resources/stubs/command/Command.php.stub index d3848db..a7edce7 100644 --- a/resources/stubs/command/Command.php.stub +++ b/resources/stubs/command/Command.php.stub @@ -11,7 +11,7 @@ class {{ MAKE_CLASSNAME }} extends Command * * @var string */ - protected $signature = 'command:name'; + protected $signature = '{{ PACKAGE_SLUG }}:{{ COMMAND_SLUG }}'; /** * The console command description. @@ -39,7 +39,7 @@ class {{ MAKE_CLASSNAME }} extends Command */ private function askQuestion() { - $answer = $this->ask('Do you use Laravel?'); + $answer = $this->ask('Do you love Laravel?'); // this answer required if (!$answer) { diff --git a/resources/stubs/command/Controller.php.stub b/resources/stubs/command/Controller.php.stub index a389931..a627175 100644 --- a/resources/stubs/command/Controller.php.stub +++ b/resources/stubs/command/Controller.php.stub @@ -10,6 +10,6 @@ class {{ MAKE_CLASSNAME }} extends BaseController { public function index(Request $request) { - // add your controller code here + // add your controller methods here } } diff --git a/resources/stubs/command/Service.php.stub b/resources/stubs/command/Service.php.stub index 9baf003..4a8ba3f 100644 --- a/resources/stubs/command/Service.php.stub +++ b/resources/stubs/command/Service.php.stub @@ -7,4 +7,9 @@ class {{ MAKE_CLASSNAME }} public function __construct() { } + + public function sayHello() + { + return 'Hello World!'; + } } diff --git a/src/Command/Make/DefaultController.php b/src/Command/Make/DefaultController.php index c4f5d80..ac55f43 100644 --- a/src/Command/Make/DefaultController.php +++ b/src/Command/Make/DefaultController.php @@ -59,12 +59,24 @@ public function handle(): void return; } + $result = false; + if ($command['name'] === 'migration') { $type = $this->hasParam('--type') && in_array($this->getParam('--type'), $this->makeMigrationList) ? $this->getParam('--type') : 'create'; $result = $this->packagerService->makeMigration($command['value'], $type); + } else { + $result = $this->packagerService->make($command['name'], $command['value']); + } + + if ($result === true) { + $this->getPrinter()->success("Make {$command['name']}: \"{$command['value']}\" created successfully."); + } else if ($result === false) { + $this->getPrinter()->error("Make {$command['name']}: \"{$command['value']}\" failed. Please retry."); + } else if ($result === null) { + $this->getPrinter()->display("Make {$command['name']}: \"{$command['value']}\" already exists."); } } diff --git a/src/Services/PackagerService.php b/src/Services/PackagerService.php index 9a1985c..7786963 100644 --- a/src/Services/PackagerService.php +++ b/src/Services/PackagerService.php @@ -22,14 +22,70 @@ class PackagerService private StubSupport $stubSupport; + /** + * Relative paths for selected commands + */ + private $relativePaths = [ + 'controller' => 'Http\Controllers', + 'command' => 'Console\Commands', + 'model' => 'Models', + 'request' => 'Http\Requests', + 'service' => 'Services', + 'middleware' => 'Http\Middleware', + ]; + public function __construct() { $this->file = new Filesystem(); $this->stubSupport = new StubSupport(); + // TODO: add support for custom base path $this->basePath = realpath('./'); } + /** + * Create a new file + * + * @param string $makeCommand + * @param string $makeValue + * + * @return bool|null + */ + public function make(string $makeCommand, string $makeValue): bool|null + { + $replacements = []; + $composerJsonContent = json_decode($this->file->get("{$this->basePath}/composer.json"), true); + + $namespaces = explode('/', $composerJsonContent['name']); + $replacements['FULL_NAMESPACE'] = StrSupport::convertToPascalCase($namespaces[0]) . '\\' . StrSupport::convertToPascalCase($namespaces[1]); + $replacements['PACKAGE_SLUG'] = Str::slug($namespaces[1]); + + $parsedNamespace = PackagerSupport::parseNamespaceFrom($makeValue, $makeCommand, $this->relativePaths[$makeCommand]); + $packageFolderPath = "{$this->basePath}/{$parsedNamespace['commandFolderPath']}"; + + if (!$this->file->exists($packageFolderPath)) { + $this->file->makeDirectory($packageFolderPath, 0775, true); + } + + $targetPath = "{$this->basePath}/{$parsedNamespace['commandFolderPath']}/{$parsedNamespace['className']}.php"; + + if ($this->file->exists($targetPath)) { + return null; + } + + $replacements['APPEND_NAMESPACE'] = $parsedNamespace['commandFolder'] ? "\\{$parsedNamespace['commandFolder']}" : ''; + $replacements['MAKE_CLASSNAME'] = $parsedNamespace['className']; + $replacements['COMMAND_SLUG'] = Str::slug($parsedNamespace['classNameRaw']); + + $stubPath = __DIR__ . "/../../resources/stubs/command/{$makeCommand}.php.stub"; + + $this->stubSupport->applyStub($stubPath, $targetPath, $replacements); + + // TODO: append to service provider + + return $this->file->exists($targetPath); + } + /** * Create a new migration * diff --git a/src/Supports/PackagerSupport.php b/src/Supports/PackagerSupport.php index 02ccc3b..ef275da 100644 --- a/src/Supports/PackagerSupport.php +++ b/src/Supports/PackagerSupport.php @@ -4,7 +4,7 @@ use Illuminate\Support\Str; -use LaravelReady\Packager\Supports\StringSupport; +use LaravelReady\Packager\Supports\StrSupport; class PackagerSupport { @@ -12,38 +12,45 @@ class PackagerSupport * Parse namespace from given string * * @param string $makeValue - * @param string $makeFileType + * @param string $commandType * @param string $relativePath * * @return array */ - public static function parseNamespaceFrom(string $makeValue, string $makeFileType, string $relativePath): array + public static function parseNamespaceFrom(string $makeValue, string $commandType, string $relativePath): array { + $commandType = ucfirst($commandType); + $makeValue = Str::replace("{$commandType}.php", '', $makeValue); + $makeValue = Str::replace('.php', '', $makeValue); + $commandFolder = ''; - $makeClassName = $makeValue; + $className = $makeValue; - if (Str::contains($makeValue, '\\')) { - $makeClassName = last(explode('\\', $makeValue)); - $commandFolder = Str::replace("\\{$makeClassName}", '', $makeValue); - } else if (Str::contains($makeValue, '/')) { - $makeClassName = last(explode('/', $makeValue)); - $commandFolder = Str::replace("/{$makeClassName}", '', $makeValue); + if (Str::contains($makeValue, '.')) { + $makeValue = implode('\\', array_map(function ($part) { + return StrSupport::convertToPascalCase($part); + }, explode('.', $makeValue))); } - if (!Str::endsWith($makeClassName, $makeFileType)) { - $makeClassName .= $makeFileType; + if (Str::contains($makeValue, '\\')) { + $className = last(explode('\\', $makeValue)); + $commandFolder = Str::replace("\\{$className}", '', $makeValue); } - $makeClassName = Str::replace('.php', '', $makeClassName); - $makeClassName = StringSupport::correctClassName($makeClassName); + $className = StrSupport::convertToPascalCase($className); + $classNameRaw = $className; + + if ($commandType !== 'model' && !Str::endsWith($className, $commandType)) { + $className .= $commandType; + } - // get path in package' src folder $makeFolder = "/src/{$relativePath}/{$commandFolder}"; return [ - 'makeClassName' => $makeClassName, - 'makeFolder' => $commandFolder, - 'makeFolderPath' => $makeFolder, + 'classNameRaw' => $classNameRaw, + 'className' => $className, + 'commandFolder' => $commandFolder, + 'commandFolderPath' => $makeFolder, ]; } @@ -67,7 +74,8 @@ public static function getMigrationFilesCount(string $path): int * @return void * @throws \Exception */ - public static function validateMigrationFileName(string $name): bool{ + public static function validateMigrationFileName(string $name): bool + { return preg_match('/^[0-9]{4}_[0-9]{2}_[0-9]{2}_[0-9]{6}_[a-z_]+_table$/', $name); } }