package main // Heavily inspired by https://github.com/btcsuite/btcd/blob/master/version.go 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 = 0 appMinor uint = 1 appPatch uint = 1 // appPreRelease MUST only contain characters from semanticAlphabet // per the semantic versioning spec. appPreRelease = "alpha" ) // 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 string // 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) { result.WriteRune(r) } } return result.String() }