diff --git a/composer.json b/composer.json index a21870b..0bc5fa6 100644 --- a/composer.json +++ b/composer.json @@ -51,10 +51,10 @@ }, "require-dev": { "laravel/pint": "^1.2", - "pestphp/pest": "^1.22", - "pestphp/pest-plugin-laravel": "^1.3", + "pestphp/pest": "^2.21", + "pestphp/pest-plugin-laravel": "^2.2", "orchestra/testbench": "^7.14|^8.0", - "phpstan/phpstan": "^1.9" + "phpstan/phpstan": "^1.10" }, "config": { "allow-plugins": { diff --git a/config/diamond.php b/config/diamond.php index 7ae44db..16ba6b4 100644 --- a/config/diamond.php +++ b/config/diamond.php @@ -27,6 +27,6 @@ 'structures' => [ Layer::infrastructure->name => 'Infrastructure', Layer::domain->name => 'Domain', - Layer::application->name => 'app', + Layer::application->name => 'Application', ], ]; diff --git a/src/Actions/Command/ResolveCommandAction.php b/src/Actions/Command/ResolveCommandAction.php index b42f2c9..91db521 100644 --- a/src/Actions/Command/ResolveCommandAction.php +++ b/src/Actions/Command/ResolveCommandAction.php @@ -16,7 +16,7 @@ { public function __construct( protected Console $console, - protected Closure | null $copyStubData = null, + protected ?Closure $copyStubData = null, ) { } diff --git a/src/Actions/Composer/ResolveComposerAutoLoaderAction.php b/src/Actions/Composer/ResolveComposerAutoLoaderAction.php index 2ce8643..8821af2 100644 --- a/src/Actions/Composer/ResolveComposerAutoLoaderAction.php +++ b/src/Actions/Composer/ResolveComposerAutoLoaderAction.php @@ -25,28 +25,22 @@ public function __construct(protected Filesystem $fileSystem) * @throws UnableToWriteFile * @throws Throwable */ - public function execute(): bool + public function execute(string $domain): bool { /** @var string $baseDirectory */ $baseDirectory = config(key: 'diamond.base_directory'); $composer = $this->fetchComposerContents(); - foreach ($this->resolveBaseStructures() as $structure) { - $namespace = Str::of(string: $structure)->finish(cap: '\\'); - $directory = $namespace->replace(search: '\\', replace: '/'); + $namespace = Str::of(string: $domain)->finish(cap: '\\'); + $directory = $namespace->replace(search: '\\', replace: '/'); - if (Arr::exists(array: $composer->autoload['psr-4'], key: $namespace->toString())) { - continue; - } - - Arr::set( - array: $composer->autoload['psr-4'], - key: $namespace->toString(), - value: $directory - ->start(prefix: $baseDirectory) - ->toString() - ); - } + Arr::set( + array: $composer->autoload['psr-4'], + key: $namespace->toString(), + value: $directory + ->start(prefix: $baseDirectory) + ->toString() + ); return $this->updateComposerContents(contents: $composer); } @@ -97,15 +91,4 @@ protected function resolveBasePathForComposer(): string { return base_path(path: 'composer.json'); } - - /** - * @return array - */ - protected function resolveBaseStructures(): array - { - /** @var array $structures */ - $structures = config(key: 'diamond.structures'); - - return $structures; - } } diff --git a/src/Actions/Stub/ReplacePlaceholderAction.php b/src/Actions/Stub/ReplacePlaceholderAction.php index 9b0dc6f..615bec2 100644 --- a/src/Actions/Stub/ReplacePlaceholderAction.php +++ b/src/Actions/Stub/ReplacePlaceholderAction.php @@ -47,6 +47,7 @@ function ($value, $key) use (&$stub) { } ); + /** @var string $contents */ $contents = $stub; $filesystem->ensureDirectoryExists(path: Str::of($filePath)->beforeLast(search: '/')); diff --git a/src/Commands/Application/ResourceMakeCommand.php b/src/Commands/Application/ResourceMakeCommand.php index deb819d..111ba86 100644 --- a/src/Commands/Application/ResourceMakeCommand.php +++ b/src/Commands/Application/ResourceMakeCommand.php @@ -62,7 +62,7 @@ class: $this->getClassName(), ); } - public function resolveModelNamespace(): string | null + public function resolveModelNamespace(): ?string { if ($this->resolveModelOption()) { $namespace = Source::resolveNamespace( diff --git a/src/Commands/Concerns/HasOptions.php b/src/Commands/Concerns/HasOptions.php index 45f6f56..eb8f031 100644 --- a/src/Commands/Concerns/HasOptions.php +++ b/src/Commands/Concerns/HasOptions.php @@ -19,7 +19,7 @@ protected function resolveFactoryOption(): bool return (bool) $this->option(key: 'factory'); } - protected function resolveTableName(): string | null + protected function resolveTableName(): ?string { /** @var string|null $name */ $name = $this->option(key: 'create') ?: $this->option(key: 'table'); @@ -27,7 +27,7 @@ protected function resolveTableName(): string | null return $name; } - public function resolveEventOption(): string | null + public function resolveEventOption(): ?string { /** @var string|null $name */ $name = $this->option(key: 'event'); @@ -35,7 +35,7 @@ public function resolveEventOption(): string | null return $name; } - public function resolveModelOption(): string | null + public function resolveModelOption(): ?string { /** @var string|null $name */ $name = $this->option(key: 'model'); @@ -43,7 +43,7 @@ public function resolveModelOption(): string | null return $name; } - public function resolveRenderOption(): string | null + public function resolveRenderOption(): ?string { /** @var string|null $name */ $name = $this->option(key: 'render'); diff --git a/src/Commands/Domain/BuilderMakeCommand.php b/src/Commands/Domain/BuilderMakeCommand.php index 4b27903..8bda5b9 100644 --- a/src/Commands/Domain/BuilderMakeCommand.php +++ b/src/Commands/Domain/BuilderMakeCommand.php @@ -62,7 +62,7 @@ class: $this->getClassName(), ); } - public function resolveModelNamespace(): string | null + public function resolveModelNamespace(): ?string { if ($this->resolveModelOption()) { $namespace = Source::resolveNamespace( diff --git a/src/Commands/Infrastructure/FactoryMakeCommand.php b/src/Commands/Infrastructure/FactoryMakeCommand.php index 76b8ea5..ab1be7e 100644 --- a/src/Commands/Infrastructure/FactoryMakeCommand.php +++ b/src/Commands/Infrastructure/FactoryMakeCommand.php @@ -17,7 +17,7 @@ class FactoryMakeCommand extends Command implements Console { - use InteractsWithConsole, HasOptions, HasArguments; + use HasArguments, HasOptions, InteractsWithConsole; protected $signature = 'infrastructure:make:factory {name} {domain} {--model=} {--force}'; @@ -60,7 +60,7 @@ class: $this->resolveNameArgument(), ); } - protected function getModelNamespace(): string | null + protected function getModelNamespace(): ?string { return Source::resolveNamespace( data: new NamespaceData( diff --git a/src/Commands/InstallCommand.php b/src/Commands/InstallCommand.php index 114eaa5..d5d824c 100644 --- a/src/Commands/InstallCommand.php +++ b/src/Commands/InstallCommand.php @@ -5,16 +5,18 @@ use Illuminate\Console\Command; use Illuminate\Contracts\Filesystem\FileNotFoundException; use Illuminate\Filesystem\Filesystem; -use Illuminate\Support\Arr; -use Illuminate\Support\Str; +// use Illuminate\Support\Str; use KoalaFacade\DiamondConsole\Actions\Composer\ResolveComposerAutoLoaderAction; +use KoalaFacade\DiamondConsole\Commands\Concerns\HasArguments; use KoalaFacade\DiamondConsole\Enums\Layer; use KoalaFacade\DiamondConsole\Support\Source; use Throwable; class InstallCommand extends Command { - protected $signature = 'diamond:install {--skip-refactor}'; + use HasArguments; + + protected $signature = 'domain:install {domain}'; protected $description = 'Install the Domain Driven Structure in your project'; @@ -30,8 +32,10 @@ public function handle(): void $fileSystem->ensureDirectoryExists(path: $this->resolveBaseDirectoryPath()); + $domainName = $this->resolveDomainArgument(); + foreach ($this->resolveBaseStructures() as $structure) { - $path = $this->resolveBaseDirectoryPath() . $structure; + $path = $this->resolveBaseDirectoryPath() . $domainName . '/' . $structure; if ($fileSystem->exists(path: $path)) { $this->line(string: 'Skipping generate ' . $structure . ' , the base directory is exists'); @@ -39,12 +43,12 @@ public function handle(): void continue; } - $fileSystem->makeDirectory(path: $path); + $fileSystem->ensureDirectoryExists(path: $path); } - ResolveComposerAutoLoaderAction::resolve()->execute(); + ResolveComposerAutoLoaderAction::resolve()->execute($domainName); - $this->resolveRefactor(); + // $this->resolveRefactor(); $this->info(string: 'Successfully generate base file'); } @@ -62,43 +66,47 @@ protected function resolveBaseStructures(): array /** @var array $structures */ $structures = config(key: 'diamond.structures'); - return Arr::except(array: $structures, keys: Layer::application->name); + return $structures; } protected function resolveInfrastructurePath(): string { - return Layer::infrastructure->resolvePath(suffix: '/Laravel/Providers'); + return Layer::infrastructure->resolvePath(prefix: $this->resolveDomainArgument(), suffix: '/Laravel/Providers'); } protected function resolveNamespace(): string { - return Layer::infrastructure->resolveNamespace(suffix: '\\Laravel\\Providers'); + return Layer::infrastructure->resolveNamespace(prefix: $this->resolveDomainArgument() . '\\', suffix: '\\Laravel\\Providers'); } - protected function resolveRefactor(): void - { - if (! $this->option('skip-refactor')) { - $filesystem = new Filesystem; - $filesystem->ensureDirectoryExists($this->resolveInfrastructurePath()); - $filesystem->moveDirectory(from: app_path(path: 'Providers'), to: $this->resolveInfrastructurePath()); - $configPath = base_path(path: '/config/app.php'); - $contents = Str::replace( - search: 'App\\Providers', - replace: $this->resolveNamespace(), - subject: $filesystem->get($configPath) - ); - - $filesystem->put(path: $configPath, contents: $contents); - - foreach ($filesystem->files($this->resolveInfrastructurePath()) as $file) { - $contents = Str::replace( - search: 'App\\Providers', - replace: $this->resolveNamespace(), - subject: $filesystem->get($file) - ); - - $filesystem->put(path: $file, contents: $contents); - } - } - } + // disable auto refactor app path for now, because we need further planning + // + // protected function resolveRefactor(): void + // { + // if (! $this->option('skip-refactor')) { + // $filesystem = new Filesystem; + // $filesystem->ensureDirectoryExists($this->resolveInfrastructurePath()); + // $filesystem->moveDirectory(from: app_path(path: 'Providers'), to: $this->resolveInfrastructurePath()); + // $configPath = base_path(path: '/config/app.php'); + // /** @var string $contents */ + // $contents = Str::replace( + // search: 'App\\Providers', + // replace: $this->resolveNamespace(), + // subject: $filesystem->get($configPath) + // ); + // + // $filesystem->put(path: $configPath, contents: $contents); + // + // foreach ($filesystem->files($this->resolveInfrastructurePath()) as $file) { + // /** @var string $contents */ + // $contents = Str::replace( + // search: 'App\\Providers', + // replace: $this->resolveNamespace(), + // subject: $filesystem->get($file) + // ); + // + // $filesystem->put(path: $file, contents: $contents); + // } + // } + // } } diff --git a/src/Contracts/Console.php b/src/Contracts/Console.php index 72b3f44..c742cce 100644 --- a/src/Contracts/Console.php +++ b/src/Contracts/Console.php @@ -2,7 +2,7 @@ namespace KoalaFacade\DiamondConsole\Contracts; -interface Console extends Options, Placeholders, Arguments, LifeCycle +interface Console extends Arguments, LifeCycle, Options, Placeholders { public function getFullPath(): string; diff --git a/src/DataTransferObjects/NamespaceData.php b/src/DataTransferObjects/NamespaceData.php index ce8772e..02840bc 100644 --- a/src/DataTransferObjects/NamespaceData.php +++ b/src/DataTransferObjects/NamespaceData.php @@ -10,7 +10,7 @@ public function __construct( public string $structures, public string $domainArgument, public string $nameArgument, - public string | null $endsWith = null + public ?string $endsWith = null ) { } } diff --git a/src/DataTransferObjects/PlaceholderData.php b/src/DataTransferObjects/PlaceholderData.php index ffabfb2..5417654 100644 --- a/src/DataTransferObjects/PlaceholderData.php +++ b/src/DataTransferObjects/PlaceholderData.php @@ -8,17 +8,17 @@ readonly class PlaceholderData extends DataTransferObject { final public function __construct( - public null | string $namespace = null, - public null | string $class = null, - public null | string $subject = null, - public null | string $tableName = null, - public null | string $factoryContract = null, - public null | string $factoryContractNamespace = null, - public null | string $factoryContractAlias = null, - public null | string $event = null, - public null | string $eventNamespace = null, - public null | string $model = null, - public null | string $modelNamespace = null, + public ?string $namespace = null, + public ?string $class = null, + public ?string $subject = null, + public ?string $tableName = null, + public ?string $factoryContract = null, + public ?string $factoryContractNamespace = null, + public ?string $factoryContractAlias = null, + public ?string $event = null, + public ?string $eventNamespace = null, + public ?string $model = null, + public ?string $modelNamespace = null, ) { } diff --git a/src/DiamondConsoleServiceProvider.php b/src/DiamondConsoleServiceProvider.php index 4e08f79..b99a124 100644 --- a/src/DiamondConsoleServiceProvider.php +++ b/src/DiamondConsoleServiceProvider.php @@ -57,7 +57,7 @@ public function diamondCommands(): array return Arr::flatten(array: array_merge($generalCommands, $domainDrivenCommands)); } - protected function resolveCommandNamespace(SplFileInfo $file, string | null $directory = null): string + protected function resolveCommandNamespace(SplFileInfo $file, string $directory = null): string { return Str::of(string: $file->getFilenameWithoutExtension()) ->prepend(values: $directory ? "$directory\\" : '') diff --git a/src/Enums/Layer.php b/src/Enums/Layer.php index d60e35f..6af3ed4 100644 --- a/src/Enums/Layer.php +++ b/src/Enums/Layer.php @@ -10,15 +10,15 @@ enum Layer case infrastructure; - public function resolveNamespace(string $suffix = ''): string + public function resolveNamespace(string $prefix = '', string $suffix = ''): string { $key = $this->name; - return config(key: 'diamond.structures.' . $key) . $suffix; + return $prefix . config(key: 'diamond.structures.' . $key) . $suffix; } - public function resolvePath(string $suffix): string + public function resolvePath(string $prefix, string $suffix): string { - return base_path() . '/' . config(key: 'diamond.base_directory') . $this->resolveNamespace(suffix: $suffix); + return base_path() . '/' . config(key: 'diamond.base_directory') . $prefix . '/' . $this->resolveNamespace(suffix: $suffix); } } diff --git a/src/Foundation/DataTransferObject.php b/src/Foundation/DataTransferObject.php index b05ccf3..d39f26e 100644 --- a/src/Foundation/DataTransferObject.php +++ b/src/Foundation/DataTransferObject.php @@ -10,9 +10,9 @@ abstract readonly class DataTransferObject { + use Cloneable; use HasResolvable; use Tappable; - use Cloneable; /** * Prevent properties to included on create diff --git a/src/Support/Source.php b/src/Support/Source.php index d5b9ad0..2849321 100644 --- a/src/Support/Source.php +++ b/src/Support/Source.php @@ -41,7 +41,8 @@ public static function resolveApplicationPath(): string public static function resolveNamespace(NamespaceData $data): string { - return Str::replace( + /** @var string $result */ + $result = Str::replace( search: '/', replace: '\\', subject: static::resolveNamespaceDir( @@ -52,6 +53,8 @@ public static function resolveNamespace(NamespaceData $data): string ->finish(cap: $data->endsWith ? '/' . $data->endsWith : '') ) ); + + return $result; } public static function resolveNamespaceDir(NamespaceData $data, string $namespace): string @@ -72,11 +75,14 @@ public static function resolveNamespacePath(string $namespace): string public static function transformNamespaceToPath(string $namespace): string { - return Str::replace( + /** @var string $result */ + $result = Str::replace( search: '\\', replace: '/', subject: $namespace ); + + return $result; } public static function resolveNameFromPHP(string $name): string @@ -86,11 +92,17 @@ public static function resolveNameFromPHP(string $name): string public static function resolveNameFromFile(string $name, string $suffix): string { - return Str::replace(search: Str::start($suffix, prefix: '.'), replace: '', subject: $name); + /** @var string $result */ + $result = Str::replace(search: Str::start($suffix, prefix: '.'), replace: '', subject: $name); + + return $result; } public static function resolveStubForPath(string $name): string { - return Str::replace(search: ':name', replace: $name, subject: __DIR__ . '/../../stubs/:name.stub'); + /** @var string $result */ + $result = Str::replace(search: ':name', replace: $name, subject: __DIR__ . '/../../stubs/:name.stub'); + + return $result; } } diff --git a/tests/Feature/Commands/InstallBaseStructureCommandTest.php b/tests/Feature/Commands/InstallBaseStructureCommandTest.php index 5d1c696..3511e3b 100644 --- a/tests/Feature/Commands/InstallBaseStructureCommandTest.php +++ b/tests/Feature/Commands/InstallBaseStructureCommandTest.php @@ -1,8 +1,6 @@ name); + $baseStructures = config(key: 'diamond.structures'); $this->assertFalse(condition: file_exists($baseDirectoryPath)); @@ -26,38 +25,39 @@ $this->assertFalse(condition: file_exists($baseDirectoryPath . $structure)); } - Artisan::call(command: 'diamond:install'); + Artisan::call(command: 'domain:install ' . $domain); $this->assertTrue(condition: file_exists($baseDirectoryPath)); - $this->assertTrue(condition: file_exists($baseDirectoryPath . '/' . config(key: 'diamond.structures.infrastructure') . '/Laravel/Providers')); - - $this->assertFalse(condition: file_exists(app_path('Providers'))); + // $this->assertTrue(condition: file_exists($baseDirectoryPath . $domain . '/' . config('diamond.structures.infrastructure') . '/Laravel/Providers')); + // + // $this->assertFalse(condition: file_exists(app_path('Providers'))); foreach ($baseStructures as $structure) { - $this->assertTrue(condition: file_exists($baseDirectoryPath . $structure)); + $this->assertTrue(condition: file_exists($baseDirectoryPath . $domain . '/' . $structure)); } } )->group('commands'); -it( - description: 'can generate base structure with skip refactor', - closure: function () { - $baseDirectoryPath = base_path(path: config(key: 'diamond.base_directory')); - $baseStructures = Arr::except(array: config(key: 'diamond.structures'), keys: Layer::application->name); - - $this->assertFalse(condition: file_exists($baseDirectoryPath)); - - foreach ($baseStructures as $structure) { - $this->assertFalse(condition: file_exists($baseDirectoryPath . $structure)); - } - - Artisan::call(command: 'diamond:install --skip-refactor'); - - $this->assertTrue(condition: file_exists($baseDirectoryPath)); - - foreach ($baseStructures as $structure) { - $this->assertTrue(condition: file_exists($baseDirectoryPath . $structure)); - } - } -)->group('commands'); +// it( +// description: 'can generate base structure with skip refactor', +// closure: function () { +// $domain = 'MyApp'; +// $baseDirectoryPath = base_path(path: config(key: 'diamond.base_directory')); +// $baseStructures = config(key: 'diamond.structures'); +// +// $this->assertFalse(condition: file_exists($baseDirectoryPath)); +// +// foreach ($baseStructures as $structure) { +// $this->assertFalse(condition: file_exists($baseDirectoryPath . $structure)); +// } +// +// Artisan::call(command: 'domain:install ' . $domain . ' --skip-refactor'); +// +// $this->assertTrue(condition: file_exists($baseDirectoryPath)); +// +// foreach ($baseStructures as $structure) { +// $this->assertTrue(condition: file_exists($baseDirectoryPath . $domain . '/' . $structure)); +// } +// } +// )->group('commands'); diff --git a/tests/Pest.php b/tests/Pest.php index a9ffb06..dedb633 100644 --- a/tests/Pest.php +++ b/tests/Pest.php @@ -88,14 +88,14 @@ function applicationPath(): string return resolvePathForStructure(key: Layer::application->name); } -function fileExists(string $relativeFileName, null | string $prefix = null): bool +function fileExists(string $relativeFileName, string $prefix = null): bool { return File::exists( path: basePath() . ($prefix ?? domainPath()) . Str::start($relativeFileName, prefix: '/') ); } -function fileGet(string $relativeFileName, null | string $prefix = null): string +function fileGet(string $relativeFileName, string $prefix = null): string { return File::get( path: basePath() . ($prefix ?? domainPath()) . Str::start($relativeFileName, prefix: '/') diff --git a/tests/Unit/DataTransferObjects/Fixtures/RoleData.php b/tests/Unit/DataTransferObjects/Fixtures/RoleData.php index a5e0a3b..0c44fd6 100644 --- a/tests/Unit/DataTransferObjects/Fixtures/RoleData.php +++ b/tests/Unit/DataTransferObjects/Fixtures/RoleData.php @@ -5,7 +5,7 @@ class RoleData { public function __construct( - public string | null $name, + public ?string $name, ) { } } diff --git a/tests/Unit/DataTransferObjects/Fixtures/UserData.php b/tests/Unit/DataTransferObjects/Fixtures/UserData.php index 8262d22..7cd8b27 100644 --- a/tests/Unit/DataTransferObjects/Fixtures/UserData.php +++ b/tests/Unit/DataTransferObjects/Fixtures/UserData.php @@ -7,14 +7,14 @@ readonly class UserData extends DataTransferObject { public function __construct( - public string | null $name = null, + public ?string $name = null, /** @var array | null $roles */ - public array | null $roles = null, - public RoleData | null $mainRole = null, - public int | null $age = null, - public GenderEnum | null $gender = null, + public ?array $roles = null, + public ?RoleData $mainRole = null, + public ?int $age = null, + public ?GenderEnum $gender = null, /** @var array | null $address */ - public array | null $addresses = null + public ?array $addresses = null ) { } }