From 34df31ecfeb73b358a65addd4cc34d455dfd9126 Mon Sep 17 00:00:00 2001 From: =?UTF-8?q?Ula=C5=9F=20=27Sophylax=27=20Sert?= Date: Tue, 31 Mar 2026 00:48:12 +0300 Subject: [PATCH 1/2] fix: derive version from build info --- main.go | 2 +- version.go | 19 +++++++++++++++++++ version_test.go | 19 +++++++++++++++++++ 3 files changed, 39 insertions(+), 1 deletion(-) create mode 100644 version.go create mode 100644 version_test.go diff --git a/main.go b/main.go index 635e82e..25df5ae 100644 --- a/main.go +++ b/main.go @@ -11,7 +11,7 @@ import ( var version = "dev" func main() { - if err := cmd.Execute(version); err != nil { + if err := cmd.Execute(resolveVersion(version)); err != nil { if !errors.Is(err, cmd.ErrFindings) { fmt.Fprintln(os.Stderr, err) } diff --git a/version.go b/version.go new file mode 100644 index 0000000..414fb7d --- /dev/null +++ b/version.go @@ -0,0 +1,19 @@ +package main + +import "runtime/debug" + +// resolveVersion prefers an injected build version, then falls back to module build info. +func resolveVersion(injected string) string { + if injected != "" && injected != "dev" { + return injected + } + + info, ok := debug.ReadBuildInfo() + if !ok { + return injected + } + if info.Main.Version == "" || info.Main.Version == "(devel)" { + return injected + } + return info.Main.Version +} diff --git a/version_test.go b/version_test.go new file mode 100644 index 0000000..1ba0b48 --- /dev/null +++ b/version_test.go @@ -0,0 +1,19 @@ +package main + +import "testing" + +func TestResolveVersionPrefersInjectedVersion(t *testing.T) { + t.Parallel() + + if got := resolveVersion("v1.2.3"); got != "v1.2.3" { + t.Fatalf("resolveVersion() = %q, want %q", got, "v1.2.3") + } +} + +func TestResolveVersionFallsBackToInjectedDevWhenNoBuildInfoVersion(t *testing.T) { + t.Parallel() + + if got := resolveVersion("dev"); got != "dev" { + t.Fatalf("resolveVersion() = %q, want %q", got, "dev") + } +} From 585b757dc372b32e75446413093813b777477247 Mon Sep 17 00:00:00 2001 From: =?UTF-8?q?Ula=C5=9F=20=27Sophylax=27=20Sert?= Date: Tue, 31 Mar 2026 00:52:25 +0300 Subject: [PATCH 2/2] test: cover build-info version fallback --- README.md | 2 +- version.go | 4 +++- version_test.go | 23 ++++++++++++++++++++++- 3 files changed, 26 insertions(+), 3 deletions(-) diff --git a/README.md b/README.md index b771455..60a95f2 100644 --- a/README.md +++ b/README.md @@ -138,7 +138,7 @@ Add a finding fingerprint to `.envguard-ignore` in the repository root. ### `envguard version` -Print the build version injected at compile time. +Print the resolved build or module version. ## Allowlist Workflow diff --git a/version.go b/version.go index 414fb7d..a54506f 100644 --- a/version.go +++ b/version.go @@ -2,13 +2,15 @@ package main import "runtime/debug" +var readBuildInfo = debug.ReadBuildInfo + // resolveVersion prefers an injected build version, then falls back to module build info. func resolveVersion(injected string) string { if injected != "" && injected != "dev" { return injected } - info, ok := debug.ReadBuildInfo() + info, ok := readBuildInfo() if !ok { return injected } diff --git a/version_test.go b/version_test.go index 1ba0b48..15aaba2 100644 --- a/version_test.go +++ b/version_test.go @@ -1,6 +1,9 @@ package main -import "testing" +import ( + "runtime/debug" + "testing" +) func TestResolveVersionPrefersInjectedVersion(t *testing.T) { t.Parallel() @@ -17,3 +20,21 @@ func TestResolveVersionFallsBackToInjectedDevWhenNoBuildInfoVersion(t *testing.T t.Fatalf("resolveVersion() = %q, want %q", got, "dev") } } + +func TestResolveVersionFallsBackToBuildInfoVersion(t *testing.T) { + original := readBuildInfo + readBuildInfo = func() (*debug.BuildInfo, bool) { + return &debug.BuildInfo{ + Main: debug.Module{ + Version: "v0.1.1", + }, + }, true + } + t.Cleanup(func() { + readBuildInfo = original + }) + + if got := resolveVersion("dev"); got != "v0.1.1" { + t.Fatalf("resolveVersion() = %q, want %q", got, "v0.1.1") + } +}