From 39adc34d70d0c011523637e2466f1f5ad0b6e9fd Mon Sep 17 00:00:00 2001 From: Mior Muhammad Zaki Date: Mon, 18 Sep 2023 08:23:16 +0800 Subject: [PATCH 01/25] wip Signed-off-by: Mior Muhammad Zaki --- src/CodeGenerator.php | 85 +++--- src/Commands/Generator.php | 221 ++------------- src/Commands/Generators/Code.php | 31 --- src/Commands/Generators/ConsoleGenerator.php | 87 ------ src/CommandsProvider.php | 36 --- src/Contracts/GeneratesCode.php | 28 ++ src/Contracts/GeneratesCodeListener.php | 53 ---- src/GeneratesCode.php | 254 ------------------ src/GeneratesCodeWithComponent.php | 34 --- src/GeneratesCodeWithEloquent.php | 87 ------ src/GeneratesCodeWithMarkdown.php | 20 -- src/GeneratesCommandCode.php | 19 -- src/LaravelServiceProvider.php | 34 --- src/Presets/Laravel.php | 40 +-- src/Presets/Package.php | 50 +--- src/Presets/Preset.php | 52 +--- src/TestGenerator.php | 10 +- .../Concerns/InteractsWithPublishedFiles.php | 157 ----------- 18 files changed, 116 insertions(+), 1182 deletions(-) delete mode 100644 src/Commands/Generators/Code.php delete mode 100644 src/Commands/Generators/ConsoleGenerator.php delete mode 100644 src/CommandsProvider.php create mode 100644 src/Contracts/GeneratesCode.php delete mode 100644 src/Contracts/GeneratesCodeListener.php delete mode 100644 src/GeneratesCode.php delete mode 100644 src/GeneratesCodeWithComponent.php delete mode 100644 src/GeneratesCodeWithEloquent.php delete mode 100644 src/GeneratesCodeWithMarkdown.php delete mode 100644 src/GeneratesCommandCode.php delete mode 100644 src/LaravelServiceProvider.php delete mode 100644 src/Testing/Concerns/InteractsWithPublishedFiles.php diff --git a/src/CodeGenerator.php b/src/CodeGenerator.php index 311806c..becc0ec 100644 --- a/src/CodeGenerator.php +++ b/src/CodeGenerator.php @@ -2,27 +2,11 @@ namespace Orchestra\Canvas\Core; +use Illuminate\Console\Concerns\CreatesMatchingTest; +use Symfony\Component\Console\Command\Command; + trait CodeGenerator { - /** - * Canvas preset. - * - * @var \Orchestra\Canvas\Core\Presets\Preset - */ - protected $preset; - - /** - * Set Preset for generator. - * - * @return $this - */ - public function setPreset(Presets\Preset $preset) - { - $this->preset = $preset; - - return $this; - } - /** * Generate code. * @@ -30,7 +14,31 @@ public function setPreset(Presets\Preset $preset) */ public function generateCode(bool $force = false) { - return $this->resolveGeneratesCodeProcessor()($force); + $name = $this->getInputName(); + $className = $this->qualifyClass($name); + $path = $this->getPath($this->qualifyClass($name)); + + // Next, We will check to see if the class already exists. If it does, we don't want + // to create the class and overwrite the user's code. So, we will bail out so the + // code is untouched. Otherwise, we will continue generating this class' files. + if (! $force && $this->alreadyExists($name)) { + return $this->codeAlreadyExists($className); + } + + // Next, we will generate the path to the location where this class' file should get + // written. Then, we will build the class and make the proper replacements on the + // stub files so that it gets the correctly formatted namespace and class name. + $this->makeDirectory($path); + + $this->files->put($path, $this->sortImports($this->buildClass($className))); + + return tap($this->codeHasBeenGenerated($className), function ($exitCode) use ($className, $path) { + if (\in_array(CreatesMatchingTest::class, class_uses_recursive($this))) { + $this->handleTestCreationUsingCanvas($path); + } + + $this->afterCodeHasBeenGenerated($className, $path); + }); } /** @@ -42,7 +50,7 @@ public function codeAlreadyExists(string $className) { $this->components->error(sprintf('%s [%s] already exists!', $this->type, $className)); - return 1; + return Command::FAILURE; } /** @@ -54,39 +62,18 @@ public function codeHasBeenGenerated(string $className) { $this->components->info(sprintf('%s [%s] created successfully.', $this->type, $className)); - return 0; - } - - /** - * Get the default namespace for the class. - */ - public function getDefaultNamespace(string $rootNamespace): string - { - return $rootNamespace; + return Command::SUCCESS; } /** - * Generator options. + * Run after code successfully generated. * - * @return array + * @return void */ - public function generatorOptions(): array + public function afterCodeHasBeenGenerated(string $className, string $path) { - return [ - 'name' => $this->generatorName(), - ]; - } - - /** - * Resolve generates code processor. - */ - protected function resolveGeneratesCodeProcessor(): GeneratesCode - { - /** @var \Orchestra\Canvas\Core\GeneratesCode $class */ - $class = property_exists($this, 'processor') - ? $this->processor - : GeneratesCode::class; - - return new $class($this->preset, $this); + if (\in_array(CreatesMatchingTest::class, class_uses_recursive($this))) { + $this->handleTestCreationUsingCanvas($path); + } } } diff --git a/src/Commands/Generator.php b/src/Commands/Generator.php index 83153d9..bcdab60 100644 --- a/src/Commands/Generator.php +++ b/src/Commands/Generator.php @@ -2,176 +2,26 @@ namespace Orchestra\Canvas\Core\Commands; -use Illuminate\Console\Concerns\CreatesMatchingTest; -use Illuminate\Contracts\Console\PromptsForMissingInput; +use Illuminate\Console\GeneratorCommand; use Orchestra\Canvas\Core\CodeGenerator; -use Orchestra\Canvas\Core\Contracts\GeneratesCodeListener; -use Orchestra\Canvas\Core\GeneratesCode; -use Orchestra\Canvas\Core\Presets\Preset; use Orchestra\Canvas\Core\TestGenerator; -use Symfony\Component\Console\Input\InputArgument; -use Symfony\Component\Console\Input\InputInterface; -use Symfony\Component\Console\Output\OutputInterface; /** * @property string|null $name * @property string|null $description */ -abstract class Generator extends Command implements GeneratesCodeListener, PromptsForMissingInput +abstract class Generator extends GeneratorCommand { use CodeGenerator, TestGenerator; /** - * The filesystem instance. + * Execute the console command. * - * @var \Illuminate\Filesystem\Filesystem - */ - protected $files; - - /** - * The type of class being generated. - */ - protected string $type; - - /** - * The type of file being generated. - */ - protected string $fileType = 'class'; - - /** - * Generator processor. - * - * @var class-string<\Orchestra\Canvas\Core\GeneratesCode> - */ - protected string $processor = GeneratesCode::class; - - /** - * Reserved names that cannot be used for generation. - * - * @var array - */ - protected array $reservedNames = [ - '__halt_compiler', - 'abstract', - 'and', - 'array', - 'as', - 'break', - 'callable', - 'case', - 'catch', - 'class', - 'clone', - 'const', - 'continue', - 'declare', - 'default', - 'die', - 'do', - 'echo', - 'else', - 'elseif', - 'empty', - 'enddeclare', - 'endfor', - 'endforeach', - 'endif', - 'endswitch', - 'endwhile', - 'enum', - 'eval', - 'exit', - 'extends', - 'false', - 'final', - 'finally', - 'fn', - 'for', - 'foreach', - 'function', - 'global', - 'goto', - 'if', - 'implements', - 'include', - 'include_once', - 'instanceof', - 'insteadof', - 'interface', - 'isset', - 'list', - 'match', - 'namespace', - 'new', - 'or', - 'print', - 'private', - 'protected', - 'public', - 'readonly', - 'require', - 'require_once', - 'return', - 'self', - 'static', - 'switch', - 'throw', - 'trait', - 'true', - 'try', - 'unset', - 'use', - 'var', - 'while', - 'xor', - 'yield', - '__CLASS__', - '__DIR__', - '__FILE__', - '__FUNCTION__', - '__LINE__', - '__METHOD__', - '__NAMESPACE__', - '__TRAIT__', - ]; - - /** - * Construct a new generator command. - */ - public function __construct(Preset $preset) - { - $this->files = $preset->filesystem(); - - parent::__construct($preset); - } - - /** - * Configure the command options. - * - * @return void - */ - protected function configure() - { - $this->ignoreValidationErrors(); - - $this->setName($this->getName()) - ->setDescription($this->getDescription()) - ->addArgument('name', InputArgument::REQUIRED, "The name of the {$this->fileType}"); - - if (\in_array(CreatesMatchingTest::class, class_uses_recursive($this))) { - /** @phpstan-ignore-next-line */ - $this->addTestOptions(); - } - } - - /** - * Execute the command. - * - * @return int 0 if everything went fine, or an exit code + * @return bool|null * * @throws \Illuminate\Contracts\Filesystem\FileNotFoundException */ - protected function execute(InputInterface $input, OutputInterface $output) + public function handle() { // First we need to ensure that the given name is not a reserved word within the PHP // language and that the class name will actually be valid. If it is not valid we @@ -179,7 +29,7 @@ protected function execute(InputInterface $input, OutputInterface $output) if ($this->isReservedName($name = $this->generatorName())) { $this->components->error('The name "'.$name.'" is reserved by PHP.'); - return Command::FAILURE; + return GeneratorCommand::FAILURE; } $force = $this->hasOption('force') && $this->option('force') === true; @@ -188,63 +38,24 @@ protected function execute(InputInterface $input, OutputInterface $output) } /** - * Handle generating code. - */ - public function generatingCode(string $stub, string $className): string - { - return $stub; - } - - /** - * Run after code successfully generated. + * Build the class with the given name. * - * @return void - */ - public function afterCodeHasBeenGenerated(string $className, string $path) - { - if (\in_array(CreatesMatchingTest::class, class_uses_recursive($this))) { - $this->handleTestCreationUsingCanvas($path); - } - } - - /** - * Get the published stub file for the generator. - */ - public function getPublishedStubFileName(): ?string - { - return null; - } - - /** - * Get the desired class name from the input. - */ - public function generatorName(): string - { - return transform($this->argument('name'), function ($name) { - /** @var string $name */ - return trim($name); - }); - } - - /** - * Checks whether the given name is reserved. + * @throws \Illuminate\Contracts\Filesystem\FileNotFoundException */ - protected function isReservedName(string $name): bool + protected function buildClass($name) { - $name = strtolower($name); + $stub = $this->files->get($this->getStub()); - return \in_array($name, $this->reservedNames); + return $this->generatingCode( + $this->replaceNamespace($stub, $name)->replaceClass($stub, $name), $name + ); } /** - * Prompt for missing input arguments using the returned questions. - * - * @return array + * Handle generating code. */ - protected function promptForMissingArgumentsUsing() + public function generatingCode(string $stub, string $className): string { - return [ - 'name' => 'What should the '.strtolower($this->type).' be named?', - ]; + return $stub; } } diff --git a/src/Commands/Generators/Code.php b/src/Commands/Generators/Code.php deleted file mode 100644 index 33f12d4..0000000 --- a/src/Commands/Generators/Code.php +++ /dev/null @@ -1,31 +0,0 @@ -getStubFileName(); - } - - /** - * Get the stub file name for the generator. - */ - public function getStubFileName(): string - { - return __DIR__.'/../../../storage/canvas/code.stub'; - } -} diff --git a/src/Commands/Generators/ConsoleGenerator.php b/src/Commands/Generators/ConsoleGenerator.php deleted file mode 100644 index de76c1a..0000000 --- a/src/Commands/Generators/ConsoleGenerator.php +++ /dev/null @@ -1,87 +0,0 @@ - - */ - protected string $processor = GeneratesCommandCode::class; - - /** - * Get the stub file for the generator. - */ - public function getPublishedStubFileName(): ?string - { - return null; - } - - /** - * Get the stub file for the generator. - */ - public function getStubFile(): string - { - return __DIR__.'/../../../storage/canvas/generator.stub'; - } - - /** - * Get the default namespace for the class. - */ - public function getDefaultNamespace(string $rootNamespace): string - { - return $this->preset->config('console.namespace', $rootNamespace.'\Console\Commands'); - } - - /** - * Generator options. - * - * @return array - */ - public function generatorOptions(): array - { - /** @var string $command */ - $command = $this->option('command'); - - if (! Str::startsWith($command, 'make:')) { - $command = "make:{$command}"; - } - - return [ - 'command' => $command, - 'force' => $this->option('force'), - ]; - } - - /** - * Get the console command options. - * - * @return array - */ - protected function getOptions() - { - return [ - ['force', 'f', InputOption::VALUE_NONE, 'Create the class even if the generator already exists'], - ['command', null, InputOption::VALUE_OPTIONAL, 'The terminal command that should be assigned', 'make:name'], - ]; - } -} diff --git a/src/CommandsProvider.php b/src/CommandsProvider.php deleted file mode 100644 index 314c504..0000000 --- a/src/CommandsProvider.php +++ /dev/null @@ -1,36 +0,0 @@ -bound('orchestra.canvas')) { - return $app->make('orchestra.canvas'); - } - - return new Presets\Laravel([ - 'preset' => 'laravel', - 'namespace' => trim($this->app->getNamespace(), '\\'), - 'user-auth-provider' => $this->userProviderModel(), - ], $app->basePath(), $app->make('files')); - } - - /** - * Get the model for the default guard's user provider. - */ - protected function userProviderModel(): ?string - { - $guard = config('auth.defaults.guard'); - - $provider = config("auth.guards.{$guard}.provider"); - - return config("auth.providers.{$provider}.model"); - } -} diff --git a/src/Contracts/GeneratesCode.php b/src/Contracts/GeneratesCode.php new file mode 100644 index 0000000..3cfec1a --- /dev/null +++ b/src/Contracts/GeneratesCode.php @@ -0,0 +1,28 @@ + - */ - protected $options = []; - - /** - * Construct a new processor. - */ - public function __construct( - protected Presets\Preset $preset, - protected Contracts\GeneratesCodeListener $listener - ) { - $this->files = $preset->filesystem(); - $this->options = $listener->generatorOptions(); - } - - /** - * Execute generates code processor. - * - * @return int - */ - public function __invoke(bool $force = false) - { - $name = $this->listener->generatorName(); - - $className = $this->qualifyClass($name); - - $path = $this->getPath($className); - - // First we will check to see if the class already exists. If it does, we don't want - // to create the class and overwrite the user's code. So, we will bail out so the - // code is untouched. Otherwise, we will continue generating this class' files. - if (! $force && $this->alreadyExists($name)) { - return $this->listener->codeAlreadyExists($className); - } - - // Next, we will generate the path to the location where this class' file should get - // written. Then, we will build the class and make the proper replacements on the - // stub files so that it gets the correctly formatted namespace and class name. - $this->makeDirectory($path); - - $this->files->put($path, $this->sortImports($this->buildClass($className))); - - return tap($this->listener->codeHasBeenGenerated($className), function ($exitCode) use ($className, $path) { - $this->listener->afterCodeHasBeenGenerated($className, Str::of($path)->after($this->preset->sourcePath())); - }); - } - - /** - * Parse the class name and format according to the root namespace. - */ - protected function qualifyClass(string $name): string - { - $name = ltrim($name, '\\/'); - - $rootNamespace = $this->rootNamespace(); - - if (Str::startsWith($name, $rootNamespace)) { - return $name; - } - - $name = str_replace('/', '\\', $name); - - return $this->qualifyClass( - $this->getDefaultNamespace(trim($rootNamespace, '\\')).'\\'.$name - ); - } - - /** - * Get the default namespace for the class. - */ - protected function getDefaultNamespace(string $rootNamespace): string - { - return $this->listener->getDefaultNamespace($rootNamespace); - } - - /** - * Determine if the class already exists. - */ - protected function alreadyExists(string $rawName): bool - { - return $this->files->exists($this->getPath($this->qualifyClass($rawName))); - } - - /** - * Get the destination class path. - */ - protected function getPath(string $name): string - { - $name = Str::replaceFirst($this->rootNamespace(), '', $name); - - return $this->preset->sourcePath().'/'.str_replace('\\', '/', $name).'.php'; - } - - /** - * Build the directory for the class if necessary. - */ - protected function makeDirectory(string $path): string - { - if (! $this->files->isDirectory(\dirname($path))) { - $this->files->makeDirectory(\dirname($path), 0777, true, true); - } - - return $path; - } - - /** - * Build the class with the given name. - * - * @throws \Illuminate\Contracts\Filesystem\FileNotFoundException - */ - protected function buildClass(string $name): string - { - return $this->generatingCode( - $this->files->get($this->getListenerStubFile()), $name - ); - } - - /** - * Handle generating code. - */ - protected function generatingCode(string $stub, string $name): string - { - return $this->listener->generatingCode( - $this->replaceClass( - $this->replaceNamespace($stub, $name), $name - ), $name - ); - } - - /** - * Get generator stub file. - */ - protected function getListenerStubFile(): string - { - if (\is_null($publishedStubFile = $this->listener->getPublishedStubFileName())) { - return $this->listener->getStubFile(); - } - - $stubFile = sprintf( - '%s/stubs/%s', $this->preset->basePath(), $publishedStubFile - ); - - if (! $this->files->exists($stubFile)) { - return $this->listener->getStubFile(); - } - - return $stubFile; - } - - /** - * Replace the namespace for the given stub. - */ - protected function replaceNamespace(string $stub, string $name): string - { - $stub = str_replace( - ['DummyRootNamespace\\', '{{ rootNamespace }}\\', '{{rootNamespace}}\\'], - '{{rootNamespace}}', - $stub - ); - - $searches = [ - ['DummyNamespace', 'DummyRootNamespace', 'NamespacedDummyUserModel'], - ['{{ namespace }}', '{{ rootNamespace }}', '{{ namespacedUserModel }}'], - ['{{namespace}}', '{{rootNamespace}}', '{{namespacedUserModel}}'], - ]; - - foreach ($searches as $search) { - $stub = str_replace( - $search, - [$this->getNamespace($name), $this->rootNamespace().'\\', $this->userProviderModel()], - $stub - ); - } - - return $stub; - } - - /** - * Replace the class name for the given stub. - */ - protected function replaceClass(string $stub, string $name): string - { - $class = str_replace($this->getNamespace($name).'\\', '', $name); - - $stub = str_replace( - ['DummyClass', '{{ class }}', '{{class}}'], $class, $stub - ); - - return str_replace( - ['DummyUser', '{{ userModel }}', '{{userModel}}'], - class_basename($this->userProviderModel()), - $stub - ); - } - - /** - * Get the full namespace for a given class, without the class name. - */ - protected function getNamespace(string $name): string - { - return trim(implode('\\', \array_slice(explode('\\', $name), 0, -1)), '\\'); - } - - /** - * Alphabetically sorts the imports for the given stub. - */ - protected function sortImports(string $stub): string - { - if (preg_match('/(?P(?:use [^;]+;$\n?)+)/m', $stub, $match)) { - $imports = explode("\n", trim($match['imports'])); - - sort($imports); - - return str_replace(trim($match['imports']), implode("\n", $imports), $stub); - } - - return $stub; - } - - /** - * Get the root namespace for the class. - */ - protected function rootNamespace(): string - { - return $this->preset->rootNamespace().'\\'; - } - - /** - * Get the model for the default guard's user provider. - */ - protected function userProviderModel(): string - { - return $this->preset->config('user-auth-provider', User::class); - } -} diff --git a/src/GeneratesCodeWithComponent.php b/src/GeneratesCodeWithComponent.php deleted file mode 100644 index d467832..0000000 --- a/src/GeneratesCodeWithComponent.php +++ /dev/null @@ -1,34 +0,0 @@ -options['inline'])) { - $stub = str_replace( - ['DummyView', '{{ view }}', '{{view}}'], - "<<<'blade'\n
\n ".Inspiring::quote()."\n
\nblade", - $stub - ); - } - - return str_replace( - ['DummyView', '{{ view }}', '{{view}}'], - 'view(\'components.'.Str::kebab(class_basename($name)).'\')', - $stub - ); - } -} diff --git a/src/GeneratesCodeWithEloquent.php b/src/GeneratesCodeWithEloquent.php deleted file mode 100644 index 1c9e5a4..0000000 --- a/src/GeneratesCodeWithEloquent.php +++ /dev/null @@ -1,87 +0,0 @@ -options['model']; - - return ! empty($model) ? $this->replaceModel($stub, $model) : $stub; - } - - /** - * Replace the model for the given stub. - */ - protected function replaceModel(string $stub, string $model): string - { - $modelClass = $this->parseModel($model); - - $replace = [ - 'DummyFullModelClass' => $modelClass, - '{{ namespacedModel }}' => $modelClass, - '{{namespacedModel}}' => $modelClass, - 'DummyModelClass' => class_basename($modelClass), - '{{ model }}' => class_basename($modelClass), - '{{model}}' => class_basename($modelClass), - 'DummyModelVariable' => lcfirst(class_basename($modelClass)), - '{{ modelVariable }}' => lcfirst(class_basename($modelClass)), - '{{modelVariable}}' => lcfirst(class_basename($modelClass)), - ]; - - return str_replace( - array_keys($replace), array_values($replace), $stub - ); - } - - /** - * Get the fully-qualified model class name. - * - * @param string $model - * - * @throws \InvalidArgumentException - */ - protected function parseModel($model): string - { - if (preg_match('([^A-Za-z0-9_/\\\\])', $model)) { - throw new InvalidArgumentException('Model name contains invalid characters.'); - } - - return $this->qualifyModel($model); - } - - /** - * Qualify the given model class base name. - */ - protected function qualifyModel(string $model): string - { - $model = ltrim($model, '\\/'); - - $model = str_replace('/', '\\', $model); - - $rootNamespace = $this->rootNamespace(); - $namespaceModel = $this->preset->modelNamespace().'\\'.$model; - - if (Str::startsWith($model, $namespaceModel)) { - return $model; - } elseif (! \is_null($this->preset->config('model.namespace'))) { - return $namespaceModel; - } - - return is_dir($this->preset->sourcePath().'/Models') - ? $rootNamespace.'Models\\'.$model - : $namespaceModel; - } -} diff --git a/src/GeneratesCodeWithMarkdown.php b/src/GeneratesCodeWithMarkdown.php deleted file mode 100644 index cdbe111..0000000 --- a/src/GeneratesCodeWithMarkdown.php +++ /dev/null @@ -1,20 +0,0 @@ -options['view'])) { - $stub = str_replace(['DummyView', '{{ view }}', '{{view}}'], $this->options['view'], $stub); - } - - return $stub; - } -} diff --git a/src/GeneratesCommandCode.php b/src/GeneratesCommandCode.php deleted file mode 100644 index a648d0c..0000000 --- a/src/GeneratesCommandCode.php +++ /dev/null @@ -1,19 +0,0 @@ -options['command'], $stub); - } -} diff --git a/src/LaravelServiceProvider.php b/src/LaravelServiceProvider.php deleted file mode 100644 index 6e446a9..0000000 --- a/src/LaravelServiceProvider.php +++ /dev/null @@ -1,34 +0,0 @@ -app->singleton(Presets\Preset::class, fn (Container $app) => $this->presetForLaravel($app)); - } - - /** - * Get the services provided by the provider. - * - * @return array - */ - public function provides() - { - return [ - Presets\Preset::class, - ]; - } -} diff --git a/src/Presets/Laravel.php b/src/Presets/Laravel.php index 23b296f..4082f26 100644 --- a/src/Presets/Laravel.php +++ b/src/Presets/Laravel.php @@ -2,9 +2,6 @@ namespace Orchestra\Canvas\Core\Presets; -use Illuminate\Support\Arr; -use Symfony\Component\Console\Application; - class Laravel extends Preset { /** @@ -32,24 +29,12 @@ public function name(): string return 'laravel'; } - /** - * Get the path to the base working directory. - */ - public function laravelPath(): string - { - return $this->basePath(); - } - /** * Get the path to the source directory. */ public function sourcePath(): string { - return sprintf( - '%s/%s', - $this->basePath(), - $this->config('paths.src', 'app') - ); + return implode('/', [$this->basePath(), $this->config('paths.src', 'app')]); } /** @@ -61,11 +46,11 @@ public function rootNamespace(): string } /** - * Testing namespace. + * Command namespace. */ - public function testingNamespace(): string + public function commandNamespace(): string { - return $this->config('testing.namespace', 'Tests'); + return $this->config('console.namespace', $this->rootNamespace().'\Console\Commands'); } /** @@ -85,23 +70,18 @@ public function providerNamespace(): string } /** - * Get custom stub path. + * Testing namespace. */ - public function getCustomStubPath(): ?string + public function testingNamespace(): string { - return sprintf('%s/%s', $this->basePath(), 'stubs'); + return $this->config('testing.namespace', 'Tests'); } /** - * Sync commands to preset. + * Get custom stub path. */ - public function addAdditionalCommands(Application $app): void + public function getCustomStubPath(): ?string { - parent::addAdditionalCommands($app); - - foreach (Arr::wrap(static::$generators) as $generator) { - /** @var class-string<\Symfony\Component\Console\Command\Command> $generator */ - $app->add(new $generator($this)); - } + return sprintf('%s/%s', $this->basePath(), 'stubs'); } } diff --git a/src/Presets/Package.php b/src/Presets/Package.php index c977120..899754b 100644 --- a/src/Presets/Package.php +++ b/src/Presets/Package.php @@ -2,29 +2,10 @@ namespace Orchestra\Canvas\Core\Presets; -use Illuminate\Support\Arr; use InvalidArgumentException; -use Symfony\Component\Console\Application; class Package extends Preset { - /** - * List of global generators. - * - * @var array> - */ - protected static $generators = []; - - /** - * Add global command. - * - * @param array> $generators - */ - public static function commands(array $generators): void - { - static::$generators = array_merge(static::$generators, $generators); - } - /** * Preset name. */ @@ -33,14 +14,6 @@ public function name(): string return 'package'; } - /** - * Get the path to the base working directory. - */ - public function laravelPath(): string - { - return sprintf('%s/orchestra/testbench-core/laravel', $this->vendorPath()); - } - /** * Get the path to the source directory. */ @@ -68,11 +41,11 @@ public function rootNamespace(): string } /** - * Testing namespace. + * Command namespace. */ - public function testingNamespace(): string + public function commandNamespace(): string { - return $this->config('testing.namespace', $this->rootNamespace().'\Tests'); + return $this->config('console.namespace', $this->rootNamespace().'\Console'); } /** @@ -92,23 +65,18 @@ public function providerNamespace(): string } /** - * Get custom stub path. + * Testing namespace. */ - public function getCustomStubPath(): ?string + public function testingNamespace(): string { - return sprintf('%s/stubs', $this->basePath()); + return $this->config('testing.namespace', $this->rootNamespace().'\Tests'); } /** - * Sync commands to preset. + * Get custom stub path. */ - public function addAdditionalCommands(Application $app): void + public function getCustomStubPath(): ?string { - parent::addAdditionalCommands($app); - - foreach (Arr::wrap(static::$generators) as $generator) { - /** @var class-string<\Symfony\Component\Console\Command\Command> $generator */ - $app->add(new $generator($this)); - } + return null; } } diff --git a/src/Presets/Preset.php b/src/Presets/Preset.php index c62a001..0444452 100644 --- a/src/Presets/Preset.php +++ b/src/Presets/Preset.php @@ -2,9 +2,7 @@ namespace Orchestra\Canvas\Core\Presets; -use Illuminate\Filesystem\Filesystem; use Illuminate\Support\Arr; -use Symfony\Component\Console\Application; abstract class Preset { @@ -15,8 +13,7 @@ abstract class Preset */ public function __construct( protected array $config, - protected string $basePath, - protected Filesystem $files + protected string $basePath ) { // } @@ -34,7 +31,7 @@ public function is(string $name): bool * * @param mixed|null $default */ - public function config(?string $key = null, $default = null) + public function config(?string $key = null, $default = null): mixed { if (\is_null($key)) { return $this->config; @@ -43,14 +40,6 @@ public function config(?string $key = null, $default = null) return Arr::get($this->config, $key, $default); } - /** - * Get the filesystem instance. - */ - public function filesystem(): Filesystem - { - return $this->files; - } - /** * Get the path to the base working directory. */ @@ -136,28 +125,7 @@ public function factoryNamespace(): string */ public function seederNamespace(): string { - return $this->config('seeder.path', 'Database\Seeders'); - } - - /** - * Sync commands to preset. - */ - public function addAdditionalCommands(Application $app): void - { - tap($this->config('generators') ?? [], function ($generators) use ($app) { - foreach (Arr::wrap($generators) as $generator) { - /** @var class-string<\Symfony\Component\Console\Command\Command> $generator */ - $app->add(new $generator($this)); - } - }); - } - - /** - * Preset has custom stub path. - */ - public function hasCustomStubPath(): bool - { - return ! \is_null($this->getCustomStubPath()); + return $this->config('seeder.namespace', 'Database\Seeders'); } /** @@ -165,11 +133,6 @@ public function hasCustomStubPath(): bool */ abstract public function name(): string; - /** - * Get the path to the base working directory. - */ - abstract public function laravelPath(): string; - /** * Get the path to the source directory. */ @@ -181,9 +144,9 @@ abstract public function sourcePath(): string; abstract public function rootNamespace(): string; /** - * Testing namespace. + * Command namespace. */ - abstract public function testingNamespace(): string; + abstract public function commandNamespace(): string; /** * Model namespace. @@ -195,6 +158,11 @@ abstract public function modelNamespace(): string; */ abstract public function providerNamespace(): string; + /** + * Testing namespace. + */ + abstract public function testingNamespace(): string; + /** * Get custom stub path. */ diff --git a/src/TestGenerator.php b/src/TestGenerator.php index 2c4f453..543c62c 100644 --- a/src/TestGenerator.php +++ b/src/TestGenerator.php @@ -9,14 +9,18 @@ trait TestGenerator /** * Create the matching test case if requested. */ - protected function handleTestCreationUsingCanvas(string $path): bool + protected function handleTestCreationViaCanvas(string $path): bool { if (! $this->option('test') && ! $this->option('pest')) { return false; } - return $this->callSilent('make:test', [ - 'name' => Str::of($path)->after($this->preset->sourcePath())->beforeLast('.php')->append('Test')->replace('\\', '/'), + $sourcePath = \in_array(CreatesUsingGeneratorPreset::class, class_uses_recursive($this)) + ? $this->generatorPreset()->sourcePath() + : $this->laravel['path']; + + return $this->call('make:test', [ + 'name' => Str::of($path)->after($sourcePath)->beforeLast('.php')->append('Test')->replace('\\', '/'), '--pest' => $this->option('pest'), ]) == 0; } diff --git a/src/Testing/Concerns/InteractsWithPublishedFiles.php b/src/Testing/Concerns/InteractsWithPublishedFiles.php deleted file mode 100644 index 23815c2..0000000 --- a/src/Testing/Concerns/InteractsWithPublishedFiles.php +++ /dev/null @@ -1,157 +0,0 @@ -filesystem = $this->app['files']; - - $this->cleanUpFiles(); - $this->cleanUpMigrationFiles(); - } - - /** - * Teardown Interacts with Published Files environment. - */ - protected function tearDownInteractsWithPublishedFiles(): void - { - $this->cleanUpFiles(); - $this->cleanUpMigrationFiles(); - - unset($this->filesystem); - } - - /** - * Assert file does contains data. - * - * @param array $contains - */ - protected function assertFileContains(array $contains, string $file, string $message = ''): void - { - $this->assertFilenameExists($file); - - $haystack = $this->filesystem->get( - $this->app->basePath($file) - ); - - foreach ($contains as $needle) { - $this->assertStringContainsString($needle, $haystack, $message); - } - } - - /** - * Assert file doesn't contains data. - * - * @param array $contains - */ - protected function assertFileNotContains(array $contains, string $file, string $message = ''): void - { - $this->assertFilenameExists($file); - - $haystack = $this->filesystem->get( - $this->app->basePath($file) - ); - - foreach ($contains as $needle) { - $this->assertStringNotContainsString($needle, $haystack, $message); - } - } - - /** - * Assert file does contains data. - * - * @param array $contains - */ - protected function assertMigrationFileContains(array $contains, string $file, string $message = ''): void - { - $haystack = $this->filesystem->get($this->getMigrationFile($file)); - - foreach ($contains as $needle) { - $this->assertStringContainsString($needle, $haystack, $message); - } - } - - /** - * Assert file doesn't contains data. - * - * @param array $contains - */ - protected function assertMigrationFileNotContains(array $contains, string $file, string $message = ''): void - { - $haystack = $this->filesystem->get($this->getMigrationFile($file)); - - foreach ($contains as $needle) { - $this->assertStringNotContainsString($needle, $haystack, $message); - } - } - - /** - * Assert filename exists. - */ - protected function assertFilenameExists(string $file): void - { - $appFile = $this->app->basePath($file); - - $this->assertTrue($this->filesystem->exists($appFile), "Assert file {$file} does exist"); - } - - /** - * Assert filename not exists. - */ - protected function assertFilenameNotExists(string $file): void - { - $appFile = $this->app->basePath($file); - - $this->assertTrue(! $this->filesystem->exists($appFile), "Assert file {$file} doesn't exist"); - } - - /** - * Removes generated files. - */ - protected function cleanUpFiles(): void - { - $this->filesystem->delete( - Collection::make($this->files ?? []) - ->transform(fn ($file) => $this->app->basePath($file)) - ->filter(fn ($file) => $this->filesystem->exists($file)) - ->all() - ); - } - - /** - * Removes generated migration files. - */ - protected function getMigrationFile(string $filename): string - { - $migrationPath = $this->app->databasePath('migrations'); - - return $this->filesystem->glob("{$migrationPath}/*{$filename}")[0]; - } - - /** - * Removes generated migration files. - */ - protected function cleanUpMigrationFiles(): void - { - $this->filesystem->delete( - Collection::make($this->filesystem->files($this->app->databasePath('migrations'))) - ->filter(fn ($file) => Str::endsWith($file, '.php')) - ->all() - ); - } -} From 88e4c4b0114d28b5916fd8d0ec52b6b1e717cdbf Mon Sep 17 00:00:00 2001 From: Mior Muhammad Zaki Date: Mon, 18 Sep 2023 08:39:07 +0800 Subject: [PATCH 02/25] wip Signed-off-by: Mior Muhammad Zaki --- composer.json | 13 ++- src/Concerns/CreatesUsingGeneratorPreset.php | 31 +++++++ src/Generators/Generator.php | 0 src/LaravelServiceProvider.php | 31 +++++++ src/PresetManager.php | 46 ++++++++++ src/{Presets => Recipes}/Laravel.php | 25 +----- src/{Presets => Recipes}/Package.php | 8 +- .../Preset.php => Recipes/Recipe.php} | 8 +- src/Testing/TestCase.php | 4 +- .../Feature/Commands/Generators/CodeTest.php | 53 ----------- .../Generators/ConsoleGeneratorTest.php | 87 ------------------- tests/Feature/CommandsProviderTest.php | 34 -------- .../Unit/{Presets => Recipes}/LaravelTest.php | 29 +------ .../Unit/{Presets => Recipes}/PackageTest.php | 29 +------ 14 files changed, 138 insertions(+), 260 deletions(-) create mode 100644 src/Concerns/CreatesUsingGeneratorPreset.php create mode 100644 src/Generators/Generator.php create mode 100644 src/LaravelServiceProvider.php create mode 100644 src/PresetManager.php rename src/{Presets => Recipes}/Laravel.php (69%) rename src/{Presets => Recipes}/Package.php (93%) rename src/{Presets/Preset.php => Recipes/Recipe.php} (96%) delete mode 100644 tests/Feature/Commands/Generators/CodeTest.php delete mode 100644 tests/Feature/Commands/Generators/ConsoleGeneratorTest.php delete mode 100644 tests/Feature/CommandsProviderTest.php rename tests/Unit/{Presets => Recipes}/LaravelTest.php (72%) rename tests/Unit/{Presets => Recipes}/PackageTest.php (74%) diff --git a/composer.json b/composer.json index 14100e7..4475480 100644 --- a/composer.json +++ b/composer.json @@ -28,13 +28,18 @@ }, "require": { "php": "^8.0", - "illuminate/console": "^9.45", - "illuminate/filesystem": "^9.45" + "illuminate/console": "^9.52.15", + "illuminate/filesystem": "^9.52.15" }, "require-dev": { + "fakerphp/faker": "^1.21", + "mockery/mockery": "^1.5.1", + "laravel/framework": "^9.52.15", "laravel/pint": "^1.1", - "orchestra/testbench": "^7.30", - "phpstan/phpstan": "^1.10.6" + "orchestra/testbench-core": "^7.30", + "phpstan/phpstan": "^1.10.6", + "phpunit/phpunit": "^9.6", + "symfony/yaml": "^6.0.9" }, "conflict": { "orchestra/canvas": "<7.8.0", diff --git a/src/Concerns/CreatesUsingGeneratorPreset.php b/src/Concerns/CreatesUsingGeneratorPreset.php new file mode 100644 index 0000000..a3e0be7 --- /dev/null +++ b/src/Concerns/CreatesUsingGeneratorPreset.php @@ -0,0 +1,31 @@ +getDefinition()->addOption(new InputOption( + 'preset', + null, + InputOption::VALUE_OPTIONAL, + sprintf('Preset used when generating %s', Str::lower($this->type)), + null, + )); + } + + protected function generatorPreset() + { + return $this->laravel[PresetManager::class]->driver($this->option('preset')); + } +} diff --git a/src/Generators/Generator.php b/src/Generators/Generator.php new file mode 100644 index 0000000..e69de29 diff --git a/src/LaravelServiceProvider.php b/src/LaravelServiceProvider.php new file mode 100644 index 0000000..8e84ff6 --- /dev/null +++ b/src/LaravelServiceProvider.php @@ -0,0 +1,31 @@ +app->singleton(PresetManager::class, fn ($app) => new PresetManager($app)); + } + + /** + * Get the services provided by the provider. + * + * @return array + */ + public function provides() + { + return [ + PresetManager::class, + ]; + } +} diff --git a/src/PresetManager.php b/src/PresetManager.php new file mode 100644 index 0000000..d11af6b --- /dev/null +++ b/src/PresetManager.php @@ -0,0 +1,46 @@ +container); + } + + /** + * Set the default driver name. + * + * @param string $name + * @return void + */ + public function setDefaultDriver($name) + { + $this->defaultPreset = $name; + } + + /** + * Get the default driver name. + * + * @return string + */ + public function getDefaultDriver() + { + return $this->defaultPreset; + } +} diff --git a/src/Presets/Laravel.php b/src/Recipes/Laravel.php similarity index 69% rename from src/Presets/Laravel.php rename to src/Recipes/Laravel.php index 4082f26..b6aa34f 100644 --- a/src/Presets/Laravel.php +++ b/src/Recipes/Laravel.php @@ -1,28 +1,11 @@ > - */ - protected static $generators = []; - - /** - * Add global command. - * - * @param array> $generators - */ - public static function commands(array $generators): void - { - static::$generators = array_merge(static::$generators, $generators); - } - - /** - * Preset name. + * Recipe name. */ public function name(): string { @@ -38,7 +21,7 @@ public function sourcePath(): string } /** - * Preset namespace. + * Root namespace. */ public function rootNamespace(): string { diff --git a/src/Presets/Package.php b/src/Recipes/Package.php similarity index 93% rename from src/Presets/Package.php rename to src/Recipes/Package.php index 899754b..e5e9bad 100644 --- a/src/Presets/Package.php +++ b/src/Recipes/Package.php @@ -1,13 +1,13 @@ 'App', 'generators' => [Generators\Code::class]], $this->app->basePath(), $this->filesystem - ); - - $this->instance('orchestra.canvas', $preset); - - Artisan::starting(fn ($artisan) => $preset->addAdditionalCommands($artisan)); - - $this->artisan('make:class', ['name' => 'Value/Foo']) - ->assertExitCode(0); - - $this->assertFileContains([ - 'namespace App\Value;', - 'class Foo', - ], 'app/Value/Foo.php'); - } - - /** @test */ - public function it_cant_generate_class_file() - { - $this->expectException('Symfony\Component\Console\Exception\CommandNotFoundException'); - $this->expectExceptionMessage('The command "make:class" does not exist.'); - - $this->artisan('make:class', ['name' => 'Foo']) - ->assertExitCode(0); - - $this->assertFileContains([ - 'namespace App\Value;', - 'class Foo', - ], 'app/Value/Foo.php'); - } -} diff --git a/tests/Feature/Commands/Generators/ConsoleGeneratorTest.php b/tests/Feature/Commands/Generators/ConsoleGeneratorTest.php deleted file mode 100644 index c7a48f6..0000000 --- a/tests/Feature/Commands/Generators/ConsoleGeneratorTest.php +++ /dev/null @@ -1,87 +0,0 @@ - 'App', 'generators' => [Generators\ConsoleGenerator::class]], $this->app->basePath(), $this->filesystem - ); - - $this->instance('orchestra.canvas', $preset); - - Artisan::starting(fn ($artisan) => $preset->addAdditionalCommands($artisan)); - - $this->artisan('make:generator', ['name' => 'FooCommand']) - ->assertExitCode(0); - - $this->assertFileContains([ - 'namespace App\Console\Commands;', - 'use Orchestra\Canvas\Commands\Generator;', - 'use Symfony\Component\Console\Attribute\AsCommand;', - '#[AsCommand(name: \'make:name\', description: \'Create a new class\')]', - 'class FooCommand extends Generator', - ], 'app/Console/Commands/FooCommand.php'); - } - - /** @test */ - public function it_can_generate_command_file_with_command_name() - { - $preset = new Laravel( - ['namespace' => 'App', 'generators' => [Generators\ConsoleGenerator::class]], $this->app->basePath(), $this->filesystem - ); - - $this->instance('orchestra.canvas', $preset); - - Artisan::starting(fn ($artisan) => $preset->addAdditionalCommands($artisan)); - - $this->artisan('make:generator', ['name' => 'FooCommand', '--command' => 'make:foobar']) - ->assertExitCode(0); - - $this->assertFileContains([ - 'namespace App\Console\Commands;', - 'use Orchestra\Canvas\Commands\Generator;', - 'use Symfony\Component\Console\Attribute\AsCommand;', - '#[AsCommand(name: \'make:foobar\', description: \'Create a new class\')]', - 'class FooCommand extends Generator', - ], 'app/Console/Commands/FooCommand.php'); - } - - /** @test */ - public function it_can_generate_command_file_with_command_name_without_make_prefix() - { - $preset = new Laravel( - ['namespace' => 'App', 'generators' => [Generators\ConsoleGenerator::class]], $this->app->basePath(), $this->filesystem - ); - - $this->instance('orchestra.canvas', $preset); - - Artisan::starting(fn ($artisan) => $preset->addAdditionalCommands($artisan)); - - $this->artisan('make:generator', ['name' => 'FooCommand', '--command' => 'foobar']) - ->assertExitCode(0); - - $this->assertFileContains([ - 'namespace App\Console\Commands;', - 'use Orchestra\Canvas\Commands\Generator;', - 'use Symfony\Component\Console\Attribute\AsCommand;', - '#[AsCommand(name: \'make:foobar\', description: \'Create a new class\')]', - 'class FooCommand extends Generator', - ], 'app/Console/Commands/FooCommand.php'); - } -} diff --git a/tests/Feature/CommandsProviderTest.php b/tests/Feature/CommandsProviderTest.php deleted file mode 100644 index 3f9c2b6..0000000 --- a/tests/Feature/CommandsProviderTest.php +++ /dev/null @@ -1,34 +0,0 @@ -getBasePath(); - $preset = $this->presetForLaravel($this->app); - - $this->assertSame('laravel', $preset->name()); - $this->assertTrue($preset->is('laravel')); - $this->assertFalse($preset->is('package')); - - $this->assertSame($directory, $preset->basePath()); - - $this->assertSame('App', $preset->rootNamespace()); - $this->assertSame('App\Models', $preset->modelNamespace()); - $this->assertSame('App\Providers', $preset->providerNamespace()); - - $this->assertSame("{$directory}/app", $preset->sourcePath()); - $this->assertSame("{$directory}/resources", $preset->resourcePath()); - $this->assertSame("{$directory}/database/factories", $preset->factoryPath()); - $this->assertSame("{$directory}/database/migrations", $preset->migrationPath()); - $this->assertSame("{$directory}/database/seeders", $preset->seederPath()); - } -} diff --git a/tests/Unit/Presets/LaravelTest.php b/tests/Unit/Recipes/LaravelTest.php similarity index 72% rename from tests/Unit/Presets/LaravelTest.php rename to tests/Unit/Recipes/LaravelTest.php index ae4bb50..890dd27 100644 --- a/tests/Unit/Presets/LaravelTest.php +++ b/tests/Unit/Recipes/LaravelTest.php @@ -1,11 +1,11 @@ assertSame('laravel', $preset->name()); $this->assertSame([], $preset->config()); @@ -31,7 +31,6 @@ public function it_has_proper_signatures() $this->assertFalse($preset->is('package')); $this->assertSame($directory, $preset->basePath()); - $this->assertSame($preset->basePath(), $preset->laravelPath()); $this->assertSame('App', $preset->rootNamespace()); $this->assertSame('Tests', $preset->testingNamespace()); @@ -47,10 +46,7 @@ public function it_has_proper_signatures() $this->assertSame("{$directory}/database/migrations", $preset->migrationPath()); $this->assertSame("{$directory}/database/seeders", $preset->seederPath()); - $this->assertTrue($preset->hasCustomStubPath()); $this->assertSame("{$directory}/stubs", $preset->getCustomStubPath()); - - $this->assertSame($files, $preset->filesystem()); } /** @test */ @@ -74,23 +70,4 @@ public function it_can_configure_provider_namespace() $this->assertSame('App\Models', $preset->modelNamespace()); $this->assertSame('App', $preset->providerNamespace()); } - - /** @test */ - public function it_can_add_additional_commands() - { - Laravel::commands([ - Generators\Code::class, - ]); - - $app = m::mock(Application::class); - $app->shouldReceive('add') - ->once() - ->with(m::type(Generators\Code::class)) - ->andReturnUsing(fn ($generator) => $this->assertInstanceOf(Generators\Code::class, $generator)); - - $directory = __DIR__; - $preset = new Laravel(['namespace' => 'App', 'provider' => ['namespace' => 'App']], $directory, new Filesystem()); - - $preset->addAdditionalCommands($app); - } } diff --git a/tests/Unit/Presets/PackageTest.php b/tests/Unit/Recipes/PackageTest.php similarity index 74% rename from tests/Unit/Presets/PackageTest.php rename to tests/Unit/Recipes/PackageTest.php index 38655e3..79213a6 100644 --- a/tests/Unit/Presets/PackageTest.php +++ b/tests/Unit/Recipes/PackageTest.php @@ -1,11 +1,11 @@ assertFalse($preset->is('laravel')); $this->assertSame($directory, $preset->basePath()); - $this->assertSame("{$directory}/vendor/orchestra/testbench-core/laravel", $preset->laravelPath()); $this->assertSame('FooBar', $preset->rootNamespace()); $this->assertSame('FooBar\Tests', $preset->testingNamespace()); @@ -39,10 +38,7 @@ public function it_has_proper_signatures() $this->assertSame("{$directory}/database/migrations", $preset->migrationPath()); $this->assertSame("{$directory}/database/seeders", $preset->seederPath()); - $this->assertTrue($preset->hasCustomStubPath()); - $this->assertSame("{$directory}/stubs", $preset->getCustomStubPath()); - - $this->assertSame($files, $preset->filesystem()); + $this->assertNull($preset->getCustomStubPath()); } /** @test */ @@ -77,23 +73,4 @@ public function it_requires_root_namespace_to_be_configured() $preset->rootNamespace(); } - - /** @test */ - public function it_can_add_additional_commands() - { - Package::commands([ - Generators\Code::class, - ]); - - $app = m::mock(Application::class); - $app->shouldReceive('add') - ->once() - ->with(m::type(Generators\Code::class)) - ->andReturnUsing(fn ($generator) => $this->assertInstanceOf(Generators\Code::class, $generator)); - - $directory = __DIR__; - $preset = new Package(['namespace' => 'App', 'provider' => ['namespace' => 'App']], $directory, new Filesystem()); - - $preset->addAdditionalCommands($app); - } } From f2c4ae2e8bc5c3eecbf06dcdaee675051b042e36 Mon Sep 17 00:00:00 2001 From: Mior Muhammad Zaki Date: Mon, 18 Sep 2023 08:50:14 +0800 Subject: [PATCH 03/25] wip Signed-off-by: Mior Muhammad Zaki --- src/CodeGenerator.php | 22 +++- src/Commands/Command.php | 105 ------------------ src/Commands/Generator.php | 5 +- src/Concerns/CreatesUsingGeneratorPreset.php | 5 + src/Concerns/ResolvesPresetStubs.php | 32 ++++++ .../Generator.php => Presets/Preset.php} | 0 6 files changed, 61 insertions(+), 108 deletions(-) delete mode 100644 src/Commands/Command.php create mode 100644 src/Concerns/ResolvesPresetStubs.php rename src/{Generators/Generator.php => Presets/Preset.php} (100%) diff --git a/src/CodeGenerator.php b/src/CodeGenerator.php index becc0ec..b27928b 100644 --- a/src/CodeGenerator.php +++ b/src/CodeGenerator.php @@ -1,6 +1,6 @@ listener->getPublishedStubFileName())) { + return $this->listener->getStubFile(); + } + + $stubFile = sprintf( + '%s/stubs/%s', $this->preset->basePath(), $publishedStubFile + ); + + if (! $this->files->exists($stubFile)) { + return $this->listener->getStubFile(); + } + + return $stubFile; + } + /** * Code already exists. * diff --git a/src/Commands/Command.php b/src/Commands/Command.php deleted file mode 100644 index a6bc19f..0000000 --- a/src/Commands/Command.php +++ /dev/null @@ -1,105 +0,0 @@ -preset = $preset; - - parent::__construct(); - - $this->specifyParameters(); - } - - /** - * Initializes the command after the input has been bound and before the input - * is validated. - * - * @return void - * - * @phpstan-param \Symfony\Component\Console\Output\OutputInterface&\Illuminate\Console\OutputStyle $output - */ - protected function initialize(InputInterface $input, OutputInterface $output) - { - $this->components = new Factory($output); - } - - /** - * Run the console command. - */ - public function run(InputInterface $input, OutputInterface $output): int - { - $container = Container::getInstance(); - - $this->laravel = $container->bound('app') - ? $container->get('app') - : Testbench::create(basePath: $this->preset->laravelPath()); - - return parent::run( - $this->input = $input, - $this->output = new OutputStyle($input, $output) - ); - } - - /** - * Resolve the console command instance for the given command. - * - * @param \Symfony\Component\Console\Command\Command|string $command - * @return \Symfony\Component\Console\Command\Command - */ - protected function resolveCommand($command) - { - return $this->getApplication()->find( - $command instanceof SymfonyConsole - ? $command->getName() - : $command - ); - } - - /** - * Get the Laravel application instance. - * - * @return \Illuminate\Contracts\Foundation\Application - */ - public function getLaravel() - { - return $this->laravel; - } -} diff --git a/src/Commands/Generator.php b/src/Commands/Generator.php index bcdab60..9978dc8 100644 --- a/src/Commands/Generator.php +++ b/src/Commands/Generator.php @@ -4,13 +4,14 @@ use Illuminate\Console\GeneratorCommand; use Orchestra\Canvas\Core\CodeGenerator; +use Orchestra\Canvas\Core\Contracts\GeneratesCode; use Orchestra\Canvas\Core\TestGenerator; /** * @property string|null $name * @property string|null $description */ -abstract class Generator extends GeneratorCommand +abstract class Generator extends GeneratorCommand implements GeneratesCode { use CodeGenerator, TestGenerator; @@ -44,7 +45,7 @@ public function handle() */ protected function buildClass($name) { - $stub = $this->files->get($this->getStub()); + $stub = $this->files->get($this->getStubFile()); return $this->generatingCode( $this->replaceNamespace($stub, $name)->replaceClass($stub, $name), $name diff --git a/src/Concerns/CreatesUsingGeneratorPreset.php b/src/Concerns/CreatesUsingGeneratorPreset.php index a3e0be7..ee46cc4 100644 --- a/src/Concerns/CreatesUsingGeneratorPreset.php +++ b/src/Concerns/CreatesUsingGeneratorPreset.php @@ -24,6 +24,11 @@ protected function addGeneratorPresetOptions() )); } + /** + * Resolve the generator preset. + * + * @return \Preset + */ protected function generatorPreset() { return $this->laravel[PresetManager::class]->driver($this->option('preset')); diff --git a/src/Concerns/ResolvesPresetStubs.php b/src/Concerns/ResolvesPresetStubs.php new file mode 100644 index 0000000..b2b1c94 --- /dev/null +++ b/src/Concerns/ResolvesPresetStubs.php @@ -0,0 +1,32 @@ +generatorPreset(); + + return $preset->hasCustomStubPath() && file_exists($customPath = implode('/', [$preset->basePath(), trim($stub, '/')])) + ? $customPath + : $this->resolveDefaultStubPath($stub); + } + + /** + * Resolve the default fully-qualified path to the stub. + * + * @param string $stub + * @return string + */ + protected function resolveDefaultStubPath($stub) + { + return $stub; + } +} diff --git a/src/Generators/Generator.php b/src/Presets/Preset.php similarity index 100% rename from src/Generators/Generator.php rename to src/Presets/Preset.php From 45fde05980de0afa31006347f81ca710c6d50b5c Mon Sep 17 00:00:00 2001 From: Mior Muhammad Zaki Date: Mon, 18 Sep 2023 09:04:08 +0800 Subject: [PATCH 04/25] wip Signed-off-by: Mior Muhammad Zaki --- .../{Generator.php => GeneratorCommand.php} | 7 +- src/{ => Concerns}/CodeGenerator.php | 20 -- src/Concerns/CreatesUsingGeneratorPreset.php | 2 +- src/{ => Concerns}/TestGenerator.php | 0 src/LaravelServiceProvider.php | 4 +- src/PresetManager.php | 2 +- src/Presets/Laravel.php | 180 ++++++++++++++++++ src/Presets/Preset.php | 176 +++++++++++++++++ src/Recipes/Laravel.php | 70 ------- src/Recipes/Package.php | 82 -------- src/Recipes/Recipe.php | 170 ----------------- src/Testing/TestCase.php | 17 -- 12 files changed, 365 insertions(+), 365 deletions(-) rename src/Commands/{Generator.php => GeneratorCommand.php} (88%) rename src/{ => Concerns}/CodeGenerator.php (82%) rename src/{ => Concerns}/TestGenerator.php (100%) create mode 100644 src/Presets/Laravel.php delete mode 100644 src/Recipes/Laravel.php delete mode 100644 src/Recipes/Package.php delete mode 100644 src/Recipes/Recipe.php delete mode 100644 src/Testing/TestCase.php diff --git a/src/Commands/Generator.php b/src/Commands/GeneratorCommand.php similarity index 88% rename from src/Commands/Generator.php rename to src/Commands/GeneratorCommand.php index 9978dc8..3e9908d 100644 --- a/src/Commands/Generator.php +++ b/src/Commands/GeneratorCommand.php @@ -2,7 +2,7 @@ namespace Orchestra\Canvas\Core\Commands; -use Illuminate\Console\GeneratorCommand; +use Orchestra\Canvas\Core\Concerns; use Orchestra\Canvas\Core\CodeGenerator; use Orchestra\Canvas\Core\Contracts\GeneratesCode; use Orchestra\Canvas\Core\TestGenerator; @@ -11,9 +11,10 @@ * @property string|null $name * @property string|null $description */ -abstract class Generator extends GeneratorCommand implements GeneratesCode +abstract class GeneratorCommand extends \Illuminate\Console\GeneratorCommand implements GeneratesCode { - use CodeGenerator, TestGenerator; + use Concerns\CodeGenerator; + use Concerns\TestGenerator; /** * Execute the console command. diff --git a/src/CodeGenerator.php b/src/Concerns/CodeGenerator.php similarity index 82% rename from src/CodeGenerator.php rename to src/Concerns/CodeGenerator.php index b27928b..bb720ee 100644 --- a/src/CodeGenerator.php +++ b/src/Concerns/CodeGenerator.php @@ -41,26 +41,6 @@ public function generateCode(bool $force = false) }); } - /** - * Get generator stub file. - */ - protected function getListenerStubFile(): string - { - if (\is_null($publishedStubFile = $this->listener->getPublishedStubFileName())) { - return $this->listener->getStubFile(); - } - - $stubFile = sprintf( - '%s/stubs/%s', $this->preset->basePath(), $publishedStubFile - ); - - if (! $this->files->exists($stubFile)) { - return $this->listener->getStubFile(); - } - - return $stubFile; - } - /** * Code already exists. * diff --git a/src/Concerns/CreatesUsingGeneratorPreset.php b/src/Concerns/CreatesUsingGeneratorPreset.php index ee46cc4..123236b 100644 --- a/src/Concerns/CreatesUsingGeneratorPreset.php +++ b/src/Concerns/CreatesUsingGeneratorPreset.php @@ -2,8 +2,8 @@ namespace Orchestra\Canvas\Core\Concerns; -use Illuminate\Console\Generators\PresetManager; use Illuminate\Support\Str; +use Orchestra\Canvas\Core\PresetManager; use Symfony\Component\Console\Input\InputOption; trait CreatesUsingGeneratorPreset diff --git a/src/TestGenerator.php b/src/Concerns/TestGenerator.php similarity index 100% rename from src/TestGenerator.php rename to src/Concerns/TestGenerator.php diff --git a/src/LaravelServiceProvider.php b/src/LaravelServiceProvider.php index 8e84ff6..510373f 100644 --- a/src/LaravelServiceProvider.php +++ b/src/LaravelServiceProvider.php @@ -3,7 +3,9 @@ namespace Orchestra\Canvas\Core; use Illuminate\Contracts\Support\DeferrableProvider; +use Illuminate\Support\Arr; use Illuminate\Support\ServiceProvider; +use Symfony\Component\Yaml\Yaml; class LaravelServiceProvider extends ServiceProvider implements DeferrableProvider { @@ -20,7 +22,7 @@ public function register() /** * Get the services provided by the provider. * - * @return array + * @return array */ public function provides() { diff --git a/src/PresetManager.php b/src/PresetManager.php index d11af6b..4d94304 100644 --- a/src/PresetManager.php +++ b/src/PresetManager.php @@ -16,7 +16,7 @@ class PresetManager extends Manager /** * Create "laravel" driver. * - * @return \Illuminate\Console\Generators\Presets\Laravel + * @return \Orchestra\Canvas\Core\Presets\Laravel */ public function createLaravelDriver() { diff --git a/src/Presets/Laravel.php b/src/Presets/Laravel.php new file mode 100644 index 0000000..e6f8a1a --- /dev/null +++ b/src/Presets/Laravel.php @@ -0,0 +1,180 @@ +app->basePath(); + } + + /** + * Get the path to the source directory. + * + * @return string + */ + public function sourcePath() + { + return $this->app->basePath('app'); + } + + /** + * Get the path to the testing directory. + * + * @return string + */ + public function testingPath() + { + return $this->app->basePath('tests'); + } + + /** + * Get the path to the resource directory. + * + * @return string + */ + public function resourcePath() + { + return $this->app->resourcePath(); + } + + /** + * Get the path to the view directory. + * + * @return string + */ + public function viewPath() + { + return $this->app['config']['view.paths'][0] ?? $this->app->resourcePath('views'); + } + + /** + * Get the path to the factory directory. + * + * @return string + */ + public function factoryPath() + { + return $this->app->databasePath('factories'); + } + + /** + * Get the path to the migration directory. + * + * @return string + */ + public function migrationPath() + { + return $this->app->databasePath('migrations'); + } + + /** + * Get the path to the seeder directory. + * + * @return string + */ + public function seederPath(): string + { + if (is_dir($seederPath = $this->app->databasePath('seeds'))) { + return $seederPath; + } + + return $this->app->databasePath('seeders'); + } + + /** + * Preset namespace. + * + * @return string + */ + public function rootNamespace() + { + return $this->app->getNamespace(); + } + + /** + * Command namespace. + * + * @return string + */ + public function commandNamespace() + { + return "{$this->rootNamespace()}Console\Commands\\"; + } + + /** + * Model namespace. + * + * @return string + */ + public function modelNamespace() + { + return is_dir("{$this->sourcePath()}/Models") ? "{$this->rootNamespace()}Models\\" : $this->rootNamespace(); + } + + /** + * Provider namespace. + * + * @return string + */ + public function providerNamespace() + { + return "{$this->rootNamespace()}Providers\\"; + } + + /** + * Testing namespace. + * + * @return string + */ + public function testingNamespace() + { + return 'Tests\\'; + } + + /** + * Database factory namespace. + * + * @return string + */ + public function factoryNamespace() + { + return 'Database\Factories\\'; + } + + /** + * Database seeder namespace. + * + * @return string + */ + public function seederNamespace() + { + return 'Database\Seeders\\'; + } + + /** + * Preset has custom stub path. + * + * @return bool + */ + public function hasCustomStubPath() + { + return true; + } +} diff --git a/src/Presets/Preset.php b/src/Presets/Preset.php index e69de29..68bab44 100644 --- a/src/Presets/Preset.php +++ b/src/Presets/Preset.php @@ -0,0 +1,176 @@ +app = $app; + } + + /** + * Check if preset name equal to $name. + * + * @param string $name + * @return bool + */ + public function is($name) + { + return $this->name() === $name; + } + + /** + * Get the model for the default guard's user provider. + * + * @param string|null $guard + * @return string|null + */ + public function userProviderModel($guard = null) + { + $config = $this->app['config']; + + $guard = $guard ?: $config->get('auth.defaults.guard'); + + if (is_null($provider = $config->get('auth.guards.'.$guard.'.provider'))) { + throw new LogicException('The ['.$guard.'] guard is not defined in your "auth" configuration file.'); + } + + return $config->get("auth.providers.{$provider}.model"); + } + + /** + * Preset name. + * + * @return string + */ + abstract public function name(); + + /** + * Get the path to the base working directory. + * + * @return string + */ + abstract public function basePath(); + + /** + * Get the path to the source directory. + * + * @return string + */ + abstract public function sourcePath(); + + /** + * Get the path to the testing directory. + * + * @return string + */ + abstract public function testingPath(); + + /** + * Get the path to the resource directory. + * + * @return string + */ + abstract public function resourcePath(); + + /** + * Get the path to the view directory. + * + * @return string + */ + abstract public function viewPath(); + + /** + * Get the path to the factory directory. + * + * @return string + */ + abstract public function factoryPath(); + + /** + * Get the path to the migration directory. + * + * @return string + */ + abstract public function migrationPath(); + + /** + * Get the path to the seeder directory. + * + * @return string + */ + abstract public function seederPath(); + + /** + * Preset namespace. + * + * @return string + */ + abstract public function rootNamespace(); + + /** + * Command namespace. + * + * @return string + */ + abstract public function commandNamespace(); + + /** + * Model namespace. + * + * @return string + */ + abstract public function modelNamespace(); + + /** + * Provider namespace. + * + * @return string + */ + abstract public function providerNamespace(); + + /** + * Testing namespace. + * + * @return string + */ + abstract public function testingNamespace(); + + /** + * Database factory namespace. + * + * @return string + */ + abstract public function factoryNamespace(); + + /** + * Database seeder namespace. + * + * @return string + */ + abstract public function seederNamespace(); + + /** + * Preset has custom stub path. + * + * @return bool + */ + abstract public function hasCustomStubPath(); +} diff --git a/src/Recipes/Laravel.php b/src/Recipes/Laravel.php deleted file mode 100644 index b6aa34f..0000000 --- a/src/Recipes/Laravel.php +++ /dev/null @@ -1,70 +0,0 @@ -basePath(), $this->config('paths.src', 'app')]); - } - - /** - * Root namespace. - */ - public function rootNamespace(): string - { - return $this->config['namespace'] ?? 'App'; - } - - /** - * Command namespace. - */ - public function commandNamespace(): string - { - return $this->config('console.namespace', $this->rootNamespace().'\Console\Commands'); - } - - /** - * Model namespace. - */ - public function modelNamespace(): string - { - return $this->config('model.namespace', $this->rootNamespace().'\Models'); - } - - /** - * Provider namespace. - */ - public function providerNamespace(): string - { - return $this->config('provider.namespace', $this->rootNamespace().'\Providers'); - } - - /** - * Testing namespace. - */ - public function testingNamespace(): string - { - return $this->config('testing.namespace', 'Tests'); - } - - /** - * Get custom stub path. - */ - public function getCustomStubPath(): ?string - { - return sprintf('%s/%s', $this->basePath(), 'stubs'); - } -} diff --git a/src/Recipes/Package.php b/src/Recipes/Package.php deleted file mode 100644 index e5e9bad..0000000 --- a/src/Recipes/Package.php +++ /dev/null @@ -1,82 +0,0 @@ -basePath(), - $this->config('paths.src', 'src') - ); - } - - /** - * Root namespace. - */ - public function rootNamespace(): string - { - $namespace = trim($this->config['namespace'] ?? ''); - - if (empty($namespace)) { - throw new InvalidArgumentException("Please configure namespace configuration under 'canvas.yaml'"); - } - - return $namespace; - } - - /** - * Command namespace. - */ - public function commandNamespace(): string - { - return $this->config('console.namespace', $this->rootNamespace().'\Console'); - } - - /** - * Model namespace. - */ - public function modelNamespace(): string - { - return $this->config('model.namespace', $this->rootNamespace()); - } - - /** - * Provider namespace. - */ - public function providerNamespace(): string - { - return $this->config('provider.namespace', $this->rootNamespace()); - } - - /** - * Testing namespace. - */ - public function testingNamespace(): string - { - return $this->config('testing.namespace', $this->rootNamespace().'\Tests'); - } - - /** - * Get custom stub path. - */ - public function getCustomStubPath(): ?string - { - return null; - } -} diff --git a/src/Recipes/Recipe.php b/src/Recipes/Recipe.php deleted file mode 100644 index 813021d..0000000 --- a/src/Recipes/Recipe.php +++ /dev/null @@ -1,170 +0,0 @@ - $config - */ - public function __construct( - protected array $config, - protected string $basePath - ) { - // - } - - /** - * Check if preset name equal to $name. - */ - public function is(string $name): bool - { - return $this->name() === $name; - } - - /** - * Get configuration. - * - * @param mixed|null $default - */ - public function config(?string $key = null, $default = null): mixed - { - if (\is_null($key)) { - return $this->config; - } - - return Arr::get($this->config, $key, $default); - } - - /** - * Get the path to the base working directory. - */ - public function basePath(): string - { - return $this->basePath; - } - - /** - * Get the path to the testing directory. - */ - public function testingPath(): string - { - return "{$this->basePath}/tests"; - } - - /** - * Get the path to the vendor directory. - */ - public function vendorPath(): string - { - return "{$this->basePath}/vendor"; - } - - /** - * Get the path to the resource directory. - */ - public function resourcePath(): string - { - return sprintf( - '%s/%s', - $this->basePath(), - $this->config('paths.resource', 'resources') - ); - } - - /** - * Get the path to the factory directory. - */ - public function factoryPath(): string - { - return sprintf( - '%s/%s', - $this->basePath(), - $this->config('factory.path', 'database/factories') - ); - } - - /** - * Get the path to the migration directory. - */ - public function migrationPath(): string - { - return sprintf( - '%s/%s', - $this->basePath(), - $this->config('migration.path', 'database/migrations') - ); - } - - /** - * Get the path to the seeder directory. - */ - public function seederPath(): string - { - return sprintf( - '%s/%s', - $this->basePath(), - $this->config('seeder.path', 'database/seeders') - ); - } - - /** - * Database factory namespace. - */ - public function factoryNamespace(): string - { - return $this->config('factory.namespace', 'Database\Factories'); - } - - /** - * Database seeder namespace. - */ - public function seederNamespace(): string - { - return $this->config('seeder.namespace', 'Database\Seeders'); - } - - /** - * Recipe name. - */ - abstract public function name(): string; - - /** - * Get the path to the source directory. - */ - abstract public function sourcePath(): string; - - /** - * Root namespace. - */ - abstract public function rootNamespace(): string; - - /** - * Command namespace. - */ - abstract public function commandNamespace(): string; - - /** - * Model namespace. - */ - abstract public function modelNamespace(): string; - - /** - * Provider namespace. - */ - abstract public function providerNamespace(): string; - - /** - * Testing namespace. - */ - abstract public function testingNamespace(): string; - - /** - * Get custom stub path. - */ - abstract public function getCustomStubPath(): ?string; -} diff --git a/src/Testing/TestCase.php b/src/Testing/TestCase.php deleted file mode 100644 index 99a3e86..0000000 --- a/src/Testing/TestCase.php +++ /dev/null @@ -1,17 +0,0 @@ -|null - */ - protected $files = []; -} From 296460ba261c1c73497fafd4d8e6f117970c6afd Mon Sep 17 00:00:00 2001 From: Mior Muhammad Zaki Date: Mon, 18 Sep 2023 09:07:46 +0800 Subject: [PATCH 05/25] wip Signed-off-by: Mior Muhammad Zaki --- tests/Presets/LaravelPresetTest.php | 53 ++++++++++++++++++++ tests/Unit/Recipes/LaravelTest.php | 73 --------------------------- tests/Unit/Recipes/PackageTest.php | 76 ----------------------------- 3 files changed, 53 insertions(+), 149 deletions(-) create mode 100644 tests/Presets/LaravelPresetTest.php delete mode 100644 tests/Unit/Recipes/LaravelTest.php delete mode 100644 tests/Unit/Recipes/PackageTest.php diff --git a/tests/Presets/LaravelPresetTest.php b/tests/Presets/LaravelPresetTest.php new file mode 100644 index 0000000..97689a4 --- /dev/null +++ b/tests/Presets/LaravelPresetTest.php @@ -0,0 +1,53 @@ +app[PresetManager::class]->driver('laravel'); + + $this->assertInstanceOf(Laravel::class, $preset); + $this->assertSame('laravel', $preset->name()); + $this->assertTrue($preset->is('laravel')); + + $this->assertSame($this->app->basePath(), $preset->basePath()); + $this->assertSame($this->app->basePath('app'), $preset->sourcePath()); + $this->assertSame($this->app->basePath('tests'), $preset->testingPath()); + $this->assertSame($this->app->resourcePath(), $preset->resourcePath()); + $this->assertSame($this->app->resourcePath('views'), $preset->viewPath()); + $this->assertSame($this->app->databasePath('factories'), $preset->factoryPath()); + $this->assertSame($this->app->databasePath('migrations'), $preset->migrationPath()); + $this->assertSame($this->app->databasePath('seeders'), $preset->seederPath()); + + $this->assertSame($this->app->getNamespace(), $preset->rootNamespace()); + $this->assertSame($this->app->getNamespace().'Console\Commands\\', $preset->commandNamespace()); + $this->assertSame($this->app->getNamespace().'Models\\', $preset->modelNamespace()); + $this->assertSame($this->app->getNamespace().'Providers\\', $preset->providerNamespace()); + $this->assertSame('Database\Factories\\', $preset->factoryNamespace()); + $this->assertSame('Database\Seeders\\', $preset->seederNamespace()); + $this->assertSame('Tests\\', $preset->testingNamespace()); + + $this->assertTrue($preset->hasCustomStubPath()); + $this->assertSame('Illuminate\Foundation\Auth\User', $preset->userProviderModel()); + } + + /** @test */ + public function it_available_as_default_driver() + { + $preset = $this->app[PresetManager::class]->driver(); + + $this->assertInstanceOf(Laravel::class, $preset); + $this->assertSame('laravel', $preset->name()); + $this->assertTrue($preset->is('laravel')); + } +} diff --git a/tests/Unit/Recipes/LaravelTest.php b/tests/Unit/Recipes/LaravelTest.php deleted file mode 100644 index 890dd27..0000000 --- a/tests/Unit/Recipes/LaravelTest.php +++ /dev/null @@ -1,73 +0,0 @@ -assertSame('laravel', $preset->name()); - $this->assertSame([], $preset->config()); - $this->assertTrue($preset->is('laravel')); - $this->assertFalse($preset->is('package')); - - $this->assertSame($directory, $preset->basePath()); - - $this->assertSame('App', $preset->rootNamespace()); - $this->assertSame('Tests', $preset->testingNamespace()); - $this->assertSame('App\Models', $preset->modelNamespace()); - $this->assertSame('App\Providers', $preset->providerNamespace()); - $this->assertSame('Database\Factories', $preset->factoryNamespace()); - $this->assertSame('Database\Seeders', $preset->seederNamespace()); - - $this->assertSame("{$directory}/app", $preset->sourcePath()); - $this->assertSame("{$directory}/vendor", $preset->vendorPath()); - $this->assertSame("{$directory}/resources", $preset->resourcePath()); - $this->assertSame("{$directory}/database/factories", $preset->factoryPath()); - $this->assertSame("{$directory}/database/migrations", $preset->migrationPath()); - $this->assertSame("{$directory}/database/seeders", $preset->seederPath()); - - $this->assertSame("{$directory}/stubs", $preset->getCustomStubPath()); - } - - /** @test */ - public function it_can_configure_model_namespace() - { - $directory = __DIR__; - $preset = new Laravel(['namespace' => 'App', 'model' => ['namespace' => 'App\Model']], $directory, new Filesystem()); - - $this->assertSame('App', $preset->rootNamespace()); - $this->assertSame('App\Model', $preset->modelNamespace()); - $this->assertSame('App\Providers', $preset->providerNamespace()); - } - - /** @test */ - public function it_can_configure_provider_namespace() - { - $directory = __DIR__; - $preset = new Laravel(['namespace' => 'App', 'provider' => ['namespace' => 'App']], $directory, new Filesystem()); - - $this->assertSame('App', $preset->rootNamespace()); - $this->assertSame('App\Models', $preset->modelNamespace()); - $this->assertSame('App', $preset->providerNamespace()); - } -} diff --git a/tests/Unit/Recipes/PackageTest.php b/tests/Unit/Recipes/PackageTest.php deleted file mode 100644 index 79213a6..0000000 --- a/tests/Unit/Recipes/PackageTest.php +++ /dev/null @@ -1,76 +0,0 @@ - 'FooBar'], $directory, $files = new Filesystem()); - - $this->assertSame('package', $preset->name()); - $this->assertSame(['namespace' => 'FooBar'], $preset->config()); - $this->assertTrue($preset->is('package')); - $this->assertFalse($preset->is('laravel')); - - $this->assertSame($directory, $preset->basePath()); - - $this->assertSame('FooBar', $preset->rootNamespace()); - $this->assertSame('FooBar\Tests', $preset->testingNamespace()); - $this->assertSame('FooBar', $preset->modelNamespace()); - $this->assertSame('FooBar', $preset->providerNamespace()); - $this->assertSame('Database\Factories', $preset->factoryNamespace()); - $this->assertSame('Database\Seeders', $preset->seederNamespace()); - - $this->assertSame("{$directory}/src", $preset->sourcePath()); - $this->assertSame("{$directory}/vendor", $preset->vendorPath()); - $this->assertSame("{$directory}/resources", $preset->resourcePath()); - $this->assertSame("{$directory}/database/factories", $preset->factoryPath()); - $this->assertSame("{$directory}/database/migrations", $preset->migrationPath()); - $this->assertSame("{$directory}/database/seeders", $preset->seederPath()); - - $this->assertNull($preset->getCustomStubPath()); - } - - /** @test */ - public function it_can_configure_model_namespace() - { - $directory = __DIR__; - $preset = new Package(['namespace' => 'FooBar', 'model' => ['namespace' => 'FooBar\Model']], $directory, new Filesystem()); - - $this->assertSame('FooBar', $preset->rootNamespace()); - $this->assertSame('FooBar\Model', $preset->modelNamespace()); - $this->assertSame('FooBar', $preset->providerNamespace()); - } - - /** @test */ - public function it_can_configure_provider_namespace() - { - $directory = __DIR__; - $preset = new Package(['namespace' => 'FooBar', 'provider' => ['namespace' => 'FooBar\Providers']], $directory, new Filesystem()); - - $this->assertSame('FooBar', $preset->rootNamespace()); - $this->assertSame('FooBar', $preset->modelNamespace()); - $this->assertSame('FooBar\Providers', $preset->providerNamespace()); - } - - /** @test */ - public function it_requires_root_namespace_to_be_configured() - { - $this->expectException('InvalidArgumentException'); - $this->expectExceptionMessage("Please configure namespace configuration under 'canvas.yaml'"); - $directory = __DIR__; - $preset = new Package([], $directory, new Filesystem()); - - $preset->rootNamespace(); - } -} From 07b72535ed865dba67eef8059ebb52f4e4cc8249 Mon Sep 17 00:00:00 2001 From: Mior Muhammad Zaki Date: Mon, 18 Sep 2023 09:08:39 +0800 Subject: [PATCH 06/25] wip Signed-off-by: Mior Muhammad Zaki --- composer.json | 2 +- 1 file changed, 1 insertion(+), 1 deletion(-) diff --git a/composer.json b/composer.json index 4475480..5e5dacd 100644 --- a/composer.json +++ b/composer.json @@ -42,7 +42,7 @@ "symfony/yaml": "^6.0.9" }, "conflict": { - "orchestra/canvas": "<7.8.0", + "orchestra/canvas": "<7.9.0", "orchestra/testbench-core": "<7.25.0" }, "config": { From add1586c5e9fac1cb7ca84bc2e21344557948941 Mon Sep 17 00:00:00 2001 From: Mior Muhammad Zaki Date: Mon, 18 Sep 2023 09:19:09 +0800 Subject: [PATCH 07/25] wip Signed-off-by: Mior Muhammad Zaki --- phpstan-baseline.neon | 18 ++++---------- src/Commands/GeneratorCommand.php | 9 ++++--- src/Concerns/CodeGenerator.php | 25 +++++++------------- src/Concerns/CreatesUsingGeneratorPreset.php | 4 ++-- src/Concerns/TestGenerator.php | 4 ++-- src/Contracts/GeneratesCode.php | 4 ++-- src/LaravelServiceProvider.php | 2 -- src/Presets/Laravel.php | 2 -- src/Presets/Preset.php | 6 ++--- 9 files changed, 25 insertions(+), 49 deletions(-) diff --git a/phpstan-baseline.neon b/phpstan-baseline.neon index 1eede53..0703a7f 100644 --- a/phpstan-baseline.neon +++ b/phpstan-baseline.neon @@ -1,21 +1,11 @@ parameters: ignoreErrors: - - message: "#^Method Orchestra\\\\Canvas\\\\Core\\\\Contracts\\\\GeneratesCodeListener\\:\\:codeAlreadyExists\\(\\) has no return type specified\\.$#" + message: "#^Cannot access offset 'path' on Illuminate\\\\Contracts\\\\Foundation\\\\Application\\.$#" count: 1 - path: src/Contracts/GeneratesCodeListener.php + path: src/Commands/GeneratorCommand.php - - message: "#^Method Orchestra\\\\Canvas\\\\Core\\\\Contracts\\\\GeneratesCodeListener\\:\\:codeHasBeenGenerated\\(\\) has no return type specified\\.$#" + message: "#^Parameter \\#1 \\$app of class Orchestra\\\\Canvas\\\\Core\\\\Presets\\\\Laravel constructor expects Illuminate\\\\Contracts\\\\Foundation\\\\Application, Illuminate\\\\Contracts\\\\Container\\\\Container given\\.$#" count: 1 - path: src/Contracts/GeneratesCodeListener.php - - - - message: "#^Call to an undefined method Illuminate\\\\Contracts\\\\Container\\\\Container\\:\\:basePath\\(\\)\\.$#" - count: 1 - path: src/LaravelServiceProvider.php - - - - message: "#^Method Orchestra\\\\Canvas\\\\Core\\\\Presets\\\\Preset\\:\\:config\\(\\) has no return type specified\\.$#" - count: 1 - path: src/Presets/Preset.php + path: src/PresetManager.php diff --git a/src/Commands/GeneratorCommand.php b/src/Commands/GeneratorCommand.php index 3e9908d..ce33776 100644 --- a/src/Commands/GeneratorCommand.php +++ b/src/Commands/GeneratorCommand.php @@ -3,9 +3,7 @@ namespace Orchestra\Canvas\Core\Commands; use Orchestra\Canvas\Core\Concerns; -use Orchestra\Canvas\Core\CodeGenerator; use Orchestra\Canvas\Core\Contracts\GeneratesCode; -use Orchestra\Canvas\Core\TestGenerator; /** * @property string|null $name @@ -14,6 +12,7 @@ abstract class GeneratorCommand extends \Illuminate\Console\GeneratorCommand implements GeneratesCode { use Concerns\CodeGenerator; + use Concerns\CreatesUsingGeneratorPreset; use Concerns\TestGenerator; /** @@ -28,10 +27,10 @@ public function handle() // First we need to ensure that the given name is not a reserved word within the PHP // language and that the class name will actually be valid. If it is not valid we // can error now and prevent from polluting the filesystem using invalid files. - if ($this->isReservedName($name = $this->generatorName())) { + if ($this->isReservedName($name = $this->getNameInput())) { $this->components->error('The name "'.$name.'" is reserved by PHP.'); - return GeneratorCommand::FAILURE; + return false; } $force = $this->hasOption('force') && $this->option('force') === true; @@ -46,7 +45,7 @@ public function handle() */ protected function buildClass($name) { - $stub = $this->files->get($this->getStubFile()); + $stub = $this->files->get($this->getStub()); return $this->generatingCode( $this->replaceNamespace($stub, $name)->replaceClass($stub, $name), $name diff --git a/src/Concerns/CodeGenerator.php b/src/Concerns/CodeGenerator.php index bb720ee..d416155 100644 --- a/src/Concerns/CodeGenerator.php +++ b/src/Concerns/CodeGenerator.php @@ -3,18 +3,17 @@ namespace Orchestra\Canvas\Core\Concerns; use Illuminate\Console\Concerns\CreatesMatchingTest; -use Symfony\Component\Console\Command\Command; trait CodeGenerator { /** * Generate code. * - * @return int + * @return bool|null */ public function generateCode(bool $force = false) { - $name = $this->getInputName(); + $name = $this->getNameInput(); $className = $this->qualifyClass($name); $path = $this->getPath($this->qualifyClass($name)); @@ -43,37 +42,29 @@ public function generateCode(bool $force = false) /** * Code already exists. - * - * @return int */ - public function codeAlreadyExists(string $className) + public function codeAlreadyExists(string $className): ?bool { $this->components->error(sprintf('%s [%s] already exists!', $this->type, $className)); - return Command::FAILURE; + return false; } /** * Code successfully generated. - * - * @return int */ - public function codeHasBeenGenerated(string $className) + public function codeHasBeenGenerated(string $className): ?bool { $this->components->info(sprintf('%s [%s] created successfully.', $this->type, $className)); - return Command::SUCCESS; + return true; } /** * Run after code successfully generated. - * - * @return void */ - public function afterCodeHasBeenGenerated(string $className, string $path) + public function afterCodeHasBeenGenerated(string $className, string $path): void { - if (\in_array(CreatesMatchingTest::class, class_uses_recursive($this))) { - $this->handleTestCreationUsingCanvas($path); - } + // } } diff --git a/src/Concerns/CreatesUsingGeneratorPreset.php b/src/Concerns/CreatesUsingGeneratorPreset.php index 123236b..df5bff4 100644 --- a/src/Concerns/CreatesUsingGeneratorPreset.php +++ b/src/Concerns/CreatesUsingGeneratorPreset.php @@ -27,10 +27,10 @@ protected function addGeneratorPresetOptions() /** * Resolve the generator preset. * - * @return \Preset + * @return \Orchestra\Canvas\Core\Presets\Preset */ protected function generatorPreset() { - return $this->laravel[PresetManager::class]->driver($this->option('preset')); + return $this->laravel->make(PresetManager::class)->driver($this->option('preset')); } } diff --git a/src/Concerns/TestGenerator.php b/src/Concerns/TestGenerator.php index 543c62c..f0247ee 100644 --- a/src/Concerns/TestGenerator.php +++ b/src/Concerns/TestGenerator.php @@ -1,6 +1,6 @@ option('test') && ! $this->option('pest')) { return false; diff --git a/src/Contracts/GeneratesCode.php b/src/Contracts/GeneratesCode.php index 3cfec1a..0b17d96 100644 --- a/src/Contracts/GeneratesCode.php +++ b/src/Contracts/GeneratesCode.php @@ -7,7 +7,7 @@ interface GeneratesCode /** * Code already exists. */ - public function codeAlreadyExists(string $className); + public function codeAlreadyExists(string $className): mixed; /** * Handle generating code. @@ -17,7 +17,7 @@ public function generatingCode(string $stub, string $className): string; /** * Code successfully generated. */ - public function codeHasBeenGenerated(string $className); + public function codeHasBeenGenerated(string $className): mixed; /** * Run after code successfully generated. diff --git a/src/LaravelServiceProvider.php b/src/LaravelServiceProvider.php index 510373f..cac9650 100644 --- a/src/LaravelServiceProvider.php +++ b/src/LaravelServiceProvider.php @@ -3,9 +3,7 @@ namespace Orchestra\Canvas\Core; use Illuminate\Contracts\Support\DeferrableProvider; -use Illuminate\Support\Arr; use Illuminate\Support\ServiceProvider; -use Symfony\Component\Yaml\Yaml; class LaravelServiceProvider extends ServiceProvider implements DeferrableProvider { diff --git a/src/Presets/Laravel.php b/src/Presets/Laravel.php index e6f8a1a..73d5115 100644 --- a/src/Presets/Laravel.php +++ b/src/Presets/Laravel.php @@ -86,8 +86,6 @@ public function migrationPath() /** * Get the path to the seeder directory. - * - * @return string */ public function seederPath(): string { diff --git a/src/Presets/Preset.php b/src/Presets/Preset.php index 68bab44..8b6de9e 100644 --- a/src/Presets/Preset.php +++ b/src/Presets/Preset.php @@ -17,7 +17,6 @@ abstract class Preset /** * Construct a new preset. * - * @param \Illuminate\Contracts\Foundation\Application $app * @return void */ public function __construct(Application $app) @@ -44,11 +43,12 @@ public function is($name) */ public function userProviderModel($guard = null) { - $config = $this->app['config']; + /** @var \Illuminate\Contracts\Config\Repository $config */ + $config = $this->app->make('config'); $guard = $guard ?: $config->get('auth.defaults.guard'); - if (is_null($provider = $config->get('auth.guards.'.$guard.'.provider'))) { + if (\is_null($provider = $config->get('auth.guards.'.$guard.'.provider'))) { throw new LogicException('The ['.$guard.'] guard is not defined in your "auth" configuration file.'); } From 83fe7559cfca3f33526e980ae392a7538b2b4388 Mon Sep 17 00:00:00 2001 From: Mior Muhammad Zaki Date: Mon, 18 Sep 2023 09:56:25 +0800 Subject: [PATCH 08/25] wip Signed-off-by: Mior Muhammad Zaki --- src/Commands/GeneratorCommand.php | 14 ++++++++++++++ 1 file changed, 14 insertions(+) diff --git a/src/Commands/GeneratorCommand.php b/src/Commands/GeneratorCommand.php index ce33776..5225a1c 100644 --- a/src/Commands/GeneratorCommand.php +++ b/src/Commands/GeneratorCommand.php @@ -15,6 +15,20 @@ abstract class GeneratorCommand extends \Illuminate\Console\GeneratorCommand imp use Concerns\CreatesUsingGeneratorPreset; use Concerns\TestGenerator; + + /** + * Create a new controller creator command instance. + * + * @param \Illuminate\Filesystem\Filesystem $files + * @return void + */ + public function __construct(Filesystem $files) + { + parent::__construct($files); + + $this->addGeneratorPresetOptions(); + } + /** * Execute the console command. * From 8b7d7eea535628c180ac2204dbe4ec2467c6ae11 Mon Sep 17 00:00:00 2001 From: Mior Muhammad Zaki Date: Mon, 18 Sep 2023 09:59:19 +0800 Subject: [PATCH 09/25] wip Signed-off-by: Mior Muhammad Zaki --- src/Commands/GeneratorCommand.php | 3 +-- 1 file changed, 1 insertion(+), 2 deletions(-) diff --git a/src/Commands/GeneratorCommand.php b/src/Commands/GeneratorCommand.php index 5225a1c..2cc411f 100644 --- a/src/Commands/GeneratorCommand.php +++ b/src/Commands/GeneratorCommand.php @@ -2,6 +2,7 @@ namespace Orchestra\Canvas\Core\Commands; +use Illuminate\Filesystem\Filesystem; use Orchestra\Canvas\Core\Concerns; use Orchestra\Canvas\Core\Contracts\GeneratesCode; @@ -15,11 +16,9 @@ abstract class GeneratorCommand extends \Illuminate\Console\GeneratorCommand imp use Concerns\CreatesUsingGeneratorPreset; use Concerns\TestGenerator; - /** * Create a new controller creator command instance. * - * @param \Illuminate\Filesystem\Filesystem $files * @return void */ public function __construct(Filesystem $files) From 7898d5fc73b76606c6c1949021ca29a6d2602851 Mon Sep 17 00:00:00 2001 From: Mior Muhammad Zaki Date: Mon, 18 Sep 2023 10:27:40 +0800 Subject: [PATCH 10/25] wip Signed-off-by: Mior Muhammad Zaki --- phpunit.xml | 24 +++++++++++----------- src/Commands/GeneratorCommand.php | 33 ------------------------------- src/Concerns/CodeGenerator.php | 27 +++++++++++++++++++++++-- src/Concerns/TestGenerator.php | 2 ++ 4 files changed, 39 insertions(+), 47 deletions(-) diff --git a/phpunit.xml b/phpunit.xml index 7c2f46a..09476a3 100644 --- a/phpunit.xml +++ b/phpunit.xml @@ -1,17 +1,17 @@ + xsi:noNamespaceSchemaLocation="https://schema.phpunit.de/9.3/phpunit.xsd" + backupGlobals="false" + backupStaticAttributes="false" + bootstrap="vendor/autoload.php" + colors="true" + convertDeprecationsToExceptions="true" + convertErrorsToExceptions="true" + convertNoticesToExceptions="true" + convertWarningsToExceptions="true" + processIsolation="false" + stopOnFailure="false" + verbose="true"> src/ diff --git a/src/Commands/GeneratorCommand.php b/src/Commands/GeneratorCommand.php index 2cc411f..9b2f329 100644 --- a/src/Commands/GeneratorCommand.php +++ b/src/Commands/GeneratorCommand.php @@ -37,39 +37,6 @@ public function __construct(Filesystem $files) */ public function handle() { - // First we need to ensure that the given name is not a reserved word within the PHP - // language and that the class name will actually be valid. If it is not valid we - // can error now and prevent from polluting the filesystem using invalid files. - if ($this->isReservedName($name = $this->getNameInput())) { - $this->components->error('The name "'.$name.'" is reserved by PHP.'); - - return false; - } - - $force = $this->hasOption('force') && $this->option('force') === true; - return $this->generateCode($force); } - - /** - * Build the class with the given name. - * - * @throws \Illuminate\Contracts\Filesystem\FileNotFoundException - */ - protected function buildClass($name) - { - $stub = $this->files->get($this->getStub()); - - return $this->generatingCode( - $this->replaceNamespace($stub, $name)->replaceClass($stub, $name), $name - ); - } - - /** - * Handle generating code. - */ - public function generatingCode(string $stub, string $className): string - { - return $stub; - } } diff --git a/src/Concerns/CodeGenerator.php b/src/Concerns/CodeGenerator.php index d416155..6b58eb8 100644 --- a/src/Concerns/CodeGenerator.php +++ b/src/Concerns/CodeGenerator.php @@ -6,17 +6,30 @@ trait CodeGenerator { + use CreatesUsingGeneratorPreset; + /** * Generate code. * * @return bool|null */ - public function generateCode(bool $force = false) + public function generateCode() { $name = $this->getNameInput(); + $force = $this->hasOption('force') && $this->option('force') === true; + $className = $this->qualifyClass($name); $path = $this->getPath($this->qualifyClass($name)); + // First we need to ensure that the given name is not a reserved word within the PHP + // language and that the class name will actually be valid. If it is not valid we + // can error now and prevent from polluting the filesystem using invalid files. + if ($this->isReservedName($name)) { + $this->components->error('The name "'.$name.'" is reserved by PHP.'); + + return false; + } + // Next, We will check to see if the class already exists. If it does, we don't want // to create the class and overwrite the user's code. So, we will bail out so the // code is untouched. Otherwise, we will continue generating this class' files. @@ -29,7 +42,9 @@ public function generateCode(bool $force = false) // stub files so that it gets the correctly formatted namespace and class name. $this->makeDirectory($path); - $this->files->put($path, $this->sortImports($this->buildClass($className))); + $this->files->put( + $path, $this->sortImports($this->generatingCode($this->buildClass($className), $className)) + ); return tap($this->codeHasBeenGenerated($className), function ($exitCode) use ($className, $path) { if (\in_array(CreatesMatchingTest::class, class_uses_recursive($this))) { @@ -40,6 +55,14 @@ public function generateCode(bool $force = false) }); } + /** + * Handle generating code. + */ + public function generatingCode(string $stub, string $className): string + { + return $stub; + } + /** * Code already exists. */ diff --git a/src/Concerns/TestGenerator.php b/src/Concerns/TestGenerator.php index f0247ee..5704281 100644 --- a/src/Concerns/TestGenerator.php +++ b/src/Concerns/TestGenerator.php @@ -6,6 +6,8 @@ trait TestGenerator { + use CreatesUsingGeneratorPreset; + /** * Create the matching test case if requested. */ From 02f3d9ecd1ecdb149ce2626aaca51a847ac4cc49 Mon Sep 17 00:00:00 2001 From: Mior Muhammad Zaki Date: Mon, 18 Sep 2023 10:33:54 +0800 Subject: [PATCH 11/25] wip Signed-off-by: Mior Muhammad Zaki --- src/Commands/GeneratorCommand.php | 3 +-- src/Concerns/CodeGenerator.php | 11 +++++------ 2 files changed, 6 insertions(+), 8 deletions(-) diff --git a/src/Commands/GeneratorCommand.php b/src/Commands/GeneratorCommand.php index 9b2f329..6fa7f94 100644 --- a/src/Commands/GeneratorCommand.php +++ b/src/Commands/GeneratorCommand.php @@ -13,7 +13,6 @@ abstract class GeneratorCommand extends \Illuminate\Console\GeneratorCommand implements GeneratesCode { use Concerns\CodeGenerator; - use Concerns\CreatesUsingGeneratorPreset; use Concerns\TestGenerator; /** @@ -37,6 +36,6 @@ public function __construct(Filesystem $files) */ public function handle() { - return $this->generateCode($force); + return $this->generateCode(); } } diff --git a/src/Concerns/CodeGenerator.php b/src/Concerns/CodeGenerator.php index 6b58eb8..ce01820 100644 --- a/src/Concerns/CodeGenerator.php +++ b/src/Concerns/CodeGenerator.php @@ -46,13 +46,12 @@ public function generateCode() $path, $this->sortImports($this->generatingCode($this->buildClass($className), $className)) ); - return tap($this->codeHasBeenGenerated($className), function ($exitCode) use ($className, $path) { - if (\in_array(CreatesMatchingTest::class, class_uses_recursive($this))) { - $this->handleTestCreationUsingCanvas($path); - } + if (\in_array(CreatesMatchingTest::class, class_uses_recursive($this))) { + $this->handleTestCreationUsingCanvas($path); + } - $this->afterCodeHasBeenGenerated($className, $path); - }); + $this->codeHasBeenGenerated($className); + $this->afterCodeHasBeenGenerated($className, $path); } /** From 93282d4b97fc7dff9b4bece377a9f7a8eff6ab2b Mon Sep 17 00:00:00 2001 From: Mior Muhammad Zaki Date: Mon, 18 Sep 2023 10:40:48 +0800 Subject: [PATCH 12/25] wip Signed-off-by: Mior Muhammad Zaki --- src/Commands/GeneratorCommand.php | 8 +++++++- 1 file changed, 7 insertions(+), 1 deletion(-) diff --git a/src/Commands/GeneratorCommand.php b/src/Commands/GeneratorCommand.php index 6fa7f94..26c461c 100644 --- a/src/Commands/GeneratorCommand.php +++ b/src/Commands/GeneratorCommand.php @@ -36,6 +36,12 @@ public function __construct(Filesystem $files) */ public function handle() { - return $this->generateCode(); + $status = $this->generateCode(); + + if (is_bool($status) && $status === false) { + return self::FAILURE; + } + + return self::SUCCESS; } } From 371515c63e3ebe0e99912e098093583469a7f58b Mon Sep 17 00:00:00 2001 From: Mior Muhammad Zaki Date: Mon, 18 Sep 2023 10:45:04 +0800 Subject: [PATCH 13/25] wip Signed-off-by: Mior Muhammad Zaki --- phpstan-baseline.neon | 5 +++++ src/Commands/GeneratorCommand.php | 8 +------- src/Concerns/CodeGenerator.php | 11 ++++++----- src/Contracts/GeneratesCode.php | 4 ++-- 4 files changed, 14 insertions(+), 14 deletions(-) diff --git a/phpstan-baseline.neon b/phpstan-baseline.neon index 0703a7f..55f9a9e 100644 --- a/phpstan-baseline.neon +++ b/phpstan-baseline.neon @@ -5,6 +5,11 @@ parameters: count: 1 path: src/Commands/GeneratorCommand.php + - + message: "#^Method Orchestra\\\\Canvas\\\\Core\\\\Commands\\\\GeneratorCommand\\:\\:handle\\(\\) should return bool\\|null but returns int\\.$#" + count: 1 + path: src/Commands/GeneratorCommand.php + - message: "#^Parameter \\#1 \\$app of class Orchestra\\\\Canvas\\\\Core\\\\Presets\\\\Laravel constructor expects Illuminate\\\\Contracts\\\\Foundation\\\\Application, Illuminate\\\\Contracts\\\\Container\\\\Container given\\.$#" count: 1 diff --git a/src/Commands/GeneratorCommand.php b/src/Commands/GeneratorCommand.php index 26c461c..c7588d4 100644 --- a/src/Commands/GeneratorCommand.php +++ b/src/Commands/GeneratorCommand.php @@ -36,12 +36,6 @@ public function __construct(Filesystem $files) */ public function handle() { - $status = $this->generateCode(); - - if (is_bool($status) && $status === false) { - return self::FAILURE; - } - - return self::SUCCESS; + return $this->generateCode() ? self::SUCCESS : self::FAILURE; } } diff --git a/src/Concerns/CodeGenerator.php b/src/Concerns/CodeGenerator.php index ce01820..6b31891 100644 --- a/src/Concerns/CodeGenerator.php +++ b/src/Concerns/CodeGenerator.php @@ -11,7 +11,7 @@ trait CodeGenerator /** * Generate code. * - * @return bool|null + * @return bool */ public function generateCode() { @@ -50,8 +50,9 @@ public function generateCode() $this->handleTestCreationUsingCanvas($path); } - $this->codeHasBeenGenerated($className); - $this->afterCodeHasBeenGenerated($className, $path); + return tap($this->codeHasBeenGenerated($className), function ($exitCode) use ($className, $path) { + $this->afterCodeHasBeenGenerated($className, $path); + }); } /** @@ -65,7 +66,7 @@ public function generatingCode(string $stub, string $className): string /** * Code already exists. */ - public function codeAlreadyExists(string $className): ?bool + public function codeAlreadyExists(string $className): bool { $this->components->error(sprintf('%s [%s] already exists!', $this->type, $className)); @@ -75,7 +76,7 @@ public function codeAlreadyExists(string $className): ?bool /** * Code successfully generated. */ - public function codeHasBeenGenerated(string $className): ?bool + public function codeHasBeenGenerated(string $className): bool { $this->components->info(sprintf('%s [%s] created successfully.', $this->type, $className)); diff --git a/src/Contracts/GeneratesCode.php b/src/Contracts/GeneratesCode.php index 0b17d96..692d665 100644 --- a/src/Contracts/GeneratesCode.php +++ b/src/Contracts/GeneratesCode.php @@ -7,7 +7,7 @@ interface GeneratesCode /** * Code already exists. */ - public function codeAlreadyExists(string $className): mixed; + public function codeAlreadyExists(string $className): bool; /** * Handle generating code. @@ -17,7 +17,7 @@ public function generatingCode(string $stub, string $className): string; /** * Code successfully generated. */ - public function codeHasBeenGenerated(string $className): mixed; + public function codeHasBeenGenerated(string $className): bool; /** * Run after code successfully generated. From afc0bb6ff752b81f58e0d03bbeb61fccb9fbae5a Mon Sep 17 00:00:00 2001 From: Mior Muhammad Zaki Date: Mon, 18 Sep 2023 11:46:36 +0800 Subject: [PATCH 14/25] wip Signed-off-by: Mior Muhammad Zaki --- src/Commands/GeneratorCommand.php | 46 +++++++++++++++++++++++++++++++ 1 file changed, 46 insertions(+) diff --git a/src/Commands/GeneratorCommand.php b/src/Commands/GeneratorCommand.php index c7588d4..780dea4 100644 --- a/src/Commands/GeneratorCommand.php +++ b/src/Commands/GeneratorCommand.php @@ -38,4 +38,50 @@ public function handle() { return $this->generateCode() ? self::SUCCESS : self::FAILURE; } + + /** + * Get the destination class path. + * + * @param string $name + * @return string + */ + protected function getPath($name) + { + $name = Str::replaceFirst($this->rootNamespace(), '', $name); + + return $this->generatorPreset()->sourcePath().'/'.str_replace('\\', '/', $name).'.php'; + } + + /** + * Get the root namespace for the class. + * + * @return string + */ + protected function rootNamespace() + { + return $this->generatorPreset()->rootNamespace(); + } + + /** + * Get the model for the default guard's user provider. + * + * @return string|null + */ + protected function userProviderModel() + { + return $this->generatorPreset()->userProviderModel(); + } + + /** + * Get the first view directory path from the application configuration. + * + * @param string $path + * @return string + */ + protected function viewPath($path = '') + { + $views = $this->generatorPreset()->viewPath(); + + return $views.($path ? DIRECTORY_SEPARATOR.$path : $path); + } } From 5b38f1944fe5ce3bd6070a1566c7c293d177c09c Mon Sep 17 00:00:00 2001 From: Mior Muhammad Zaki Date: Mon, 18 Sep 2023 11:47:57 +0800 Subject: [PATCH 15/25] wip Signed-off-by: Mior Muhammad Zaki --- src/Commands/GeneratorCommand.php | 46 ------------------------------- src/Concerns/CodeGenerator.php | 46 +++++++++++++++++++++++++++++++ 2 files changed, 46 insertions(+), 46 deletions(-) diff --git a/src/Commands/GeneratorCommand.php b/src/Commands/GeneratorCommand.php index 780dea4..c7588d4 100644 --- a/src/Commands/GeneratorCommand.php +++ b/src/Commands/GeneratorCommand.php @@ -38,50 +38,4 @@ public function handle() { return $this->generateCode() ? self::SUCCESS : self::FAILURE; } - - /** - * Get the destination class path. - * - * @param string $name - * @return string - */ - protected function getPath($name) - { - $name = Str::replaceFirst($this->rootNamespace(), '', $name); - - return $this->generatorPreset()->sourcePath().'/'.str_replace('\\', '/', $name).'.php'; - } - - /** - * Get the root namespace for the class. - * - * @return string - */ - protected function rootNamespace() - { - return $this->generatorPreset()->rootNamespace(); - } - - /** - * Get the model for the default guard's user provider. - * - * @return string|null - */ - protected function userProviderModel() - { - return $this->generatorPreset()->userProviderModel(); - } - - /** - * Get the first view directory path from the application configuration. - * - * @param string $path - * @return string - */ - protected function viewPath($path = '') - { - $views = $this->generatorPreset()->viewPath(); - - return $views.($path ? DIRECTORY_SEPARATOR.$path : $path); - } } diff --git a/src/Concerns/CodeGenerator.php b/src/Concerns/CodeGenerator.php index 6b31891..e1f18d8 100644 --- a/src/Concerns/CodeGenerator.php +++ b/src/Concerns/CodeGenerator.php @@ -90,4 +90,50 @@ public function afterCodeHasBeenGenerated(string $className, string $path): void { // } + + /** + * Get the destination class path. + * + * @param string $name + * @return string + */ + protected function getPath($name) + { + $name = Str::replaceFirst($this->rootNamespace(), '', $name); + + return $this->generatorPreset()->sourcePath().'/'.str_replace('\\', '/', $name).'.php'; + } + + /** + * Get the root namespace for the class. + * + * @return string + */ + protected function rootNamespace() + { + return $this->generatorPreset()->rootNamespace(); + } + + /** + * Get the model for the default guard's user provider. + * + * @return string|null + */ + protected function userProviderModel() + { + return $this->generatorPreset()->userProviderModel(); + } + + /** + * Get the first view directory path from the application configuration. + * + * @param string $path + * @return string + */ + protected function viewPath($path = '') + { + $views = $this->generatorPreset()->viewPath(); + + return $views.($path ? DIRECTORY_SEPARATOR.$path : $path); + } } From 08c51a8a43b291267c41464f8e704bd2881cdf38 Mon Sep 17 00:00:00 2001 From: Mior Muhammad Zaki Date: Mon, 18 Sep 2023 11:48:43 +0800 Subject: [PATCH 16/25] wip Signed-off-by: Mior Muhammad Zaki --- src/Concerns/CodeGenerator.php | 1 + 1 file changed, 1 insertion(+) diff --git a/src/Concerns/CodeGenerator.php b/src/Concerns/CodeGenerator.php index e1f18d8..4306fcc 100644 --- a/src/Concerns/CodeGenerator.php +++ b/src/Concerns/CodeGenerator.php @@ -3,6 +3,7 @@ namespace Orchestra\Canvas\Core\Concerns; use Illuminate\Console\Concerns\CreatesMatchingTest; +use Illuminate\Support\Str; trait CodeGenerator { From 347115fad8000ef040b015e676b22994bc511c26 Mon Sep 17 00:00:00 2001 From: Mior Muhammad Zaki Date: Mon, 18 Sep 2023 12:07:14 +0800 Subject: [PATCH 17/25] wip Signed-off-by: Mior Muhammad Zaki --- src/Commands/GeneratorCommand.php | 1 + src/Concerns/CodeGenerator.php | 7 ++- src/Concerns/CreatesUsingGeneratorPreset.php | 9 ++++ src/Concerns/UsesGeneratorOverrides.php | 52 ++++++++++++++++++++ 4 files changed, 68 insertions(+), 1 deletion(-) create mode 100644 src/Concerns/UsesGeneratorOverrides.php diff --git a/src/Commands/GeneratorCommand.php b/src/Commands/GeneratorCommand.php index c7588d4..68e336f 100644 --- a/src/Commands/GeneratorCommand.php +++ b/src/Commands/GeneratorCommand.php @@ -14,6 +14,7 @@ abstract class GeneratorCommand extends \Illuminate\Console\GeneratorCommand imp { use Concerns\CodeGenerator; use Concerns\TestGenerator; + use Concerns\UsesGeneratorOverrides; /** * Create a new controller creator command instance. diff --git a/src/Concerns/CodeGenerator.php b/src/Concerns/CodeGenerator.php index 4306fcc..83c8304 100644 --- a/src/Concerns/CodeGenerator.php +++ b/src/Concerns/CodeGenerator.php @@ -102,7 +102,12 @@ protected function getPath($name) { $name = Str::replaceFirst($this->rootNamespace(), '', $name); - return $this->generatorPreset()->sourcePath().'/'.str_replace('\\', '/', $name).'.php'; + return $this->getSourcePath().'/'.str_replace('\\', '/', $name).'.php'; + } + + protected function getSourcePath() + { + return $this->generatorPreset()->sourcePath(); } /** diff --git a/src/Concerns/CreatesUsingGeneratorPreset.php b/src/Concerns/CreatesUsingGeneratorPreset.php index df5bff4..630d4ca 100644 --- a/src/Concerns/CreatesUsingGeneratorPreset.php +++ b/src/Concerns/CreatesUsingGeneratorPreset.php @@ -33,4 +33,13 @@ protected function generatorPreset() { return $this->laravel->make(PresetManager::class)->driver($this->option('preset')); } + + + /** + * Get the generator preset source path. + */ + protected function getGeneratorSourcePath(): string + { + return $this->generatorPreset()->sourcePath(); + } } diff --git a/src/Concerns/UsesGeneratorOverrides.php b/src/Concerns/UsesGeneratorOverrides.php new file mode 100644 index 0000000..23e9301 --- /dev/null +++ b/src/Concerns/UsesGeneratorOverrides.php @@ -0,0 +1,52 @@ +rootNamespace(), '', $name); + + return $this->getGeneratorSourcePath().'/'.str_replace('\\', '/', $name).'.php'; + } + + /** + * Get the root namespace for the class. + * + * @return string + */ + protected function rootNamespace() + { + return $this->generatorPreset()->rootNamespace(); + } + + /** + * Get the model for the default guard's user provider. + * + * @return string|null + */ + protected function userProviderModel() + { + return $this->generatorPreset()->userProviderModel(); + } + + /** + * Get the first view directory path from the application configuration. + * + * @param string $path + * @return string + */ + protected function viewPath($path = '') + { + $views = $this->generatorPreset()->viewPath(); + + return $views.($path ? DIRECTORY_SEPARATOR.$path : $path); + } +} From 2f6b4e78121a67bbee72b8652654b5f6c6200a64 Mon Sep 17 00:00:00 2001 From: Mior Muhammad Zaki Date: Mon, 18 Sep 2023 12:13:23 +0800 Subject: [PATCH 18/25] wip Signed-off-by: Mior Muhammad Zaki --- src/Commands/GeneratorCommand.php | 43 +++++++++++++++++++++++++ src/Concerns/UsesGeneratorOverrides.php | 18 +++-------- 2 files changed, 47 insertions(+), 14 deletions(-) diff --git a/src/Commands/GeneratorCommand.php b/src/Commands/GeneratorCommand.php index 68e336f..a5e6a13 100644 --- a/src/Commands/GeneratorCommand.php +++ b/src/Commands/GeneratorCommand.php @@ -39,4 +39,47 @@ public function handle() { return $this->generateCode() ? self::SUCCESS : self::FAILURE; } + + + /** + * Get the destination class path. + * + * @param string $name + * @return string + */ + protected function getPath($name) + { + return $this->getPathUsingCanvas($name); + } + + /** + * Get the root namespace for the class. + * + * @return string + */ + protected function rootNamespace() + { + return $this->rootNamespaceUsingCanvas(); + } + + /** + * Get the model for the default guard's user provider. + * + * @return string|null + */ + protected function userProviderModel(): ?string + { + return $this->userProviderModelUsingCanvas(); + } + + /** + * Get the first view directory path from the application configuration. + * + * @param string $name + * @return string + */ + protected function viewPath($path = '') + { + return $this->viewPathUsingCanvas($path); + } } diff --git a/src/Concerns/UsesGeneratorOverrides.php b/src/Concerns/UsesGeneratorOverrides.php index 23e9301..5f0335b 100644 --- a/src/Concerns/UsesGeneratorOverrides.php +++ b/src/Concerns/UsesGeneratorOverrides.php @@ -6,11 +6,8 @@ trait UsesGeneratorOverrides { /** * Get the destination class path. - * - * @param string $name - * @return string */ - protected function getPath($name) + protected function getPathUsingCanvas(string $name): string { $name = Str::replaceFirst($this->rootNamespace(), '', $name); @@ -19,31 +16,24 @@ protected function getPath($name) /** * Get the root namespace for the class. - * - * @return string */ - protected function rootNamespace() + protected function rootNamespaceUsingCanvas(): string { return $this->generatorPreset()->rootNamespace(); } /** * Get the model for the default guard's user provider. - * - * @return string|null */ - protected function userProviderModel() + protected function userProviderModelUsingCanvas(): ?string { return $this->generatorPreset()->userProviderModel(); } /** * Get the first view directory path from the application configuration. - * - * @param string $path - * @return string */ - protected function viewPath($path = '') + protected function viewPathUsingCanvas(string $path = ''): string { $views = $this->generatorPreset()->viewPath(); From bfa837fd3a0c6bcb388160e4ac952f5178469506 Mon Sep 17 00:00:00 2001 From: Mior Muhammad Zaki Date: Mon, 18 Sep 2023 12:14:13 +0800 Subject: [PATCH 19/25] wip Signed-off-by: Mior Muhammad Zaki --- src/Concerns/CodeGenerator.php | 51 ---------------------------------- 1 file changed, 51 deletions(-) diff --git a/src/Concerns/CodeGenerator.php b/src/Concerns/CodeGenerator.php index 83c8304..f27dc8d 100644 --- a/src/Concerns/CodeGenerator.php +++ b/src/Concerns/CodeGenerator.php @@ -91,55 +91,4 @@ public function afterCodeHasBeenGenerated(string $className, string $path): void { // } - - /** - * Get the destination class path. - * - * @param string $name - * @return string - */ - protected function getPath($name) - { - $name = Str::replaceFirst($this->rootNamespace(), '', $name); - - return $this->getSourcePath().'/'.str_replace('\\', '/', $name).'.php'; - } - - protected function getSourcePath() - { - return $this->generatorPreset()->sourcePath(); - } - - /** - * Get the root namespace for the class. - * - * @return string - */ - protected function rootNamespace() - { - return $this->generatorPreset()->rootNamespace(); - } - - /** - * Get the model for the default guard's user provider. - * - * @return string|null - */ - protected function userProviderModel() - { - return $this->generatorPreset()->userProviderModel(); - } - - /** - * Get the first view directory path from the application configuration. - * - * @param string $path - * @return string - */ - protected function viewPath($path = '') - { - $views = $this->generatorPreset()->viewPath(); - - return $views.($path ? DIRECTORY_SEPARATOR.$path : $path); - } } From 1f9d6a68fdb569a9b6bc679602f04fdf17ad17e7 Mon Sep 17 00:00:00 2001 From: Mior Muhammad Zaki Date: Mon, 18 Sep 2023 12:16:15 +0800 Subject: [PATCH 20/25] wip Signed-off-by: Mior Muhammad Zaki --- src/Commands/GeneratorCommand.php | 4 ---- src/Concerns/CodeGenerator.php | 1 - src/Concerns/CreatesUsingGeneratorPreset.php | 1 - 3 files changed, 6 deletions(-) diff --git a/src/Commands/GeneratorCommand.php b/src/Commands/GeneratorCommand.php index a5e6a13..6d5bf04 100644 --- a/src/Commands/GeneratorCommand.php +++ b/src/Commands/GeneratorCommand.php @@ -40,7 +40,6 @@ public function handle() return $this->generateCode() ? self::SUCCESS : self::FAILURE; } - /** * Get the destination class path. * @@ -64,8 +63,6 @@ protected function rootNamespace() /** * Get the model for the default guard's user provider. - * - * @return string|null */ protected function userProviderModel(): ?string { @@ -75,7 +72,6 @@ protected function userProviderModel(): ?string /** * Get the first view directory path from the application configuration. * - * @param string $name * @return string */ protected function viewPath($path = '') diff --git a/src/Concerns/CodeGenerator.php b/src/Concerns/CodeGenerator.php index f27dc8d..6b31891 100644 --- a/src/Concerns/CodeGenerator.php +++ b/src/Concerns/CodeGenerator.php @@ -3,7 +3,6 @@ namespace Orchestra\Canvas\Core\Concerns; use Illuminate\Console\Concerns\CreatesMatchingTest; -use Illuminate\Support\Str; trait CodeGenerator { diff --git a/src/Concerns/CreatesUsingGeneratorPreset.php b/src/Concerns/CreatesUsingGeneratorPreset.php index 630d4ca..436ef0a 100644 --- a/src/Concerns/CreatesUsingGeneratorPreset.php +++ b/src/Concerns/CreatesUsingGeneratorPreset.php @@ -34,7 +34,6 @@ protected function generatorPreset() return $this->laravel->make(PresetManager::class)->driver($this->option('preset')); } - /** * Get the generator preset source path. */ From a7793d96e757a966949286e4738e3b87c50893af Mon Sep 17 00:00:00 2001 From: Mior Muhammad Zaki Date: Mon, 18 Sep 2023 12:17:39 +0800 Subject: [PATCH 21/25] wip Signed-off-by: Mior Muhammad Zaki --- src/Concerns/UsesGeneratorOverrides.php | 10 ++++++---- 1 file changed, 6 insertions(+), 4 deletions(-) diff --git a/src/Concerns/UsesGeneratorOverrides.php b/src/Concerns/UsesGeneratorOverrides.php index 5f0335b..3f7674e 100644 --- a/src/Concerns/UsesGeneratorOverrides.php +++ b/src/Concerns/UsesGeneratorOverrides.php @@ -2,12 +2,14 @@ namespace Orchestra\Canvas\Core\Concerns; +use Illuminate\Support\Str; + trait UsesGeneratorOverrides { /** * Get the destination class path. */ - protected function getPathUsingCanvas(string $name): string + protected function getPath(string $name): string { $name = Str::replaceFirst($this->rootNamespace(), '', $name); @@ -17,7 +19,7 @@ protected function getPathUsingCanvas(string $name): string /** * Get the root namespace for the class. */ - protected function rootNamespaceUsingCanvas(): string + protected function rootNamespace(): string { return $this->generatorPreset()->rootNamespace(); } @@ -25,7 +27,7 @@ protected function rootNamespaceUsingCanvas(): string /** * Get the model for the default guard's user provider. */ - protected function userProviderModelUsingCanvas(): ?string + protected function userProviderModel(): ?string { return $this->generatorPreset()->userProviderModel(); } @@ -33,7 +35,7 @@ protected function userProviderModelUsingCanvas(): ?string /** * Get the first view directory path from the application configuration. */ - protected function viewPathUsingCanvas(string $path = ''): string + protected function viewPath(string $path = ''): string { $views = $this->generatorPreset()->viewPath(); From 2607694aae97c6d697d43ce5ba40f7276ad1ebbc Mon Sep 17 00:00:00 2001 From: Mior Muhammad Zaki Date: Mon, 18 Sep 2023 12:21:14 +0800 Subject: [PATCH 22/25] wip Signed-off-by: Mior Muhammad Zaki --- src/Concerns/UsesGeneratorOverrides.php | 8 ++++---- 1 file changed, 4 insertions(+), 4 deletions(-) diff --git a/src/Concerns/UsesGeneratorOverrides.php b/src/Concerns/UsesGeneratorOverrides.php index 3f7674e..14333f7 100644 --- a/src/Concerns/UsesGeneratorOverrides.php +++ b/src/Concerns/UsesGeneratorOverrides.php @@ -9,7 +9,7 @@ trait UsesGeneratorOverrides /** * Get the destination class path. */ - protected function getPath(string $name): string + protected function getPathUsingCanvas(string $name): string { $name = Str::replaceFirst($this->rootNamespace(), '', $name); @@ -19,7 +19,7 @@ protected function getPath(string $name): string /** * Get the root namespace for the class. */ - protected function rootNamespace(): string + protected function rootNamespacUsingCanvas(): string { return $this->generatorPreset()->rootNamespace(); } @@ -27,7 +27,7 @@ protected function rootNamespace(): string /** * Get the model for the default guard's user provider. */ - protected function userProviderModel(): ?string + protected function userProviderModelUsingCanvas(): ?string { return $this->generatorPreset()->userProviderModel(); } @@ -35,7 +35,7 @@ protected function userProviderModel(): ?string /** * Get the first view directory path from the application configuration. */ - protected function viewPath(string $path = ''): string + protected function viewPathUsingCanvas(string $path = ''): string { $views = $this->generatorPreset()->viewPath(); From 91935297eb4fcb9d62ee3a6845df2e2876974697 Mon Sep 17 00:00:00 2001 From: Mior Muhammad Zaki Date: Mon, 18 Sep 2023 12:21:35 +0800 Subject: [PATCH 23/25] wip Signed-off-by: Mior Muhammad Zaki --- src/Concerns/UsesGeneratorOverrides.php | 2 +- 1 file changed, 1 insertion(+), 1 deletion(-) diff --git a/src/Concerns/UsesGeneratorOverrides.php b/src/Concerns/UsesGeneratorOverrides.php index 14333f7..7ac2984 100644 --- a/src/Concerns/UsesGeneratorOverrides.php +++ b/src/Concerns/UsesGeneratorOverrides.php @@ -19,7 +19,7 @@ protected function getPathUsingCanvas(string $name): string /** * Get the root namespace for the class. */ - protected function rootNamespacUsingCanvas(): string + protected function rootNamespaceUsingCanvas(): string { return $this->generatorPreset()->rootNamespace(); } From 00588071a9dec42ec224270001cf4f2f00bebd4b Mon Sep 17 00:00:00 2001 From: Mior Muhammad Zaki Date: Mon, 18 Sep 2023 15:42:21 +0800 Subject: [PATCH 24/25] wip Signed-off-by: Mior Muhammad Zaki --- src/Concerns/UsesGeneratorOverrides.php | 4 ++-- 1 file changed, 2 insertions(+), 2 deletions(-) diff --git a/src/Concerns/UsesGeneratorOverrides.php b/src/Concerns/UsesGeneratorOverrides.php index 7ac2984..6c77f81 100644 --- a/src/Concerns/UsesGeneratorOverrides.php +++ b/src/Concerns/UsesGeneratorOverrides.php @@ -27,9 +27,9 @@ protected function rootNamespaceUsingCanvas(): string /** * Get the model for the default guard's user provider. */ - protected function userProviderModelUsingCanvas(): ?string + protected function userProviderModelUsingCanvas(?string $guard = null): ?string { - return $this->generatorPreset()->userProviderModel(); + return $this->generatorPreset()->userProviderModel($guard); } /** From 0c2aae465548c389fbaebd0dfdde7d042c340160 Mon Sep 17 00:00:00 2001 From: Mior Muhammad Zaki Date: Mon, 18 Sep 2023 15:56:05 +0800 Subject: [PATCH 25/25] wip Signed-off-by: Mior Muhammad Zaki --- src/Commands/GeneratorCommand.php | 10 ++++++++++ src/Concerns/UsesGeneratorOverrides.php | 16 ++++++++++++++++ 2 files changed, 26 insertions(+) diff --git a/src/Commands/GeneratorCommand.php b/src/Commands/GeneratorCommand.php index 6d5bf04..09f1229 100644 --- a/src/Commands/GeneratorCommand.php +++ b/src/Commands/GeneratorCommand.php @@ -51,6 +51,16 @@ protected function getPath($name) return $this->getPathUsingCanvas($name); } + /** + * Qualify the given model class base name. + * + * @return string + */ + protected function qualifyModel(string $model) + { + return $this->qualifyModelUsingCanvas($model); + } + /** * Get the root namespace for the class. * diff --git a/src/Concerns/UsesGeneratorOverrides.php b/src/Concerns/UsesGeneratorOverrides.php index 6c77f81..38d4486 100644 --- a/src/Concerns/UsesGeneratorOverrides.php +++ b/src/Concerns/UsesGeneratorOverrides.php @@ -6,6 +6,22 @@ trait UsesGeneratorOverrides { + /** + * Qualify the given model class base name. + */ + protected function qualifyModelUsingCanvas(string $model): string + { + $model = ltrim($model, '\\/'); + + $model = str_replace('/', '\\', $model); + + if (Str::startsWith($model, $this->rootNamespace())) { + return $model; + } + + return $this->generatorPreset()->modelNamespace().$model; + } + /** * Get the destination class path. */