2012-08-13 9 views
12

Acabo de terminar la primera versión de trabajo de un script bash más complejo, y me estoy volviendo loco sobre cómo mantener la versión de scripts.¿Cómo mantengo el número de versión de mi script bash que está controlado por git source?

¿Por qué necesito esto? Después de GNU Coding Standards For Commandline Interfaces, agregué una opción de versión que, entre una licencia y un encabezado de derechos de autor, muestra la versión actual.

Aún así, no sé cómo mantener la versión 'actualizada'.

Mi idea hasta ahora es usar etiquetas git para major | menor | parche de versiones, y de alguna manera reemplazar una variable contenida en el script.

Por lo tanto, si tengo una etiqueta llamada 1.1.0, entonces

$ myscript --version 

debe hacer salir algo como:

myscript 1.1.0 

El guión contiene una variable de shell para esto:

version=1.1.0 

Sin embargo, ahora no sé cómo mantener la versión sincronizada con la última etiqueta.

EDITAR

Sry para esta pregunta un poco confuso ...

+1

http://stackoverflow.com/questions/677436/how-to-get-the-git-commit-count/677888 también tiene algunos indicadores – VonC

Respuesta

10

Por lo que puedo decir, lo que quieres es imposible. Para que el número de versión se confirme en el software de control de versiones, debe editar el número de versión, confirmar y luego etiquetar; no de la otra manera. Sin embargo, puede tener el proceso un poco más racionalizado.

Podemos hacerlo escribiendo un enlace de confirmación posterior que leerá el número de versión de su script y, si ha cambiado desde la última vez, escriba una nueva etiqueta. Para hacer esto, cd en .git/hooks desde su directorio de proyectos, cree un archivo llamado post-commit (o mueva post-commit.sample) y hágalo ejecutable. A continuación, edite para que se vea algo como esto:

#!/bin/bash 

NEWEST_TAG=$(git describe --abbrev=0 --tags) 

SCRIPT_VERSION=$(grep "^version=" myscript | awk -F= '{print $2}') 

if [ x$NEWEST_TAG != x$SCRIPT_VERSION ]; then 
    git tag -a $SCRIPT_VERSION -m "version $SCRIPT_VERSION" 
fi 

La próxima vez te encuentras con número de versión de su guión y de confirmar sus cambios, verá una nueva etiqueta que se añade a su última confirmación.

2

En lugar de crear la etiqueta a sí mismo, utilizar un gancho post-commit. La idea es verificar si HEAD contiene una línea que modifique la asignación de versión, y si es así, crear una nueva etiqueta. Este es solo un ejemplo aproximado; puede tener errores, y definitivamente no es tan eficiente como podría ser.

#!/bin/bash 

before=$(git log HEAD | awk -F= '/-version=/ {print $1}') 
after=$(git log HEAD | awk -F= '/+version=/ {print $1}') 

if [[ $before != $after ]]; then 
    git tag myscript-$after 
fi 
2

Aún así, no sé cómo mantener la versión 'actualizada'.

Me gustan las recomendaciones de post-gancho. Sin embargo, un enfoque alternativo, también podría usar un sistema de compilación si ya tiene uno disponible. ¿Tienes un sistema de compilación automático? Jenkins o Bamboo? Nuestro sistema de compilación crea una nueva etiqueta para cada compilación exitosa que pasa todas las pruebas unitarias. De acuerdo, se trata de un script, por lo que puede que solo tenga que ejecutar pruebas unitarias, si las tiene.Puede agregar tareas en su trabajo de construcción para incrementar o hacer coincidir la versión con la etiqueta de la compilación exitosa o la última confirmación que se ejecuta y pasa las pruebas.

6

Las respuestas basadas en enganches que se dieron anteriormente juntan estrechamente la sincronización de la cadena de versión con un git commit; sin embargo, parece que quiere que funcione al revés, es decir, la versión se extrae de los metadatos git tag creados manualmente. Resulta que, de hecho, esto es más o menos el enfoque de la git source code sí utiliza, así que vamos a aprender cómo se podría adoptar algo similar mediante el examen de su enfoque:

  • que tiene una secuencia de comandos GIT-VERSION-GEN cáscara que intenta determinar de forma inteligente la corriente versión. Básicamente trata de extraer la cadena de versión a través de git describe, pero vuelve a un valor predeterminado codificado si eso no funciona. La versión está escrita en GIT-VERSION-FILE en la parte superior del árbol de fuentes.
  • El Makefile invoca este script y include s el archivo generado:

    GIT-VERSION-FILE: FORCE 
         @$(SHELL_PATH) ./GIT-VERSION-GEN 
    -include GIT-VERSION-FILE 
    

    Ahora la versión es accesible para el resto de la vía Makefile$(GIT_VERSION).

  • Varios hacer reglas a continuación, utilizar esto para realizar sustituciones en los archivos que necesitan la cadena de versión codificada, tales como varios scripts de Perl:

    $(patsubst %.perl,%,$(SCRIPT_PERL)): % : %.perl GIT-VERSION-FILE 
         $(QUIET_GEN)$(RM) [email protected] [email protected]+ && \ 
         INSTLIBDIR=`MAKEFLAGS= $(MAKE) -C perl -s --no-print-directory instlibdir` && \ 
         sed -e '1{' \ 
          [... snipped other substitutions ...] 
          -e 's/@@[email protected]@/$(GIT_VERSION)/g' \ 
          [email protected] >[email protected]+ && \ 
         chmod +x [email protected]+ && \ 
         mv [email protected]+ [email protected] 
    

    Por ejemplo, si se mira cerca del comienzo de git-svn.perl, que' Veremos:

    $VERSION = '@@[email protected]@'; 
    

En mi árbol de fuentes, esta regla ha compilado en un archivo git-svn que contiene la línea:

$VERSION = '1.7.11.rc0.55.gb2478aa'; 

por lo que si puedo comprobar la versión de mi compilado localmente git-svn, veo:

$ git svn --version 
    git-svn version 1.7.11.rc0.55.gb2478aa (svn 1.6.17) 

mientras que si funciono la instalación basada en RPM, veo:

$ /usr/bin/git svn --version 
    git-svn version 1.7.6.5 (svn 1.6.17) 

Este El último resultado demuestra que el enfoque funciona incluso cuando el código fuente se compila a partir de un tarball liberado que no contiene ningún metadato de control de versión en el subdirectorio .git/. Esto significa que la cadena de versión distingue muy bien entre lanzamientos estables e instantáneas de desarrollo.

Aunque git-svn es un script de Perl, es evidente que el mismo enfoque de sustitución funcionaría bien para su shell-script.

+1

+1 por mencionar 'git describe'. fue mi primer pensamiento también ... – eckes

+1

+1 Me gusta mucho el enfoque y aprecio la increíble explicación, pero es mucho trabajo para una secuencia de comandos que consta de alrededor de 100 líneas ... ¡todavía es una buena respuesta! – helpermethod

Cuestiones relacionadas