使用git从git获得动态版本 [英] Dynamic version from git with go get

查看:86
本文介绍了使用git从git获得动态版本的处理方法,对大家解决问题具有一定的参考价值,需要的朋友们下面随着小编来一起学习吧!

问题描述

我正在使用git标签在我的go程序中注入版本,例如在 Makefile :

I'm using git tags to inject versions in my go programs, e.g. in a Makefile:

VERSION = $(shell git describe --always --dirty)

github_pki: main.go
    CGO_ENABLED=0 GOOS=linux \
      go build -a \
          -ldflags="-X main.version=$(VERSION)" \
        -installsuffix cgo -o $@ $<

main.go 中将 version 定义为:

var version = "undefined"

使用 make 效果很好,但使用 go get go build 时效果不佳.有没有办法在不使用外部构建系统的情况下(即通过 go build / go get )使此 ldflags 工作?

This works great using make, but not when using go get or go build. Is there a way to make this ldflags work without using an external build system (i.e. with go build/go get)?

推荐答案

来自问题22147 cmd/go :使编译后的git SHA嵌入二进制更容易,您现在(在Go 1.12 +,Q1 2019,2年后)有了依赖项的替代方法(还不是您的主程序).

From issue 22147 cmd/go: Make it easier to embed compiled git SHA into binary , you now have (with Go 1.12+, Q1 2019, 2+ years later) an alternative for the dependencies (not yet for your main program).

因此,您仍然需要 -ldflags 来记录源代码的版本.
而不是记录依赖项的版本:现在可用.

So you still need -ldflags to record the version of your sources.
But not to record the version of your dependencies: that is now available.

从Go 1.12开始,您可以使用 runtime/debug.BuildInfo .

如果使用的版本是伪版本,它还将包含VCS提交ID的前十二个字符.

If the version in use is a pseudo-version, it also includes the first dozen or so characters of the VCS commit ID.

// BuildInfo represents the build information read from the running binary.

type BuildInfo struct {
    Path string    // The main package path
    Main Module    // The main module information
    Deps []*Module // Module dependencies
}

// ReadBuildInfo returns the build information embedded in the running binary. 
   The information is available only in binaries built with module support. 

func ReadBuildInfo() (info *BuildInfo, ok bool)

这来自提交45e9c55 :

运行时/调试:添加API以读取二进制文件中的模块信息

启用模块后,go工具会将与模块相关的构建信息嵌入二进制文件中,包括依赖项和替换信息(请参见 src/cmd/go/internal/modload#PackageBuildInfo() ,来自提交f7248f0 ).

新引入的 ReadBuildInfo 读取信息并以编程方式使其可访问.

The newly introduced ReadBuildInfo reads the information and makes it accessible programmatically.

您可以在 issue 26404中使用它:"cmd/go:以编程方式导出二进制文件的模块信息"

package main

import (
    "log"
    "runtime/debug"

    "github.com/kr/pretty"
)

func main() {
    bi, ok := debug.ReadBuildInfo()
    if !ok {
        log.Fatal("!ok")
    }
    pretty.Println(bi)
}

您得到:

&debug.BuildInfo{
    Path: "foo.to/v",
    Main: debug.Module{
        Path:    "foo.to/v",
        Version: "(devel)",
        Sum:     "",
        Replace: (*debug.Module)(nil),
    },
    Deps: {
        &debug.Module{
            Path:    "github.com/kr/pretty",
            Version: "v0.1.0",
            Sum:     "h1:L/CwN0zerZDmRFUapSPitk6f+Q3+0za1rQkzVuMiMFI=",
            Replace: (*debug.Module)(nil),
        },
        &debug.Module{
            Path:    "github.com/kr/text",
            Version: "v0.1.0",
            Sum:     "h1:45sCR5RtlFHMR4UwH9sdQ5TC8v0qDQCHnXt+kaKSTVE=",
            Replace: (*debug.Module)(nil),
        },
    },
}

如果您使用1.12在模块外部以模块模式构建二进制文件(#24250 ),那么您将获取其所有版本信息.

If you build the binary in module mode from outside of a module using 1.12 (#24250), then you'll pick up all of its version information.

,但目前报告的二进制版本始终为 (开发) .即使已提交并标记

but the reported version of the binary is always (devel) at the moment. Even if it is committed and tagged

因此主要问题仍然存在: issues/29814" cmd/go :使用版本控制来发现主模块的版本?".

So the main issue remains: issues/29814 "cmd/go: use version control to discover the main module's version? ".

从模块的源树中构建二进制文件时, runtime/debug.ReadBuildInfo 的输出当前报告该模块的版本为 (devel).

When a binary is build from within a module's source tree, the output from runtime/debug.ReadBuildInfo currently reports that module as having version (devel).

如果源树是来自版本控制系统的原始签出-或位于(只读)模块缓存中-我们可以查询版本控制系统以找到要嵌入的相应版本或伪版本

If the source tree is a pristine checkout from a version-control system — or is within the (read-only) module cache — we could instead interrogate the version-control system to find the corresponding version or pseudo-version to embed.

但是,有一些警告:

  1. 这将要求我们在用户的源代码树中运行VCS命令.从历史上看,运行VCS命令一直是导致go命令漏洞太多的根源,因此我们真的希望避免发布VCS命令,除非绝对必要.
  2. 给出一个提交,我们可以为该提交生成一个伪版本,但是我们无法确定该提交是否已发布到原始位置.
    最好保留在调试信息中仅公告已发布版本的不变性,但这可能会导致额外的网络获取.
  3. 在一个模块中,我们应用了该模块的替换和排除,并且用户的VCS结帐可能还进行了一些转换.
    (devel)当前提供了那些特定于模块的更改正在生效的线索:如果我们要指示一个显式版本,则需要提供某种方式来指示已应用替换和排除.
  1. It would require us to run VCS commands within the user's source tree. Historically, running VCS commands has been a source of entirely too many go command vulnerabilities, so we would really like to avoid issuing VCS commands except when they are absolutely necessary.
  2. Given a commit, we can produce a pseudo-version for that commit, but we can't tell whether that commit has been published to the origin.
    It would be nice to preserve the invariant that only published versions are advertised in debug info, but that may incur an extra network fetch.
  3. Within a module, we apply that module's replacements and exclusions, and the user's VCS checkout may also have applied some transformations.
    (devel) currently provides a clue that those module-specific changes are in effect: if we were to indicate an explicit version instead, we would need to provide some way to indicate that replacements and exclusions were applied.


转到1.13 (2019年第三季度)包括:


Go 1.13 (Q3 2019) includes:

go version 命令现在接受命名可执行文件和目录的参数.

The go version command now accepts arguments naming executable and directories.

  • 在可执行文件上调用时, go version 打印用于构建可执行文件的Go版本.
  • 如果使用了 -m 标志,则 go version 打印可执行文件的嵌入式模块版本信息(如果有).( runtime/debug#BuildInfo )
  • 在目录上调用时, go version 打印有关目录及其子目录中包含的可执行文件的信息.
  • When invoked on an executable, go version prints the version of Go used to build the executable.
  • If the -m flag is used, go version prints the executable's embedded module version information, if available. (runtime/debug#BuildInfo)
  • When invoked on a directory, go version prints information about executable contained in the directory and its subdirectories.

这篇关于使用git从git获得动态版本的文章就介绍到这了,希望我们推荐的答案对大家有所帮助,也希望大家多多支持IT屋!

查看全文
登录 关闭
扫码关注1秒登录
发送“验证码”获取 | 15天全站免登陆