github.com/cosmos/cosmos-sdk@v0.50.10/version/version.go (about)

     1  // Package version is a convenience utility that provides SDK
     2  // consumers with a ready-to-use version command that
     3  // produces apps versioning information based on flags
     4  // passed at compile time.
     5  //
     6  // # Configure the version command
     7  //
     8  // The version command can be just added to your cobra root command.
     9  // At build time, the variables Name, Version, Commit, and BuildTags
    10  // can be passed as build flags as shown in the following example:
    11  //
    12  //	go build -X github.com/cosmos/cosmos-sdk/version.Name=gaia \
    13  //	 -X github.com/cosmos/cosmos-sdk/version.AppName=gaiad \
    14  //	 -X github.com/cosmos/cosmos-sdk/version.Version=1.0 \
    15  //	 -X github.com/cosmos/cosmos-sdk/version.Commit=f0f7b7dab7e36c20b757cebce0e8f4fc5b95de60 \
    16  //	 -X "github.com/cosmos/cosmos-sdk/version.BuildTags=linux darwin amd64"
    17  package version
    18  
    19  import (
    20  	"encoding/json"
    21  	"fmt"
    22  	"runtime"
    23  	"runtime/debug"
    24  )
    25  
    26  // ContextKey is used to store the ExtraInfo in the context.
    27  type ContextKey struct{}
    28  
    29  var (
    30  	// application's name
    31  	Name = ""
    32  	// application binary name
    33  	AppName = "<appd>"
    34  	// application's version string
    35  	Version = ""
    36  	// commit
    37  	Commit = ""
    38  	// build tags
    39  	BuildTags = ""
    40  )
    41  
    42  func getSDKVersion() string {
    43  	deps, ok := debug.ReadBuildInfo()
    44  	if !ok {
    45  		return "unable to read deps"
    46  	}
    47  	var sdkVersion string
    48  	for _, dep := range deps.Deps {
    49  		if dep.Path == "github.com/cosmos/cosmos-sdk" {
    50  			if dep.Replace != nil && dep.Replace.Version != "(devel)" {
    51  				sdkVersion = dep.Replace.Version
    52  			} else {
    53  				sdkVersion = dep.Version
    54  			}
    55  		}
    56  	}
    57  
    58  	return sdkVersion
    59  }
    60  
    61  // ExtraInfo contains a set of extra information provided by apps
    62  type ExtraInfo map[string]string
    63  
    64  // Info defines the application version information.
    65  type Info struct {
    66  	Name             string     `json:"name" yaml:"name"`
    67  	AppName          string     `json:"server_name" yaml:"server_name"`
    68  	Version          string     `json:"version" yaml:"version"`
    69  	GitCommit        string     `json:"commit" yaml:"commit"`
    70  	BuildTags        string     `json:"build_tags" yaml:"build_tags"`
    71  	GoVersion        string     `json:"go" yaml:"go"`
    72  	BuildDeps        []buildDep `json:"build_deps" yaml:"build_deps"`
    73  	CosmosSdkVersion string     `json:"cosmos_sdk_version" yaml:"cosmos_sdk_version"`
    74  	ExtraInfo        ExtraInfo  `json:"extra_info,omitempty" yaml:"extra_info,omitempty"`
    75  }
    76  
    77  func NewInfo() Info {
    78  	sdkVersion := getSDKVersion()
    79  	return Info{
    80  		Name:             Name,
    81  		AppName:          AppName,
    82  		Version:          Version,
    83  		GitCommit:        Commit,
    84  		BuildTags:        BuildTags,
    85  		GoVersion:        fmt.Sprintf("go version %s %s/%s", runtime.Version(), runtime.GOOS, runtime.GOARCH),
    86  		BuildDeps:        depsFromBuildInfo(),
    87  		CosmosSdkVersion: sdkVersion,
    88  	}
    89  }
    90  
    91  func (vi Info) String() string {
    92  	return fmt.Sprintf(`%s: %s
    93  git commit: %s
    94  build tags: %s
    95  %s`,
    96  		vi.Name, vi.Version, vi.GitCommit, vi.BuildTags, vi.GoVersion,
    97  	)
    98  }
    99  
   100  func depsFromBuildInfo() (deps []buildDep) {
   101  	buildInfo, ok := debug.ReadBuildInfo()
   102  	if !ok {
   103  		return nil
   104  	}
   105  
   106  	for _, dep := range buildInfo.Deps {
   107  		deps = append(deps, buildDep{dep})
   108  	}
   109  
   110  	return
   111  }
   112  
   113  type buildDep struct {
   114  	*debug.Module
   115  }
   116  
   117  func (d buildDep) String() string {
   118  	if d.Replace != nil {
   119  		return fmt.Sprintf("%s@%s => %s@%s", d.Path, d.Version, d.Replace.Path, d.Replace.Version)
   120  	}
   121  
   122  	return fmt.Sprintf("%s@%s", d.Path, d.Version)
   123  }
   124  
   125  func (d buildDep) MarshalJSON() ([]byte, error)      { return json.Marshal(d.String()) }
   126  func (d buildDep) MarshalYAML() (interface{}, error) { return d.String(), nil }