Ứng dụng xây dựng phiên bản tự động


193

Có thể tự động tăng số phiên bản nhỏ mỗi lần ứng dụng Go được biên dịch không?

Tôi muốn đặt số phiên bản trong chương trình của mình, với phần tự động tăng:

$ myapp -version
MyApp version 0.5.132

Là 0,5 số phiên bản tôi đặt và 132 giá trị tự động tăng lên mỗi khi nhị phân được biên dịch.

Điều này có thể có trong Go?

Câu trả lời:


337

Trình liên kết Go ( liên kết công cụ đi ) có một tùy chọn để đặt giá trị của biến chuỗi chưa được khởi tạo:

-X importpath.name=value
  Set the value of the string variable in importpath named name to

giá trị. Lưu ý rằng trước Go 1.5, tùy chọn này có hai đối số riêng biệt. Bây giờ phải mất một đối số phân chia trên dấu = đầu tiên.

Là một phần của quá trình xây dựng của bạn, bạn có thể đặt biến chuỗi phiên bản bằng cách sử dụng biến này. Bạn có thể vượt qua điều này thông qua các gocông cụ bằng cách sử dụng -ldflags. Ví dụ: được cung cấp tệp nguồn sau:

package main

import "fmt"

var xyz string

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

Sau đó:

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

Để đặt main.minversionngày và giờ xây dựng khi xây dựng:

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

Nếu bạn biên dịch mà không khởi tạo main.minversiontheo cách này, nó sẽ chứa chuỗi trống.


4
Giá trị đó sẽ được lưu vào nhị phân nếu tôi sử dụng go bouildthay vì go run?
Sebastián Grignoli

6
go build -ldflags "-X main.minversion `date -u +.%Y%m%d%.H%M%S`" service.go
Sebastián Grignoli

4
goxc thực hiện điều này cho bạn :) theo mặc định, nó biên dịch với -ldflags "-Xmain.VERSION xxx -Xmain.BUILD_DATE CurrentDateInISO8601", nhưng bạn có thể định cấu hình các tên biến đó nếu muốn. Xem github.com/laher/goxc ... (từ chối trách nhiệm: Tôi đã viết goxc)
laher

7
ví dụ hoạt động với cú pháp 1.5 mới để thêm biến thời gian xây dựnggo build -ldflags "-X 'main.buildtime=$(date -u '+%Y-%m-%d %H:%M:%S')'"
xorpaul

26
Lưu ý rằng tên gói đầy đủ là bắt buộc. go build -ldflags "-X pkg.version=123"sẽ không làm việc trong khi go build -ldflags "-X path/to/pkg.version=123"làm việc như mong đợi. hy vọng nó giúp.
csyangchen

27

Ngoài ra, tôi muốn đăng một ví dụ nhỏ về cách sử dụng git và 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

Các tập tin make sẽ tạo ra hai thực thi. Một cái đang thực thi chức năng một, cái còn lại sẽ lấy chức năng hai làm mục chính:

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

}

Sau đó chỉ cần chạy:

make

Bạn sẽ nhận được:

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

5
Hoặc đơn giản hơn: chỉ cần tạo hai chính trong hai thư mục khác nhau. Giải pháp này dường như được áp đảo nghiêm trọng.
heo

26

Tôi gặp sự cố khi sử dụng -ldflagstham số khi xây dựng dự án thư viện và ứng dụng dòng lệnh hỗn hợp của mình, vì vậy tôi đã kết thúc bằng cách sử dụng mục tiêu Makefile để tạo tệp nguồn Go chứa phiên bản ứng dụng của tôi và ngày xây dựng:

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)

Trong init()phương pháp của tôi , tôi làm điều này:

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

Tuy nhiên, nếu bạn muốn số bản dựng tăng nguyên tử thay vì ngày xây dựng, có lẽ bạn cần tạo tệp cục bộ chứa số bản dựng cuối cùng. Makefile của bạn sẽ đọc nội dung tệp thành một biến, tăng nó, chèn nó vào version.gotệp thay vì ngày và ghi số bản dựng mới trở lại tệp.


2
Giải pháp tốt đẹp. Tuy nhiên, tôi nghĩ rằng tôi đã tìm thấy lý do cho những rắc rối -ldflags. Nếu tệp chứa biến được cập nhật bởi -X không được chạm vào, thì quá trình biên dịch sẽ không kích hoạt và bạn có phiên bản cũ trong tệp nhị phân. Giải pháp của tôi là chạm vào một tệp nhỏ chỉ chứa biến được đặt lại thông qua -ldflags "-X ..."
Wojciech Kaczmarek

20

Sử dụng ldflagsđể đặt biến trong maingói:

Với tập tin main.go:

package main

import "fmt"

var (
    version string
    build   string
)

func main() {
    fmt.Println("version=", version)
    fmt.Println("build=", build)
}

Sau đó chạy:

go run \
  -ldflags "-X main.version=1.0.0 -X main.build=12082019" \ 
  main.go

Xây dựng:

go build -o mybinary \
  -ldflags "-X main.version=1.0.0 -X 'main.build=$(date)'" \ 
  main.go

Sử dụng ldflagsđể đặt biến trong non-maingói:

Với tập tin config.go:

package config

import "fmt"

var (
    Version string
)

func LogVersion() {
    fmt.Println("version=", Version)
}

Bạn cũng sẽ cần tập tin main.go:

package main

import (
    "fmt"
    "github.com/user/repo/config"
}

func main() {
    config.LogVersion()
}

Xây dựng nhị phân của bạn đầu tiên:

go build -o mybinary main.go 

Tìm đường dẫn đầy đủ của tên biến bạn muốn đặt:

go tool nm <path_to_binary> | grep Version

Chạy và xây dựng nhị phân một lần nữa nhưng với ldflags:

go run \
  -ldflags "-X github.com/user/repo/config.Version=1.0.0" \
  main.go --version       


go build -o mybinary \
  -ldflags "-X github.com/user/repo/config.Version=1.0.0" \
  main.go     

Lấy cảm hứng từ https://github.com/golang/go/wiki/GcToolchainTricks#including-build-inif-in-the-executable


Ngoài ra nếu bạn đang sử dụng goreleaserthì hãy đọc https://goreleaser.com/#USE-the-main-version :

GoReleaser mặc định đặt ba ldflags:

main.version: Thẻ Git hiện tại
main.commit: Cam kết git hiện tại SHA
main.date: Ngày theo RFC3339


Nếu bạn muốn thấy điều này trong hành động: https://github.com/hoto/fuzzy-repo-finder/blob/master/pkg/config/config.go


12

sử dụng đa -ldflags:

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

12

Trên hệ điều hành Windows được cung cấp chương trình dưới đây

package main

import "fmt"

var (
    version string
    date    string
)

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

Bạn có thể xây dựng bằng cách sử dụng

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

Định dạng ngày giả định môi trường của bạn echo %date%Fri 07/22/2016echo %time%16:21:52.88

Sau đó, đầu ra sẽ là: version=0.0.1, date=2016-07-22T16:21:52

Khi sử dụng trang web của chúng tôi, bạn xác nhận rằng bạn đã đọc và hiểu Chính sách cookieChính sách bảo mật của chúng tôi.
Licensed under cc by-sa 3.0 with attribution required.