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