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  }