Sep 09

Hooks en subversion

Hace ya un par de años que me convertí en el administrador del repositorio de subversion de nuestro departamento. Incluso prestamos servicio de subversion a otros departamentos para sus proyectos.

Uno de los problemas que me he encontrado es que la gente por despiste, por "pasotismo"  o por no saber dónde guardar las cosas, mete en subversion ficheros binarios (.exe, .dll, etc) documentos (.doc, .docx, .pdf), etc, etc que no es el sitio adecuado para guardarlos, además que abusar de ello puede llenar el disco en un pis-pas. Y no es un problema específico de un administrador de subversion, pero tampoco me gusta que la gente suba a subversion sin poner el correspondiente comentario en el commit.

Así que me puse a investigar cómo evitarlo y descubrí los "hooks" de subversion. Son scripts que se guardan en el servidor y que se ejecutan cuando ocurren ciertas acciones en subversion, como un commit, un bloqueo, etc.

En el directorio /path/REPOSITORIO_SVN/hooks de un proyecto basta con poner un script de nombre pre-commit.bat (en windows también vale un pre-commit.exe o pre-commit.com, para unix bastaría un fichero de nombre pre-commit, sin extensión, con permisos de ejecución) que se ejecutará siempre que se intente hacer un commit y se ejecutará antes del commit, pudiendo rechazarlo en un momento dado. Ese directorio ya está lleno de scripts con extensión .tmpl, no ejecutables por tanto. Cada uno corresponde a uno de los posibles "hooks" y nos bastaría con copiarlo poniendo extensión .bat (o dándole permisos de ejecución en linux) y modificarlo por dentro para que haga lo que queramos.

Este script debe salir de forma normal (exit 0) si el commit se acepta, y salir con error (exit 1) si no se acepta el commit. En este último caso, lo que el script saque por la salida de error estándar, será lo que subversion le muestre al usuario como mensaje de error.

El que yo he puesto, pre-commit.bat, verifica las extensiones de los ficheros que se quieren subir y verifica que hay un comentario. El script es el siguiente y me disculpareis si hay forma mejor de hacerlo (seguro que la hay), pero se más bien nada de "scripts" en windows.

 

set REPOS=%1
set TXN=%2
svnlook changed %REPOS% -t %TXN% | findstr ".\exe \.dll \.o \.lib \.a \.so \.jar \.class \.doc \.docx \.pdf \.zip" >&2
if %errorlevel% equ 0 (goto err)
 
svnlook log %REPOS% -t %TXN% | findstr . > nul
if %errorlevel% gtr 0 (goto err2)
 
exit 0
 
:err
echo No se admiten ficheros binarios >&2
exit 1
 
:err2
echo Como no metas un comentario …. >&2
exit 1

 

Como parámetros del script, subversion nos pasará el repositorio y una "cosa extraña" que contiene la información de lo que se está pretendiendo meter. Nos guardamos esos dos parámetros %1 y %2 en las variables REPOS y TXN.

El comando de subversion svnlook, pasándole estas dos cosas, es capaz de darnos información sobre el commit. Así, svnlook changed nos da un listado de los ficheros que se pretenden modificar/añadir/borrar. svnlook log nos da el comentario del commit.

El comando findstr de windows nos permite buscar una cadena. En el primer uso buscamos extensiones de ficheros no permitidos. En el segundo caso, buscamos cualquier caracter (el punto de findstr equivale a cualquier caracter). Este comando findstr da un error si no encuentra la cadena, por lo que inmediatamente detrás pongo un if de %errorlevel% (que es donde se guarda si ha habido error) para decidir si se acepta el commit (exit 0) o saco algún error.

En fin, las posibilidades serían muchas, como verificar si el comentario lleva un número de incidencia para admitirlo, analizar el contenido del fichero que se va a meter buscando cosas no permitidas (código sin comentar, que no cumpla métricas, paths absolutos dentro, etc) o incluso ¿por qué no? si compila o no compila y pasa los test.

Jun 04

Migrando a Subversion

 

¡¡ Por fin tenemos nuestro primer proyecto migrado a subversion !!.

La historia ha sido una verdadera odisea. Normalmente usamos CVS, pero en el momento de empezar a trabajar con ramas un poco en serio, el tema se hacía demasiado pesado. CVS crea las ramas recorriendo todos los ficheros del repositorio y marcando la rama para cada uno de ellos. Crear una rama en CVS tardaba cerca de media hora en cada proyecto implicado. Subversion, al tener todo el repositorio con un número de versión único, no necesita recorrer todos los ficheros uno a uno para hacer la rama, le basta con marcar en algún sitio que en ese número de versión comienza una rama. Tarda como la mitad de medio segundo (es un decir) en hacer la rama de un repositorio, independientemente de la cantidad de ficheros que haya almacenados.

Por otro lado, nuestro servidor de CVS se estaba quedando "viejito". Una estación solaris del año del "catapúm" con 128 megas de ram (al que hace poco se le estropeo un módulo de 64 y creo que de esos ya no hay ni el rastro), con el disco duro (de pocos gigas) permanentemente al 99%. Total, que se imponía también un cambio de máquina.

Así que aprovechando lo uno con lo otro, decidí que nos pasabamos a Subversion en un servidor nuevo. Dicho….. y a esperar.

Primero convencer a la gente de las excelencias de Subversion sobre CVS. Como siempre, a unos pocos les parece estupendo, a muchos les importa tres pepinos y a algunos lo de "¿Para qué vamos a cambiar si ahora funciona?". A base de dar la paliza, conseguí convencer (o al menos dejaron de protestar) a todos.

Después lo de conseguir el servidor nuevo. Ni el departamento ni los proyectos para los que trabajamos estaban dispuestos a comprar un servidor (pensé seriamente en ir a tomar los cafés encima del servidor actual, para que ocurriera "una desgracia"). Así que a negociar con el departamento de informática de la empresa, a ver cuánto nos cobran por darnos un subversion en uno de sus servidores. Tras mucho tira y afloja (y sobre todo gracias a la persona que nos hizo de intermediaria en la software lab con la que trabajamos), nos dieron el subversion gratis. Entre pedir el servidor a los proyectos, intentar convencerles y hablar con el departamento de informática pasaron casi dos meses.

Y hoy, por fin, la primera migración. Me bajé el cvs2svn e intenté migrar uno de nuestros proyectos. Desgraciadamente, intenté hacerlo sobre windows y no hubo manera. Tenía el cygwin y teóricamente todo lo necesario, pero me fallaba en un punto en el que se hace una llamada al comando "sort". El de windows no vale, porque funciona distinto del de unix. El de cygwin aparentemente me daba problemas porque se liaba con las \ de los directorios (al ser unix, espera / de directorio). Me bajé los UnxUtils, pero al ejecutar el comando sort daba un error muy raro (insuficiente espacio en disco, o algo así, habiendo más de 20 Gigas libres). Así que reinicié el ordenador para arrancar en linux y ahí fue todo rodado a la primera.

Total, ya tenemos nuestro primer proyecto en subversion. El primero de una larga lista de ellos que debemos ir migrando poco a poco.

Nov 21

Apaches como setas

 

Ultimamente me ha dado por probar algunas herramientas nuevas e incluso volver a probar algunas que ya había probado. En concreto, me he vuelto a instalar un servidor de subversion, he vuelto a intentar instalar trac, también otra cosa que he encontrado por equivocación y que se llama traks (una aplicación web para usar GDT, con lo cual me resultó interesante), etc, etc.

Como soy vago y encima estoy mal acostumbrado a Windows, para todas ellas me he buscado instaladores de windows, de esos que se instala todo solo con un par de clicks. En concreto, he usado los instaladores de bitnami, u otros del estilo, cuya principal ventaja es que con un par de clicks instalan TODO lo necesario para tener la aplicación funcionando.

Y la ventaja de estos instaladores es precisamente su problema.

Casi todo lo que he instalado son aplicaciones web, así que creo que tengo todos los puertos desde el 8080 al 9999 ocupados con servidores apache, cada uno para su aplicación. Debo tener como tres o cuatro versiones de python instaladas en distintos directorios (que además ya tenía instaladas previamente), varios servidores MySql y sabe Dios cuántas cosas más por tripitido.

Menos mal que después de probada un poco la aplicación, se desinstala igual de fácil que se ha instalado.

Por cierto, los tra* no me van bien. trac me sigue pareciendo demasiado complejo de configurar sin el instalador, aparte de que me da errores al ejecutar los python. Y el bitnami stack de track, después de la instalación, me ha fallado en el arranque, por lo que no he podido siquiera verlo en marcha.

Nov 12

Más de Subversion

Hace poco me tocó hacer una rama CVS de los proyectos para estabilizar una versión para unas pruebas con el cliente. Ya se sabe, rama del repositorio del proyecto y rama de todos los repositorios con librerías que utilice el proyecto.

Pues bien, ha sido horrible. Son cuatro o cinco repositorios y cada uno de los proyectos/librerías a "enramar" tienen fácilmente tres mil ficheros java. Eché toda la tarde en hacer las dichosas ramas. Primero un update, luego el cvs tag para poner una etiqueta justo en el punto donde comienza la rama y luego el cvs tag -b para crear la rama. Al hacerlo CVS fichero a fichero, media hora larga con algunos de los repositorios mientras cvs hace el trabajo.

Se me ocurrió, harto de ello, montar un servidor de subversion, migrar alguno de los repositorios CVS a subversion (usando cvs2svn) y mirar a ver cuánto tarda subversion en hacer la rama (svn cp). Es casi inmediato, ya que realmente no realiza la copia real de todos los ficheros (lo hará cuando se vayan modificando si se van modificando) y tampoco tiene que andar recorriendo todos los ficheros para ver su versión actual (CVS tienen un número de versión para cada fichero, mientras que subversion tiene un único número para todo el repositorio).

Todo el mundo habla que los sistemas de control de versiones distribuidos, estilo Bazaar o Git son maravillosos. También se habla mejor de Subversion que de CVS, aunque no todos lo hacen. A mí realmente todo eso me parece bien, pero mientras no veo una necesidad real o una mejora importante, no veo tampoco necesidad de cambiar. Ahora sí he encontrado un motivo, así que es cuestión de empezar a mirar en serio la posibilidad de migrarlo todo a Subversion.

De momento descarto Bazaar o Git por tener menos soporte para los IDEs habituales (eclipse en concreto). Tampoco tengo muy claro lo veloz que puede ser hacer un branch de un repositorio grande si eso implica la copia completa de todo el repositorio, con su historia (ya digo, repositorios de tres mil clases java con cuatro o cinco años de historia y alrededor de veinte desarrolladores de media desarrollando día a día).