-
Notifications
You must be signed in to change notification settings - Fork 0
Expand file tree
/
Copy pathversion.go
More file actions
127 lines (111 loc) · 3.34 KB
/
version.go
File metadata and controls
127 lines (111 loc) · 3.34 KB
1
2
3
4
5
6
7
8
9
10
11
12
13
14
15
16
17
18
19
20
21
22
23
24
25
26
27
28
29
30
31
32
33
34
35
36
37
38
39
40
41
42
43
44
45
46
47
48
49
50
51
52
53
54
55
56
57
58
59
60
61
62
63
64
65
66
67
68
69
70
71
72
73
74
75
76
77
78
79
80
81
82
83
84
85
86
87
88
89
90
91
92
93
94
95
96
97
98
99
100
101
102
103
104
105
106
107
108
109
110
111
112
113
114
115
116
117
118
119
120
121
122
123
124
125
126
127
package version
import (
"encoding/json"
"fmt"
"runtime"
"runtime/debug"
"time"
"github.com/spf13/cobra"
)
var (
// Version information - automatically populated from VCS
Version = "dev"
GitCommit = "unknown" // Short commit hash (12 chars) for display
BuildTime = "unknown"
// Additional version metadata
GitCommitFull = "unknown" // Full commit hash
GitModified = false // Whether there are uncommitted changes
CommitTime = "unknown" // Commit timestamp (vcs.time)
)
func init() {
// Try to read VCS information from build info
// This works automatically when building in a git repository with plain `go build`
info, ok := debug.ReadBuildInfo()
if !ok {
return
}
var revision, vcsTime, modified string
for _, setting := range info.Settings {
switch setting.Key {
case "vcs.revision":
revision = setting.Value
case "vcs.time":
vcsTime = setting.Value
case "vcs.modified":
modified = setting.Value
}
}
// Populate GitCommit if we have revision info
if revision != "" {
GitCommitFull = revision // Store full commit hash
// Use short commit hash (first 12 chars) for display
if len(revision) > 12 {
GitCommit = revision[:12]
} else {
GitCommit = revision
}
}
// Populate BuildTime and CommitTime if we have VCS time info
if vcsTime != "" {
BuildTime = vcsTime
CommitTime = vcsTime
}
// Store modified flag
if modified == "true" {
GitModified = true
}
// Append "-dirty" to version if there are uncommitted changes
if GitModified && Version == "dev" {
Version = "dev-dirty"
}
}
// PrintVersion prints version information for the given tool name.
func PrintVersion(toolName string) {
// Format build time as human-readable in local time
buildTimeStr := BuildTime
if t, err := time.Parse(time.RFC3339, BuildTime); err == nil {
buildTimeStr = t.Local().Format("Jan 2, 2006 15:04 MST")
}
fmt.Printf("%s version %s\n", toolName, Version)
fmt.Printf(" commit: %s\n", GitCommit)
fmt.Printf(" built: %s\n", buildTimeStr)
fmt.Printf(" go: %s\n", runtime.Version())
}
// NewVersionCommand creates a new version command for the given tool name.
// The tool name is used to customize the output (e.g., "tk version 1.0.0").
func NewVersionCommand(toolName string) *cobra.Command {
cmd := &cobra.Command{
Use: "version",
Short: "Show version information",
RunE: func(cmd *cobra.Command, args []string) error {
jsonOutput, _ := cmd.Flags().GetBool("json")
if jsonOutput {
// Output as JSON with ISO timestamp
versionInfo := map[string]string{
"version": Version,
"commit": GitCommit,
"build_time": BuildTime,
"go_version": runtime.Version(),
}
output, err := json.MarshalIndent(versionInfo, "", " ")
if err != nil {
return fmt.Errorf("failed to marshal JSON: %w", err)
}
fmt.Println(string(output))
} else {
// Format build time as human-readable in local time
buildTimeStr := BuildTime
if t, err := time.Parse(time.RFC3339, BuildTime); err == nil {
buildTimeStr = t.Local().Format("Jan 2, 2006 15:04 MST")
}
fmt.Printf("%s version %s\n", toolName, Version)
fmt.Printf(" commit: %s\n", GitCommit)
fmt.Printf(" built: %s\n", buildTimeStr)
fmt.Printf(" go: %s\n", runtime.Version())
}
return nil
},
}
cmd.Flags().Bool("json", false, "Output version information as JSON")
return cmd
}