Google Analytics

quarta-feira, 16 de maio de 2012

Árvore de fontes

Neste post vou falar como eu costumo organizar os arquivos-fonte de meus projetos. A divisão que eu uso obviamente não é a única adequada e nem a melhor, mas tem funcionado relativamente bem. As características que foram buscadas nesta formatação são:
  • Facilidade de localização do material.
  • Formato estruturado e hierárquico.
  • Manter todo o material de entrada necessário para o trabalho versionado e baixável com um comando único.
  • Possibilidade de usar integração contínua e builds CRISP.
 Vamos então à estrutura.

project-x
├── code
│   ├── build
│   │   ├── output (não guardado no sistema de versionamento)
│   ├── internalDocs
│   │   └── TestPlans
│   ├── skels
│   ├── thirdparty
│   │   ├── bin
│   │   ├── dll
│   │   ├── include
│   │   └── lib
│   └── userDeliverables
│       ├── part1
│       ├── part2
│       ├── installers
│       └── userDocs
├── continuous-integration
└── thirdparty-originals

No primeiro nível, temos a divisão em code, continuous-integration e thirdparty-originals. Code vai conter o grosso do trabalho, e será descrito por último.

Em thirdparty-originals,  coloco todos os arquivos de peças de software de terceiros que serão usados no projeto. Importante: eu os coloco do jeito que eles vêm do terceiro, sem nenhum processamento. Todo o processamento que estes arquivos requeiram eu faço através de scripts para garantir a repetibilidade do processo e facilitar no caso de upgrade de uma peça. Os scripts de processamento criados para isto vão ficar em um lugar abaixo do dir code, que será descrito mais para a frente.


Em continuous-integration, coloco os arquivos usados para fazer integração contínua do projeto. Por exemplo, se vai ser usado cruise-control, aqui ficarão um cruise-control-config.xml e um delegating.xml.


O diretório code está organizado do modo abaixo descrito:

No diretório build, coloco os scripts de build que permitem buildar o sistema em linha de comando. Sempre procuro ter um script que permita, rodando um único comando, gerar o pacote pronto para envio para clientes. Gosto que este script crie um sub-dir chamado output e coloque seus produtos ali. Notem que este script de build master deve gerar inclusive a documentação de produto e empacotá-la do jeito necessário para a entrega (zip contendo os documentos e o instalador, por exemplo).

No diretório  internalDocs coloco a documentação de projeto. Por exemplo, diagramas de projeto, instruções de trabalho para programadores, user stories, planos de teste, etc. Vou usando sub-dirs para agrupar coisas relacionadas. Por exemplo, se tenho mais de um plano de teste, crio um sub-dir chamado testPlans, se tenho vários arquivos de user stories, crio um chamado userStories.

Em skels, coloco os arquivos de esqueleto que serão usados no projeto. É interessante que a maioria das pessoas que conheço guardam os esqueletos no armário (ok, normalmente é na pasta da qualidade ou no diretório de políticas da empresa) e não junto de onde eles são usados e, guardando no armário, não dão oportunidade de customização por projeto e muita gente acaba não usando-os por estarem longe. Eu gosto de meus esqueletos evoluindo, versionados e sempre à mão para serem usados de modo efetivo. A propósito, esqueletos são aqueles arquivos modelo que ajudam a ter uma homogeneidade visual no código e também ajudam a gente a se lembrar de detalhes como esconder o copy ctor de classes. Se você quer uns exemplos de esqueletos, de uma olhada aqui.

Em thirdparty ficam os arquivos de peças de software de terceiros, cujos originais estão em thirdparty-originals, no formato em que eles precisam estar para serem usados no projeto. Aqui ficam também os scripts necessários para transformar o que temos em thirdparty-originals para o formato necessário. Um exemplo disto é uma biblioteca de terceiros. Digamos, por exemplo, que eu use a OpenSSL em Windows. O targz dos fontes dela estaria em thirdparty-originals e um script chamado buildOpenSSL, guardado em thirdparty compilaria as libs e as copiaria para thirdparty/dll e os includes públicos para thirdparty/include.

Em UserDeliverables coloco os fontes das várias partes do projeto (ou da única parte, se for o caso) e também a documentação de produto (manual do usuário, readme, history, etc).