- Update Makefile install target to extract and pass git commit/branch via ldflags - Add -X main.Commit and -X main.Branch to all build configurations in .goreleaser.yml - Create scripts/install.sh helper for explicit version control during installation - Add comprehensive tests for commit/branch resolution and output formatting Fixes github #503: 'bd version' now reports as-built commit hash and branch information regardless of installation method (make install, go install, or released binaries from goreleaser).
266 lines
6.4 KiB
Go
266 lines
6.4 KiB
Go
package main
|
|
|
|
import (
|
|
"bytes"
|
|
"encoding/json"
|
|
"os"
|
|
"strings"
|
|
"testing"
|
|
)
|
|
|
|
func TestVersionCommand(t *testing.T) {
|
|
// Save original stdout
|
|
oldStdout := os.Stdout
|
|
defer func() { os.Stdout = oldStdout }()
|
|
|
|
t.Run("plain text version output", func(t *testing.T) {
|
|
// Create a pipe to capture output
|
|
r, w, err := os.Pipe()
|
|
if err != nil {
|
|
t.Fatalf("Failed to create pipe: %v", err)
|
|
}
|
|
os.Stdout = w
|
|
jsonOutput = false
|
|
|
|
// Run version command
|
|
versionCmd.Run(versionCmd, []string{})
|
|
|
|
// Close writer and read output
|
|
w.Close()
|
|
var buf bytes.Buffer
|
|
buf.ReadFrom(r)
|
|
output := buf.String()
|
|
|
|
// Verify output contains version info
|
|
if !strings.Contains(output, "bd version") {
|
|
t.Errorf("Expected output to contain 'bd version', got: %s", output)
|
|
}
|
|
if !strings.Contains(output, Version) {
|
|
t.Errorf("Expected output to contain version %s, got: %s", Version, output)
|
|
}
|
|
})
|
|
|
|
t.Run("json version output", func(t *testing.T) {
|
|
// Create a pipe to capture output
|
|
r, w, err := os.Pipe()
|
|
if err != nil {
|
|
t.Fatalf("Failed to create pipe: %v", err)
|
|
}
|
|
os.Stdout = w
|
|
jsonOutput = true
|
|
|
|
// Run version command
|
|
versionCmd.Run(versionCmd, []string{})
|
|
|
|
// Close writer and read output
|
|
w.Close()
|
|
var buf bytes.Buffer
|
|
buf.ReadFrom(r)
|
|
output := buf.String()
|
|
|
|
// Parse JSON output
|
|
var result map[string]string
|
|
if err := json.Unmarshal([]byte(output), &result); err != nil {
|
|
t.Fatalf("Failed to parse JSON output: %v", err)
|
|
}
|
|
|
|
// Verify JSON contains version and build
|
|
if result["version"] != Version {
|
|
t.Errorf("Expected version %s, got %s", Version, result["version"])
|
|
}
|
|
if result["build"] == "" {
|
|
t.Error("Expected build field to be non-empty")
|
|
}
|
|
})
|
|
|
|
// Restore default
|
|
jsonOutput = false
|
|
}
|
|
|
|
func TestResolveCommitHash(t *testing.T) {
|
|
// Save original Commit value
|
|
origCommit := Commit
|
|
defer func() { Commit = origCommit }()
|
|
|
|
t.Run("returns ldflag value when set", func(t *testing.T) {
|
|
testCommit := "abc123def456"
|
|
Commit = testCommit
|
|
result := resolveCommitHash()
|
|
if result != testCommit {
|
|
t.Errorf("Expected %q, got %q", testCommit, result)
|
|
}
|
|
})
|
|
|
|
t.Run("returns empty string when not set", func(t *testing.T) {
|
|
Commit = ""
|
|
result := resolveCommitHash()
|
|
// Result could be from git or empty - just verify it doesn't panic
|
|
if result == "" || len(result) >= 7 {
|
|
// Either empty or looks like a git hash
|
|
return
|
|
}
|
|
t.Errorf("Unexpected result format: %q", result)
|
|
})
|
|
}
|
|
|
|
func TestResolveBranch(t *testing.T) {
|
|
// Save original Branch value
|
|
origBranch := Branch
|
|
defer func() { Branch = origBranch }()
|
|
|
|
t.Run("returns ldflag value when set", func(t *testing.T) {
|
|
testBranch := "main"
|
|
Branch = testBranch
|
|
result := resolveBranch()
|
|
if result != testBranch {
|
|
t.Errorf("Expected %q, got %q", testBranch, result)
|
|
}
|
|
})
|
|
|
|
t.Run("returns empty string or git branch when not set", func(t *testing.T) {
|
|
Branch = ""
|
|
result := resolveBranch()
|
|
// Result could be from git or empty - just verify it doesn't panic
|
|
if result == "" || result == "main" || strings.Contains(result, "detached") {
|
|
return
|
|
}
|
|
t.Logf("Got branch: %q", result)
|
|
})
|
|
}
|
|
|
|
func TestVersionOutputWithCommitAndBranch(t *testing.T) {
|
|
// Save original values
|
|
oldStdout := os.Stdout
|
|
origCommit := Commit
|
|
origBranch := Branch
|
|
defer func() {
|
|
os.Stdout = oldStdout
|
|
Commit = origCommit
|
|
Branch = origBranch
|
|
}()
|
|
|
|
t.Run("text output includes commit and branch when available", func(t *testing.T) {
|
|
Commit = "7e709405b38c472d8cbc996c7cd26df7e3b438d0"
|
|
Branch = "main"
|
|
|
|
r, w, err := os.Pipe()
|
|
if err != nil {
|
|
t.Fatalf("Failed to create pipe: %v", err)
|
|
}
|
|
os.Stdout = w
|
|
jsonOutput = false
|
|
|
|
versionCmd.Run(versionCmd, []string{})
|
|
|
|
w.Close()
|
|
var buf bytes.Buffer
|
|
buf.ReadFrom(r)
|
|
output := buf.String()
|
|
|
|
// Should contain both branch and commit
|
|
if !strings.Contains(output, "main@") {
|
|
t.Errorf("Expected output to contain 'main@', got: %s", output)
|
|
}
|
|
if !strings.Contains(output, "7e70940") { // first 7 chars of commit
|
|
t.Errorf("Expected output to contain commit hash, got: %s", output)
|
|
}
|
|
})
|
|
|
|
t.Run("json output includes commit and branch when available", func(t *testing.T) {
|
|
Commit = "7e709405b38c472d8cbc996c7cd26df7e3b438d0"
|
|
Branch = "main"
|
|
|
|
r, w, err := os.Pipe()
|
|
if err != nil {
|
|
t.Fatalf("Failed to create pipe: %v", err)
|
|
}
|
|
os.Stdout = w
|
|
jsonOutput = true
|
|
|
|
versionCmd.Run(versionCmd, []string{})
|
|
|
|
w.Close()
|
|
var buf bytes.Buffer
|
|
buf.ReadFrom(r)
|
|
output := buf.String()
|
|
|
|
var result map[string]string
|
|
if err := json.Unmarshal([]byte(output), &result); err != nil {
|
|
t.Fatalf("Failed to parse JSON output: %v", err)
|
|
}
|
|
|
|
if result["commit"] != Commit {
|
|
t.Errorf("Expected commit %q, got %q", Commit, result["commit"])
|
|
}
|
|
if result["branch"] != Branch {
|
|
t.Errorf("Expected branch %q, got %q", Branch, result["branch"])
|
|
}
|
|
})
|
|
}
|
|
|
|
func TestVersionFlag(t *testing.T) {
|
|
// Save original stdout
|
|
oldStdout := os.Stdout
|
|
defer func() { os.Stdout = oldStdout }()
|
|
|
|
t.Run("--version flag", func(t *testing.T) {
|
|
// Create a pipe to capture output
|
|
r, w, err := os.Pipe()
|
|
if err != nil {
|
|
t.Fatalf("Failed to create pipe: %v", err)
|
|
}
|
|
os.Stdout = w
|
|
|
|
// Set version flag and run root command
|
|
rootCmd.SetArgs([]string{"--version"})
|
|
rootCmd.Execute()
|
|
|
|
// Close writer and read output
|
|
w.Close()
|
|
var buf bytes.Buffer
|
|
buf.ReadFrom(r)
|
|
output := buf.String()
|
|
|
|
// Verify output contains version info
|
|
if !strings.Contains(output, "bd version") {
|
|
t.Errorf("Expected output to contain 'bd version', got: %s", output)
|
|
}
|
|
if !strings.Contains(output, Version) {
|
|
t.Errorf("Expected output to contain version %s, got: %s", Version, output)
|
|
}
|
|
|
|
// Reset args
|
|
rootCmd.SetArgs(nil)
|
|
})
|
|
|
|
t.Run("-v shorthand", func(t *testing.T) {
|
|
// Create a pipe to capture output
|
|
r, w, err := os.Pipe()
|
|
if err != nil {
|
|
t.Fatalf("Failed to create pipe: %v", err)
|
|
}
|
|
os.Stdout = w
|
|
|
|
// Set version flag and run root command
|
|
rootCmd.SetArgs([]string{"-v"})
|
|
rootCmd.Execute()
|
|
|
|
// Close writer and read output
|
|
w.Close()
|
|
var buf bytes.Buffer
|
|
buf.ReadFrom(r)
|
|
output := buf.String()
|
|
|
|
// Verify output contains version info
|
|
if !strings.Contains(output, "bd version") {
|
|
t.Errorf("Expected output to contain 'bd version', got: %s", output)
|
|
}
|
|
if !strings.Contains(output, Version) {
|
|
t.Errorf("Expected output to contain version %s, got: %s", Version, output)
|
|
}
|
|
|
|
// Reset args
|
|
rootCmd.SetArgs(nil)
|
|
})
|
|
}
|