terça-feira, 8 de novembro de 2011

Gerenciamento de Dependências com Bundler e PIP

No post anterior, foi mostrado como criar novos projetos em Rails e Django. Neste estágio inicial de projeto, algumas preocupações começam a surgir: que bibliotecas usar no projeto? Como irei baixar e instalar essas bibliotecas? Meus colegas de time conseguirão baixar o projeto de um repositório e configurar facilmente seus ambientes com as bibliotecas selecionadas?

Neste momento, fica muito evidente o poder do RVM e do VirtualEnv, e seus companheiros Bundler e PIP.

Em Rails, as dependências são configuradas no arquivo Gemfile, gerado automaticamente na raiz do projeto quando ele é criado. Em Django, um arquivo de configuração de dependências pode ser gerado através do comando pip freeze.

Bundler e o arquivo Gemfile

Um projeto Rails 3.1 é criado inicialmente com as seguintes dependências:

Note que as versões requeridas de cada dependência são especificadas. Isto é importante para evitar que a aplicação deixe de funcionar devido à atualização de alguma das bibliotecas das quais ela depende.

Neste caso, foi declarada uma dependência exata ao Rails na versão 3.1.1. Para o uglifier, a aplicação exige no mínimo (>=) a versão 1.0.3. Para o sass-rails e para o cofee-rails, são exigidas no mínimo as versões 3.1.4 e 3.1.1, respectivamente. O operador (~>) tem um significado especial: para o sass, ele denota "qualquer versão 3.1.X maior que 3.1.4, ou posto de outra forma, maior ou igual a 3.1.4 e menor que 3.2".

Outro ponto a ser notado é que, além das versões, o Gemfile permite também o agrupamento de dependências. no trecho acima, o sass-rails, o coffee-rails e o uglifier foram colocados no grupo :assets. Outro grupo bastante comum é o :tests. Por exemplo, num projeto usando cucumber, teríamos:

Através do Gemfile, também é possível adicionar uma dependência direta ao repositório de código de uma biblioteca - desta forma, o projeto estará sempre usando o "latest build", o "nightly snapshot" dessas dependências.

Agora que já conhecemos o Gemfile, resta dizer que a instalação das dependências é simples quanto executar na linha de comando:

Este comando oferece também a opção de filtrar grupos de pacotes para não serem instalados:

PIP e o arquivo requirements.txt

Apesar de o django não gerar automaticamente um arquivo de dependências quando o projeto é criado - muito provavelmente para não amarrar o desenvolvedor ao uso do PIP - podemos usar o comando pip freeze para ter benefícios semelhantes aos proporcionados pelo Gemfile no Rails. Execute na raiz no projeto django:

E um arquivo com o seguinte conteúdo será gerado:

O nome requirements.txt não é obrigatório, mas é comumente usado. Assim como o Gemfile, pode-se especificar quais as versões são requeridas para cada dependência, porém a sintaxe é bem diferente.

Possui apenas os operadores ==, >=, >, <=, <. Para funcionalidade similar ao ~, permite combinar operadores, por exemplo: Django>=1.3,<1.4.

Também permite configurar as dependências para serem baixadas diretamente de repositórios, usando o operador -e (de "editable"):

Mais detalhes sobre como usar o -e com Mercurial, Bazar, etc em http://www.pip-installer.org/en/latest/requirement-format.html.

Diferente do Gemfile, o requirements.txt não fornece a opção de criar grupos. Para este comportamento, costuma-se agrupar as dependências em diferentes arquivos, por exemplo, um arquivo test-requirements.txt para testes. Dada esta filosofia, existe a opção de incluir arquivos dentro de outros, através do -r

Agora que já conhecemos o requirements.txt, podemos executar o comando pip install -r para instalar as dependências do projeto:

Considerações Finais

Com o Bundler e o PIP conseguimos resolver parte do problema: gerenciar as dependências do projeto. No próximo post, será simulado um segundo e grande benefício: a facilitação do setup do projeto em outras máquinas, por exemplo, entre os vários integrantes do time.

Nenhum comentário:

Postar um comentário