Skip to content

Commit

Permalink
[MERGE] - PR #8 to develop
Browse files Browse the repository at this point in the history
[FEAT]: Add Install Command
  • Loading branch information
asciito authored Oct 4, 2023
2 parents 7bcc9b2 + 90b153a commit e5dcb2a
Show file tree
Hide file tree
Showing 6 changed files with 265 additions and 2 deletions.
13 changes: 13 additions & 0 deletions src/Console/Commands/InstallPackageCommand.php
Original file line number Diff line number Diff line change
@@ -0,0 +1,13 @@
<?php

namespace Asciito\LaravelPackage\Console\Commands;

use Illuminate\Console\Command;

class InstallPackageCommand extends Command
{
protected function configure(): void
{

}
}
119 changes: 119 additions & 0 deletions src/Package/Concerns/HasInstallCommand.php
Original file line number Diff line number Diff line change
@@ -0,0 +1,119 @@
<?php

namespace Asciito\LaravelPackage\Package\Concerns;

use Closure;
use Illuminate\Console\Command;
use Illuminate\Support\Facades\Artisan;

use function Laravel\Prompts\intro;
use function Laravel\Prompts\outro;
use function Laravel\Prompts\spin;

trait HasInstallCommand
{
protected string $commandSignature;

protected ?Closure $afterCallback;

protected array $components = [
'config' => '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 ($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');

$command::macro('sponsor', function (string $message, string $url) use ($command) {
$ans = $command->confirm($message);

if (! $ans) {
return;
}

$url = urlencode($url);

if (PHP_OS_FAMILY == 'Darwin') {
exec("open $url");
}

if (PHP_OS_FAMILY == 'Windows') {
exec("start $url");
}

if (PHP_OS_FAMILY == 'Linux') {
exec("xdg-open $url");
}

$command->info('Thanks!');
});
}
}
36 changes: 36 additions & 0 deletions src/Package/Contracts/WithInstallCommand.php
Original file line number Diff line number Diff line change
@@ -0,0 +1,36 @@
<?php

namespace Asciito\LaravelPackage\Package\Contracts;

use Closure;
use Illuminate\Console\Command;

interface WithInstallCommand
{
/**
* Check if the installation command is available
*/
public function hasInstallCommand(): bool;

/**
* Register and configure the installation command
*/
public function withInstallCommand(string $signature = '', Closure $after = null): static;

/**
* The installation command itself
*
* @param Command $command The instance of the command to be run as the installation command
*/
public function command(Command $command): int;

/**
* Return the command signature
*/
public function getInstallCommandSignature(): string;

/**
* Pre-configure the command with a fresh instance of the command
*/
public function preConfigureInstallCommand(Command $command): void;
}
6 changes: 4 additions & 2 deletions src/Package/Package.php
Original file line number Diff line number Diff line change
Expand Up @@ -4,9 +4,11 @@

use Asciito\LaravelPackage\Package\Concerns\HasCommand;
use Asciito\LaravelPackage\Package\Concerns\HasConfig;
use Asciito\LaravelPackage\Package\Concerns\HasInstallCommand;
use Asciito\LaravelPackage\Package\Concerns\HasMigration;
use Asciito\LaravelPackage\Package\Contracts\WithCommand;
use Asciito\LaravelPackage\Package\Contracts\WithConfig;
use Asciito\LaravelPackage\Package\Contracts\WithInstallCommand;
use Asciito\LaravelPackage\Package\Contracts\WithMigration;
use Illuminate\Contracts\Filesystem\FileNotFoundException;
use Illuminate\Support\Arr;
Expand All @@ -16,9 +18,9 @@
use Illuminate\Support\Str;
use Symfony\Component\Finder\SplFileInfo;

class Package implements WithCommand, WithConfig, WithMigration
class Package implements WithCommand, WithConfig, WithInstallCommand, WithMigration
{
use HasCommand, HasConfig, HasMigration;
use HasCommand, HasConfig, HasInstallCommand, HasMigration;

/**
* @var string The package name
Expand Down
9 changes: 9 additions & 0 deletions src/Package/PackageServiceProvider.php
Original file line number Diff line number Diff line change
Expand Up @@ -2,6 +2,7 @@

namespace Asciito\LaravelPackage\Package;

use Illuminate\Support\Facades\Artisan;
use Illuminate\Support\ServiceProvider;

abstract class PackageServiceProvider extends ServiceProvider
Expand Down Expand Up @@ -161,5 +162,13 @@ protected function publishesCommands(Package $package): void
if ($package->hasCommand()) {
$this->commands($package->getRegisteredCommand()->all());
}

if ($package->hasInstallCommand()) {
$command = Artisan::command($package->getInstallCommandSignature(), function () use ($package) {
$package->command($this); // @phpstan-ignore-line
});

$package->preConfigureInstallCommand($command);
}
}
}
84 changes: 84 additions & 0 deletions tests/Feature/Command/PackageInstallCommandTest.php
Original file line number Diff line number Diff line change
@@ -0,0 +1,84 @@
<?php

use Asciito\LaravelPackage\Package\Package;
use Laravel\Prompts\Prompt;

use function Pest\Laravel\artisan;

trait PackageInstallCommandTest
{
protected function configurePackage(Package $package): void
{
$package
->setName('install-package')
->withConfig()
->withMigration()
->withInstallCommand(
'package:install',
function ($command) {
$command->info('This is a message');

$command->sponsor('Please, give us a star on Github', 'https://example.com');
}
);
}
}

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')
->expectsQuestion('Please, give us a star on Github', 'yes')
->expectsOutputToContain('Thanks!')
->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')
->expectsQuestion('Please, give us a star on Github', false)
->doesntExpectOutputToContain('Thanks!')
->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')
->expectsQuestion('Please, give us a star on Github', false)
->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')
->expectsQuestion('Please, give us a star on Github', false)
->assertSuccessful();
});

0 comments on commit e5dcb2a

Please sign in to comment.