2012-08-13 12 views
12

Ho appena terminato la prima versione funzionante di uno script di bash più complesso, e sto pensando a come mantenere la versione degli script.Come faccio a mantenere il numero di versione del mio script bash controllato da git source?

Perché ho bisogno di questo? Dopo GNU Coding Standards For Commandline Interfaces ho aggiunto un'opzione di versione che tra l'intestazione di licenza e copyright mostra la versione corrente.

Ancora, non so come mantenere la versione 'aggiornata'.

La mia idea è di usare i tag git per major | minore | patch rilascia e sostituisce in qualche modo una variabile contenuta nello script.

Quindi, se ho un tag di nome 1.1.0, quindi

$ myscript --version 

dovrebbe produrre qualcosa di simile:

myscript 1.1.0 

Lo script contiene una variabile di shell per questo:

version=1.1.0 

Tuttavia, non ora come mantenere la versione sincronizzata con l'ultimo tag?

EDIT

Sry per questa domanda un po 'di confusione ...

+1

http://stackoverflow.com/questions/677436/how-to-get-the-git-commit-count/677888 ha anche alcuni puntatori – VonC

risposta

10

Per quanto posso dire, quello che vuoi è impossibile. Per poter inserire il numero di versione nel software di controllo della versione, devi modificare il numero di versione, eseguire il commit, quindi taggare; Non il contrario. Puoi comunque avere il processo un po 'più snello.

Possiamo farlo scrivendo un hook post-commit che leggerà il numero di versione dello script e se è stato modificato dall'ultima volta, scrivere un nuovo tag. Per fare ciò, cd in .git/hooks dalla directory del progetto, creare un file chiamato post-commit (o spostare post-commit.sample) e renderlo eseguibile. Quindi modificarlo in modo che appaia qualcosa di simile:

#!/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 

prossima volta che si imbatterà il numero di versione del copione e commit delle modifiche, vedrete un nuovo tag aggiunto al tuo ultimo commit.

2

Invece di creare il tag da soli, utilizzare un post-commit hook. L'idea è di verificare se HEAD contiene una linea che modifica l'assegnazione della versione e, in tal caso, creare un nuovo tag. Questo è solo un esempio approssimativo; potrebbe essere bacato, e non è sicuramente così efficiente come potrebbe essere.

#!/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

Ancora, non so come mantenere la versione 'aggiornata'.

Mi piacciono i consigli post-hook. Tuttavia, un approccio alternativo, potresti anche utilizzare un sistema di build se ne hai già uno disponibile. Hai un sistema di compilazione automatico? Jenkins o Bamboo? Il nostro sistema di build crea un nuovo tag per ogni build di successo superando tutti i test unitari. Dato che si tratta di uno script, è possibile che tu debba solo eseguire i test unitari, se li hai.È possibile aggiungere un'attività nel processo di compilazione per incrementare o abbinare la versione con il tag della build di successo o dell'ultima commit che esegue e supera tutti i test.

6

Le risposte basate su hook precedentemente fornite accoppiano strettamente la sincronizzazione della stringa di versione con un git commit; tuttavia sembra che tu voglia che funzioni al contrario, ovvero la versione viene estratta dai metadati git tag creati manualmente. Si scopre che in realtà questo è più o meno l'approccio della git source code si utilizza, quindi cerchiamo di imparare come si potrebbe adottare qualcosa di simile, esaminando il suo approccio:

  • Ha uno script GIT-VERSION-GEN shell che tenta di determinare in modo intelligente la corrente versione. Essenzialmente tenta di estrarre la stringa della versione tramite git describe, ma ricade su un valore predefinito hardcoded se non funziona. La versione è scritta in GIT-VERSION-FILE nella parte superiore dell'albero dei sorgenti.
  • Il Makefile invoca questo script e include s il file generato:

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

    Ora la versione accessibile al resto della Makefile via $(GIT_VERSION).

  • Vari fare le regole quindi utilizzare questo per eseguire le sostituzioni su tutti i file che devono la stringa della versione hardcoded, come ad esempio vari script 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] 
    

    Per esempio se si guarda verso l'inizio del git-svn.perl, è' ll vedere:

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

Nel mio albero dei sorgenti, questa regola ha compilato un file git-svn che contiene la linea:

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

quindi se controllo la versione del mio locale compilato git-svn, vedo:

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

mentre se corro l'installazione rpm-based, vedo:

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

Questo l'ultimo output dimostra che l'approccio funziona anche quando il codice sorgente è compilato da un tarball rilasciato che non contiene alcun metadata di controllo della versione nella sottodirectory .git/. Ciò significa che la stringa di versione distingue bene tra versioni stabili e snapshot di sviluppo.

Anche se git-svn è uno script Perl, chiaramente lo stesso approccio di sostituzione funzionerebbe correttamente per lo script di shell.

+1

+1 per menzionare 'git describe'. è stato anche il mio primo pensiero ... – eckes

+1

+1 Mi piace molto l'approccio e apprezzo la splendida spiegazione, ma è solo molto lavoro per una sceneggiatura composta da circa 100 linee ... ancora una buona risposta! – helpermethod

Problemi correlati