cerbero/command-validator
Cerbero Command Validator brings Laravel-style validation to Artisan console commands. Define rules for arguments and options, validate input before your command runs, and show clear errors—making CLI tools safer and easier to maintain.
Architecture fit. cerbero/command-validator is a single-responsibility Laravel package that injects Laravel's existing Validator into the console kernel's command lifecycle, letting an Artisan command declare $rules for its arguments and options rather than hand-rolling if (! is_numeric($this->argument('id'))) checks inside handle(). Architecturally this is a thin decorator over two stable framework contracts (Illuminate\Console\Command and Illuminate\Contracts\Validation\Factory), so it does not introduce a new abstraction or a parallel validation dialect — it reuses rule strings, rule objects, custom messages and attribute names that the team already knows. That is the strongest argument in its favour: near-zero conceptual surface area and no new mental model to onboard.
Integration feasibility. High on paper, contingent on one gate: framework version support. With 223 stars and zero dependents, this is a low-signal, likely single-maintainer project; the practical question is whether its composer.json constraints track our current Laravel major. Because service-provider auto-discovery and the console lifecycle have been stable since Laravel 5.5, the code is probably trivially forward-portable even if the manifest is stale, but we should confirm rather than assume. Integration is additive and per-command, so the blast radius of a failed pilot is one command.
Technical risk. Low-to-moderate, and almost entirely supply-chain rather than technical. The code surface is small enough to audit in under an hour, MIT-licensed, and forkable at negligible cost. The real risks are: (1) abandonment — a Laravel major bump with no upstream release forces an internal fork; (2) semantic mismatches at the edges — how it handles array options (--tag=*), negatable/boolean flags, variadic arguments, and interactive prompts versus --no-interaction in CI; (3) exit-code behaviour — a validation failure must yield a non-zero exit code and machine-parseable stderr, or it will silently break deployment scripts and pipelines that rely on artisan return codes; (4) programmatic invocation — whether commands dispatched via Artisan::call() or the scheduler get the same validation treatment as a shell invocation. Items (2)–(4) are the ones that actually bite in production; they are testable in a day.
Key questions for the maintainer/sponsor.
--no-interaction handled?Rule::in/Rule::enum supported, or only string rules?--json-style output is requested?Stack fit. Narrow but clean: Laravel/Artisan CLI only. It fits internal tooling, operational runbooks, data-migration commands, seeding/backfill commands, and any Artisan command that is invoked from CI or a deploy pipeline by humans or scripts. It is not applicable to standalone Symfony Console apps, non-Laravel PHP services, or commands we intend to extract into a framework-agnostic binary — so treat it as an internal-DX investment, not a platform component. Given the low adoption signal (0 dependents) and opportunity score of 24.68, it should be scoped as a local standard, not a company-wide mandate.
Migration path. Purely additive and reversible: adopt the trait/base class on one command, keep the existing manual checks in place behind it, and delete the manual checks only after parity is proven in tests. Because the package is MIT and tiny, the credible exit strategy is "vendor it" — copy the trait into our own app/Console/Concerns directory and drop the dependency if upstream goes quiet. That escape hatch is what makes adoption low-risk; document it up front so we never feel locked in.
Compatibility. Pin the constraint, commit composer.lock, and add an upgrade-checklist item for every Laravel major: run the command test suite, confirm the package resolves, confirm exit codes. If a fork becomes necessary, the fork becomes the pinned source and the constraint points at it.
Sequencing.
$rules lives, how messages are declared, what the failure output must look like, how array options are expressed.Maintenance. The dominant ongoing cost is not code — it is tracking an unmaintained dependency across Laravel upgrades. With 0 dependents and a single maintainer, assume "abandoned" as the base case and price the fork accordingly: under a day of engineering to internalise, which is cheaper than a single blocked framework upgrade. Assign explicit ownership; a dependency in the deploy path with no owner is a latent incident.
Support. No vendor, no SLA, no security advisory channel beyond GitHub. Acceptable for internal tooling invoked by engineers who can read the stack trace; not acceptable anywhere in a customer-facing path. Ramp-up is effectively zero for anyone who already writes Laravel validation rules — the learning cost is "where do I put $rules", which the standards doc covers in one paragraph.
Scaling. Runtime cost is a single Validator instantiation per command invocation — noise. There is no query, no cache, no network, no new infrastructure, no config surface worth managing. Scaling concerns are organisational, not technical: the convention spreads by copy-paste, so the risk is drift — five commands each expressing array-option validation slightly differently — rather than load. Counter that with the standards doc and a shared base class.
Failure modes to instrument.
composer update resolves a Laravel major that the package does not support, or resolves one whose behaviour changed. Guard with a pinned constraint plus a smoke test in CI.Ramp-up. Under a day for a Laravel-fluent engineer, and that estimate should be treated as the ceiling for the whole evaluation: this is a small, tidy convenience that removes boilerplate from a handful of Artisan commands. It is worth adopting as an internal standard behind a one-command pilot and a documented vendor-it escape hatch — and not worth a platform initiative, a cross-team rollout, or any dependency in the critical deploy path that we are not prepared to own.
How can I help you explore Laravel packages today?