diff --git a/src/Package/Concerns/HasCommands.php b/src/Package/Concerns/HasCommands.php index e019750..7a07ade 100644 --- a/src/Package/Concerns/HasCommands.php +++ b/src/Package/Concerns/HasCommands.php @@ -10,11 +10,27 @@ trait HasCommands { protected array $commands = []; + protected bool $preventLoadDefaultCommandsFolder = false; + protected bool $shouldLoadCommandsFromDefaultFolder = false; + protected array $excludedCommands = []; + public function hasCommands(): bool { - return filled($this->commands) || $this->shouldLoadCommandsFromDefaultFolder; + return $this->shouldLoadDefaultCommandsFolder() || filled($this->commands); + } + + private function shouldLoadDefaultCommandsFolder(): bool + { + return !$this->preventLoadDefaultCommandsFolder && $this->shouldLoadCommandsFromDefaultFolder; + } + + public function preventDefaultCommands(): static + { + $this->preventLoadDefaultCommandsFolder = true; + + return $this; } public function withCommands(string|array ...$command): static @@ -22,7 +38,6 @@ public function withCommands(string|array ...$command): static if (filled($command)) { $this->commands = collect($command) ->flatten() - ->mapWithKeys(fn (string $value) => [$value => true]) ->merge($this->commands) ->all(); } @@ -36,29 +51,36 @@ public function getRegisteredCommands(): Collection { $commands = []; - if ($this->shouldLoadCommandsFromDefaultFolder) { + if ($this->shouldLoadDefaultCommandsFolder()) { $commands = $this->loadCommandsFromDefaultFolder(); } return collect($this->commands) ->merge($commands) - ->keys(); + ->filter(fn (string $command) => !in_array($command, $this->excludedCommands)); } public function loadCommandsFromDefaultFolder() { return collect(File::files($this->getBasePath('Console/Commands'))) ->filter(fn (SplFileInfo $file) => $file->getExtension() === 'php') - ->mapWithKeys(function (SplFileInfo $file) { - $fqcn = str($file) - ->after('Console/') - ->replace('/', '\\') - ->remove('.php') - ->prepend($this->getNamespace().'\\Console\\') - ->toString(); - - return [$fqcn => true]; - }) + ->map(fn (SplFileInfo $file) => str($file) + ->after('Console/') + ->replace('/', '\\') + ->remove('.php') + ->prepend($this->getNamespace() . '\\Console\\') + ->toString() + ) ->all(); } + + /** + * Un-register a previously registered command + */ + public function unregisterCommand(string $fqcn): static + { + $this->excludedCommands[] = $fqcn; + + return $this; + } } diff --git a/src/Package/Contracts/WithCommands.php b/src/Package/Contracts/WithCommands.php index 2fd98bd..8c2fe2d 100644 --- a/src/Package/Contracts/WithCommands.php +++ b/src/Package/Contracts/WithCommands.php @@ -13,6 +13,14 @@ interface WithCommands */ public function hasCommands(): bool; + /** + * Prevent registering the default command folder + * + * Calling this method ensures that the command files in the default folder + * wouldn't be loaded automatically. + */ + public function preventDefaultCommands(): static; + /** * Register the config file(s) for the package * @@ -29,4 +37,9 @@ public function withCommands(string|array ...$command): static; * @return Collection The commands registered in the package */ public function getRegisteredCommands(): Collection; + + /** + * Un-register a previously registered command + */ + public function unregisterCommand(string $fqcn): static; } diff --git a/tests/Feature/Package/UnregisterCommandsTest.php b/tests/Feature/Package/UnregisterCommandsTest.php new file mode 100644 index 0000000..eb6f344 --- /dev/null +++ b/tests/Feature/Package/UnregisterCommandsTest.php @@ -0,0 +1,34 @@ +withCommands(PackageTestCommandTwo::class) + ->unregisterCommand(PackageTestCommandOne::class); + } +} + +uses(UnregisterPackageCommand::class); + +it('register commands', function () { + artisan('list') + ->expectsOutputToContain('package:two') + ->doesntExpectOutputToContain('package:one') + ->assertSuccessful(); +}); + +it('run commands', function () { + artisan('package:two') + ->expectsOutput('Package command two') + ->assertSuccessful(); + + artisan('package:one')->run(); +})->throws(CommandNotFoundException::class);