Phing

Phing, automatizar tareas, instalación y ejemplo de despliegue en local

La primera vez que conocí un automatizador de tareas fue con Ant para Java, desde el primer momento me quede maravillado del poder de esta herramienta, desde poder crear y borrar carpetas o ficheros hasta desplegar todo un proyecto entero mediante ssh y tan solo haciendo click. La verdad es que es muy útil para olvidarte de tener que hacer ciertas tareas repetitivas.
Despues de unos años trabajando con Java y con Ant, volví al mundo de PHP. Tenía que empezar un proyecto con Symfony y obviamente queria poder tener la posibilidad de hacer todo lo que hacia con Ant, así que me puse a investigar y descubrí que existe una herramienta para automatizar tareas en PHP y aquí es donde entra Phing, que no es otra cosa que un port de Ant.
Tal y como aparece en su documentación oficial:

PHing Is Not GNU make; it’s a PHP project build system or build tool based on ​Apache Ant. You can do anything with it that you could do with a traditional build system like GNU make, and its use of simple XML build files and extensible PHP “task” classes make it an easy-to-use and highly flexible build framework.

Con Phing, al igual que con Ant, se define un fichero XML en el que se especifican las diferentes tareas que queremos automatizar, como he dicho, estas tareas pueden ir desde la creación de directorios, dar permisos, despliegues de proyectos o la ejecución de test unitarios.

Así que, manos a la obra y vamos a instalar esta herramienta en nuestros equipos. La mejor manera de instalar Phing es a través de PEAR y del canal PEAR de Phing, así pues hay que entrar en la terminal e introducir los siguientes comandos.

pear channel-discover pear.phing.info
pear install --alldeps phing/phing

Si por un casual nos da un error en la instalación diciendo que no hay publicaciones disponibles para el paquete, la solución pasa por limpiar la cache de PEAR.

pear clear-cache

Una vez que se haya instalado, para utilizarlo en nuestro proyecto tan solo tendremos que activar el plugin de Phing en las opciones de configuración de nuestro Jetbrains PhpStorm.
Por lo general, todas las distribuciones de PhpStorm ya vienen con el plugin activo.

Lo siguiente que tendremos que hacer será crear un fichero en la raíz de nuestro proyecto con el nombre build.xml y ahí escribir las tareas o targets.
Lo bueno de las tareas automatizadas es que no son independientes unas de otras, sino que desde una tarea puedes hacer una llamada a otra o incluso pueden existir tareas que dependan de otras para que puedan ser ejecutadas.

Por ejemplo, para desplegar una proyecto en local se suelen seguir las siguientes tareas.

  • Borrar directorio de despliegue
  • Crear directorio de despliegue
  • Mover archivos y directorios
  • Dar permisos si fuera necesario

Así pues definiríamos un primer target inicial llamado “crear_proyecto” que sería el encargado de ejecutar el resto de tareas.

<target name=”crear_proyecto” depends=”crear_directorio”>
<echo msg=”Copiando proyecto a /var/www/proyecto ….”/>
<exec command=”cp -R /home/usuario/Proyectos/proyecto/ /var/www/proyecto/”/>
<phingcall target=”dar_permisos”></phingcall>
</target>

Tal y como se puede ver, la primera linea define nuestro primer target, mediante el atributo name especificamos el nombre de la tarea y con el atributo depends le decimos a Phing que ejecute la tarea que especifiquemos antes que nuestro target principal.

La segunda linea imprime un mensaje de salida por la terminal, es una buena practica ir imprimiendo mensajes para así conocer en todo momento en que tarea se encuentra la ejecución.

La tercera línea hace una llamada al ya tan conocido cp para mover el proyecto, realmente mediante la instrucción exec puedes hacer llamadas a cualquier comando que utilizarias de normal en la terminal.

La cuarta línea realiza mediante la instrucción phingcall una llamada a otra tarea que hayamos definido.

Antes de ejecutar este target se llama a la tarea crear_directorio. que no hace otra cosa que preparar el entorno y los directorios para alojar el proyecto en el servidor local.

<target name=”crear_directorio” depends=”borrar”>
<echo msg=”Creando directorio /var/www/proyecto”/>
<mkdir dir=”/var/www/proyecto”/>
</target>

Como se puede ver, esta nueva tarea, también depende de otra llamada borrar. Lo único que hace es imprimir un mensaje de salida (buenas prácticas) y crear la carpeta proyecto dentro del servidor.

La tarea de la que depende, borrar, como su nombre indica, borra la carpeta del servidor para así más tarde realizar un despliegue limpio.

<target name=”borrar”>
<echo msg=”Borrando directorio en /var/www/proyecto”/>
<exec command=”rm -rf /var/www/proyecto”/>
</target>

Realmente he comenzado los ejemplos por el final pero la secuencia lineal de las tareas al hacer click sobre nuestro target principal crear_proyecto sería la siguiente:

Click tarea crear_proyecto > Llamada crear_directorio > Llamada borrar > Ejecución instrucciones borrar > Ejecución instrucciones crear_directorio > Ejecución instrucciones crear_proyecto > Llamada tarea dar_permisos > Ejecución instrucciones dar_permisos

La última tarea, dar_permisos, la que es llamada desde el target principal mediante phingcall, es tan sencilla como escribir la instrucción exec y hacer una llamada al comando chmod.

target name=”dar_permisos_chmod”>
<echo msg=”Dando permisos chmod a /var/www/proyecto”/>
<exec command=”chmod -R 777 /var/www/proyecto”/>
</target>

Con estas tareas, estaríamos copiando todo nuestro proyecto al servidor y asegurándonos que se realiza un despliegue limpio. Como veis Phing es muy util y eficiente en su tarea, podemos hacer cualquier cosa que se nos ocurra con un par de instrucciones nada mas. En post mas adelante contare como definir y utilizar variables para no tener que repetir el origen y destino del proyecto por ejemplo o como conectar con un servidor remoto mediante ssh y copiar el proyecto mediante scp.

Así pues, la sintaxis aprendida hoy es la siguiente:

  • target: define una nueva tarea, como atributo obligatorio name para nombrar esa tarea y como atributo opcional depends si queremos que se ejecute otra tarea antes.
  • echo: imprime un mensaje de salida por la terminal, debemos especificar le mensaje dentro del atributo msg
  • exec: ejecuta el comando de terminal especificado dentro del atributo command
  • phingcall: ejecuta la tarea especificada en el atributo target
  • mkdir: crea un directorio en la ruta indicada en el atributo dir

Esta es un primer acercamiento al poder de Phing, sin duda se le puede sacar mucho más jugo, pero para ir empezando a manejar esta herramienta no esta mal. Dejo el código del ejemplo totalmente montado tanto aquí como en pastebin.

<?xml version=”1.0″ encoding=”UTF-8″?>
<project name=”mi-proyecto” default=”crear_proyecto”>
<target name=”crear_proyecto” depends=”crear_directorio”>
<echo msg=”Copiando proyecto a /var/www/proyecto ….”/>
<exec command=”cp -R /home/usuario/Proyectos/proyecto/ /var/www/proyecto/”/>
<phingcall target=”dar_permisos”></phingcall>
</target>
<target name=”crear_directorio” depends=”borrar”>
<echo msg=”Creando directorio /var/www/proyecto”/>
<mkdir dir=”/var/www/proyecto”/>
</target>
<target name=”borrar”>
<echo msg=”Borrando directorio en /var/www/proyecto”/>
<exec command=”rm -rf /var/www/proyecto”/>
</target>
<target name=”dar_permisos_chmod”>
<echo msg=”Dando permisos chmod a /var/www/proyecto”/>
<exec command=”chmod -R 777 /var/www/proyecto”/>
</target>
</project>

Gorka Muñoz Andrés

Me llamo Gorka Muñoz y soy un desarrollador melómano. Combino a la perfección la búsqueda de nuevos grupos con la pasión por la tecnología. Desde chiquitito me ha gustado la programación, ahora que soy mayor estoy metido en el mundo del SEO sin olvidarme del /Dev.

This Post Has 3 Comments

  1. Pingback: Cómo instalar Android Studio en Linux - GM

  2. Pingback: Sobre los permisos en symfony y cual es mi solución - Gorkamu

  3. Pingback: Gulpjs o cómo librarnos de tareas repetitivas - Gorkamu

  4. Maria

    Hola Gorkamu muy interesante el artículo. Sigue así 😉

Deja un comentario

Tu dirección de correo electrónico no será publicada. Los campos obligatorios están marcados con *