diff --git a/docs/api.md b/docs/api.md index 53399b9..15c632f 100644 --- a/docs/api.md +++ b/docs/api.md @@ -43,7 +43,8 @@ when a VSP is closed will result in an error. "pubkey":"SjAmrAqH7LScCUwM1qo5O6Cu7aKhrM1ORszgZwD7HmU=", "feepercentage":3.0, "vspclosed":false, - "network":"testnet3" + "network":"testnet3", + "vspdversion":"1.0.0-pre" } ``` diff --git a/version/version.go b/version/version.go new file mode 100644 index 0000000..98ac734 --- /dev/null +++ b/version/version.go @@ -0,0 +1,61 @@ +package version + +import ( + "bytes" + "fmt" + "strings" +) + +// semverAlphabet is an alphabet of all characters allowed in semver prerelease +// identifiers, and the . separator. +const semverAlphabet = "0123456789ABCDEFGHIJKLMNOPQRSTUVWXYZabcdefghijklmnopqrstuvwxyz-." + +// Constants defining the application version number. +const ( + Major = 1 + Minor = 0 + Patch = 0 +) + +// PreRelease contains the prerelease name of the application. It is a variable +// so it can be modified at link time (e.g. +// `-ldflags "-X decred.org/vspd/version.PreRelease=rc1"`). +// It must only contain characters from the semantic version alphabet. +var PreRelease = "pre" + +// String returns the application version as a properly formed string per the +// semantic versioning 2.0.0 spec (https://semver.org/). +func String() string { + // Start with the major, minor, and path versions. + 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 := normalizeVerString(PreRelease) + if preRelease != "" { + version = version + "-" + preRelease + } + + 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 buf bytes.Buffer + for _, r := range str { + if strings.ContainsRune(semverAlphabet, r) { + _, err := buf.WriteRune(r) + // Writing to a bytes.Buffer panics on OOM, and all + // errors are unexpected. + if err != nil { + panic(err) + } + } + } + return buf.String() +} diff --git a/main.go b/vspd.go similarity index 94% rename from main.go rename to vspd.go index 47b40c5..f286a5a 100644 --- a/main.go +++ b/vspd.go @@ -5,11 +5,13 @@ import ( "errors" "fmt" "os" + "runtime" "sync" "github.com/decred/vspd/background" "github.com/decred/vspd/database" "github.com/decred/vspd/rpc" + "github.com/decred/vspd/version" "github.com/decred/vspd/webapi" ) @@ -39,6 +41,10 @@ func run(ctx context.Context) error { return err } + // Show version at startup. + log.Infof("Version %s (Go version %s %s/%s)", version.String(), runtime.Version(), + runtime.GOOS, runtime.GOARCH) + if cfg.VspClosed { log.Warnf("Config --vspclosed is set. This will prevent vspd from " + "accepting new tickets.") diff --git a/webapi/types.go b/webapi/types.go index e5b0bc1..d532b25 100644 --- a/webapi/types.go +++ b/webapi/types.go @@ -6,6 +6,7 @@ type vspInfoResponse struct { FeePercentage float64 `json:"feepercentage"` VspClosed bool `json:"vspclosed"` Network string `json:"network"` + VspdVersion string `json:"vspdversion"` } type FeeAddressRequest struct { diff --git a/webapi/vspstatus.go b/webapi/vspstatus.go index 3c71f4d..c9f00ba 100644 --- a/webapi/vspstatus.go +++ b/webapi/vspstatus.go @@ -3,6 +3,7 @@ package webapi import ( "time" + "github.com/decred/vspd/version" "github.com/gin-gonic/gin" ) @@ -14,5 +15,6 @@ func vspInfo(c *gin.Context) { FeePercentage: cfg.VSPFee, Network: cfg.NetParams.Name, VspClosed: cfg.VspClosed, + VspdVersion: version.String(), }, c) }