File: meta.go

package info (click to toggle)
golang-github-nicholas-fedor-shoutrrr 0.8.17-1
  • links: PTS, VCS
  • area: main
  • in suites: forky, sid
  • size: 4,332 kB
  • sloc: sh: 61; makefile: 5
file content (161 lines) | stat: -rw-r--r-- 4,346 bytes parent folder | download
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
}