1 2 3 4 5 6 7 8 9 10 11 12 13 14 15 16 17 18 19 20 21 22 23 24 25 26 27 28 29 30 31 32 33 34 35 36 37 38 39 40 41 42 43 44 45 46 47 48 49 50 51 52 53 54 55 56 57 58 59 60 61 62 63 64 65 66 67 68 69 70 71 72 73 74 75 76 77 78 79 80 81 82 83 84 85 86 87 88 89 90 91 92 93 94 95 96 97 98 99 100 101 102 103 104 105 106 107 108 109 110 111 112 113 114 115 116 117 118 119 120 121 122 123 124 125 126 127 128 129 130 131 132 133 134 135 136 137 138 139 140 141 142 143 144 145 146 147 148 149 150 151 152 153 154 155 156 157 158 159 160 161
|
package meta
import (
"fmt"
"runtime/debug"
"time"
)
// Constants for repeated string values.
const (
devVersion = "dev"
unknownValue = "unknown"
trueValue = "true"
commitSHALength = 7 // Length to shorten Git commit SHA
)
// These values are populated by GoReleaser during release builds.
var (
// Version is the Shoutrrr version (e.g., "v0.0.1").
Version = devVersion
// Commit is the Git commit SHA (e.g., "abc123").
Commit = unknownValue
// Date is the build or commit timestamp in RFC3339 format (e.g., "2025-05-07T00:00:00Z").
Date = unknownValue
)
// Info holds version information for Shoutrrr.
type Info struct {
Version string
Commit string
Date string
}
// GetMetaStr returns the formatted version string, including commit info only if available.
func GetMetaStr() string {
version := GetVersion()
date := GetDate()
commit := GetCommit()
if commit == unknownValue {
return fmt.Sprintf("%s (Built on %s)", version, date)
}
return fmt.Sprintf("%s (Built on %s from Git SHA %s)", version, date, commit)
}
// GetVersion returns the version string, using debug.ReadBuildInfo for source builds
// or GoReleaser variables for release builds.
func GetVersion() string {
version := Version
// If building from source (not GoReleaser), try to get version from debug.ReadBuildInfo
if version == devVersion || version == "" {
if info, ok := debug.ReadBuildInfo(); ok {
// Get the module version (e.g., v1.1.4 or v1.1.4+dirty)
version = info.Main.Version
if version == "(devel)" || version == "" {
version = devVersion
}
// Check for dirty state
for _, setting := range info.Settings {
if setting.Key == "vcs.modified" && setting.Value == trueValue &&
version != unknownValue && !contains(version, "+dirty") {
version += "+dirty"
}
}
}
} else {
// GoReleaser provides a valid version without 'v' prefix, so add it
if version != "" && version != "v" {
version = "v" + version
}
}
// Fallback default if still unset or invalid
if version == "" || version == devVersion || version == "v" {
return unknownValue
}
return version
}
// GetCommit returns the commit SHA, using debug.ReadBuildInfo for source builds
// or GoReleaser variables for release builds.
func GetCommit() string {
// Return Commit if set by GoReleaser (non-empty and not "unknown")
if Commit != unknownValue && Commit != "" {
if len(Commit) >= commitSHALength {
return Commit[:commitSHALength]
}
return Commit
}
// Try to get commit from debug.ReadBuildInfo for source builds
if info, ok := debug.ReadBuildInfo(); ok {
for _, setting := range info.Settings {
if setting.Key == "vcs.revision" && setting.Value != "" {
if len(setting.Value) >= commitSHALength {
return setting.Value[:commitSHALength]
}
return setting.Value
}
}
}
// Fallback to unknown if no commit is found
return unknownValue
}
// GetDate returns the build or commit date, using debug.ReadBuildInfo for source builds
// or GoReleaser variables for release builds.
func GetDate() string {
date := Date
// If building from source (not GoReleaser), try to get date from debug.ReadBuildInfo
if date == unknownValue || date == "" {
if info, ok := debug.ReadBuildInfo(); ok {
for _, setting := range info.Settings {
if setting.Key == "vcs.time" {
if t, err := time.Parse(time.RFC3339, setting.Value); err == nil {
return t.Format("2006-01-02") // Shorten to YYYY-MM-DD
}
}
}
}
// Fallback to current date if no VCS time is available
return time.Now().UTC().Format("2006-01-02")
}
// Shorten date if provided by GoReleaser
if date != "" && date != unknownValue {
if t, err := time.Parse(time.RFC3339, date); err == nil {
return t.Format("2006-01-02") // Shorten to YYYY-MM-DD
}
}
// Fallback to current date if date is invalid
return time.Now().UTC().Format("2006-01-02")
}
// GetMetaInfo returns version information by combining GetVersion, GetCommit, and GetDate.
func GetMetaInfo() Info {
return Info{
Version: GetVersion(),
Commit: GetCommit(),
Date: GetDate(),
}
}
// contains checks if a string contains a substring.
func contains(s, substr string) bool {
for i := 0; i <= len(s)-len(substr); i++ {
if s[i:i+len(substr)] == substr {
return true
}
}
return false
}
|