| name | add-command |
| description | Guia para crear o modificar comandos artisan en GitHooks (wtyd/githooks). Usa esta skill cuando el usuario quiera crear un nuevo comando, modificar un comando existente, añadir opciones al CLI, cambiar el comportamiento de un comando, o cuando mencione "nuevo comando", "añadir opción", "modificar command", "flag", "argumento CLI". También cuando se toque ConfigurationParser, FlowPreparer, FlowExecutor, o cualquier fichero en app/Commands/.
|
Crear o modificar comandos artisan en GitHooks
GitHooks usa Laravel Zero como framework CLI. Los comandos viven en app/Commands/ y se
auto-descubren por config/commands.php.
Tipos de comando
| Tipo | DI principal | Ejemplos |
|---|
| Flow/Job | ConfigurationParser, FlowPreparer, FlowExecutor | FlowCommand, JobCommand |
| Hook | ConfigurationParser, HookRunner o HookInstaller | HookRunCommand, CreateHookCommand |
| Config | ConfigurationParser, FileReader, JobRegistry | CheckConfigurationFileCommand, MigrateConfigurationFileCommand |
| Status/Info | ConfigurationParser, HookStatusInspector | StatusCommand, SystemInfoCommand |
| Build | Build | PreBuildCommand, BuildCommand |
| Legacy (deprecated) | ReadConfigurationFileAction, ToolsPreparer | ExecuteToolCommand |
Flujo v3 de un comando de ejecución
CLI (FlowCommand/JobCommand)
→ ConfigurationParser::parse() → ConfigurationResult
→ FlowPreparer::prepare() → FlowPlan
→ FlowExecutor::execute() → FlowResult
→ FormatsOutput::renderFormattedResult()
Crear un nuevo comando
1. Definir la clase
<?php
declare(strict_types=1);
namespace Wtyd\GitHooks\App\Commands;
use LaravelZero\Framework\Commands\Command;
use Wtyd\GitHooks\Configuration\ConfigurationParser;
use Wtyd\GitHooks\Exception\GitHooksExceptionInterface;
class MyCommand extends Command
{
protected $signature = 'mycommand
{name : Argumento obligatorio}
{optionalArg? : Argumento opcional}
{--fail-fast : Flag booleano}
{--processes= : Opción con valor}
{--config= : Path to configuration file}';
protected $description = 'Descripción del comando';
private ConfigurationParser $parser;
public function __construct(ConfigurationParser $parser)
{
parent::__construct();
$this->parser = $parser;
}
public function handle(): int
{
$name = strval($this->argument('name'));
$configFile = strval($this->option('config'));
$failFast = (bool) $this->option('fail-fast');
$processes = $this->option('processes');
try {
$config = $this->parser->parse($configFile);
if ($config->hasErrors()) {
foreach ($config->getValidation()->getErrors() as $error) {
$this->error($error);
}
return 1;
}
return 0;
} catch (GitHooksExceptionInterface $e) {
$this->error($e->getMessage());
return 1;
}
}
}
2. Formato del signature
IMPORTANTE — Bug conocido con shortcuts:
El formato {-c|--config=} NO funciona en Laravel Zero. Produce The "-c" option does not exist.
Hasta que se investigue la causa, usar solo la forma larga:
{-c|--config= : Path to configuration file}
{--config= : Path to configuration file}
Tipos de opciones:
{name : ...}
{name? : ...}
{name=default : ...}
{--flag : ...}
{--option= : ...}
{--option=default : ...}
3. Regla crítica: toda opción DEBE leerse y propagarse
Cada opción definida en el signature DEBE:
- Leerse en
handle() con $this->option('nombre')
- Propagarse al servicio correspondiente (FlowPreparer, FlowExecutor, etc.)
- Tener un test que verifique que el valor llega al destino
Si una opción se define en el signature pero no se usa en handle(), es código muerto que engaña al usuario.
4. Registro
Los comandos se auto-descubren desde app/Commands/. Para ocultar de la ayuda:
'hidden' => [
Wtyd\GitHooks\App\Commands\MyCommand::class,
],
5. Inyección de dependencias
Bindings en src/Container/RegisterBindings.php:
ConfigurationParser::class → (factory con ToolRegistry + JobRegistry)
FlowPreparer::class → (factory con JobRegistry)
FlowExecutor::class → (factory con OutputHandler)
HookRunner::class → (factory con FlowPreparer + FlowExecutor + FileUtils)
HookInstaller::class → (factory con getcwd)
HookStatusInspector::class → (factory con getcwd)
JobRegistry::class → JobRegistry
ToolRegistry::class → ToolRegistry
OutputHandler::class → TextOutputHandler(Printer)
Si el comando necesita una nueva dependencia, añadirla en RegisterBindings::singletons().
6. Trait FormatsOutput
Para comandos que ejecutan flows/jobs y soportan --format y --monitor:
use Wtyd\GitHooks\App\Commands\Concerns\FormatsOutput;
class MyCommand extends Command
{
use FormatsOutput;
public function handle(): int
{
$this->applyFormat($this->executor);
$result = $this->executor->execute($plan);
$this->renderFormattedResult($result);
if ($this->option('monitor')) {
$this->renderMonitorReport($result);
}
}
}
7. Manejo de errores
try {
} catch (GitHooksExceptionInterface $e) {
$this->error($e->getMessage());
return 1;
}
Para config inexistente, capturar también \Throwable porque require de un fichero
inexistente lanza ErrorException.
Checklist
Estructura
Regla de opciones CLI (CRITICA)
DI y bindings
Testing
Contexto legacy
El sistema v2 (Options/Tools/CliArguments) sigue funcionando como puente de compatibilidad.
Las clases legacy están en src/ConfigurationFile/, src/Tools/, src/LoadTools/.
El comando tool en ExecuteToolCommand.php está deprecated.
No añadir funcionalidad nueva al sistema legacy — solo mantener hasta v4.0.