feat: implement core console interfaces and attributes
This commit is contained in:
parent
7cb01ed6ab
commit
62af4cea9e
17
src/Attributes/Arg.php
Normal file
17
src/Attributes/Arg.php
Normal file
|
|
@ -0,0 +1,17 @@
|
||||||
|
<?php
|
||||||
|
|
||||||
|
declare(strict_types=1);
|
||||||
|
|
||||||
|
namespace Phred\ConsoleContracts\Attributes;
|
||||||
|
|
||||||
|
use Attribute;
|
||||||
|
|
||||||
|
#[Attribute(Attribute::TARGET_CLASS | Attribute::IS_REPEATABLE)]
|
||||||
|
class Arg
|
||||||
|
{
|
||||||
|
public function __construct(
|
||||||
|
public string $name,
|
||||||
|
public string $description = ''
|
||||||
|
) {
|
||||||
|
}
|
||||||
|
}
|
||||||
17
src/Attributes/Cmd.php
Normal file
17
src/Attributes/Cmd.php
Normal file
|
|
@ -0,0 +1,17 @@
|
||||||
|
<?php
|
||||||
|
|
||||||
|
declare(strict_types=1);
|
||||||
|
|
||||||
|
namespace Phred\ConsoleContracts\Attributes;
|
||||||
|
|
||||||
|
use Attribute;
|
||||||
|
|
||||||
|
#[Attribute(Attribute::TARGET_CLASS)]
|
||||||
|
class Cmd
|
||||||
|
{
|
||||||
|
public function __construct(
|
||||||
|
public string $name,
|
||||||
|
public string $description = ''
|
||||||
|
) {
|
||||||
|
}
|
||||||
|
}
|
||||||
75
src/Attributes/HasAttributes.php
Normal file
75
src/Attributes/HasAttributes.php
Normal file
|
|
@ -0,0 +1,75 @@
|
||||||
|
<?php
|
||||||
|
|
||||||
|
declare(strict_types=1);
|
||||||
|
|
||||||
|
namespace Phred\ConsoleContracts\Attributes;
|
||||||
|
|
||||||
|
use Phred\ConsoleContracts\CommandInterface;
|
||||||
|
use ReflectionClass;
|
||||||
|
|
||||||
|
/**
|
||||||
|
* Helper trait to surface PHP 8 attributes (Cmd/Arg/Opt) via CommandInterface methods.
|
||||||
|
*
|
||||||
|
* Usage:
|
||||||
|
* class MyCommand implements CommandInterface { use HasAttributes; ... }
|
||||||
|
*
|
||||||
|
* Note: Methods are provided here; consuming class may override any for custom behavior.
|
||||||
|
*/
|
||||||
|
trait HasAttributes
|
||||||
|
{
|
||||||
|
public function getName(): string
|
||||||
|
{
|
||||||
|
$ref = new ReflectionClass($this);
|
||||||
|
$attr = $ref->getAttributes(Cmd::class)[0] ?? null;
|
||||||
|
if ($attr === null) {
|
||||||
|
return '';
|
||||||
|
}
|
||||||
|
/** @var Cmd $meta */
|
||||||
|
$meta = $attr->newInstance();
|
||||||
|
return $meta->name;
|
||||||
|
}
|
||||||
|
|
||||||
|
public function getDescription(): string
|
||||||
|
{
|
||||||
|
$ref = new ReflectionClass($this);
|
||||||
|
$attr = $ref->getAttributes(Cmd::class)[0] ?? null;
|
||||||
|
if ($attr === null) {
|
||||||
|
return '';
|
||||||
|
}
|
||||||
|
/** @var Cmd $meta */
|
||||||
|
$meta = $attr->newInstance();
|
||||||
|
return $meta->description;
|
||||||
|
}
|
||||||
|
|
||||||
|
/**
|
||||||
|
* @return array<string,string>
|
||||||
|
*/
|
||||||
|
public function getArguments(): array
|
||||||
|
{
|
||||||
|
$ref = new ReflectionClass($this);
|
||||||
|
$attrs = $ref->getAttributes(Arg::class);
|
||||||
|
$out = [];
|
||||||
|
foreach ($attrs as $attr) {
|
||||||
|
/** @var Arg $a */
|
||||||
|
$a = $attr->newInstance();
|
||||||
|
$out[$a->name] = $a->description;
|
||||||
|
}
|
||||||
|
return $out;
|
||||||
|
}
|
||||||
|
|
||||||
|
/**
|
||||||
|
* @return array<string,string>
|
||||||
|
*/
|
||||||
|
public function getOptions(): array
|
||||||
|
{
|
||||||
|
$ref = new ReflectionClass($this);
|
||||||
|
$attrs = $ref->getAttributes(Opt::class);
|
||||||
|
$out = [];
|
||||||
|
foreach ($attrs as $attr) {
|
||||||
|
/** @var Opt $o */
|
||||||
|
$o = $attr->newInstance();
|
||||||
|
$out[$o->name] = $o->description;
|
||||||
|
}
|
||||||
|
return $out;
|
||||||
|
}
|
||||||
|
}
|
||||||
17
src/Attributes/Opt.php
Normal file
17
src/Attributes/Opt.php
Normal file
|
|
@ -0,0 +1,17 @@
|
||||||
|
<?php
|
||||||
|
|
||||||
|
declare(strict_types=1);
|
||||||
|
|
||||||
|
namespace Phred\ConsoleContracts\Attributes;
|
||||||
|
|
||||||
|
use Attribute;
|
||||||
|
|
||||||
|
#[Attribute(Attribute::TARGET_CLASS | Attribute::IS_REPEATABLE)]
|
||||||
|
class Opt
|
||||||
|
{
|
||||||
|
public function __construct(
|
||||||
|
public string $name,
|
||||||
|
public string $description = ''
|
||||||
|
) {
|
||||||
|
}
|
||||||
|
}
|
||||||
24
src/CommandInterface.php
Normal file
24
src/CommandInterface.php
Normal file
|
|
@ -0,0 +1,24 @@
|
||||||
|
<?php
|
||||||
|
|
||||||
|
declare(strict_types=1);
|
||||||
|
|
||||||
|
namespace Phred\ConsoleContracts;
|
||||||
|
|
||||||
|
interface CommandInterface
|
||||||
|
{
|
||||||
|
public function getName(): string;
|
||||||
|
|
||||||
|
public function getDescription(): string;
|
||||||
|
|
||||||
|
/**
|
||||||
|
* @return array<string,string> Name => Description
|
||||||
|
*/
|
||||||
|
public function getArguments(): array;
|
||||||
|
|
||||||
|
/**
|
||||||
|
* @return array<string,string> Name => Description
|
||||||
|
*/
|
||||||
|
public function getOptions(): array;
|
||||||
|
|
||||||
|
public function execute(InputInterface $input, OutputInterface $output): int;
|
||||||
|
}
|
||||||
9
src/ConsoleExceptionInterface.php
Normal file
9
src/ConsoleExceptionInterface.php
Normal file
|
|
@ -0,0 +1,9 @@
|
||||||
|
<?php
|
||||||
|
|
||||||
|
declare(strict_types=1);
|
||||||
|
|
||||||
|
namespace Phred\ConsoleContracts;
|
||||||
|
|
||||||
|
interface ConsoleExceptionInterface extends \Throwable
|
||||||
|
{
|
||||||
|
}
|
||||||
15
src/ConsoleMiddlewareInterface.php
Normal file
15
src/ConsoleMiddlewareInterface.php
Normal file
|
|
@ -0,0 +1,15 @@
|
||||||
|
<?php
|
||||||
|
|
||||||
|
declare(strict_types=1);
|
||||||
|
|
||||||
|
namespace Phred\ConsoleContracts;
|
||||||
|
|
||||||
|
interface ConsoleMiddlewareInterface
|
||||||
|
{
|
||||||
|
public function handle(
|
||||||
|
CommandInterface $command,
|
||||||
|
InputInterface $input,
|
||||||
|
OutputInterface $output,
|
||||||
|
callable $next
|
||||||
|
): int;
|
||||||
|
}
|
||||||
19
src/ExitCode.php
Normal file
19
src/ExitCode.php
Normal file
|
|
@ -0,0 +1,19 @@
|
||||||
|
<?php
|
||||||
|
|
||||||
|
declare(strict_types=1);
|
||||||
|
|
||||||
|
namespace Phred\ConsoleContracts;
|
||||||
|
|
||||||
|
final class ExitCode
|
||||||
|
{
|
||||||
|
public const OK = 0; // Successful termination
|
||||||
|
public const FAILURE = 1; // Generic/legacy failure (non-sysexits)
|
||||||
|
public const USAGE = 64; // Command line usage error
|
||||||
|
public const DATAERR = 65; // Data format error
|
||||||
|
public const NOINPUT = 66; // Cannot open input
|
||||||
|
public const UNAVAILABLE = 69; // Service unavailable
|
||||||
|
public const SOFTWARE = 70; // Internal software error
|
||||||
|
public const IOERR = 74; // Input/output error
|
||||||
|
public const PERM = 77; // Permission denied
|
||||||
|
public const CONFIG = 78; // Configuration error
|
||||||
|
}
|
||||||
12
src/Helpers/MarkdownConverterInterface.php
Normal file
12
src/Helpers/MarkdownConverterInterface.php
Normal file
|
|
@ -0,0 +1,12 @@
|
||||||
|
<?php
|
||||||
|
|
||||||
|
declare(strict_types=1);
|
||||||
|
|
||||||
|
namespace Phred\ConsoleContracts\Helpers;
|
||||||
|
|
||||||
|
interface MarkdownConverterInterface
|
||||||
|
{
|
||||||
|
public function convert(string $markdown): string;
|
||||||
|
|
||||||
|
public function convertFile(string $path): string;
|
||||||
|
}
|
||||||
14
src/Helpers/ProgressBarInterface.php
Normal file
14
src/Helpers/ProgressBarInterface.php
Normal file
|
|
@ -0,0 +1,14 @@
|
||||||
|
<?php
|
||||||
|
|
||||||
|
declare(strict_types=1);
|
||||||
|
|
||||||
|
namespace Phred\ConsoleContracts\Helpers;
|
||||||
|
|
||||||
|
interface ProgressBarInterface
|
||||||
|
{
|
||||||
|
public function start(int $max = 0): void;
|
||||||
|
|
||||||
|
public function advance(int $step = 1): void;
|
||||||
|
|
||||||
|
public function finish(): void;
|
||||||
|
}
|
||||||
20
src/Helpers/TableInterface.php
Normal file
20
src/Helpers/TableInterface.php
Normal file
|
|
@ -0,0 +1,20 @@
|
||||||
|
<?php
|
||||||
|
|
||||||
|
declare(strict_types=1);
|
||||||
|
|
||||||
|
namespace Phred\ConsoleContracts\Helpers;
|
||||||
|
|
||||||
|
interface TableInterface
|
||||||
|
{
|
||||||
|
/**
|
||||||
|
* @param array<string> $headers
|
||||||
|
*/
|
||||||
|
public function setHeaders(array $headers): void;
|
||||||
|
|
||||||
|
/**
|
||||||
|
* @param array<mixed> $row
|
||||||
|
*/
|
||||||
|
public function addRow(array $row): void;
|
||||||
|
|
||||||
|
public function render(): void;
|
||||||
|
}
|
||||||
14
src/InputInterface.php
Normal file
14
src/InputInterface.php
Normal file
|
|
@ -0,0 +1,14 @@
|
||||||
|
<?php
|
||||||
|
|
||||||
|
declare(strict_types=1);
|
||||||
|
|
||||||
|
namespace Phred\ConsoleContracts;
|
||||||
|
|
||||||
|
interface InputInterface
|
||||||
|
{
|
||||||
|
public function getArgument(string $name, mixed $default = null): mixed;
|
||||||
|
|
||||||
|
public function getOption(string $name, mixed $default = null): mixed;
|
||||||
|
|
||||||
|
public function hasOption(string $name): bool;
|
||||||
|
}
|
||||||
19
src/InteractionInterface.php
Normal file
19
src/InteractionInterface.php
Normal file
|
|
@ -0,0 +1,19 @@
|
||||||
|
<?php
|
||||||
|
|
||||||
|
declare(strict_types=1);
|
||||||
|
|
||||||
|
namespace Phred\ConsoleContracts;
|
||||||
|
|
||||||
|
interface InteractionInterface
|
||||||
|
{
|
||||||
|
public function ask(string $question, ?string $default = null): string;
|
||||||
|
|
||||||
|
public function confirm(string $question, bool $default = true): bool;
|
||||||
|
|
||||||
|
public function secret(string $question): string;
|
||||||
|
|
||||||
|
/**
|
||||||
|
* @param array<string|int, mixed> $choices
|
||||||
|
*/
|
||||||
|
public function choice(string $question, array $choices, mixed $default = null): mixed;
|
||||||
|
}
|
||||||
26
src/OutputInterface.php
Normal file
26
src/OutputInterface.php
Normal file
|
|
@ -0,0 +1,26 @@
|
||||||
|
<?php
|
||||||
|
|
||||||
|
declare(strict_types=1);
|
||||||
|
|
||||||
|
namespace Phred\ConsoleContracts;
|
||||||
|
|
||||||
|
interface OutputInterface
|
||||||
|
{
|
||||||
|
public function write(string $message): void;
|
||||||
|
|
||||||
|
public function writeln(string $message): void;
|
||||||
|
|
||||||
|
public function success(string $message): void;
|
||||||
|
|
||||||
|
public function info(string $message): void;
|
||||||
|
|
||||||
|
public function error(string $message): void;
|
||||||
|
|
||||||
|
public function warning(string $message): void;
|
||||||
|
|
||||||
|
public function comment(string $message): void;
|
||||||
|
|
||||||
|
public function setVerbosity(int $level): void;
|
||||||
|
|
||||||
|
public function getVerbosity(): int;
|
||||||
|
}
|
||||||
14
src/Verbosity.php
Normal file
14
src/Verbosity.php
Normal file
|
|
@ -0,0 +1,14 @@
|
||||||
|
<?php
|
||||||
|
|
||||||
|
declare(strict_types=1);
|
||||||
|
|
||||||
|
namespace Phred\ConsoleContracts;
|
||||||
|
|
||||||
|
final class Verbosity
|
||||||
|
{
|
||||||
|
public const QUIET = 0;
|
||||||
|
public const NORMAL = 1;
|
||||||
|
public const VERBOSE = 2;
|
||||||
|
public const VERY_VERBOSE = 3;
|
||||||
|
public const DEBUG = 4;
|
||||||
|
}
|
||||||
Loading…
Reference in a new issue