Back-End

1 jul, 2013

Building com Phing

Publicidade

Salve, meus caros! Vou apresentar, para quem já não conhece, uma ferramenta de build feita em – e para – PHP. Você pode estar se perguntando: “Build? PHP é uma linguagem de script, então, pra que build?” ou mesmo: “O que é Build?”. Pois é, meu caro, quando precisamos automatizar tarefas entram as ferramentas de build, ou buildtools. Dentre as mais famosas estão o Make e o Ant. E para o nosso PHP temos o Phing (http://phing.info). Vou tentar passar bem rápido o conceito sobre building com o Phing em 7 parágrafos.

Uma execução de build nada mais é do que a execução em sequência de diversas tarefas pré-determinadas – sendo que se uma falhar, a execução não continua. Aí você pode pensar: “Ah, mas isso posso fazer via PHP mesmo; em um script”. Sim, pode. Mas pense em cada detalhe que isso pode ter, qual a complexidade que essas tarefas podem tomar, além de executar a tomada de decisão de continuar ou não a execução e ainda atribuir dependências entre tarefas? O Phing já resolve esses problemas e é extensível, ou seja, você pode criar tarefas novas para sua execução. É possível utilizá-lo como pacote phar ou mesmo obtê-lo via composer [phing/phing] – idealmente o instalamos via PEAR:

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

Assim como seu (distante) parente Ant, que atua para Java, o Phing utiliza XML para sua configuração. Basicamente declaramos um Projeto; dentro dele, Alvos (que agrupam tarefas e definem dependências) e dentro deles, Tarefas – tudo via tags XML. No exemplo a seguir, podemos identificar cada um desses elementos – “echo” no caso é uma tarefa. Por padrão, descrevemos a execução em um arquivo build.xml, mas podemos quebrá-lo em mais arquivos para organizar melhor e/ou usar dependências específicas, mantendo o inicial sem dependências.

build.xml

<?xml version="1.0" encoding="UTF-8"?>
<project name="7masters-1" default="start">
 <target name="start" depends="step-a,step-b,step-c"/>
 <target name="step-a">
 <echo msg="Este é o Projeto ${phing.project.name}"/>
 </target>
 <target name="step-b">
 <echo msg="Nunca chegaremos ao Passo C :D"/>
 <php expression="11/0" returnProperty="erro" level="error"/>
 <fail if="erro" msg="Você está vendo esta pois há um erro"/>
 <echo msg="você não verá essa mensagem" />
 </target>
 <target name="step-c">
 <echo msg="O Phing parou a execução do build"/>
 </target>
</project>

Sim, dependências. O Phing, por padrão, já tem tarefas que vão agilizar seu dia a dia – desde operações de filesystem, prompt para entrada de dados de usuário (via linha de comando!), estruturas condicionais (sim, no XML mesmo), execução de comandos shell ou PHP. Além disso, ele permite que você crie novas tarefas via PHP, ou embutindo código PHP no próprio XML. Como se não bastasse, o Phing conta com várias tarefas opcionais, que são habilitadas caso as dependências para cada uma delas esteja disponível. PHPUnit (com Code Coverage), Git, Requests HTTP, Lint, Amazon, SVN… Só para começar!
Vou dar um exemplo: vamos começar um projeto do zero. Sempre usamos a mesma estrutura de diretórios, sem um framework, mas no mínimo já queremos colocar um monolog para funcionar. Os códigos abaixo mostram como fazemos isso já usando o composer (considerando que o composer esteja disponível na sua raíz).

build.xml

<?xml version="1.0" encoding="UTF-8"?>
<project name="7masters-2" default="start">
 <target name="start" depends="composer,update,dirs"/>
 <target name="composer">
 <available file="composer.phar" property="composer.exists"/>
 <echo msg="${composer.exists}"/>
 <if>
 <not>
 <isset property="composer.exists"/>
 </not>
 <then>
 <php expression="file_put_contents('composer.phar',file_get_contents('https://getcomposer.org/installer'))" />
 <exec command="php composer.phar"/>
 <composer command="install"/>
 </then>
 </if>
 </target>
 <target name="update">
 <composer command="update"/>
 </target>
 <target name="dirs">
 <mkdir dir="application/library" />
 <mkdir dir="tests" />
 <mkdir dir="web/style" />
 <mkdir dir="web/script" />
 <mkdir dir="web/media" />
 </target>
</project>

composer.json

{
 "name":"7maters",
 "require":{
 "php":"5.3.*",
 "monolog/monolog":"1.5.*"
 }
}

“Ok, automatiza tarefas. O que mais isso pode fazer?” Já ouviu falar de Integração Contínua? É uma atividade vinda de metodologias ágeis que visa integrar o código de um projeto, vindo de diversas fontes (desenvolvedores fazendo commit e push, por exemplo) e integrá-lo de maneira segura e contínua. Como “segura”? Realizando testes de maneira automática a cada nova entrada de código e certificando que o branch específico do projeto ou um servidor de testes somente tenha código testado. Testado como? PHPUnit, CodeSniffer, PMD, PHPCPD, PDepend… Se você ficou com uma interrogação na cabeça para qualquer um dos itens que citei, aconselho que abra o google e pesquise por cada um deles – seu conhecimento agradece. Imagine que cada nova porção de código passe automaticamente por cada um desses testes para, só então, ser integrada com o código existente.

Mas não para por aí. Pense na infinidade de maneiras de automatizar o deploy de suas aplicações minificando os ativos CSS e Javascript, limpando caches e atualizando o banco de dados sem precisar se matar. Com um email de confirmação no fim do processo ainda! Pense em como seu trabalho de testar tudo localmente pode ficar melhor, se executar tudo de maneira uniforme. Ou mesmo fazendo uma execução de instalação para o time de infraestrutura, dando prompts para customizar a configuração de uma aplicação – inclusive para a Amazon. Ahh, para que tudo isso aconteça você deve idealmente estar na raíz do projeto, onde está o build.xml, e entrar com um comando um pouco extenso:

phing

O Projeto é muito bem documentado e estável. Tem com controle de bugs e versionamento, um time bacana desenvolvendo e bastante gente usando – inclusive Symfony e Zend Framework.

Procure conhecer ferramentas de build e as boas práticas no seu uso, para, então, tirar o melhor proveito dessa ferramenta. Contribua com o projeto: Phing é um programa modular; esteja livre para criar novas funcionalidades – na maior parte dos casos o time de desenvolvimento ficará feliz em incluí-las no projeto. Este que vos escreve é um usuário assíduo da ferramenta e está muito contente com os resultados. Good Phinging!

(em 7 parágrafos, não disse? :P)

***

Este artigo foi publicado originalmente na Revista iMastersAcesse e leia todo o conteúdo.