From dfdc6a791cc5e9051812134a9610efdc0b4299f6 Mon Sep 17 00:00:00 2001 From: asciito Date: Wed, 4 Oct 2023 11:14:39 -0600 Subject: [PATCH] feat: add install command Signed-off-by: asciito --- .../Commands/InstallPackageCommand.php | 13 +++ src/Package/Concerns/HasInstallCommand.php | 94 +++++++++++++++++++ src/Package/Contracts/WithInstallCommand.php | 36 +++++++ src/Package/Package.php | 6 +- src/Package/PackageServiceProvider.php | 9 ++ .../Command/PackageInstallCommandTest.php | 76 +++++++++++++++ 6 files changed, 232 insertions(+), 2 deletions(-) create mode 100644 src/Console/Commands/InstallPackageCommand.php create mode 100644 src/Package/Concerns/HasInstallCommand.php create mode 100644 src/Package/Contracts/WithInstallCommand.php create mode 100644 tests/Feature/Command/PackageInstallCommandTest.php diff --git a/src/Console/Commands/InstallPackageCommand.php b/src/Console/Commands/InstallPackageCommand.php new file mode 100644 index 0000000..cc7cd6f --- /dev/null +++ b/src/Console/Commands/InstallPackageCommand.php @@ -0,0 +1,13 @@ + 'Install Config Component', + 'migrations' => 'Install Migrations Component', + ]; + + protected bool $commandShouldAdded = false; + + public function hasInstallCommand(): bool + { + return $this->commandShouldAdded; + } + + public function withInstallCommand(string $signature = '', ?Closure $after = null): static + { + $this->commandSignature = $signature; + + $this->afterCallback = $after; + + $this->commandShouldAdded = true; + + return $this; + } + + public function command(Command $command): int + { + intro('Installing Package Components'); + + $all = $command->option('all'); + + $some = false; + + foreach ($this->components as $name => $description) { + $name = str($name); + + if ($all || $command->option($name)) { + spin(function () use($command, $name) { + Artisan::call( + 'vendor:publish', + ['--tag' => $this->prefixWithPackageName($name)] + ); + }, "Publishing Component [{$name->title()}] files..."); + + $some = true; + } + } + + call_user_func($this->afterCallback, $command); + + $message = 'Package Component(s) installed'; + + if (! $some) { + $message = 'None package components were installed'; + } + + outro($message); + + return $command::SUCCESS; + } + + public function getInstallCommandSignature(): string + { + if (isset($this->commandSignature)) { + return $this->commandSignature; + } + + return $this->prefixWithPackageName('install', ':'); + } + + public function preConfigureInstallCommand(Command $command): void + { + foreach ($this->components as $component => $description) { + $command->addOption($component, description: $description); + } + + $command->addOption('all', description: 'Install all the package components'); + } +} diff --git a/src/Package/Contracts/WithInstallCommand.php b/src/Package/Contracts/WithInstallCommand.php new file mode 100644 index 0000000..def749f --- /dev/null +++ b/src/Package/Contracts/WithInstallCommand.php @@ -0,0 +1,36 @@ +hasCommand()) { $this->commands($package->getRegisteredCommand()->all()); } + + if ($package->hasInstallCommand()) { + $command = Artisan::command($package->getInstallCommandSignature(), function () use ($package) { + $package->command($this); + }); + + $package->preConfigureInstallCommand($command); + } } } diff --git a/tests/Feature/Command/PackageInstallCommandTest.php b/tests/Feature/Command/PackageInstallCommandTest.php new file mode 100644 index 0000000..5373a97 --- /dev/null +++ b/tests/Feature/Command/PackageInstallCommandTest.php @@ -0,0 +1,76 @@ +setName('install-package') + ->withConfig() + ->withMigration() + ->withInstallCommand( + 'package:install', + function ($command) { + $command->info('This is a message'); + } + ); + } +} + +uses(PackageInstallCommandTest::class); + +it('install command is registered', function () { + Prompt::fake(); + + artisan('list') + ->expectsOutputToContain('package:install') + ->assertSuccessful(); + + + artisan('package:install') + ->expectsOutputToContain('Installing Package Components') + ->expectsOutput('This is a message') + ->expectsOutputToContain('None package components were installed') + ->assertSuccessful(); +}); + +it('install config', function () { + artisan('package:install --config') + ->expectsOutputToContain('Publishing Component [Config] files...') + ->doesntExpectOutputToContain('Publishing Component [Migration] files') + ->doesntExpectOutputToContain('None package components were installed') + ->expectsOutputToContain('Package Component(s) installed') + ->assertSuccessful(); + + expect(config_path('one.php')) + ->toBeFile() + ->and(config_path('two.php')) + ->toBeFile(); +}); + +it('install migrations', function () { + artisan('package:install --migrations') + ->expectsOutputToContain('Publishing Component [Migrations] files...') + ->doesntExpectOutputToContain('Publishing Component [Config] files') + ->doesntExpectOutputToContain('None package components were installed') + ->expectsOutputToContain('Package Component(s) installed') + ->assertSuccessful(); + + expect(database_path('migrations/create_package_test_one_table.php')) + ->toBeFile() + ->and(database_path('migrations/create_package_test_two_table.php')) + ->toBeFile(); +}); + +it('install all the components', function () { + artisan('package:install --all') + ->expectsOutputToContain('Publishing Component [Migrations] files...') + ->expectsOutputToContain('Publishing Component [Config] files') + ->expectsOutputToContain('Package Component(s) installed') + ->doesntExpectOutputToContain('None package components were installed') + ->assertSuccessful(); +});