github.com/cockroachdb/cockroachdb-parser@v0.23.3-0.20240213214944-911057d40c9a/pkg/build/info.go (about) 1 // Copyright 2015 The Cockroach Authors. 2 // 3 // Use of this software is governed by the Business Source License 4 // included in the file licenses/BSL.txt. 5 // 6 // As of the Change Date specified in that file, in accordance with 7 // the Business Source License, use of this software will be governed 8 // by the Apache License, Version 2.0, included in the file 9 // licenses/APL.txt. 10 11 package build 12 13 import ( 14 "bytes" 15 _ "embed" 16 "fmt" 17 "runtime" 18 "strings" 19 "text/tabwriter" 20 "time" 21 22 "github.com/cockroachdb/cockroachdb-parser/pkg/util/buildutil" 23 "github.com/cockroachdb/cockroachdb-parser/pkg/util/envutil" 24 "github.com/cockroachdb/cockroachdb-parser/pkg/util/version" 25 ) 26 27 // TimeFormat is the reference format for build.Time. Make sure it stays in sync 28 // with the string passed to the linker in the root Makefile. 29 const TimeFormat = "2006/01/02 15:04:05" 30 31 var ( 32 // These variables are initialized by Bazel via the linker -X flag 33 // when compiling release binaries. 34 utcTime string // Build time in UTC (year/month/day hour:min:sec) 35 rev string // SHA-1 of this build (git rev-parse) 36 buildTagOverride string 37 cgoCompiler = cgoVersion() 38 cgoTargetTriple string 39 platform = fmt.Sprintf("%s %s", runtime.GOOS, runtime.GOARCH) 40 // Distribution is changed by the CCL init-time hook in non-APL builds. 41 Distribution = "OSS" 42 typ string // Type of this build: <empty>, "development", or "release" 43 channel string 44 envChannel = envutil.EnvOrDefaultString("COCKROACH_CHANNEL", "unknown") 45 enabledAssertions = buildutil.CrdbTestBuild 46 //go:embed version.txt 47 cockroachVersion string 48 binaryVersion = computeBinaryVersion(cockroachVersion, rev) 49 ) 50 51 const ( 52 DefaultTelemetryChannel = "official-binary" 53 FIPSTelemetryChannel = "official-fips-binary" 54 ) 55 56 // IsRelease returns true if the binary was produced by a "release" build. 57 func IsRelease() bool { 58 return typ == "release" 59 } 60 61 // SeemsOfficial reports whether this binary is likely to have come from an 62 // official release channel. 63 func SeemsOfficial() bool { 64 return channel == DefaultTelemetryChannel || channel == FIPSTelemetryChannel 65 } 66 67 func computeBinaryVersion(versionTxt, revision string) string { 68 if buildTagOverride != "" { 69 return buildTagOverride 70 } 71 txt := strings.TrimSuffix(versionTxt, "\n") 72 v, err := version.Parse(txt) 73 if err != nil { 74 panic(fmt.Errorf("could not parse version.txt: %w", err)) 75 } 76 if IsRelease() { 77 return v.String() 78 } 79 if revision != "" { 80 return fmt.Sprintf("%s-dev-%s", v.String(), revision) 81 } 82 return fmt.Sprintf("%s-dev", v.String()) 83 } 84 85 // BinaryVersion returns the version prefix, patch number and metadata of the current build. 86 func BinaryVersion() string { 87 return binaryVersion 88 } 89 90 // BinaryVersionPrefix returns the version prefix of the current build. 91 func BinaryVersionPrefix() string { 92 v, err := version.Parse(binaryVersion) 93 if err != nil { 94 return "dev" 95 } 96 return fmt.Sprintf("v%d.%d", v.Major(), v.Minor()) 97 } 98 99 func init() { 100 // Allow tests to override the version.txt contents. 101 if versionOverride := envutil.EnvOrDefaultString( 102 "COCKROACH_TESTING_VERSION_OVERRIDE", ""); versionOverride != "" { 103 TestingOverrideVersion(versionOverride) 104 } 105 } 106 107 // Short returns a pretty printed build and version summary. 108 func (b Info) Short() string { 109 plat := b.Platform 110 if b.CgoTargetTriple != "" { 111 plat = b.CgoTargetTriple 112 } 113 return fmt.Sprintf("CockroachDB %s %s (%s, built %s, %s)", 114 b.Distribution, b.Tag, plat, b.Time, b.GoVersion) 115 } 116 117 // Long returns a pretty printed build summary 118 func (b Info) Long() string { 119 var buf bytes.Buffer 120 tw := tabwriter.NewWriter(&buf, 2, 1, 2, ' ', 0) 121 fmt.Fprintf(tw, "Build Tag: %s\n", b.Tag) 122 fmt.Fprintf(tw, "Build Time: %s\n", b.Time) 123 fmt.Fprintf(tw, "Distribution: %s\n", b.Distribution) 124 fmt.Fprintf(tw, "Platform: %s", b.Platform) 125 if b.CgoTargetTriple != "" { 126 fmt.Fprintf(tw, " (%s)", b.CgoTargetTriple) 127 } 128 fmt.Fprintln(tw) 129 fmt.Fprintf(tw, "Go Version: %s\n", b.GoVersion) 130 fmt.Fprintf(tw, "C Compiler: %s\n", b.CgoCompiler) 131 fmt.Fprintf(tw, "Build Commit ID: %s\n", b.Revision) 132 fmt.Fprintf(tw, "Build Type: %s\n", b.Type) 133 fmt.Fprintf(tw, "Enabled Assertions: %t", b.EnabledAssertions) // No final newline: cobra prints one for us. 134 _ = tw.Flush() 135 return buf.String() 136 } 137 138 // GoTime parses the utcTime string and returns a time.Time. 139 func (b Info) GoTime() time.Time { 140 val, err := time.Parse(TimeFormat, b.Time) 141 if err != nil { 142 return time.Time{} 143 } 144 return val 145 } 146 147 // Timestamp parses the utcTime string and returns the number of seconds since epoch. 148 func (b Info) Timestamp() (int64, error) { 149 val, err := time.Parse(TimeFormat, b.Time) 150 if err != nil { 151 return 0, err 152 } 153 return val.Unix(), nil 154 } 155 156 // GetInfo returns an Info struct populated with the build information. 157 func GetInfo() Info { 158 ch := channel 159 if ch == "" { 160 ch = "unknown" 161 } 162 return Info{ 163 GoVersion: runtime.Version(), 164 Tag: binaryVersion, 165 Time: utcTime, 166 Revision: rev, 167 CgoCompiler: cgoCompiler, 168 CgoTargetTriple: cgoTargetTriple, 169 Platform: platform, 170 Distribution: Distribution, 171 Type: typ, 172 Channel: ch, 173 EnvChannel: envChannel, 174 EnabledAssertions: enabledAssertions, 175 } 176 } 177 178 // TestingOverrideVersion allows tests to override the binary version 179 // reported by cockroach. 180 func TestingOverrideVersion(v string) func() { 181 prevBinaryVersion := binaryVersion 182 binaryVersion = v 183 return func() { binaryVersion = prevBinaryVersion } 184 } 185 186 // MakeIssueURL produces a URL to a CockroachDB issue. 187 func MakeIssueURL(issue int) string { 188 return fmt.Sprintf("https://go.crdb.dev/issue-v/%d/%s", issue, BinaryVersionPrefix()) 189 }