Skip to content

version: preserve semantic version separators - #662

Merged
zquestz merged 1 commit into
gcash:masterfrom
pucedoteth:fix-version-separators
Aug 22, 2026
Merged

version: preserve semantic version separators#662
zquestz merged 1 commit into
gcash:masterfrom
pucedoteth:fix-version-separators

Conversation

@pucedoteth

Copy link
Copy Markdown
Contributor

SemVer separates pre-release identifiers and build metadata with periods, but semanticAlphabet omits the period.

String() uses normalizeVerString as a validator rather than a sanitizer — it only appends the metadata when the string round-trips unchanged:

if appBuild != "" {
    build := normalizeVerString(appBuild)
    if build == appBuild {
        version = fmt.Sprintf("%s+%s", version, build)
    }
}

So a dot-separated build stamp is not mangled, it is dropped from the version entirely, as if it had never been set. Adding a case to TestString shows it on master:

--- FAIL: TestString
    version_test.go:42: with-dotted-build: expected 0.22.2+exp.sha.5114f85, got 0.22.2

This is reachable rather than latent. appBuild is documented as settable at build time via -ldflags, and SemVer build metadata is dot-separated — exp.sha.5114f85 is an example from the spec itself. The same applies to AppPreRelease: a value like beta.rc1 would be dropped rather than reported.

The existing with-out-of-spec-build case (012_abc, underscore) still passes, so genuinely invalid metadata is still rejected.

btcd, which this code came from, fixed its copy in 65db493 ("version: preserve semantic version separators", btcsuite/btcd#2578).

go build ./..., go test ./version/, gofmt and go vet are clean.

One thing I noticed but left alone to keep the diff to the fix: the comment above appBuild says -X main.appBuild, but this copy lives in package version, so the flag is really -X github.com/gcash/bchd/version.appBuild. It was accurate before the code moved out of main.


Disclosure: written with AI assistance; the analysis, fix and test were verified locally.

SemVer separates pre-release identifiers and build metadata with
periods, but semanticAlphabet omits the period. String() treats
normalizeVerString as a validator and only appends build metadata when
the string round-trips unchanged, so a dot-separated stamp is dropped
from the version entirely rather than reported.

appBuild is settable at build time via -ldflags, and SemVer build
metadata is dot-separated, so a build stamped exp.sha.5114f85 reports
0.22.2 instead of 0.22.2+exp.sha.5114f85.

Add the period and extend TestString with a dotted build case.
@zquestz
zquestz merged commit 910dfea into gcash:master Aug 22, 2026
Sign up for free to join this conversation on GitHub. Already have an account? Sign in to comment

Labels

None yet

Projects

None yet

Development

Successfully merging this pull request may close these issues.

2 participants