Build e Integração Contínua no PHP com Composer, Phing, Travis-CI e Scrutinizer-CI

Olá, pessoal,

Há tempos que não fazia uma limpeza no meu Github, seja para excluir projetos que não fazem mais sentido, forks que não ia mais utilizar, ou mesmo para atualizar algum repositório e me lembrar de tudo que venho estudando desde que conheci o Github (segundo o site dos caras, outubro de 2010).

  

E foi no meio dessa limpeza (na verdade bem no começo mesmo :-) ) que achei o https://github.com/rogeriopradoj/ManoWars, fork de um projeto criado pelo Rafael Dohms e pelo Augusto Pascutti há muito tempo para ensinar sobre Testes Unitários e Integração Contínua.

Foi aí que pensei: porque não dar uma relembrada no assunto, e também atualizar com coisas que tenha aprendido nesse período (poxa, são quase 3 anos!)?

Phing???

Logo Phing

Muita coisa ainda não havia tocado, caso do Phing, que o Hussani e o Duodraco já haviam apresentado mais de uma vez em palestras. Também não estava muito habituado com as ferramentas para geração de relatórios de métricas, como o PHPMD, ou o PDepend.

Mas aí estava a graça, um bom desafio! E com a ótima estrutura que o Dohms e o Pascutti haviam deixado, não foi tão difícil começar.

Composer

Composer logo

A primeira coisa que fiz foi usar o Composer para gerenciar as dependências do projeto.

Aqui uma decisão tinha que ser tomada: o projeto foi todo baseado em PHP 5.2+, e eu poderia continuar deixando essa versão como a mínima necessária. Só que muitas das ferramentas de métricas e o próprio PHPUnit que hoje está disponível via Composer é apenas 5.3+. Então decidi subir para 5.3 a dependência mínima.

Como o Composer além de gerenciar as dependências também gera um autoloader completo (tanto com o código do meu projeto quanto das dependências), pude retirar sem dó o Zend/Loader que estava no projeto, pois ele não era mais necessário.

E com um mágico $ composer install estava lá: todas as dependências na pasta vendor, um autoloader funcional completo, e o melhor, todas as ferramentas binárias (PHPUnit, PHPPdepend etc., e o próprio Phing) já disponíveis também na pasta vendor/bin.

É, o Composer é uma mão na roda!

E lógico, com o PHP 5.4+ com servidor web embutido, foi brincadeira de criança subir testar a aplicação rodando no navegador, só com um $ php -S localhost:8080 -t public.

Estrututura de pastas e arquivos

Como o Composer coloca todas as dependências dentro da pasta vendor na raiz, e é meio que padrão os projetos PHP que vejo deixarem uma estrutura baseada na raiz também, mudei um pouquinho as pastas de lugar. A maior mudança foi colocar as pastas que estavam dentro de ManoWars na raiz, assim a hierarquia ficou um pouco menor.

  • /libs: contém o código da aplicação
  • /public: o document root do servidor web
  • /tests: testes unitários
  • init.php: bootstrap da aplicação (usado tanto na aplicação web quanto nos testes)

phpunit.xml.dist

Já havia lido sobre a vantagem de usar o phpunit.xml.dist no artigo [Best practice] How to ship PHPUnit configuration do test.ical.ly, e até já mandei um Pull Request para o Ophportunidades sobre isso.

Então foi um passo para criar um arquivo de configuração para o PHPUnit, já desde o começo um .dist.

Vantagem: agora para rodar o phpunit não é preciso entrar na pasta tests, é só rodar a partir da raiz. Outro ponto, não é mais necessário o arquivo AllTests.php, pois a definição da suíte de testes é feita também nesse arquivo de configuração.

PHP CodeSniffer

Uma task do Phing que não estava sendo executada era a de verificação do padrão de codificação, com o phpcs. Pensei em colocar o padrão PSR2 logo de cara, mas como o projeto foi feito a muito tempo, muitos erros iriam aparecer. Preferi deixar com o padrão Zend que foi provavelmente o que o Dohms e o Pascutti usaram.

Na minha lista de tarefas está evoluir o padrão para PSR2.

Outras ferramentas

Todas as ferramentas que estão sendo usadas para métricas, testes e build estão no composer.json, dê uma olhada lá, ok?

README

E no LEIAME do projeto a principal mudança foi trocar o formato para Markdown (na verdade o GFM) que é uma beleza para escrever e o Github já faz a renderização muito bem para HTML.

Ferramentas de Integração Contínua Online (Travis e Scrutinizer)

Depois de todos os pequenos ajustes, era hora de mexer de verdade no projeto.

A primeira coisa que percebi é que tinham poucos testes falhando. Tinha a ver com a API do PHPUnit ter mudado, e com um teste que esperava nulo, mas na verdade o método retornava um inteiro. Fiz o ajuste nos testes e eles passaram a funcionar.

Agora era hora de resolver todos os outros problemas do código: padrão de codificação, aumentar cobertura de testes, complexidade, etc. etc., tudo relacionado a QA/Garantia de Qualidade. Também analisar os relatórios gerados, uma parte interessante que nunca tinha olhado mais de perto.

Mas por que não ser um pouco poser e colocar um monte de badges no projeto? Esses badges seriam para mostrar a evolução do projeto, e fui atrás das ferramentas online que me permitiriam isso

Travis

Logo do Travis

Comecei pela mais conhecida, o Travis-CI, que já tinha usado em outros projetos. Nele começei colocando o PHPUnit para rodar, nas 3 últimas grandes versões do PHP, 5.3, 5.4 e 5.5.

O Travis conta um conceito interessante de matriz de build, onde você cruza algumas configurações e o build é feito em todas as combinações dela. Isso me ajudou no passo seguinte.  O Travis já tem um executável do PHPUnit disponível para usarmos, mas eu gostaria de rodar o PHPUnit instalado pelo Composer também. Fácil: criei uma variável de ambiente RUN, que no primeiro momento era definida como phpunit, e no segundo momento como vendor/bin/phpunit. E o Travis se encarregou de rodar os builds 6 vezes (3 versões do PHP x 2 PHPUnit diferentes).

No fim, coloquei mais uma definição para a variável de ambiente RUN como vendor/bin/phing, e o Phing inteiro foi rodado lá no Travis, muito bacana!

Scrutinizer

Logo do scrutinizer

Só um problema: o Travis sozinho não avalia os relatórios gerados. Foi aí que peguei o Scrutinizer-CI, que já havia também usado anteriormente, mas quando o Alexandre Eher lembrou dele no PHPSPub de Agosto, vi que era uma boa ideia usá-lo de verdade.

Depois de bater um pouco de cabeça, consegui fazer a maioria das métricas serem executadas, e no fim, o que mais queria: os badges!!!

Travis
Scrutinizer – Quality
Scrutinizer – Coverage

E para renderizar o README um pouco melhor, e lógico que usando outra ferramenta online, fui de DocumentUp.

É isso aí, pessoal, escrevi bastante e tem bastante coisa para fazer ainda.

Se quiser acompanhar, lá no https://github.com/rogeriopradoj/ManoWars.

Até mais!

 

Este artigo foi publicado originalmente em RogerioPradoJ.com.

E o site do PHPSP voltou!

Olá, pessoal,

Voltar aqui para dizer que o site do PHPSP, http://www.phpsp.org.br, voltou ao ar e cheio de conteúdo!

O processo começou em março no Hackathon PHPSP que ocorreu no iMasters, e durante esses meses veio sendo feito a passos largos (mudança de hospedagem, criação do tema, novos colaboradores, etc etc.).

E na reunião de 08/08/2013 do grupo foram fechadas uma série de novidades!

Eventos, encontros, artigos novos, tudo beleza!

Tem até um artigo meu lá, http://phpsp.org.br/index.php/pra-nao-dizer-que-nao-falei-de-vagrant/, Pra não dizer que não falei de Vagrant.

É isso aí, como diz o Duodraco, We rock!!!

Este artigo foi publicado originalmente em RogerioPradoJ.com.

CodeIgniter Skeleton para uso com Composer no Packagist

Olá, pessoal!

Alguém aí usando CodeIgniter e quer facilitar o gerenciamento das suas dependências usando o Composer?

Então vai aí uma dica de pacote no Packagist:

Packagist

https://packagist.org/packages/rogeriopradoj/codeigniter-skeleton

Se você já tem o Composer instalado, é só rodar:

$ composer create-project rogeriopradoj/codeigniter-skeleton /pasta/para/seu/projeto

E se não tem o Composer instalado, está esperando o quê?!?!?! Siga a documentação oficial, e instale agora!

É isso aí, pessoal, até mais!

Este artigo foi publicado originalmente em RogerioPradoJ.com.

Plugin PHP Coding Standards Fixer (php-cs-fixer) para o PHP-Build

Olá, pessoal!

Depois do plugin do Composer para quem usa o php-build do CHH (já tinha falado dele aqui e aqui), consegui lançar mais um plugin: o Plugin do PHP Coding Standards Fixer (php-cs-fixer). Primeiro vamos contar a história do php-cs-fixer:

Logo do php-cs-fixer
Logo do php-cs-fixer

Criado pelo Fabien Potencier, chefe da Sensio Labs, o php-cs-fixer é uma ferramenta que corrige automaticamente um código fonte para seguir os padrões da PSR2. Ele foi criado com foco na correção automática do código do framework Symfony, do qual é o Fabien é mantenedor; e hoje a ferramenta está liberada com código aberto para a comunidade PHP.

Composer?

Sempre que possível, gosto de utilizar o Composer nos projetos para gerenciar minhas dependências. O php-cs-fixer está listado no Packagist, e pode ser instalado por lá, mas o que fazer nos casos que não vai usar o composer? Aí foi procurar qual a melhor forma de fazer isso: deixar a ferramenta instalada globalmente junto do meu PHP.

No próprio site oficial do php-cs-fixer eles sugerem que a forma de instalação é usando o arquivo PHAR que eles disponibilizam para download, e foi em cima desse arquivo PHAR que o plugin para o php-build foi desenvolvido.

Plugin

O que o php-build faz é o seguinte:

  • logo depois de compilar a versão sua do PHP, ele abre o plugin como um after_install
  • o plugin baixa o php-cs-fixer.phar mais recente
  • esse arquivo é renomeado para php-cs-fixer
  • ele é colocado numa pasta acessível ao PATH definido pelo php-build/phpenv nessa versão que você acabou de compilar
  • e no fim, é dada permissão de execução nesse script php-cs-fixer

Pronto! Agora, sempre que precisar rodar a ferramenta é só executar $ php-cs-fixer com os parâmetros desejados.

Considerações

Para facilitar:

– Github: https://github.com/rogeriopradoj/php-build-plugin-phpcsfixer

– DocumentUp: http://documentup.com/rogeriopradoj/php-build-plugin-phpcsfixer

Fiquem à vontade para tirar dúvidas e dizer o que acharam.

Até mais!

Este artigo foi publicado originalmente em RogerioPradoJ.com.

Python e Virtualenv no Mac OS X Mountain Lion 10.8

Este artigo é uma tradução livre de Python and Virtualenv on Mac OS X Mountain Lion 10.8, do Justin Mayer, disponível em http://hackercodex.com/guide/python-virtualenv-on-mac-osx-mountain-lion-10.8/.

A instalação do Python e do Virtualenv no Mac OS X 10.8 Mountain Lion pode ser feita de muitas formas. Embora não exista uma configuração perfeita, esse tutorial te guiará no processo de configuração de uma instalação padrão do Mountain Lion num ótimo sistema para desenvolvimento Python.

Primeiros passos

Esse guia pressupõe que você já tenha instalado o Xcode e o Homebrew. Para detalhes, siga os passos do Mountain Lion Configuration Guide.

Python

Vamos instalar a última versão 2.7.x do Python pelo Homebrew. Para que fazer isso, você pode perguntar, quando a Apple já inclui o Python no Mountain Lion? Aqui temos algumas razões:

  • O Homebrew sempre fornece a versão mais recente (hoje 2.7.4). A versão embutida no OS X está parada no 2.7.2.
  • A Apple fez mudanças significativas no Python embutido, o que pode resultar em bugs escondidos.
  • O Python do Homebrew inclui as últimas ferramentas para gerenciamento de pacotes: o pip e o Distribute.

Seguindo pelo mesmo caminho, a versão do OpenSSL no Mountain Lion, a 0.9.8) é de fevereiro de 2011, por isso estamos dizendo ao Homebrew para baixar o OpenSSL mais recente e compilar o Python com ele.

Use o comando a seguir para instalar o Python via Homebrew:

Você já deve ter alterado seu PATH como mencionado no artigo acima, certo? Caso contrário, faça isso agora.

Também podemos instalar o Python 3.x junto com o Python 2.x:

… o que facilita para testar seu código tanto no Python 2.x quanto no Python 3.x.

Pip

Digamos que você quer instalar um pacote Python, como a fantástica ferramenta para isolamento de ambientes virtualenv. Quase todo artigo para Mac OS X relacionado ao  Python diz para o leitor instalá-lo assim:

Aqui estão os motivos porque eu não faço dessa forma:

  1. instalação com permissão root
  2. instalação é feita na sistema em /Library
  3. instalação é feita pelo obsoleto easy_install em vez de usar as ferramentas mais modernas como o pip ou o Distribute
  4. o uso das ferramentas fornecidas pelo Homebrew leva a um ambiente mais confiável

 

Como você deve ter percebido, estamos usando as ferramentas fornecidas pelo Homebrew para instalar os pacotes que você quiser que estão disponíveis globalmente. Quando fizer instalações usando o pip do Python do Homebrew, os pacotes serão postos em /usr/local/lib/python2.7/site-packages, com os binários sendo colocados em /usr/local/share/python.

Controle de versão (opcional)

A primeira coisa que eu instalo pelo pip é o Mercurial. Uma vez que eu tenho repositórios Mercurial para empurrar tanto para o Bitbucket quanto para o Github, eu instalo o Mercurial e o hg-git em todos meus sistemas:

Pelo menos, você terá que adicionar umas poucas linhas no seu arquivo .hgrc para utilizar o Mercurial:

As linhas a seguir devem te permitir começar; apenas garanta que tenha alterado os valores para seu nome e endereço e-mail respectivamente.

Para testar seu o Mercurial foi configurado e está pronto para ser usado, execute o comando a seguir:

Se a última linha da saída for “No problem detected”, então o Mercurial foi instalado e configurado adequadamente.

Virtualenv

Os pacotes Python instalados pelos passos acima são globais no sentido que eles ficam disponíveis em todos os seus projetos. Isso pode ser conveniente algumas vezes, mas também pode criar problemas. Por exemplo, as vezes um projeto precisa da última versão do Django, enquanto outro precisa do Django 1.3 para manter a compatibilidade com uma extensão crítica de terceiros. Esse é um dos muitos casos de uso que o virtualenv foi criado para solucionar. Nos meus sistemas, apenas um punhado de pacotes Python de uso geral (como o Mercurial e o próprio virtualenv) ficam disponíveis globalmente – qualquer outro pacote fica confinado em um ambiente virtual.

Com essa explicação, vamos instalar o virtualenv:

Crie alguns diretórios para armazenar seus projetos e os ambientes virtuais, respectivamente:

Depois vamos abrir o arquivo ~/.bashrc…

… e adicionar algumas linhas nele:

Vamos recarregar nosso ambiente bash:

Agora nós temos o virtualenv instalado e pronto para criar novos ambientes virtuais, que serão armazenados em ~/Virtualenvs. Novos ambientes virtuais podem ser criados assim:

Se você tiver tanto o Python 2.x quanto o 3.x e quiser criar um virtualenv do Python 3.x:

… o que facilita a troca entre os ambientes foobar do Python 2.x com o do Python 3.x.

Restringindo o pip aos ambientes virtuais

O que acontece se pensarmos que estamos trabalhando em uma ambiente virtual ativo, mas na verdade não existir nenhum ambiente virtual ativo e instalarmos algo via pip install foobar? Bem, nesse caso o pacote foobar é instalado no nosso site-packages global, estragando o propósito do isolamento do nosso ambiente virtual.

Na tentativa de evitar instalar por engano via pip um pacote específico de um projeto no meu site-packages global, anteriormente eu usava o easy_install para pacotes globais e o pip embutido no virtualevn para instalar pacotes dentro dos ambientes virtuais. Isso atingia o objetivo do isolamento, uma vez que o pip estava disponível apenas dentro dos ambientes virtuais, tornando impossível para mim rodar pip install foobar por engano no meu site-packages global. No entanto o easy_install tem algumas deficiências, como a impossibilidade de desinstalar um pacote, e me vi querendo usar o pip tanto para pacotes globais quanto nos virtualenvs.

Felizmente, o pip tem um configuração com documentação escassa que diz para ele falhar se não existir uma ambiente virtual ativo, que é exatamente o que eu quero. Na verdade, nós já fizemos essa configuração acima, pela diretiva PIP_REQUIRE_VIRTUALENV=true. Por exemplo, vamos ver o que acontece quando tentamos instalar um pacote quando não temos um ambiente virtual ativo:

Perfeito! Mas, agora que essa opção está definida, como instalamos ou configuramos um pacote global. Nós podemos temporariamente desligar essa restrição adicionando o seguinte no seu ~/.bashrc:

Se no futuro quisermos atualizar nossos pacotes globais, a função acima nos permite isso dessa forma:

É claro que você podia fazer o mesmo usando PIP_REQUIRE_VIRTUALENV="" pip install --upgrade foobar, mas isso é muito mais chato de digitar.

Criando ambientes virtuais

Vamos criar um ambiente virtual para o Pelican, um gerador de site estáticos baseado em Python:

Mude para o novo ambiente e ative-o assim:

Para instalar o Pelican no ambiente virtual, vamos usar o pip:

Para mais informações sobre ambientes virtuais, leia a documentação do virtualenv.

Dotfiles

Estes são obviamente apenas os passos básicos para se ter configurado um ambiente de desenvolvimento Python. Se tiver achado este artigo útil, você pode dar uma olhada no projeto Dotfiles do Justin Mayer no Bitbucket ou no Github, que ele recentemente começou a reconstruir do zero. Ele ainda está no começo do processo de ir adicionando seletivamente um pedaço de cada vez, e logo deve aumentar isso.

É isso aí pessoal, até mais!

Este artigo foi publicado originalmente em RogerioPradoJ.com.

Plugin Composer para o PHP-Build

Olá, pessoal.

Logo do Composer
Logo do Composer

Para os que já utilizam o php-build, do CHH, foi lançado o plugin para já deixar disponível o Composer na linha de comando automaticamente a cada novo Build do PHP.

https://github.com/rogeriopradoj/php-build-plugin-composer

http://documentup.com/rogeriopradoj/php-build-plugin-composer

Eu já falei um pouco sobre o php-build nesse artigo sobre como eu atualizei a versão do meu PHP no meu Mac.

 

Feedback?

 

Este artigo foi publicado originalmente em RogerioPradoJ.com.

Como atualizar a versão do Openssl no Mac OSX Mountain Lion

Olá, pessoal,

Vou mostrar aqui como fiz para atualizar a versão do Openssl no meu Mac OSX Mountain Lion.

O Openssl atualizado é uma das dependências para compilar o PHP com a extensão Openssl.

Esse artigo ainda está relacionado com a atualização do PHP na minha máquina usando o php-build e o phpenv do CHH.

Então vamos lá, e só para não esquecer, este artigo foi baseado nessa resposta do stack overflow e nesse outro artigo aqui.

Para começar, abra seu terminal para verificar qual a versão do Openssl que você tem instalada:

$ openssl version

Aqui, aparecia a versão OpenSSL 0.9.8r 8 Feb 2011.

No momento da escrita, março de 2013, a última versão disponível no site oficial era a openssl 1.0.1e, vamos então atualizar o nosso sistema.

No início, tentei utilizar a versão disponibilizada pelo Homebrew, mas, mesmo após usar o brew install openssl e o brew link openssl --force (comandos que instalariam o Openssl e depois o registrariam como o Openssl padrão do sistema), a versão disponível no meu terminal continuava desatualizada.

Foi aí que decidi compilar eu mesmo a versão mais nova, fazendo o seguinte:

  • descobrir se o seu sistema operacional é 64bit ou 32bit, você vai precisar dessa informação mais à frente. Para isso, executar: $ uname -m. Se aparecer x86_64 seu computador é 64bit, se aparecer i386 ele é 32bit (estou supondo que o processador do seu Mac seja Intel, e não seja PowerPC. Ele já é Intel, certo? Se não for, melhor parar por aqui…)
  • baixar o fonte do Openssl, última versão, no site  http://www.openssl.org/source/ (geralmente é o primeiro link dessa página, marcado em vermelho como [LATEST]), no meu caso foi o openssl-1.0.1e.tar.gz
  • entrar pelo seu terminal onde você baixou o arquivo (padrão no Mac e na pasta Downloads dentro da sua pasta de usuário, exemplo: $ cd ~/Downloads
  • descompactar o arquivo openssl-1.0.1e.tar.gz, exemplo: $ tar -zxvf openssl-1.0.1e.tar.gz
  • entrar na pasta que acabou de ser criada com a descompactação, exemplo: $ cd openssl-1.0.1e
  • Configurar o fonte, exemplo para 64bit: $ ./Configure darwin64-x86_64-cc --prefix=/usr no-threads shared. Exemplo para 32bit$ ./Configure darwin-i386-cc --prefix=/usr no-threads shared
  • Rodar o make, tente primeiro sem usar o sudo, e, apenas se der erro, rode com o sudo. Exemplo: $ make. Apenas se tiver dado algum erro de permissão: $ sudo make
  • Rodar o make install, mesma orientação acima. Exemplo: $ make install. Se tiver dado algum erro de permissão: $ sudo make install.
  • Feche o terminal.

Pronto, agora você já deve ter instalada a última versão do Openssl, baixada diretamente do site oficial e compilada para o seu sistema.

Para confirmar que deu tudo certo, execute:

$ openssl version

Aqui para mim apareceu OpenSSL 1.0.1e 11 Feb 2013, e para você?

Deixe seus apontamentos aí nos comentários, ou entre em contato, ok?

Até mais!

Este artigo foi publicado originalmente em RogerioPradoJ.com.