-
-
Notifications
You must be signed in to change notification settings - Fork 89
Commit
This commit does not belong to any branch on this repository, and may belong to a fork outside of the repository.
feat(console): add
make:view
command (#864)
Co-authored-by: Enzo Innocenzi <[email protected]>
- Loading branch information
1 parent
08df98c
commit a4ab813
Showing
5 changed files
with
173 additions
and
0 deletions.
There are no files selected for viewing
This file contains bidirectional Unicode text that may be interpreted or compiled differently than what appears below. To review, open the file in an editor that reveals hidden Unicode characters.
Learn more about bidirectional Unicode characters
Original file line number | Diff line number | Diff line change |
---|---|---|
@@ -0,0 +1,86 @@ | ||
<?php | ||
|
||
declare(strict_types=1); | ||
|
||
namespace Tempest\View\Commands; | ||
|
||
use InvalidArgumentException; | ||
use Tempest\Console\ConsoleArgument; | ||
use Tempest\Console\ConsoleCommand; | ||
use Tempest\Core\PublishesFiles; | ||
use Tempest\Generation\DataObjects\StubFile; | ||
use Tempest\Generation\Enums\StubFileType; | ||
use Tempest\Generation\Exceptions\FileGenerationAbortedException; | ||
use Tempest\Generation\Exceptions\FileGenerationFailedException; | ||
use Tempest\View\Enums\ViewType; | ||
use Tempest\View\Stubs\ViewStub; | ||
use function Tempest\Support\str; | ||
|
||
final class MakeViewCommand | ||
{ | ||
use PublishesFiles; | ||
|
||
#[ConsoleCommand( | ||
name: 'make:view', | ||
description: 'Creates a view file', | ||
aliases: ['view:make', 'view:create', 'create:view'], | ||
)] | ||
public function __invoke( | ||
#[ConsoleArgument( | ||
description: 'The file name of the view', | ||
)] | ||
string $fileName, | ||
#[ConsoleArgument( | ||
name: 'type', | ||
description: 'The type of the view to create', | ||
)] | ||
ViewType $viewType = ViewType::RAW, | ||
): void { | ||
try { | ||
$suggestedPath = str($this->getSuggestedPath('Dummy')); | ||
$suggestedPath = ($viewType === ViewType::RAW) | ||
? $suggestedPath->replace('Dummy', $fileName . '.view') | ||
: $suggestedPath->replace('Dummy', $fileName); | ||
|
||
$suggestedPath = $suggestedPath->toString(); | ||
$targetPath = $this->promptTargetPath($suggestedPath); | ||
$shouldOverride = $this->askForOverride($targetPath); | ||
|
||
$stubFile = $this->getStubFileFromViewType($viewType); | ||
|
||
if ($stubFile->type === StubFileType::RAW_FILE) { | ||
$this->stubFileGenerator->generateRawFile( | ||
stubFile: $stubFile, | ||
targetPath: $targetPath, | ||
shouldOverride: $shouldOverride, | ||
); | ||
} else { | ||
$this->stubFileGenerator->generateClassFile( | ||
stubFile: $stubFile, | ||
targetPath: $targetPath, | ||
shouldOverride: $shouldOverride, | ||
replacements: [ | ||
'dummy.view.php' => str($fileName)->kebab()->toString() . '.view.php', | ||
], | ||
); | ||
} | ||
|
||
$this->success(sprintf('View successfully created at "%s".', $targetPath)); | ||
} catch (FileGenerationAbortedException|FileGenerationFailedException|InvalidArgumentException $e) { | ||
$this->error($e->getMessage()); | ||
} | ||
} | ||
|
||
private function getStubFileFromViewType(ViewType $viewType): StubFile | ||
{ | ||
try { | ||
return match ($viewType) { | ||
ViewType::RAW => StubFile::from(dirname(__DIR__) . '/Stubs/view.stub.php'), | ||
ViewType::OBJECT => StubFile::from(ViewStub::class), // @phpstan-ignore match.alwaysTrue (Because this is a guardrail for the future implementations) | ||
default => throw new InvalidArgumentException(sprintf('The "%s" view type has no supported stub file.', $viewType->value)), | ||
}; | ||
} catch (InvalidArgumentException $invalidArgumentException) { | ||
throw new FileGenerationFailedException(sprintf('Cannot retrieve stub file: %s', $invalidArgumentException->getMessage())); | ||
} | ||
} | ||
} |
This file contains bidirectional Unicode text that may be interpreted or compiled differently than what appears below. To review, open the file in an editor that reveals hidden Unicode characters.
Learn more about bidirectional Unicode characters
Original file line number | Diff line number | Diff line change |
---|---|---|
@@ -0,0 +1,15 @@ | ||
<?php | ||
|
||
declare(strict_types=1); | ||
|
||
namespace Tempest\View\Enums; | ||
|
||
/** | ||
* Represents the type of view. | ||
* Used to differentiate between raw and class views. | ||
*/ | ||
enum ViewType: string | ||
{ | ||
case RAW = 'raw'; | ||
case OBJECT = 'class'; | ||
} |
This file contains bidirectional Unicode text that may be interpreted or compiled differently than what appears below. To review, open the file in an editor that reveals hidden Unicode characters.
Learn more about bidirectional Unicode characters
Original file line number | Diff line number | Diff line change |
---|---|---|
@@ -0,0 +1,18 @@ | ||
<?php | ||
|
||
declare(strict_types=1); | ||
|
||
namespace Tempest\View\Stubs; | ||
|
||
use Tempest\View\IsView; | ||
use Tempest\View\View; | ||
|
||
final class ViewStub implements View | ||
{ | ||
use IsView; | ||
|
||
public function __construct() | ||
{ | ||
$this->path = __DIR__ . '/dummy.view.php'; | ||
} | ||
} |
Empty file.
This file contains bidirectional Unicode text that may be interpreted or compiled differently than what appears below. To review, open the file in an editor that reveals hidden Unicode characters.
Learn more about bidirectional Unicode characters
Original file line number | Diff line number | Diff line change |
---|---|---|
@@ -0,0 +1,54 @@ | ||
<?php | ||
|
||
declare(strict_types=1); | ||
|
||
namespace Tests\Tempest\Integration\Console\Commands; | ||
|
||
use PHPUnit\Framework\Attributes\Test; | ||
use Tempest\Core\ComposerNamespace; | ||
use Tests\Tempest\Integration\FrameworkIntegrationTestCase; | ||
|
||
/** | ||
* @internal | ||
*/ | ||
final class MakeViewCommandTest extends FrameworkIntegrationTestCase | ||
{ | ||
protected function setUp(): void | ||
{ | ||
parent::setUp(); | ||
|
||
$this->installer->configure( | ||
__DIR__ . '/install', | ||
new ComposerNamespace('App\\', __DIR__ . '/install/App'), | ||
); | ||
} | ||
|
||
protected function tearDown(): void | ||
{ | ||
$this->installer->clean(); | ||
|
||
parent::tearDown(); | ||
} | ||
|
||
#[Test] | ||
public function make_view(): void | ||
{ | ||
$this->console | ||
->call('make:view home') | ||
->submit(); | ||
|
||
$this->installer->assertFileExists('App/home.view.php'); | ||
|
||
$this->console | ||
->call('make:view HomeView class') | ||
->submit(); | ||
|
||
$filepath = 'App/HomeView.php'; | ||
$this->installer | ||
->assertFileExists($filepath) | ||
->assertFileContains($filepath, 'implements View') | ||
->assertFileContains($filepath, "use Tempest\View\View") | ||
->assertFileContains($filepath, 'use IsView') | ||
->assertFileContains($filepath, "use Tempest\View\IsView"); | ||
} | ||
} |