Wersja automatycznego kompilowania aplikacji Golang

Czy możliwe jest automatyczne zwiększanie podrzędnego numeru wersji za każdym razem, gdy aplikacja Go jest kompilowana?

Chciałbym ustawić numer wersji w moim programie, z sekcją autoincrementing:

$ myapp -version
MyApp version 0.5.132

Jest 0.5 numerem wersji, który ustawiłem, a 132 wartością, która zwiększa się automatycznie za każdym razem, gdy plik binarny jest kompilowany.

Czy to możliwe w Go?
 133
go
Author: Sebastián Grignoli, 2012-07-06

5 answers

Go linker (go tool link) ma możliwość ustawienia wartości niezainicjalizowanej zmiennej łańcuchowej:

-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.

Jako część procesu budowania, możesz ustawić zmienną ciągu wersji używając tego. Możesz to przekazać za pomocą narzędzia go za pomocą narzędzia -ldflags. Na przykład, biorąc pod uwagę następujący plik źródłowy:

package main

import "fmt"

var xyz string

func main() {
    fmt.Println(xyz)
}

Potem:

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

Aby ustawić main.minversion na datę i godzinę budowy:

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

Jeśli skompilujesz bez inicjalizacji main.minversion w ten sposób, będzie zawierać pusty ciąg znaków.

 258
Author: axw,
Warning: date(): Invalid date.timezone value 'Europe/Kyiv', we selected the timezone 'UTC' for now. in /var/www/agent_stack/data/www/doraprojects.net/template/agent.layouts/content.php on line 54
2016-02-25 22:53:16

Miałem problemy z użyciem parametru -ldflags podczas budowania mieszanej aplikacji wiersza poleceń i projektu biblioteki, więc skończyło się na użyciu pliku docelowego Makefile do wygenerowania pliku źródłowego go zawierającego wersję mojej aplikacji i datę kompilacji:

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)

W mojej metodzie init() robię to:

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()
}

Jeśli jednak chcesz zwiększyć liczbę kompilacji atomicznie zamiast daty kompilacji, prawdopodobnie będziesz musiał utworzyć plik lokalny, który zawierał ostatni numer kompilacji. Twój plik Makefile odczytałby plik zawartość do zmiennej, zwiększ ją, Wstaw ją do pliku version.go zamiast daty i zapisz nowy numer kompilacji z powrotem do pliku.

 20
Author: pegli,
Warning: date(): Invalid date.timezone value 'Europe/Kyiv', we selected the timezone 'UTC' for now. in /var/www/agent_stack/data/www/doraprojects.net/template/agent.layouts/content.php on line 54
2014-07-28 20:26:32

Dodatkowo chciałbym zamieścić mały przykład jak używać git i 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

Plik make utworzy dwa pliki wykonywalne. Jeden wykonuje funkcję jeden, drugi przyjmuje funkcję drugą jako wejście główne:

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]()

}

Następnie po prostu uruchom:

make

Otrzymasz:

mab@h2470988:~/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
mab@h2470988:~/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
mab@h2470988:~/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
 13
Author: Maciej A. Bednarz,
Warning: date(): Invalid date.timezone value 'Europe/Kyiv', we selected the timezone 'UTC' for now. in /var/www/agent_stack/data/www/doraprojects.net/template/agent.layouts/content.php on line 54
2016-09-07 20:48:42

Aby użyć multi -ldflags:

$ go build -ldflags "-X name1=value1 -X name2=value2" -o path/to/output
 6
Author: Kimia Zhu,
Warning: date(): Invalid date.timezone value 'Europe/Kyiv', we selected the timezone 'UTC' for now. in /var/www/agent_stack/data/www/doraprojects.net/template/agent.layouts/content.php on line 54
2016-06-18 02:29:38

W systemie operacyjnym Windows podany poniżej program

package main

import "fmt"

var (
    version string
    date    string
)

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

Możesz budować używając

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%"

Format daty zakłada, że Twoje środowisko echo %date% to Fri 07/22/2016, a echo %time% to 16:21:52.88

Następnie wyjście będzie: version=0.0.1, date=2016-07-22T16:21:52

 5
Author: ostati,
Warning: date(): Invalid date.timezone value 'Europe/Kyiv', we selected the timezone 'UTC' for now. in /var/www/agent_stack/data/www/doraprojects.net/template/agent.layouts/content.php on line 54
2016-07-22 20:28:31