欧美bbbwbbbw肥妇,免费乱码人妻系列日韩,一级黄片

使用 Go 管理版本的方法示例

 更新時(shí)間:2019年10月31日 10:17:30   作者:帥氣貓咪  
這篇文章主要介紹了使用 Go 管理版本的方法示例,文中通過(guò)示例代碼介紹的非常詳細(xì),對(duì)大家的學(xué)習(xí)或者工作具有一定的參考學(xué)習(xí)價(jià)值,需要的朋友們下面隨著小編來(lái)一起學(xué)習(xí)學(xué)習(xí)吧

簡(jiǎn)介

如果你曾經(jīng)運(yùn)行過(guò) docker version,

就會(huì)發(fā)現(xiàn)它提供了很多信息:

PS C:\Users\tzh> docker version
Client: Docker Engine - Community
 Version:      19.03.4
 API version:    1.40
 Go version:    go1.12.10
 Git commit:    9013bf5
 Built:       Thu Oct 17 23:44:48 2019
 OS/Arch:      windows/amd64
 Experimental:   false

Server: Docker Engine - Community
 Engine:
 Version:     19.03.4
 API version:   1.40 (minimum version 1.12)
 Go version:    go1.12.10
 Git commit:    9013bf5
 Built:      Thu Oct 17 23:50:38 2019
 OS/Arch:     linux/amd64
 Experimental:   false
 containerd:
 Version:     v1.2.10
 GitCommit:    b34a5c8af56e510852c35414db4c1f4fa6172339
 runc:
 Version:     1.0.0-rc8+dev
 GitCommit:    3e425f80a8c931f88e6d94a8c831b9d5aa481657
 docker-init:
 Version:     0.18.0
 GitCommit:    fec3683

對(duì)于編譯好的二進(jìn)制文件而言, 獲取版本信息是非常重要的.
盡可能地提供詳細(xì)信息, 有利于后期的維護(hù)和排錯(cuò).

如何實(shí)現(xiàn)

對(duì)于版本信息等, 有兩種方式,

一種從外部獲取, 比如配置文件等,

另一種從源代碼中獲取, 將配置信息寫(xiě)死在源代碼中.

這兩種都不太好, 比如編譯時(shí)間就不太好確定.
最好是能在 go build 時(shí)確定這些信息.

幸好, go build 提供了一個(gè)選項(xiàng)叫做 -ldflags '[pattern=]arg list'.

-X importpath.name=value
  Set the value of the string variable in importpath named name to value.
  This is only effective if the variable is declared in the source code either uninitialized
  or initialized to a constant string expression. -X will not work if the initializer makes
  a function call or refers to other variables.
  Note that before Go 1.5 this option took two separate arguments.

這使得我們可以在編譯生成二進(jìn)制文件時(shí), 指定某些變量的值.

比如我們有個(gè)文件是 company/buildinfo 包的一部分.

package buildinfo

var BuildTime string

運(yùn)行 go build -ldflags="-X 'company/buildinfo.BuildTime=$(date)'" 會(huì)記錄編譯時(shí)間,

將 BuildTime 的值設(shè)置為編譯時(shí)的時(shí)間, 即從 $(date) 中獲取的時(shí)間.

參考:

Compile packages and dependencies
Command link
Including build information in the executable

實(shí)踐

新增 pkg/version 包, 用于獲取版本信息.

package version

// 這些值應(yīng)該是從外部傳入的
var (
  gitTag    string = ""
  gitCommit  string = "$Format:%H$"     // sha1 from git, output of $(git rev-parse HEAD)
  gitTreeState string = "not a git tree"    // state of git tree, either "clean" or "dirty"
  buildDate  string = "1970-01-01T00:00:00Z" // build date in ISO8601 format, output of $(date -u +'%Y-%m-%dT%H:%M:%SZ')
)

package version

import (
  "fmt"
  "runtime"
)

// 構(gòu)建時(shí)的版本信息
type VersionInfo struct {
  GitTag    string `json:"git_tag"`
  GitCommit  string `json:"git_commit"`
  GitTreeState string `json:"git_tree_state"`
  BuildDate  string `json:"build_date"`
  GoVersion  string `json:"go_version"`
  Compiler   string `json:"compiler"`
  Platform   string `json:"platform"`
}

func (info VersionInfo) String() string {
  return info.GitTag
}

func Get() VersionInfo {
  return VersionInfo{
    GitTag:    gitTag,
    GitCommit:  gitCommit,
    GitTreeState: gitTreeState,
    BuildDate:  buildDate,
    GoVersion:  runtime.Version(),
    Compiler:   runtime.Compiler,
    Platform:   fmt.Sprintf("%s/%s", runtime.GOOS, runtime.GOARCH),
  }
}

主要定義了一個(gè)結(jié)構(gòu)體, 保持版本信息.

有些信息可以通過(guò) runtime 獲取, 有些是編譯時(shí)傳進(jìn)來(lái)的.

這里沒(méi)有明確的版本號(hào), 而是使用 git tag 作為版本標(biāo)簽.

最后, 定義一個(gè)命令 version.

package cmd

import (
  "encoding/json"
  "fmt"

  "github.com/spf13/cobra"
  "tzh.com/web/pkg/version"
)

var versionCmd = &cobra.Command{
  Use:  "version",
  Short: "Print the version info of server",
  Long: "Print the version info of server",
  Run: func(cmd *cobra.Command, args []string) {
    printVersion()
  },
}

func printVersion() {
  info := version.Get()
  infoj, err := json.MarshalIndent(&info, "", " ") // 加一點(diǎn)縮進(jìn)
  if err != nil {
    fmt.Printf("遇到了錯(cuò)誤: %v\n", err)
  }
  fmt.Println(string(infoj))
}

別忘了使用 AddCommand 添加子命令.

// 初始化, 設(shè)置 flag 等
func init() {
  cobra.OnInitialize(initConfig)
  rootCmd.PersistentFlags().StringVarP(&cfgFile, "config", "c", "./conf/config.yaml", "config file (default: ./conf/config.yaml)")
  rootCmd.AddCommand(versionCmd)
}

由此, 代碼基本已經(jīng)改完了, 還剩下最后一點(diǎn), 修改 Makefile 文件,

以便簡(jiǎn)化操作過(guò)程.

修改 Makefile

SHELL := /bin/bash
BASEDIR = $(shell pwd)

# build with version infos
versionDir = "tzh.com/web/pkg/version"
gitTag = $(shell if [ "`git describe --tags --abbrev=0 2>/dev/null`" != "" ];then git describe --tags --abbrev=0; else git log --pretty=format:'%h' -n 1; fi)
buildDate = $(shell TZ=UTC date +%FT%T%z)
gitCommit = $(shell git log --pretty=format:'%H' -n 1)
gitTreeState = $(shell if git status|grep -q 'clean';then echo clean; else echo dirty; fi)

ldflags="-w -X ${versionDir}.gitTag=${gitTag} -X ${versionDir}.buildDate=${buildDate} -X ${versionDir}.gitCommit=${gitCommit} -X ${versionDir}.gitTreeState=${gitTreeState}"

all: gotool build
build:
  go build -ldflags ${ldflags} ./
run:
  go run -ldflags ${ldflags} ./
docker:
  go run -ldflags ${ldflags} ./ -c ./conf/config_docker.yaml

首行定義了運(yùn)行的 shell, 默認(rèn)是 /bin/sh, 這里改成了更常用的 /bin/bash.

然后, 就是定義了一大堆需要的參數(shù).
在運(yùn)行 go build 的時(shí)候添加了參數(shù) -ldflags ${ldflags}.

如此, 以后只要使用 make build 就能生成具有版本信息的二進(jìn)制文件了.

編譯好之后, 可以運(yùn)行 ./web version 查看具體的版本信息.

總結(jié)

通過(guò)為編譯時(shí)添加額外信息, 可以生成更具交互性的二進(jìn)制文件.
同時(shí), 也能體會(huì)到 Makefile 帶來(lái)的便捷.

當(dāng)前部分的代碼
作為版本 v0.12.0

以上就是本文的全部?jī)?nèi)容,希望對(duì)大家的學(xué)習(xí)有所幫助,也希望大家多多支持腳本之家。

相關(guān)文章

  • Go語(yǔ)言題解LeetCode455分發(fā)餅干示例詳解

    Go語(yǔ)言題解LeetCode455分發(fā)餅干示例詳解

    這篇文章主要為大家介紹了Go語(yǔ)言題解LeetCode455分發(fā)餅干示例詳解,有需要的朋友可以借鑒參考下,希望能夠有所幫助,祝大家多多進(jìn)步,早日升職加薪
    2022-12-12
  • Golang服務(wù)的請(qǐng)求調(diào)度的實(shí)現(xiàn)

    Golang服務(wù)的請(qǐng)求調(diào)度的實(shí)現(xiàn)

    Golang服務(wù)請(qǐng)求調(diào)度是一種使用Go語(yǔ)言實(shí)現(xiàn)的服務(wù)請(qǐng)求管理方法,本文主要介紹了Golang服務(wù)的請(qǐng)求調(diào)度的實(shí)現(xiàn),具有一定的參考價(jià)值,感興趣的可以了解一下
    2023-08-08
  • Go導(dǎo)入不同目錄下包報(bào)錯(cuò)的解決方法

    Go導(dǎo)入不同目錄下包報(bào)錯(cuò)的解決方法

    包(package)是多個(gè)Go源碼的集合,是一種高級(jí)的代碼復(fù)用方案,下面這篇文章主要給大家介紹了關(guān)于Go導(dǎo)入不同目錄下包報(bào)錯(cuò)的解決方法,文中通過(guò)實(shí)例代碼介紹的非常詳細(xì),需要的朋友可以參考下
    2023-06-06
  • Go使用sync.Map來(lái)解決map的并發(fā)操作問(wèn)題

    Go使用sync.Map來(lái)解決map的并發(fā)操作問(wèn)題

    在 Golang 中 map 不是并發(fā)安全的,sync.Map 的引入確實(shí)解決了 map 的并發(fā)安全問(wèn)題,本文就詳細(xì)的介紹一下如何使用,感興趣的可以了解一下
    2021-10-10
  • go語(yǔ)言中的interface使用實(shí)例

    go語(yǔ)言中的interface使用實(shí)例

    這篇文章主要介紹了go語(yǔ)言中的interface使用實(shí)例,go語(yǔ)言中的interface是一組未實(shí)現(xiàn)的方法的集合,如果某個(gè)對(duì)象實(shí)現(xiàn)了接口中的所有方法,那么此對(duì)象就實(shí)現(xiàn)了此接口,需要的朋友可以參考下
    2015-05-05
  • Golang交叉編譯(跨平臺(tái)編譯)的使用

    Golang交叉編譯(跨平臺(tái)編譯)的使用

    本文主要介紹了Golang交叉編譯(跨平臺(tái)編譯)的使用,文中通過(guò)示例代碼介紹的非常詳細(xì),對(duì)大家的學(xué)習(xí)或者工作具有一定的參考學(xué)習(xí)價(jià)值,需要的朋友們下面隨著小編來(lái)一起學(xué)習(xí)學(xué)習(xí)吧
    2022-08-08
  • Golang 定時(shí)器(Timer 和 Ticker),這篇文章就夠了

    Golang 定時(shí)器(Timer 和 Ticker),這篇文章就夠了

    這篇文章主要介紹了Golang 定時(shí)器(Timer 和 Ticker),這篇文章就夠了,文中通過(guò)示例代碼介紹的非常詳細(xì),對(duì)大家的學(xué)習(xí)或者工作具有一定的參考學(xué)習(xí)價(jià)值,需要的朋友們下面隨著小編來(lái)一起學(xué)習(xí)學(xué)習(xí)吧
    2020-10-10
  • go語(yǔ)言context包功能及操作使用詳解

    go語(yǔ)言context包功能及操作使用詳解

    這篇文章主要為大家介紹了go語(yǔ)言context包功能及操作使用詳解,有需要的朋友可以借鑒參考下,希望能夠有所幫助,祝大家多多進(jìn)步早日升職加薪
    2022-04-04
  • 深入了解Golang中的格式化輸出

    深入了解Golang中的格式化輸出

    fmt是Go語(yǔ)言中用于控制文本輸出的常用標(biāo)準(zhǔn)庫(kù),文中將通過(guò)示例詳細(xì)講解一下Go語(yǔ)言中不同形式的格式化輸出,感興趣的小伙伴可以了解一下
    2022-11-11
  • Go語(yǔ)言使用protojson庫(kù)實(shí)現(xiàn)Protocol Buffers與JSON轉(zhuǎn)換

    Go語(yǔ)言使用protojson庫(kù)實(shí)現(xiàn)Protocol Buffers與JSON轉(zhuǎn)換

    本文主要介紹Google開(kāi)源的工具庫(kù)Protojson庫(kù)如何Protocol Buffers與JSON進(jìn)行轉(zhuǎn)換,以及和標(biāo)準(zhǔn)庫(kù)encoding/json的性能對(duì)比,需要的朋友可以參考下
    2023-09-09

最新評(píng)論