martes 20 de enero de 2009
Automatizando el proceso de build de tu proyecto (2/n)
Development tRee
Seguimos con las series dedicadas a automatizar el proceso de build para nuestros proyectos.
En esta entrada definiremos un development tree a utilizar en nuestro proyecto. Esto no es más que un nombre sofisticado para denominar una estructura de organización para todos los ficheros que forman nuestros proyectos, ya sean ficheros de código, recursos, scripts, etc.
Esta no sólo persigue la organización de los ficheros, sino que es básico que tengamos una estructura "estandar" para poder referenciar los diferentes elementos de cara a construir un script que podamos reutilizar. Entrecomillo estándar porque obviamente no hay unas reglas categóricas para estructurar nuestros proyectos: es algo que depende de nuestros gustos y necesidades.
La estructura de directorios (representados por \) y los ficheros (representados por ->) que tengo definida actualmente es la siguiente.
base
|- \tools
|
|- \builds
| -> <MainProjectName>.<builddate>.zip
| |-\output
| |-\reports
| |-\documentation
| -> ...
|
|- \libs
|
|- \projects
| |- \<VisualStudioProject1>
| | |- \Properties
| | -> guid.txt
| | -> version.txt
| | -> publickey.snk
| |- \<VisualStudioProject2>
| | |- \Properties
| | -> guid.txt
| | -> version.txt
| | -> publickey.snk
| |- ...
| |
| |- \<VisualStudioProjectN>
| | |- \Properties
| | -> guid.txt
| | -> version.txt
| | -> publickey.snk
| |- \tests
| |- \unit
| |- \ui
| |- \ ...
|
|- \resources
|- \icons
|- \images
|- \sounds
|- ...
La idea es que la estructura completa desde el directorio root va al repositorio de código, de forma que al hacer un checkout obtengamos todo lo necesario para generar el proyecto, aunque eso implique que tendremos datos repetidos entre diferentes proyectos.
- root: Aquí va el fichero de build para NAnt y algunos más que servirán para definir
- tools: En este directorio van los binarios necesarios para el proceso de build: NAnt, NUnit, etc.
- builds: Aquí se generará las última build del proyecto. Contendrá un fichero zip con el proyecto listo para ejecutar y opcionalmente unos informes con los resultados de las pruebas y la documentación.
- libs: Todas las librerías externas necesarias para generar el proyecto van aquí. Pueden organizarse también en subdirectorios si es necesario
- projects: Aquí van todos los ficheros de código necesarios para generar el proyecto. En mi caso sólo tengo en este directorio el fichero de solución de visual studio. El resto de proyectos va cada uno en un subcarpetas:
- <VisualStudioProjectN> Contiene el código y el fichero de proyecto de Visual studio para generar un assembly (librería o ejecutable). En la subcarpeta Properties tenemos además tres ficheros necesarios para generar siempre un assembly firmado:
- guid.txt: contiene un número Guid asociado al proyecto
- publickey.snk: clave pública para fir
- version.txt: contiene un número de versión para el ensamblado en formato Major.Minor.Build.Revision.
- guid.txt: contiene un número Guid asociado al proyecto
- tests: Aquí van todos los proyectos de visual studio con los assemblies de tests que utilicemos en el proyecto, también organizados en subcarpetas si es necesario.
- <VisualStudioProjectN> Contiene el código y el fichero de proyecto de Visual studio para generar un assembly (librería o ejecutable). En la subcarpeta Properties tenemos además tres ficheros necesarios para generar siempre un assembly firmado:
- resources: Resto de ficheros que pertenecen al proyecto: imágenes con logos, sonidos, etc.
Por supuesto aquí hay bastante margen para añadir cosas: scripts para generar bases de datos, ficheros de localización, etc. La idea principal a transmitir es que una vez definida una estructura que nos sirva, podemos automatizar el proceso de generación en base a dicha estructura. Por ejemplo podemos crear un target para NAnt que compile todo fichero .csproj encontrado en projects/tests, y luego utilizando esos resultados, ejecutar nunit desde la consola de comandos para generar un informe que nos indique el estado de los tests.
En mi proceso, además, he definido propiedades para cada uno de los directorios principales de la estructura, de forma que sea más cómodo utilizarlo en los scripts. Por ejemplo, para acceder al directorio root se define la propiedad ${dir.root}. Para acceder al directorio de proyectos, utilizo ${dir.projects}. Para ser consistente en realidad ésta última debería ser ${dir.root.projects}, pero hace que las propiedades aumenten su tamaño, y decidí optar por eliminarlo. Las propiedades se definirían:
<properties>
<!-- DO NOT DELETE ANY PROPERTY DEFINED IN THIS FILE -->
<property
name="dir.root"
value="${project::get-base-directory()}" />
<property
name="dir.tools"
value="${dir.root}/tools" />
<property
name="dir.resources"
value="${dir.root}/resources" />
<property
name="dir.builds"
value="${dir.root}/builds" />
<property
name="dir.libs"
value="${dir.root}/libs" />
<property
name="dir.projects"
value="${dir.root}/projects" />
<property
name="dir.tests"
value="${dir.projects}/tests" />
<property
name="dir.tests.unit"
value="${dir.tests}/unit" />
<property
name="dir.projects.temp"
value="${dir.projects}/tmp" />
<property
name="dir.projects.temp.output"
value="${dir.projects.temp}/output" />
<property
name="dir.projects.temp.reports"
value="${dir.projects.temp}/reports" />
<property
name="dir.projects.temp.docs"
value="${dir.projects.temp}/docs" />
</properties>
Y eso es todo por hoy! Cualquier comentario o sugerencia sobre la estructura elegida será -como siempre- bien recibida.
Automatizando el proceso de build de tu proyecto 1





0 Comentarios:
Publicar un comentario en la entrada