Versione dell’applicazione Golang per la compilazione automatica

È ansible incrementare automaticamente un numero di versione minore ogni volta che viene compilata un’app Go?

Mi piacerebbe impostare un numero di versione all’interno del mio programma, con una sezione autoincremento:

$ myapp -version MyApp version 0.5.132 

Essendo 0.5 il numero di versione impostato, e 132 un valore che aumenta automaticamente ogni volta che il binario viene compilato.

È ansible in Go?

Il linker Go ( go tool link ) ha un’opzione per impostare il valore di una variabile stringa non inizializzata:

 -X importpath.name=value Set the value of the string variable in importpath named name to value. Note that before Go 1.5 this option took two separate arguments. Now it takes one argument split on the first = sign. 

Come parte del processo di compilazione, è ansible impostare una variabile di stringa di versione utilizzando questo. Puoi passare questo attraverso lo strumento go usando -ldflags . Ad esempio, dato il seguente file sorgente:

 package main import "fmt" var xyz string func main() { fmt.Println(xyz) } 

Poi:

 $ go run -ldflags "-X main.xyz=abc" main.go abc 

Per impostare main.minversion alla data e all’ora di costruzione durante la costruzione:

 go build -ldflags "-X main.minversion=`date -u +.%Y%m%d.%H%M%S`" service.go 

Se si compila senza inizializzare main.minversion in questo modo, conterrà la stringa vuota.

Ho avuto problemi nell’usare il parametro -ldflags durante la creazione della mia app di riga di comando mista e progetto di libreria, quindi ho finito per utilizzare una destinazione Makefile per generare un file di origine Go contenente la versione della mia app e la data di costruzione:

 BUILD_DATE := `date +%Y-%m-%d\ %H:%M` VERSIONFILE := cmd/myapp/version.go gensrc: rm -f $(VERSIONFILE) @echo "package main" > $(VERSIONFILE) @echo "const (" >> $(VERSIONFILE) @echo " VERSION = \"1.0\"" >> $(VERSIONFILE) @echo " BUILD_DATE = \"$(BUILD_DATE)\"" >> $(VERSIONFILE) @echo ")" >> $(VERSIONFILE) 

Nel mio metodo init() , lo faccio:

 flag.Usage = func() { fmt.Fprintf(os.Stderr, "%s version %s\n", os.Args[0], VERSION) fmt.Fprintf(os.Stderr, "built %s\n", BUILD_DATE) fmt.Fprintln(os.Stderr, "usage:") flag.PrintDefaults() } 

Se si desiderava un numero di build che aumenta in modo atomico invece di una data di compilazione, tuttavia, sarebbe probabilmente necessario creare un file locale che contenesse l’ultimo numero di build. Il tuo Makefile leggerà il contenuto del file in una variabile, lo incrementerà, lo inserirà nel file version.go anziché nella data e scriverà il nuovo numero di build nel file.

Inoltre vorrei pubblicare un piccolo esempio su come usare git e un makefile:

 --- Makefile ---- # This how we want to name the binary output BINARY=gomake # These are the values we want to pass for VERSION and BUILD # git tag 1.0.1 # git commit -am "One more change after the tags" VERSION=`git describe --tags` BUILD=`date +%FT%T%z` # Setup the -ldflags option for go build here, interpolate the variable values LDFLAGS_f1=-ldflags "-w -s -X main.Version=${VERSION} -X main.Build=${BUILD} -X main.Entry=f1" LDFLAGS_f2=-ldflags "-w -s -X main.Version=${VERSION} -X main.Build=${BUILD} -X main.Entry=f2" # Builds the project build: go build ${LDFLAGS_f1} -o ${BINARY}_f1 go build ${LDFLAGS_f2} -o ${BINARY}_f2 # Installs our project: copies binaries install: go install ${LDFLAGS_f1} # Cleans our project: deletes binaries clean: if [ -f ${BINARY} ] ; then rm ${BINARY} ; fi .PHONY: clean install 

Il file make creerà due file eseguibili. Uno sta eseguendo la funzione uno, l’altro avrà la funzione due come voce principale:

 package main import ( "fmt" ) var ( Version string Build string Entry string funcs = map[string]func() { "f1":functionOne,"f2":functionTwo, } ) func functionOne() { fmt.Println("This is function one") } func functionTwo() { fmt.Println("This is function two") } func main() { fmt.Println("Version: ", Version) fmt.Println("Build Time: ", Build) funcs[Entry]() } 

Quindi esegui:

 make 

Otterrete:

 [email protected]:~/projects/go/gomake/3/gomake$ ls -al total 2020 drwxrwxr-x 3 mab mab 4096 Sep 7 22:41 . drwxrwxr-x 3 mab mab 4096 Aug 16 10:00 .. drwxrwxr-x 8 mab mab 4096 Aug 17 16:40 .git -rwxrwxr-x 1 mab mab 1023488 Sep 7 22:41 gomake_f1 -rwxrwxr-x 1 mab mab 1023488 Sep 7 22:41 gomake_f2 -rw-rw-r-- 1 mab mab 399 Aug 16 10:21 main.go -rw-rw-r-- 1 mab mab 810 Sep 7 22:41 Makefile [email protected]:~/projects/go/gomake/3/gomake$ ./gomake_f1 Version: 1.0.1-1-gfb51187 Build Time: 2016-09-07T22:41:38+0200 This is function one [email protected]:~/projects/go/gomake/3/gomake$ ./gomake_f2 Version: 1.0.1-1-gfb51187 Build Time: 2016-09-07T22:41:39+0200 This is function two 

usare multi -ldflags :

 $ go build -ldflags "-X name1=value1 -X name2=value2" -o path/to/output 

Su sistema operativo Windows dato il programma qui sotto

 package main import "fmt" var ( version string date string ) func main() { fmt.Printf("version=%s, date=%s", version, date) } 

Puoi build usando

 go build -ldflags "-X main.version=0.0.1 -X main.date=%date:~10,4%-%date:~4,2%-%date:~7,2%T%time:~0,2%:%time:~3,2%:%time:~6,2%" 

Il formato della data presume che l’ambiente sia echo %date% è Fri 07/22/2016 e echo %time% è 16:21:52.88

Quindi l’output sarà: version=0.0.1, date=2016-07-22T16:21:52