Автоматическое построение версий Golang

Можно ли автоматически увеличивать номер младшей версии каждый раз, когда скомпилировано приложение Go?

Я хотел бы установить номер версии внутри моей программы с секцией автоинкремента:

$ myapp -version MyApp version 0.5.132 

Быть 0.5 – номер версии, которую я установил, и 132 – значение, которое автоматически увеличивается каждый раз при компиляции двоичного файла.

Возможно ли это в Go?

Ссылка Go linker ( go tool link ) имеет возможность установить значение неинициализированной строковой переменной:

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

В рамках вашего процесса сборки вы можете установить переменную строки версии, используя это. Вы можете передать это через инструмент go , используя -ldflags . Например, учитывая следующий исходный файл:

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

Затем:

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

Чтобы установить main.minversion на дату и время сборки при создании:

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

Если вы скомпилируете без инициализации main.minversion таким образом, он будет содержать пустую строку.

У меня возникла проблема с использованием параметра -ldflags при создании моего смешанного проекта приложения и библиотеки с командной строкой, поэтому в итоге я использовал цель Makefile для создания исходного файла Go, содержащего версию моего приложения и дату сборки:

 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) 

В моем методе init() я делаю это:

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

Однако, если вы хотите получить число с добавлением атома, а не дату сборки, вам, вероятно, потребуется создать локальный файл, содержащий последний номер сборки. Ваш Makefile будет читать содержимое файла в переменной, увеличивать его, вставлять в файл version.go вместо даты и записывать новый номер сборки обратно в файл.

Кроме того, я хотел бы разместить небольшой пример использования git и make-файла:

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

Файл make создаст два исполняемых файла. Один выполняет функцию один, другой будет выполнять функцию два в качестве основной записи:

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

Затем просто запустите:

 make 

Ты получишь:

 [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 

для использования multi -ldflags :

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

В ОС Windows с учетом нижеприведенной программы

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

Вы можете использовать

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

Формат даты предполагает, что ваша среда echo %date% is Fri 07/22/2016 а echo %time%16:21:52.88

Затем вывод будет: version=0.0.1, date=2016-07-22T16:21:52

  • Преобразование структуры Go в JSON
  • В чем разница функций и методов в Go?
  • Предоставляет ли RE REPL?
  • Функции вызова со специальным префиксом / суффиксом
  • golang: slice struct! = срез интерфейса, который он реализует?
  • Как использовать C ++ в Go?
  • Почему я получаю ошибку «не могу назначить» при установке значения для структуры как значения на карте?
  • есть ли способ создать экземпляр структуры из строки?
  • Go - Строки даты / времени, которые не являются стандартными форматами
  • Как разобрать / дезертизировать динамический JSON в Голанге
  • Как создать случайную строку фиксированной длины в Go?
  • Давайте будем гением компьютера.