Skip to content
Merged
Show file tree
Hide file tree
Changes from all commits
Commits
File filter

Filter by extension

Filter by extension

Conversations
Failed to load comments.
Loading
Jump to
Jump to file
Failed to load files.
Loading
Diff view
Diff view
25 changes: 24 additions & 1 deletion main.go
Original file line number Diff line number Diff line change
Expand Up @@ -29,14 +29,37 @@ import (
"io"
"os"
"os/exec"
"runtime/debug"
"strconv"
"strings"

"github.com/DivergentCodes/commitlint/lint"
)

// version is stamped by the release workflow via -ldflags. Builds that are not
// produced by that workflow — notably `go install ...@v1.2.3`, the documented
// install path — leave it at the default, so fall back to the version the Go
// toolchain recorded in the binary.
var version = "0.0.0-dev"

// resolveVersion prefers an ldflags-stamped version, then the module version
// embedded by `go install`, and otherwise reports the default.
func resolveVersion() string {
if version != "0.0.0-dev" {
return version
}
info, ok := debug.ReadBuildInfo()
if !ok || info.Main.Version == "" {
return version
}
// A build from a local directory records "(devel)", which is less
// informative than the default.
if info.Main.Version == "(devel)" {
return version
}
return info.Main.Version
}

func main() {
if len(os.Args) < 2 {
usage()
Expand All @@ -46,7 +69,7 @@ func main() {
case "lint":
os.Exit(runLint(os.Args[2:]))
case "version", "--version", "-v":
fmt.Println(version)
fmt.Println(resolveVersion())
case "help", "--help", "-h":
usage()
default:
Expand Down
21 changes: 21 additions & 0 deletions main_test.go
Original file line number Diff line number Diff line change
Expand Up @@ -144,3 +144,24 @@ func TestWriteTextSkipsPassingMessages(t *testing.T) {
t.Errorf("failing message should be printed:\n%s", buf.String())
}
}

// `go install ...@vX.Y.Z` does not run the release workflow's -ldflags, so
// without a build-info fallback every installed binary reported 0.0.0-dev.
// Under `go test` the module version is "(devel)", so this cannot assert the
// installed-version path directly; it pins the precedence and the guarantee
// that the fallback never surfaces "(devel)" or an empty string.
func TestResolveVersion(t *testing.T) {
orig := version
defer func() { version = orig }()

version = "v2.3.4"
if got := resolveVersion(); got != "v2.3.4" {
t.Errorf("stamped version should win: got %q, want v2.3.4", got)
}

version = "0.0.0-dev"
got := resolveVersion()
if got == "" || got == "(devel)" {
t.Errorf("fallback must be informative, got %q", got)
}
}
Loading