golang收集并显示CLI版本信息及升级提示插件version的使用

Golang 收集并显示 CLI 版本信息及升级提示插件 version 的使用

快速开始

首先安装 version 包:

go get go.szostok.io/version

基本使用

导入 version 包:

import "go.szostok.io/version"

功能特性

  • 自动检测 Go 1.18+ 的 versioncommitcommitDatedirtyBuild 信息
    • 允许通过 -ldflags 覆盖版本数据
  • 支持 YAML、JSON、short 和 pretty 格式输出版本信息
  • 检测并显示新版本升级提示
  • 自动为非 tty 输出流禁用颜色输出
  • 设计灵活,可以单独使用每个组件
  • 一行代码即可启用全部功能
  • 可自定义输出格式和行为(如超时、重新检查间隔等)

示例代码

基本示例

package main

import (
	"github.com/spf13/cobra"
	"go.szostok.io/version/extension"
)

func main() {
	rootCmd := &cobra.Command{
		Use: "myapp",
	}
	
	// 添加版本命令
	rootCmd.AddCommand(
		extension.NewVersionCobraCmd(),
	)
	
	// 执行命令
	if err := rootCmd.Execute(); err != nil {
		panic(err)
	}
}

带升级提示的示例

package main

import (
	"github.com/spf13/cobra"
	"go.szostok.io/version/extension"
)

func main() {
	rootCmd := &cobra.Command{
		Use: "myapp",
	}
	
	// 添加带升级提示的版本命令
	rootCmd.AddCommand(
		extension.NewVersionCobraCmd(
			extension.WithUpgradeNotice("repo-owner", "repo-name"),
		),
	)
	
	if err := rootCmd.Execute(); err != nil {
		panic(err)
	}
}

使用 ldflags 覆盖版本信息

构建时使用 ldflags 覆盖版本信息:

go build -ldflags="-X go.szostok.io/version.version=1.42.0"

为什么使用这个包?

当创建一个新的 CLI 工具时,通常会使用 Cobra、urfave/cli 等框架。每个 CLI 都需要显示版本信息,但这个过程往往重复相同的工作:收集和显示相关信息。

这个包旨在解决这个问题,只需添加一行代码即可注册版本命令:

extension.NewVersionCobraCmd()

Go 1.18 简化了版本相关数据的收集,因为提交、日期和其他数据都是内置的。你仍然可以使用 ldflags 覆盖这些字段,例如:

-X go.szostok.io/version.version=1.42.0

通过添加以下代码可以获得更多功能,如升级提示:

extension.WithUpgradeNotice("repo-owner", "repo-name")

更多关于golang收集并显示CLI版本信息及升级提示插件version的使用的实战教程也可以访问 https://www.itying.com/category-94-b0.html

1 回复

更多关于golang收集并显示CLI版本信息及升级提示插件version的使用的实战系列教程也可以访问 https://www.itying.com/category-94-b0.html


Golang CLI 版本信息收集与升级提示插件

在Golang中实现CLI工具的版本信息收集和升级提示功能是一个常见的需求。下面我将介绍如何使用version插件来实现这一功能。

基本版本信息实现

首先,我们创建一个简单的版本信息结构体:

package main

import (
	"fmt"
	"runtime"
)

var (
	Version   = "v0.1.0"      // 版本号
	BuildTime = "2023-11-15"  // 构建时间
	GitCommit = "abcdef123"   // Git提交哈希
	GoVersion = runtime.Version() // Go版本
)

func ShowVersion() {
	fmt.Printf("Version: %s\n", Version)
	fmt.Printf("Build Time: %s\n", BuildTime)
	fmt.Printf("Git Commit: %s\n", GitCommit)
	fmt.Printf("Go Version: %s\n", GoVersion)
	fmt.Printf("OS/Arch: %s/%s\n", runtime.GOOS, runtime.GOARCH)
}

func main() {
	ShowVersion()
}

使用version插件

version是一个流行的Golang库,可以更方便地管理版本信息。首先安装:

go get github.com/hashicorp/go-version

基本用法

package main

import (
	"fmt"
	"github.com/hashicorp/go-version"
)

func main() {
	// 解析版本
	v1, _ := version.NewVersion("1.2.3")
	v2, _ := version.NewVersion("1.5.0")

	// 比较版本
	if v1.LessThan(v2) {
		fmt.Printf("%s is less than %s\n", v1, v2)
	}

	// 约束条件
	constraints, _ := version.NewConstraint(">= 1.0, < 2.0")
	if constraints.Check(v1) {
		fmt.Printf("%s satisfies constraints '%s'\n", v1, constraints)
	}
}

完整实现

下面是一个完整的CLI工具版本检查和升级提示实现:

package main

import (
	"encoding/json"
	"fmt"
	"io/ioutil"
	"net/http"
	"runtime"
	"time"

	"github.com/hashicorp/go-version"
	"github.com/spf13/cobra"
)

var (
	appVersion = "v0.1.0"
	buildTime  = "2023-11-15"
	gitCommit  = "abcdef123"
)

type ReleaseInfo struct {
	TagName string `json:"tag_name"`
	HTMLURL string `json:"html_url"`
}

func main() {
	var rootCmd = &cobra.Command{
		Use:   "mycli",
		Short: "My CLI tool",
	}

	var versionCmd = &cobra.Command{
		Use:   "version",
		Short: "Print version information",
		Run: func(cmd *cobra.Command, args []string) {
			printVersion()
			checkForUpdates()
		},
	}

	rootCmd.AddCommand(versionCmd)
	rootCmd.Execute()
}

func printVersion() {
	fmt.Printf("My CLI Tool\n")
	fmt.Printf("Version:    %s\n", appVersion)
	fmt.Printf("Build Time: %s\n", buildTime)
	fmt.Printf("Git Commit: %s\n", gitCommit)
	fmt.Printf("Go Version: %s\n", runtime.Version())
	fmt.Printf("OS/Arch:    %s/%s\n", runtime.GOOS, runtime.GOARCH)
}

func checkForUpdates() {
	current, err := version.NewVersion(appVersion)
	if err != nil {
		fmt.Printf("Error parsing current version: %v\n", err)
		return
	}

	// 从GitHub API获取最新版本
	client := &http.Client{Timeout: 5 * time.Second}
	resp, err := client.Get("https://api.github.com/repos/yourusername/yourrepo/releases/latest")
	if err != nil {
		fmt.Printf("Error checking for updates: %v\n", err)
		return
	}
	defer resp.Body.Close()

	body, err := ioutil.ReadAll(resp.Body)
	if err != nil {
		fmt.Printf("Error reading response: %v\n", err)
		return
	}

	var release ReleaseInfo
	if err := json.Unmarshal(body, &release); err != nil {
		fmt.Printf("Error parsing release info: %v\n", err)
		return
	}

	latest, err := version.NewVersion(release.TagName)
	if err != nil {
		fmt.Printf("Error parsing latest version: %v\n", err)
		return
	}

	if current.LessThan(latest) {
		fmt.Printf("\nNew version available: %s (you have %s)\n", latest, current)
		fmt.Printf("Download at: %s\n", release.HTMLURL)
	} else {
		fmt.Printf("\nYou are using the latest version: %s\n", current)
	}
}

构建时注入版本信息

为了更灵活地管理版本信息,可以在构建时通过-ldflags注入:

go build -ldflags "\
	-X main.appVersion=v0.1.0 \
	-X main.buildTime=$(date +'%Y-%m-%d') \
	-X main.gitCommit=$(git rev-parse --short HEAD)"

替代方案

除了go-version,还有其他一些版本管理库:

  1. spf13/cobra - 内置版本命令支持
  2. urfave/cli - 另一个流行的CLI库
  3. blang/semver - 语义化版本实现

最佳实践

  1. 遵循语义化版本规范(SemVer)
  2. 每次发布时更新版本号
  3. 提供清晰的升级提示
  4. 考虑支持自动更新机制
  5. --help中显示版本检查命令

通过以上方法,你可以为Golang CLI工具实现完善的版本管理和升级提示功能。

回到顶部