Skip to content

Commit 85a96d4

Browse files
authored
Merge pull request #3 from WonderNetwork/feature/base-command-traits
Simplify boilerplate around Symfony Console commands
2 parents a05736d + f1fcd03 commit 85a96d4

5 files changed

+106
-0
lines changed

src/Cli/DefaultNameTrait.php

+10
Original file line numberDiff line numberDiff line change
@@ -0,0 +1,10 @@
1+
<?php
2+
declare(strict_types=1);
3+
4+
namespace WonderNetwork\SlimKernel\Cli;
5+
6+
trait DefaultNameTrait {
7+
protected static function getNameRelativeToNamespace(string $namespace): ?string {
8+
return NamespaceRelativeNamer::ofBaseNamespace($namespace)->name(static::class);
9+
}
10+
}

src/Cli/FingersCrossedTrait.php

+22
Original file line numberDiff line numberDiff line change
@@ -0,0 +1,22 @@
1+
<?php
2+
declare(strict_types=1);
3+
4+
namespace WonderNetwork\SlimKernel\Cli;
5+
6+
use Symfony\Component\Console\Input\InputInterface;
7+
use Symfony\Component\Console\Output\OutputInterface;
8+
use Throwable;
9+
10+
trait FingersCrossedTrait {
11+
protected function execute(InputInterface $input, OutputInterface $output): int {
12+
return FingersCrossedHandler::of($input, $output)->run([$this, 'fingersCrossed']);
13+
}
14+
15+
/**
16+
* @param InputParams $inputParams
17+
* @param FingersCrossedOutput $output
18+
* @return int
19+
* @throws Throwable
20+
*/
21+
abstract public function fingersCrossed(InputParams $inputParams, FingersCrossedOutput $output): int;
22+
}
+15
Original file line numberDiff line numberDiff line change
@@ -0,0 +1,15 @@
1+
<?php
2+
declare(strict_types=1);
3+
4+
namespace WonderNetwork\SlimKernel\Cli;
5+
6+
use Symfony\Component\Console\Input\InputInterface;
7+
use Symfony\Component\Console\Output\OutputInterface;
8+
9+
trait InitializeInputParamsTrait {
10+
protected InputParams $params;
11+
12+
protected function initialize(InputInterface $input, OutputInterface $output): void {
13+
$this->params = InputParams::ofInput($input);
14+
}
15+
}

src/Cli/NamespaceRelativeNamer.php

+37
Original file line numberDiff line numberDiff line change
@@ -0,0 +1,37 @@
1+
<?php
2+
declare(strict_types=1);
3+
4+
namespace WonderNetwork\SlimKernel\Cli;
5+
6+
/**
7+
* @internal
8+
*/
9+
final class NamespaceRelativeNamer {
10+
private string $namespace;
11+
12+
public static function ofBaseNamespace(string $namespace): self {
13+
return new self($namespace);
14+
}
15+
16+
private function __construct(string $namespace) {
17+
$this->namespace = $namespace;
18+
}
19+
20+
public function name(string $className): ?string {
21+
if (false === str_starts_with($className, $this->namespace)) {
22+
return null;
23+
}
24+
25+
$relativeNamespace = substr($className, strlen($this->namespace) + 1);
26+
$commandSuffix = 'Command';
27+
if (str_ends_with($relativeNamespace, $commandSuffix)) {
28+
$relativeNamespace = substr($relativeNamespace, 0, -strlen($commandSuffix));
29+
}
30+
31+
/** @var string $dashed */
32+
$dashed = preg_replace('/([a-z])([A-Z])/', '$1-$2', $relativeNamespace);
33+
$dotted = strtr($dashed, ['\\' => ':']);
34+
return strtolower($dotted);
35+
}
36+
37+
}
+22
Original file line numberDiff line numberDiff line change
@@ -0,0 +1,22 @@
1+
<?php
2+
declare(strict_types=1);
3+
4+
namespace WonderNetwork\SlimKernel\Cli;
5+
6+
use PHPUnit\Framework\TestCase;
7+
8+
class NamespaceRelativeNamerTest extends TestCase {
9+
public function testRelativeName(): void {
10+
$namespace = 'Acme\\Foo\\Cli';
11+
$className = 'Acme\\Foo\\Cli\\Category\\AlphaBravoCommand';
12+
$sut = NamespaceRelativeNamer::ofBaseNamespace($namespace);
13+
self::assertSame("category:alpha-bravo", $sut->name($className));
14+
}
15+
16+
public function testBailsIfRootNamespaceDoesNotMAtch(): void {
17+
$namespace = 'Acme\\Foo\\Cli';
18+
$className = 'Acme\\Bar\\Cli\\Category\\AlphaBravoCommand';
19+
$sut = NamespaceRelativeNamer::ofBaseNamespace($namespace);
20+
self::assertNull($sut->name($className));
21+
}
22+
}

0 commit comments

Comments
 (0)