waffle-commons / console
A minimalist, zero-magic CLI runtime for Waffle Commons: commands registered explicitly at boot, constructor-injected dependencies, plus the Waffle Maker code generators.
Requires
- php: ^8.5
- waffle-commons/contracts: 0.1.0-beta6
- waffle-commons/utils: 0.1.0-beta6
Requires (Dev)
- carthage-software/mago: ^1.29
- cyclonedx/cyclonedx-php-composer: ^6.2
- igor-php/igor-php: ^0.7.0
- php-mock/php-mock-phpunit: ^2.15
- phpunit/phpunit: ^12.5
- vimeo/psalm: ^6.16
Suggests
None
Provides
None
Conflicts
None
Replaces
None
This package is auto-updated.
Last update: 2026-09-08 20:24:25 UTC
README
Waffle Console Component
Release:
0.1.0-beta6Β |ΒCHANGELOG.md
A minimalist, zero-magic CLI runtime for the Waffle Framework (RFC-012). Commands are registered explicitly at boot β no auto-discovery β and resolve their dependencies through constructor injection.
π¦ Installation
composer require waffle-commons/console
π§± Surface
| Class | Role |
|---|---|
Waffle\Commons\Console\ConsoleApplication |
final implementation of ConsoleApplicationInterface. Owns the command registry and the run loop. |
Waffle\Commons\Console\Command\AbstractCommand |
Base class β implements CommandInterface with shared helpers. |
Waffle\Commons\Console\Command\CacheClearCommand |
cache:clear β flushes the configured CacheInterface backend. |
Waffle\Commons\Console\Command\RouteListCommand |
route:list β renders the compiled route table. |
Waffle\Commons\Console\Command\SecurityAuditCommand |
security:audit β walks controllers and prints the resolved access ladder (#[Rule] / #[Voter]). |
Waffle\Commons\Console\Command\MigrateCommand |
db:migrate β applies pending SQL migrations through the contracts MigrationRunnerInterface, then resets the pool. |
Waffle\Commons\Console\Command\MemoryAuditCommand |
igor:audit β streams the monorepo-wide Igor memory-leak audit through the contracts AuditRunnerInterface. |
Waffle\Commons\Console\Command\DataWarmupCommand |
data:warmup β pre-compiles SQR trees / routing tables into OPcache shared memory through the contracts DataWarmerInterface (Beta-3). |
Waffle\Commons\Console\Maker\Command\Make*Command |
The nine Waffle Maker scaffolders (RFC-020): make:controller, make:dto, make:entity, make:repository, make:middleware, make:voter, make:command, make:http-client, make:event-pair. |
Waffle\Commons\Console\Input\ArgvInput |
InputInterface implementation parsing argv. |
Waffle\Commons\Console\Output\StreamOutput |
Default OutputInterface writing to STDOUT / STDERR. |
Waffle\Commons\Console\Output\NullOutput |
Silent OutputInterface for tests / quiet runs. |
Waffle\Commons\Console\Exception\ConsoleException |
Base exception (implements ConsoleExceptionInterface). |
Waffle\Commons\Console\Exception\CommandNotFoundException |
Thrown when find($name) cannot resolve. |
Waffle\Commons\Console\Exception\InvalidArgumentException |
Thrown on invalid CLI argument shape. |
π Quick start
The exact signature of ConsoleApplication::__construct, verbatim from src/ConsoleApplication.php:
public function __construct( private readonly string $name = Constant::DEFAULT_APP_NAME, private readonly string $version = '0.0.0', private readonly OutputInterface $output = new StreamOutput(), ?array $argv = null, // null β reads $_SERVER['argv'] ) { /* β¦ */ }
And the run loop:
use Waffle\Commons\Console\ConsoleApplication; use Waffle\Commons\Console\Command\CacheClearCommand; use Waffle\Commons\Console\Command\RouteListCommand; $app = new ConsoleApplication(name: 'My App', version: '1.0.0'); // your app's name/version $app->add(new CacheClearCommand($cache)); $app->add(new RouteListCommand($router)); exit($app->run()); // argv read from constructor, returns int exit code
πͺ Public API
final class ConsoleApplication implements ConsoleApplicationInterface { public function getName(): string; public function getVersion(): string; public function add(CommandInterface $command): void; public function has(string $name): bool; public function find(string $name): CommandInterface; // throws CommandNotFoundException public function all(): array; public function run(): int; // returns ExitCode::*->value }
run():
- With no arguments, prints the available-commands listing and exits with
ExitCode::USAGE. - The built-in
listcommand name reprints the same listing withExitCode::SUCCESS. -v/-vv/-vvv/--verbose/--very-verbose/--debug/--quietflags adjust output verbosity viaOutputInterface::setVerbosity(Verbosity).- Dispatches to the resolved command's
execute(InputInterface, OutputInterface): int. ConsoleExceptionInterfaceand any otherThrowableare caught and returned asExitCode::FAILURE, with the message printed to stderr.
π PHP 8.5 features used
final class ConsoleApplication.- Constructor property promotion +
private readonlyon every dependency. - Default
OutputInterface $output = new StreamOutput()β PHP 8.1new in initializers. enum ExitCode: intandenum Verbosity(from contracts) for typed exit codes / verbosity levels.- Typed constants via
Waffle\Commons\Contracts\Console\Constant.
π§ Architectural boundary (mago guard)
An active dependency perimeter is enforced on every CI run by vendor/bin/mago guard (bundled into composer mago; zero baselines). The rules live in mago.toml under [guard.perimeter] β a forbidden use statement fails the build, not a reviewer.
Production code under Waffle\Commons\Console may depend only on:
Waffle\Commons\Console\**β itselfWaffle\Commons\Contracts\**β the shared contracts package, the only Waffle dependency permittedPsr\**β PSR interfaces@global+Psl\**β PHP core and the PHP Standard Library
Test code under WaffleTests\Commons\Console is unrestricted (@all). Structural rules are guarded too: interfaces must be named *Interface, Exception\** classes must end in *Exception, and any Enum\** namespace may hold only enum declarations.
Contract-first, component-agnostic by construction: components compose through waffle-commons/contracts, never directly through one another.
π§ͺ Testing
docker exec -w /waffle-commons/console waffle-dev composer tests
π Documentation
Central framework docs (DiΓ‘taxis) for this component:
- Reference:
reference/console.md - Explanation:
explanation/aot-compilation.md - Full documentation tree: waffle-commons/documentation
π License
MIT β see LICENSE.md.