diff --git a/CHANGELOG.md b/CHANGELOG.md index 41908f5..46f21bb 100644 --- a/CHANGELOG.md +++ b/CHANGELOG.md @@ -4,6 +4,7 @@ All notable changes to `laravel-ddd` will be documented in this file. ## [Unversioned] ### Added +- `ddd:list` to show a summary of current domains in the domain folder. - Additional generator commands that extend Laravel's generators and funnel the generated objects into the domain layer: - `ddd:cast {domain}:{name}` - `ddd:channel {domain}:{name}` diff --git a/README.md b/README.md index 18d5ea8..98a820c 100644 --- a/README.md +++ b/README.md @@ -29,6 +29,10 @@ php artisan ddd:{object} {name} --domain={domain} # Specifying the domain as part of the name (short-hand syntax) php artisan ddd:{object} {domain}:{name} + +# Not specifying the domain at all, which will then prompt +# you to enter the domain name (with auto-completion) +php artisan ddd:{object} {name} ``` The following generators are currently available, shown using short-hand syntax: @@ -93,6 +97,12 @@ php artisan ddd:factory Invoicing.Customer:CustomerInvoice # Database/Factories/ # (supported by all generator commands) ``` +### Other Commands +```bash +# Show a summary of current domains in the domain folder +php artisan ddd:list +``` + This package ships with opinionated (but sensible) configuration defaults. If you need to customize, you may do so by publishing the config file and generator stubs as needed: ```bash diff --git a/src/Commands/Concerns/ResolvesDomainFromInput.php b/src/Commands/Concerns/ResolvesDomainFromInput.php index aa09c44..fd32c54 100644 --- a/src/Commands/Concerns/ResolvesDomainFromInput.php +++ b/src/Commands/Concerns/ResolvesDomainFromInput.php @@ -81,7 +81,9 @@ public function handle() // If the domain is not set, prompt for it if (! $this->domain) { - $this->domain = new Domain($this->ask('What is the domain?')); + $this->domain = new Domain( + $this->anticipate('What is the domain?', DomainResolver::domainChoices()) + ); } parent::handle(); diff --git a/src/Commands/DomainListCommand.php b/src/Commands/DomainListCommand.php index c201d77..d7a1b58 100644 --- a/src/Commands/DomainListCommand.php +++ b/src/Commands/DomainListCommand.php @@ -3,10 +3,35 @@ namespace Lunarstorm\LaravelDDD\Commands; use Illuminate\Console\Command; +use Lunarstorm\LaravelDDD\Support\Domain; +use Lunarstorm\LaravelDDD\Support\DomainResolver; class DomainListCommand extends Command { protected $name = 'ddd:list'; protected $description = 'List all current domains'; + + public function handle() + { + $headings = ['Domain', 'Namespace', 'Path']; + + $table = collect(DomainResolver::domainChoices()) + ->map(function (string $name) { + $domain = new Domain($name); + + return [ + $domain->domain, + $domain->namespace->root, + $domain->path, + ]; + }) + ->toArray(); + + $this->table($headings, $table); + + $countDomains = count($table); + + $this->info(trans_choice("{$countDomains} domain|{$countDomains} domains", $countDomains)); + } } diff --git a/src/LaravelDDDServiceProvider.php b/src/LaravelDDDServiceProvider.php index ea51236..cd5cbc4 100644 --- a/src/LaravelDDDServiceProvider.php +++ b/src/LaravelDDDServiceProvider.php @@ -2,15 +2,6 @@ namespace Lunarstorm\LaravelDDD; -use Lunarstorm\LaravelDDD\Commands\DomainActionMakeCommand; -use Lunarstorm\LaravelDDD\Commands\DomainBaseModelMakeCommand; -use Lunarstorm\LaravelDDD\Commands\DomainBaseViewModelMakeCommand; -use Lunarstorm\LaravelDDD\Commands\DomainDtoMakeCommand; -use Lunarstorm\LaravelDDD\Commands\DomainFactoryMakeCommand; -use Lunarstorm\LaravelDDD\Commands\DomainModelMakeCommand; -use Lunarstorm\LaravelDDD\Commands\DomainValueObjectMakeCommand; -use Lunarstorm\LaravelDDD\Commands\DomainViewModelMakeCommand; -use Lunarstorm\LaravelDDD\Commands\InstallCommand; use Spatie\LaravelPackageTools\Package; use Spatie\LaravelPackageTools\PackageServiceProvider; @@ -27,30 +18,31 @@ public function configurePackage(Package $package): void ->name('laravel-ddd') ->hasConfigFile() ->hasCommands([ - InstallCommand::class, - DomainModelMakeCommand::class, - DomainFactoryMakeCommand::class, - DomainBaseModelMakeCommand::class, - DomainDtoMakeCommand::class, - DomainValueObjectMakeCommand::class, - DomainViewModelMakeCommand::class, - DomainBaseViewModelMakeCommand::class, - DomainActionMakeCommand::class, - \Lunarstorm\LaravelDDD\Commands\DomainCastMakeCommand::class, - \Lunarstorm\LaravelDDD\Commands\DomainChannelMakeCommand::class, - \Lunarstorm\LaravelDDD\Commands\DomainConsoleMakeCommand::class, - \Lunarstorm\LaravelDDD\Commands\DomainEventMakeCommand::class, - \Lunarstorm\LaravelDDD\Commands\DomainExceptionMakeCommand::class, - \Lunarstorm\LaravelDDD\Commands\DomainJobMakeCommand::class, - \Lunarstorm\LaravelDDD\Commands\DomainListenerMakeCommand::class, - \Lunarstorm\LaravelDDD\Commands\DomainMailMakeCommand::class, - \Lunarstorm\LaravelDDD\Commands\DomainNotificationMakeCommand::class, - \Lunarstorm\LaravelDDD\Commands\DomainObserverMakeCommand::class, - \Lunarstorm\LaravelDDD\Commands\DomainPolicyMakeCommand::class, - \Lunarstorm\LaravelDDD\Commands\DomainProviderMakeCommand::class, - \Lunarstorm\LaravelDDD\Commands\DomainResourceMakeCommand::class, - \Lunarstorm\LaravelDDD\Commands\DomainRuleMakeCommand::class, - \Lunarstorm\LaravelDDD\Commands\DomainScopeMakeCommand::class, + Commands\InstallCommand::class, + Commands\DomainListCommand::class, + Commands\DomainModelMakeCommand::class, + Commands\DomainFactoryMakeCommand::class, + Commands\DomainBaseModelMakeCommand::class, + Commands\DomainDtoMakeCommand::class, + Commands\DomainValueObjectMakeCommand::class, + Commands\DomainViewModelMakeCommand::class, + Commands\DomainBaseViewModelMakeCommand::class, + Commands\DomainActionMakeCommand::class, + Commands\DomainCastMakeCommand::class, + Commands\DomainChannelMakeCommand::class, + Commands\DomainConsoleMakeCommand::class, + Commands\DomainEventMakeCommand::class, + Commands\DomainExceptionMakeCommand::class, + Commands\DomainJobMakeCommand::class, + Commands\DomainListenerMakeCommand::class, + Commands\DomainMailMakeCommand::class, + Commands\DomainNotificationMakeCommand::class, + Commands\DomainObserverMakeCommand::class, + Commands\DomainPolicyMakeCommand::class, + Commands\DomainProviderMakeCommand::class, + Commands\DomainResourceMakeCommand::class, + Commands\DomainRuleMakeCommand::class, + Commands\DomainScopeMakeCommand::class, ]); // Enum generator only in Laravel 11 diff --git a/src/Support/DomainResolver.php b/src/Support/DomainResolver.php index 0130924..d4e3ead 100644 --- a/src/Support/DomainResolver.php +++ b/src/Support/DomainResolver.php @@ -6,6 +6,18 @@ class DomainResolver { + public static function domainChoices(): array + { + $folders = glob(app()->basePath(static::domainPath().'/*'), GLOB_ONLYDIR); + + return collect($folders) + ->map(function ($folder) { + return basename($folder); + }) + ->sort() + ->toArray(); + } + public static function domainPath(): ?string { return config('ddd.domain_path'); diff --git a/tests/Command/ListTest.php b/tests/Command/ListTest.php new file mode 100644 index 0000000..286c1ad --- /dev/null +++ b/tests/Command/ListTest.php @@ -0,0 +1,39 @@ +artisan('ddd:model', [ + 'name' => 'Invoice', + '--domain' => 'Invoicing', + ]); + + $this->artisan('ddd:dto', [ + 'name' => 'CustomerProfile', + '--domain' => 'Customer', + ]); + + $this->expectedDomains = [ + 'Customer', + 'Invoicing', + 'Shared', + ]; +}); + +it('can list domains', function () { + $expectedTableContent = collect($this->expectedDomains) + ->map(function (string $name) { + return [ + $name, + "Domain\\{$name}", + "src/Domain/{$name}", + ]; + }) + ->toArray(); + + $this + ->artisan('ddd:list') + ->expectsTable([ + 'Domain', + 'Namespace', + 'Path', + ], $expectedTableContent); +}); diff --git a/tests/Support/DomainResolverTest.php b/tests/Support/DomainResolverTest.php new file mode 100644 index 0000000..37b63b9 --- /dev/null +++ b/tests/Support/DomainResolverTest.php @@ -0,0 +1,25 @@ +artisan('ddd:model', [ + 'name' => 'Invoice', + '--domain' => 'Invoicing', + ]); + + $this->artisan('ddd:dto', [ + 'name' => 'CustomerProfile', + '--domain' => 'Customer', + ]); + + $this->expectedDomains = [ + 'Customer', + 'Invoicing', + 'Shared', + ]; +}); + +it('can get the current domains', function () { + expect(DomainResolver::domainChoices())->toEqualCanonicalizing($this->expectedDomains); +});