Déjame decir en voz alta lo que todos callamos: el Makefile de tu proyecto PHP es una segunda base de código, escrita en un lenguaje que nadie de tu equipo domina de verdad, sostenida con tabuladores y respuestas de Stack Overflow de 2011. Nos decimos que no pasa nada porque es 'solo automatización'. Sí pasa. Es lógica sin tests y sin revisar que decide cómo despliegas, migras y reconstruyes — y en cuanto necesita un if, alguien le atornilla un script de shell y de repente mantienes tres lenguajes para publicar uno. Mi postura: si tu proyecto es PHP, tu ejecutor de tareas también debería serlo, y Castor es la primera herramienta que defiende ese argumento de forma convincente.

La propuesta es casi sospechosamente simple. Escribes funciones PHP normales y corrientes en un archivo castor.php, les plantas un atributo #[AsTask], y Castor convierte cada una en un comando de CLI. La firma de la función se convierte en la interfaz: los parámetros obligatorios pasan a ser argumentos posicionales, los opcionales se vuelven opciones, y atributos como #[AsArgument] y #[AsOption] te permiten sobrescribir los valores por defecto cuando la convención no encaja. Nada de YAML, nada de DSL, nada de boilerplate de registro. Si alguna vez has montado a mano un comando de Symfony Console, esto se siente como si por fin alguien hubiera eliminado la ceremonia y conservado el resultado.

Lo que me convenció no es la sintaxis, en todo caso — es la fontanería. Castor es una capa fina sobre componentes en los que la mayoría ya confiamos: Symfony Console para el CLI, Symfony Process detrás de run(), Filesystem y Finder detrás de fs(), nikic/php-parser para descubrir tus tareas, spatie/ssh para ejecución remota, jolicode/jolinotif para notificaciones de escritorio. Y eso importa en la práctica. Cuando tu tarea de rebuild se porta mal, estás depurando la semántica de Symfony Process que ya entiendes, no descifrando por qué Make se tragó en silencio un código de salida. Y cuando una tarea necesita lógica de verdad — reintentar una migración caprichosa, iterar sobre servicios, lanzar una excepción ante una respuesta mala — escribes el PHP que escribirías en cualquier otro sitio, con excepciones de verdad en lugar de cadenas de && cruzando los dedos.

La historia de las dependencias merece mención aparte, porque arregla lo que suele envenenar los enfoques de 'pues lo scripteo en PHP'. Castor mantiene su propio manifiesto — castor.composer.json y castor.composer.lock — e instala las dependencias de las tareas en .castor/vendor/, completamente separadas del composer.json de tu aplicación. Ejecutas castor composer require some/package y tu automatización obtiene un cliente HTTP o un parser de YAML sin contaminar las dependencias de producción ni desatar una pelea de requisitos de plataforma. ¿Necesitas una herramienta de CLI puntual? castor execute friendsofphp/php-cs-fixer fix la descarga y la ejecuta sin tocar ningún manifiesto. Esa separación es la diferencia entre un juguete y algo que puedes defender en una revisión de código.

Ahora el contraargumento honesto, porque es potente: Make está en todas partes. Está en cada runner de CI, en cada máquina de ops, en el portátil de cada colega, y seguirá ahí dentro de veinte años. Un make deploy no necesita onboarding; castor deploy necesita instalar una herramienta antes. Si tu repositorio lo tocan personas que no escriben PHP — SREs, gente de frontend, ese entusiasta de Go — un Makefile es una lingua franca y Castor es un dialecto. No pienso quitarle importancia. Pero Castor lo amortigua más de lo que esperaba: el instalador es un curl de una línea desde castor.jolicode.com, y el flag --static te da un binario autocontenido con PHP embebido, así que hasta una imagen de CI pelada o un portátil sin PHP pueden ejecutar tus tareas. La ubicuidad es un coste real, pero ahora es un coste único, no recurrente.

También hay una cuestión de madurez que conviene nombrar. Adoptar un ejecutor de tareas implica apostar a que sobrevivirá a la automatización de tu proyecto, y Make le lleva cuarenta años de ventaja. Aquí está por qué aun así me quedo con Castor para equipos de PHP: el riesgo no es realmente de Castor — es de Symfony. La herramienta es en su mayoría pegamento sobre Console, Process, Filesystem y compañía, componentes con bases de instalación enormes y horizontes de soporte largos. Si Castor desapareciera mañana, tu castor.php es PHP plano llamando a librerías bien documentadas; migrarlo es una tarde, no una excavación arqueológica. Intenta decir lo mismo de un Makefile de 400 líneas con targets .PHONY llamando a Bash llamando a Docker llamando a Bash.

Si quieres probar el agua sin una reescritura, empieza donde el dolor es menor: tus targets de QA. Un namespace qa con tareas phpunit, csFixer y phpstan — cada una una función de diez líneas que delega en run() — más una tarea qa:all que simplemente llama a las otras tres como funciones PHP normales, con argumentos con nombre como csFixer(dryRun: true). Ese último detalle es la killer feature que nadie anuncia: componer tareas es componer funciones. Sin invocaciones a sub-make, sin rituales de paso de variables, solo PHP llamando a PHP. Cuando tu equipo sienta eso, los targets de Docker vienen solos, y watch() reejecutando tareas al cambiar archivos sustituye el conjuro de entr que estabas copiando y pegando entre proyectos.

Así que aquí es donde quiero que me lleves la contraria, porque sé que esta columna va a molestar a los leales a Make — y algunos tenéis Makefiles que se merecen esa lealtad de verdad. ¿Dónde está tu línea? ¿Existe un umbral de tamaño o complejidad por debajo del cual la ubicuidad de Make gana a las tareas nativas del lenguaje, o crees que los equipos políglotas hacen inviable un ejecutor solo-PHP por muy bueno que sea? Cuéntame sobre el Makefile al que nunca renunciarías — o el que finalmente te rompió.