multi: Make use of new internal version package.

This introduces a new internal package named version to house the
version information and updates the various code to use it.  This allows
both dcrd and dcrctl to make use of the package so the version
information only needs to be bumped in one place and also ensure that
any link-time overrides to the pre-release and/or build metadata apply
to both.

Also, while here, include the OS and architecture in the version log at
start of day as well as the output from the version CLI flag.
This commit is contained in:
Dave Collins 2018-09-04 15:51:07 -05:00
parent 2a18beb4d5
commit 999ee7d863
No known key found for this signature in database
GPG Key ID: B8904D9D9C93D1F2
10 changed files with 71 additions and 115 deletions

View File

@ -7,7 +7,6 @@ services:
- docker
env:
- GOVERSION=1.10
- GOVERSION=1.11
install: true

View File

@ -18,6 +18,7 @@ import (
"github.com/decred/dcrd/dcrjson"
"github.com/decred/dcrd/dcrutil"
"github.com/decred/dcrd/internal/version"
flags "github.com/jessevdk/go-flags"
)
@ -263,7 +264,7 @@ func loadConfig() (*config, []string, error) {
appName = strings.TrimSuffix(appName, filepath.Ext(appName))
usageMessage := fmt.Sprintf("Use %s -h to show options", appName)
if preCfg.ShowVersion {
fmt.Println(appName, "version", version())
fmt.Println(appName, "version", version.String())
os.Exit(0)
}

View File

@ -1,76 +0,0 @@
// Copyright (c) 2013 The btcsuite developers
// Copyright (c) 2015-2018 The Decred developers
// Use of this source code is governed by an ISC
// license that can be found in the LICENSE file.
package main
import (
"bytes"
"fmt"
"strings"
)
// semanticAlphabet
const semanticAlphabet = "0123456789ABCDEFGHIJKLMNOPQRSTUVWXYZabcdefghijklmnopqrstuvwxyz-"
// These constants define the application version and follow the semantic
// versioning 2.0.0 spec (http://semver.org/).
const (
appMajor uint = 1
appMinor uint = 4
appPatch uint = 0
// appPreRelease MUST only contain characters from semanticAlphabet
// per the semantic versioning spec.
appPreRelease = "pre"
)
// appBuild is defined as a variable so it can be overridden during the build
// process with '-ldflags "-X main.appBuild=foo' if needed. It MUST only
// contain characters from semanticAlphabet per the semantic versioning spec.
var appBuild = "dev"
// version returns the application version as a properly formed string per the
// semantic versioning 2.0.0 spec (http://semver.org/).
func version() string {
// Start with the major, minor, and patch versions.
version := fmt.Sprintf("%d.%d.%d", appMajor, appMinor, appPatch)
// Append pre-release version if there is one. The hyphen called for
// by the semantic versioning spec is automatically appended and should
// not be contained in the pre-release string. The pre-release version
// is not appended if it contains invalid characters.
preRelease := normalizeVerString(appPreRelease)
if preRelease != "" {
version = fmt.Sprintf("%s-%s", version, preRelease)
}
// Append build metadata if there is any. The plus called for
// by the semantic versioning spec is automatically appended and should
// not be contained in the build metadata string. The build metadata
// string is not appended if it contains invalid characters.
build := normalizeVerString(appBuild)
if build != "" {
version = fmt.Sprintf("%s+%s", version, build)
}
return version
}
// normalizeVerString returns the passed string stripped of all characters which
// are not valid according to the semantic versioning guidelines for pre-release
// version and build metadata strings. In particular they MUST only contain
// characters in semanticAlphabet.
func normalizeVerString(str string) string {
var result bytes.Buffer
for _, r := range str {
if strings.ContainsRune(semanticAlphabet, r) {
// Ignoring the error here since it can only fail if
// the the system is out of memory and there are much
// bigger issues at that point.
_, _ = result.WriteRune(r)
}
}
return result.String()
}

View File

@ -26,6 +26,7 @@ import (
"github.com/decred/dcrd/database"
_ "github.com/decred/dcrd/database/ffldb"
"github.com/decred/dcrd/dcrutil"
"github.com/decred/dcrd/internal/version"
"github.com/decred/dcrd/mempool"
"github.com/decred/dcrd/sampleconfig"
"github.com/decred/slog"
@ -482,7 +483,8 @@ func loadConfig() (*config, []string, error) {
appName = strings.TrimSuffix(appName, filepath.Ext(appName))
usageMessage := fmt.Sprintf("Use %s -h to show usage", appName)
if preCfg.ShowVersion {
fmt.Printf("%s version %s (Go version %s)\n", appName, version(), runtime.Version())
fmt.Printf("%s version %s (Go version %s %s/%s)\n", appName,
version.String(), runtime.Version(), runtime.GOOS, runtime.GOARCH)
os.Exit(0)
}

View File

@ -16,6 +16,7 @@ import (
"time"
"github.com/decred/dcrd/blockchain/indexers"
"github.com/decred/dcrd/internal/version"
"github.com/decred/dcrd/limits"
)
@ -51,7 +52,8 @@ func dcrdMain(serverChan chan<- *server) error {
defer dcrdLog.Info("Shutdown complete")
// Show version and home dir at startup.
dcrdLog.Infof("Version %s (Go version %s)", version(), runtime.Version())
dcrdLog.Infof("Version %s (Go version %s %s/%s)", version.String(),
runtime.Version(), runtime.GOOS, runtime.GOARCH)
dcrdLog.Infof("Home dir: %s", cfg.HomeDir)
if cfg.NoFileLogging {
dcrdLog.Info("File logging disabled")

View File

@ -0,0 +1,19 @@
version
=======
[![Build Status](http://img.shields.io/travis/decred/dcrd.svg)](https://travis-ci.org/decred/dcrd)
[![ISC License](http://img.shields.io/badge/license-ISC-blue.svg)](http://copyfree.org)
[![GoDoc](http://img.shields.io/badge/godoc-reference-blue.svg)](http://godoc.org/github.com/decred/dcrd/internal/version)
Package version provides a single location to house the version information for
dcrd and other utilities provided in the same repository.
## Installation and Updating
This package is internal and therefore is neither directly installed nor needs
to be manually updated.
## License
Package version is licensed under the [copyfree](http://copyfree.org) ISC
License.

View File

@ -3,7 +3,9 @@
// Use of this source code is governed by an ISC
// license that can be found in the LICENSE file.
package main
// Package version provides a single location to house the version information
// for dcrd and other utilities provided in the same repository.
package version
import (
"bytes"
@ -24,36 +26,38 @@ const (
// These constants define the application version and follow the semantic
// versioning 2.0.0 spec (http://semver.org/).
const (
appMajor uint = 1
appMinor uint = 4
appPatch uint = 0
Major uint = 1
Minor uint = 4
Patch uint = 0
)
var (
// appPreRelease is defined as a variable so it can be overridden during
// the build process with '-ldflags "-X main.appPreRelease=foo"' if
// needed. It MUST only contain characters from semanticAlphabet per
// PreRelease is defined as a variable so it can be overridden during the
// build process with:
// '-ldflags "-X github.com/decred/dcrd/internal/version.PreRelease=foo"'
// if needed. It MUST only contain characters from semanticAlphabet per
// the semantic versioning spec.
appPreRelease = "pre"
PreRelease = "pre"
// appBuild is defined as a variable so it can be overridden during the
// build process with '-ldflags "-X main.appBuild=foo"' if needed. It
// MUST only contain characters from semanticBuildAlphabet per the
// semantic versioning spec.
appBuild = "dev"
// BuildMetadata is defined as a variable so it can be overridden during the
// build process with:
// '-ldflags "-X github.com/decred/dcrd/internal/version.BuildMetadata=foo"'
// if needed. It MUST only contain characters from semanticBuildAlphabet
// per the semantic versioning spec.
BuildMetadata = "dev"
)
// version returns the application version as a properly formed string per the
// String returns the application version as a properly formed string per the
// semantic versioning 2.0.0 spec (http://semver.org/).
func version() string {
func String() string {
// Start with the major, minor, and patch versions.
version := fmt.Sprintf("%d.%d.%d", appMajor, appMinor, appPatch)
version := fmt.Sprintf("%d.%d.%d", Major, Minor, Patch)
// Append pre-release version if there is one. The hyphen called for
// by the semantic versioning spec is automatically appended and should
// not be contained in the pre-release string. The pre-release version
// is not appended if it contains invalid characters.
preRelease := normalizePreRelString(appPreRelease)
preRelease := NormalizePreRelString(PreRelease)
if preRelease != "" {
version = fmt.Sprintf("%s-%s", version, preRelease)
}
@ -62,7 +66,7 @@ func version() string {
// by the semantic versioning spec is automatically appended and should
// not be contained in the build metadata string. The build metadata
// string is not appended if it contains invalid characters.
build := normalizeBuildString(appBuild)
build := NormalizeBuildString(BuildMetadata)
if build != "" {
version = fmt.Sprintf("%s+%s", version, build)
}
@ -82,18 +86,18 @@ func normalizeSemString(str, alphabet string) string {
return result.String()
}
// normalizePreRelString returns the passed string stripped of all characters
// NormalizePreRelString returns the passed string stripped of all characters
// which are not valid according to the semantic versioning guidelines for
// pre-release strings. In particular they MUST only contain characters in
// semanticAlphabet.
func normalizePreRelString(str string) string {
func NormalizePreRelString(str string) string {
return normalizeSemString(str, semanticAlphabet)
}
// normalizeBuildString returns the passed string stripped of all characters
// NormalizeBuildString returns the passed string stripped of all characters
// which are not valid according to the semantic versioning guidelines for build
// metadata strings. In particular they MUST only contain characters in
// semanticBuildAlphabet.
func normalizeBuildString(str string) string {
func NormalizeBuildString(str string) string {
return normalizeSemString(str, semanticBuildAlphabet)
}

View File

@ -44,6 +44,7 @@ import (
"github.com/decred/dcrd/dcrec/secp256k1"
"github.com/decred/dcrd/dcrjson"
"github.com/decred/dcrd/dcrutil"
"github.com/decred/dcrd/internal/version"
"github.com/decred/dcrd/mempool"
"github.com/decred/dcrd/mining"
"github.com/decred/dcrd/txscript"
@ -3229,8 +3230,8 @@ func handleGetHeaders(s *rpcServer, cmd interface{}, closeChan <-chan struct{})
func handleGetInfo(s *rpcServer, cmd interface{}, closeChan <-chan struct{}) (interface{}, error) {
best := s.chain.BestSnapshot()
ret := &dcrjson.InfoChainResult{
Version: int32(1000000*appMajor + 10000*appMinor +
100*appPatch),
Version: int32(1000000*version.Major + 10000*version.Minor +
100*version.Patch),
ProtocolVersion: int32(maxProtocolVersion),
Blocks: best.Height,
TimeOffset: int64(s.server.timeSource.Offset().Seconds()),
@ -5765,8 +5766,9 @@ func handleVerifyMessage(s *rpcServer, cmd interface{}, closeChan <-chan struct{
// handleVersion implements the version command.
func handleVersion(s *rpcServer, cmd interface{}, closeChan <-chan struct{}) (interface{}, error) {
runtimeVer := strings.Replace(runtime.Version(), ".", "-", -1)
buildMeta := normalizeBuildString(runtimeVer)
if build := normalizeBuildString(appBuild); build != "" {
buildMeta := version.NormalizeBuildString(runtimeVer)
build := version.NormalizeBuildString(version.BuildMetadata)
if build != "" {
buildMeta = fmt.Sprintf("%s.%s", build, buildMeta)
}
result := map[string]dcrjson.VersionResult{
@ -5777,11 +5779,11 @@ func handleVersion(s *rpcServer, cmd interface{}, closeChan <-chan struct{}) (in
Patch: jsonrpcSemverPatch,
},
"dcrd": {
VersionString: version(),
Major: uint32(appMajor),
Minor: uint32(appMinor),
Patch: uint32(appPatch),
Prerelease: normalizePreRelString(appPreRelease),
VersionString: version.String(),
Major: uint32(version.Major),
Minor: uint32(version.Minor),
Patch: uint32(version.Patch),
Prerelease: version.NormalizePreRelString(version.PreRelease),
BuildMetadata: buildMeta,
},
}

View File

@ -30,6 +30,7 @@ import (
"github.com/decred/dcrd/dcrutil"
"github.com/decred/dcrd/gcs"
"github.com/decred/dcrd/gcs/blockcf"
"github.com/decred/dcrd/internal/version"
"github.com/decred/dcrd/mempool"
"github.com/decred/dcrd/mining"
"github.com/decred/dcrd/peer"
@ -66,7 +67,8 @@ var (
// userAgentVersion is the user agent version and is used to help
// identify ourselves to other peers.
userAgentVersion = fmt.Sprintf("%d.%d.%d", appMajor, appMinor, appPatch)
userAgentVersion = fmt.Sprintf("%d.%d.%d", version.Major, version.Minor,
version.Patch)
)
// broadcastMsg provides the ability to house a Decred message to be broadcast
@ -1584,8 +1586,8 @@ func disconnectPeer(peerList map[int32]*serverPeer, compareFunc func(*serverPeer
// newPeerConfig returns the configuration for the given serverPeer.
func newPeerConfig(sp *serverPeer) *peer.Config {
var userAgentComments []string
if appPreRelease != "" {
userAgentComments = append(userAgentComments, appPreRelease)
if version.PreRelease != "" {
userAgentComments = append(userAgentComments, version.PreRelease)
}
return &peer.Config{

View File

@ -14,6 +14,7 @@ import (
"github.com/btcsuite/winsvc/eventlog"
"github.com/btcsuite/winsvc/mgr"
"github.com/btcsuite/winsvc/svc"
"github.com/decred/dcrd/internal/version"
)
const (
@ -37,7 +38,7 @@ var elog *eventlog.Log
// been started to the Windows event log.
func logServiceStartOfDay(srvr *server) {
var message string
message += fmt.Sprintf("Version %s\n", version())
message += fmt.Sprintf("Version %s\n", version.String())
message += fmt.Sprintf("Configuration directory: %s\n", cfg.HomeDir)
message += fmt.Sprintf("Configuration file: %s\n", cfg.ConfigFile)
message += fmt.Sprintf("Data directory: %s\n", cfg.DataDir)