Martes, Julio 10, 2007

Snapshots automáticos de SVN

Los repositorios de subversion tienen, además de una base de datos con toda la información, un directorio especial por repositorio llamado hooks donde podemos escribir scripts que se ejecutarán en diferentes situaciones. Estos scripts (bueno, o programas) pueden desde abortar un commit, a cambiar cosas, añadir información, cambiar propiedades, etc… En nuestro caso vamos a usar el hook de post-commit para generar un snapshot automático con cada nuevo tag.

Vamos a suponer que tenemos un repositorio con múltiples proyectos, cada uno de ellos con sus correspondientes ‘trunk’, ‘tags’, ‘branches’ como dice el libro de subversion. De algunos de ellos queremos hacer snapshots cuando se marque un nuevo tag, así que pondremos en el directorio hooks el siguiente script llamado post-commit ( se tiene que llamar así y además tiene que ser ejecutable, chmod +x):


#!/bin/bash
export PATH=/usr/bin:/bin
REPOS="$1"
REV="$2"
PREFIXES="/proyecto1 /proyecto2 /proyectoN"
OUTPUT_DIR=/path/donde/se/guardara/el/zip
for PREFIX in $PREFIXES; do
for tag in $(\
svn log -v -r $REV file://$REPOS | \\
awk ‘/^ *A */{if ($2~/’${PREFIX//\\//\\\\/}‘\\/tags\\/[^\\/]*$/) print $2;}/^$/{exit}’\\
); do
file=${tag##*/}
svn -r $REV export file://$REPOS/$tag $file
zip -rm $OUTPUT_DIR/$file.zip $file
done
done

(bajar) versión completa

Si tu repositorio sólo tiene un proyecto, se puede simplificar un poco más:


#!/bin/bash
export PATH=/usr/bin:/bin
REPOS="$1"
REV="$2"
OUTPUT_DIR=/path/donde/se/guardara/el/zip
for tag in $(\
svn log -v -r $REV file://$REPOS | \\
awk ‘/^ *A */{if ($2~/\\/tags\\/[^\\/]*$/) print $2;}/^$/{exit}’\\
); do
file=${tag##*/}
svn -r $REV export file://$REPOS/$tag $file
zip -rm $OUTPUT_DIR/$file.zip $file
done

(bajar) versión simplificada

posteado por PpluX @ 4:44 pm tags:recetas, subversion  

Miércoles, Febrero 28, 2007

svn:externals re-utiliza tus repositorios.

Los programadores con algo de experiencia tendemos a dar todas las vueltas del mundo necesarias antes de repetir código, por lo que también es normal que tengamos tendencia a separar un proyecto grande en varios más pequeños por aquello de reutilizar código.

Por ejemplo, en un repositorio tengo una librería que utilizo para muchos de mis proyectos, llamada SLB, y en otro repositorio tengo mi proyecto killer-ap1. El proyecto de killer-ap1 utiliza activamente SLB, hasta el punto de que voy haciendo mejoras en SLB según veo que hacen falta en killer-ap1… por lo que suelo copiar SLB enterito dentro de killer-ap1 y compilarlo todo a la vez.

$ls proyectos/killer-ap1
src
include
SLB (mi copia particular)

El problema es que esta copia esta versionada una vez en el repositorio oficial y otras tantas en cada uno de los proyectos donde la uso, concretamente en killer-ap1. Además hay que acordarse de mantener actualizadas todas esas copias… por ello los de subversion idearon una solución mejor, los svn:externals.

La propiedad svn:externals nos permite enlazar en un repositorio con otros externos a este, de forma que cuando se haga un checkout del nuestro automáticamente también se bajará los otros. Ejemplo (de la página del svnbook):

$ svn propget svn:externals calc
third-party/sounds http://sounds.red-bean.com/repos
third-party/skins http://skins.red-bean.com/repositories/skinproj
third-party/skins/toolkit -r21 http://svn.red-bean.com/repos/skin-maker

Con esto estamos diciendo que el directorio calc tiene dentro tres directorios ‘thir-party/sounds’ ‘third-party/skins’ y ‘third-party/skins/toolkit’ que hacen referencia a repositorios externos(y en el último caso una revisión concreta la 21). También le estamos diciendo a subversion que cuando pase por calc se baje automáticamente los repositorios externos, y que los mantenga sincronizados.

Para mi caso de killer-ap1 y SLB la cosa ha sido así:

svn propset svn:externals “SLB http://svn.pplux.com/SLB/trunk” path/de/killer_ap1

Esta línea dice: “en el raiz de killer-ap1 vas a poner un directorio “SLB” que está sincronizado con el repositorio http://…”

Si en vez de uno tienes varios, los separamos con “\n”, el ejemplo del svnbook hubiera sido algo como:

svn propset svn:externals “third-party/sounds http://sounds.red-bean.com/repos\n third-party/skins http://skins.red-bean.com/repositories/skinproj\n third-party/skins/toolkit -r21 http://svn.red-bean.com/repos/skin-maker” calc

Un poco largo pero ilustra lo que se pretende, tener más de un external en un mismo directorio.

Y lo mejor de todo, que todas las copias siempre están sincronizadas, ya sean externals o no :D

posteado por PpluX @ 5:57 pm tags:recetas, subversion  

Gestionado con WordPress