SVN:Externals – recursos externos em seus projetos

SubversionQue o Subversion é uma ótima ferramenta, todo mundo sabe. Mas muitos – assim como eu – acabam não a utilizando por completo, por falta de conhecimento.

Descobri o svn:externals (External Definitions é o nome correto) da pior forma possível: tendo mais trabalho que o necessário para manter dependências em projetos.

Mas em que o svn:externals facilita?

Estou recomeçando um projeto (PHPCashControl) que já estava parado há um bom tempo (e que não tinha nada além de um ‘hello world’). Decidi então utilizar o Zend Framework.

Seguindo a sugestão de estrutura de diretórios, precisava incluir o ZF dentro do meu projeto. Para isso, tinha algumas opções:

  1. Baixar a biblioteca compactada, descompactá-la em um diretório qualquer e copiar os arquivos para meu projeto, depois fazer o commit para atualizar meu projeto com a versão mais nova do ZF baixado.
  2. Criar um diretório qualquer, e nele fazer o checkout do trunk do ZF. Fazer um export desse diretório para dentro do meu projeto e, depois disso, fazer o commit para atualizar o repositório do meu projeto.

Consegue perceber os contratempos?

  1. Tenho que estar sempre preocupado em verificar se existem novas versões para as bibliotecas externas que utilizo, principalmente correções críticas. No meu caso é o Zend Framework, mas pode ser qualquer outra, como por exemplo a Smarty Template, PHPMailer, dentre outras.
  2. Além disso, tenho o trabalho de sempre baixar a última versão do seu repositório (ou baixar sua respectiva versão compactada) e enviar para o repositório do meu projeto.

Entra em cena a propriedade svn:externals
Ela permite utilizar recursos de diferentes repositórios, ou de diferentes lugares (diretórios) de um repositório no seu projeto. Basicamente, é um tipo de link para outro repositório SVN. Usando-a, você adiciona código de (vários) repositórios dentro de um único working copy.

Definindo a propriedade em nosso projeto
Vamos utilizar a mesma idéia do PHPCashControl. Temos um projeto e queremos adicionar a biblioteca ZF nele.

No raiz de nosso projeto temos os seguintes diretórios:

1
2
3
4
app
data
library
public

É dentro de library que adicionaremos o ZF. Estando no diretório raiz do projeto, basta executar no terminal:

1
2
3
svn propedit svn:externals library http://framework.zend.com/svn/framework/standard/trunk/library/Zend/
svn commit -m "Adicionado recurso externo do Zend Framework"
svn update

Na linha 1 definimos o diretório Zend (e seus subdiretórios) de seu repositório para ser importado dentro da pasta library de nosso working copy. Na linha de baixo, fazemos o commit para gravar essa alteração no repositório, com o comentário para descrever o motivo desse commit. Só depois do terceiro comando que você receberá os arquivos do repositório do ZF.

Importante: o diretório Zend não pode existir dentro do diretório library. Ele será criado automaticamente.

Externals Definitions no Eclipse PDT com Subclipse
Utilizando o plugin Subclipse para o Eclipse PDT também é muito fácil de definir recursos externos.

Para adicionar o ZF em nosso projeto pelo Eclipse:

  1. Clique com o botão direito na pasta library;
  2. Depois clique em Team, e em seguida Set Property;
  3. Em Property name, selecione svn:externals na combo;
  4. Na caixa de texto abaixo – deixe a opção Enter a text property marcada – informe o caminho do repositório. No nosso caso: http://framework.zend.com/svn/framework/standard/trunk/library/Zend/
  5. Clique em OK;
  6. Clique com o botão direito no diretório raiz do projeto, depois clique em Team e Commit;
  7. Na caixa de texto coloque o motivo do commit: Adicionado recurso externo do Zend Framework e clique em OK;
  8. Depois clique novamente com o botão direito no diretório raiz do projeto e, por fim clique em Team, depois Update;

Atenção com as revisions
Se definirmos a propriedade svn:externals conforme demonstrado nos exemplos acima, podemos ter um grande problema, caso esse não seja o comportamento esperado. Explico.

Criamos uma tag de nosso projeto na revision 10. No momento da criação da nossa tag, a revision do ZF era 15060, por exemplo. O ZF continua recebendo commits em seu repositório, e digamos que depois de 10 dias da nossa tag, a revision do ZF seja 16000. Ao fazermos o checkout da tag de nosso projeto, ao invés de termos a revision 15060 do ZF dentro do diretório library, teremos a versão 16000. É exatamente esse o problema, principalmente se há uma grande mudança no projeto do qual o teu projeto depende.

Para evitar esse tipo de problema, é recomendado que você crie dependências (svn:externals) apenas de tags de outros projetos, ou então, que se especifique a revision da qual se pretende criar a dependência.

Para criar uma dependência de uma tag, basta informar seu caminho. Exatamente como nos exemplos anteriores. O que muda nesse caso é apenas o endereço do repositório:

1
2
3
svn propedit svn:externals library http://framework.zend.com/svn/framework/standard/tags/release-1.7.8/library/Zend/
svn commit -m "Adicionado recurso externo da tag 1.7.8 do Zend Framework"
svn update

Para criar uma dependência da revision 15000 do trunk do ZF:

1
2
3
svn propedit svn:externals library -r15000 http://framework.zend.com/svn/framework/standard/trunk/library/Zend/
svn commit -m "Adicionado recurso externo da revision 15000 do trunk do Zend Framework"
svn update

Perceba o parâmetro -r15000 na linha 1 acima.

Versões utilizadas no post

  • Subversion 1.6.1 Build 16129 – 64 Bit
  • Eclipse Platform 3.4.2 Build id: M20090211-1700
  • PDT 2.0.0.v20081229-1135

Referências:

Posts relacionados:

  1. Integrando o Doctrine com o Zend Framework
  2. Surviving the deep end

This entry was posted in Artigos and tagged , , , , , , , , , . Bookmark the permalink.

2 Responses to SVN:Externals – recursos externos em seus projetos

  1. Thiago Paes says:

    Muito boa a dica, vou utilizar…

    Parabéns.

  2. Cara, fantástico! Mas é sempre bom monitorar os changelogs das bibliotecas para não ver se precisamos mudar alguma coisa em nossos códigos.

Leave a Reply

Your email address will not be published. Required fields are marked *

*

You may use these HTML tags and attributes: <a href="" title=""> <abbr title=""> <acronym title=""> <b> <blockquote cite=""> <cite> <code> <del datetime=""> <em> <i> <q cite=""> <strike> <strong> <pre lang="" line="" escaped="">