Add build metadata injection

This commit is contained in:
2025-12-24 11:32:11 +03:00
parent e7a65571c8
commit dc05c68ee2
2 changed files with 67 additions and 15 deletions

33
src/build_info.go Normal file
View File

@@ -0,0 +1,33 @@
package main
import "runtime/debug"
func init() {
if AppCommit == "" || AppCommit == "unknown" {
if commit := resolveCommitFromBuildInfo(); commit != "" {
AppCommit = commit
}
}
}
func resolveCommitFromBuildInfo() string {
info, ok := debug.ReadBuildInfo()
if !ok {
return ""
}
for _, setting := range info.Settings {
if setting.Key == "vcs.revision" && setting.Value != "" {
return shortCommit(setting.Value)
}
}
return ""
}
func shortCommit(commit string) string {
if len(commit) >= 8 {
return commit[:8]
}
return commit
}

View File

@@ -27,7 +27,7 @@ type BumpConfig struct {
func getBumpConfig(cfg_name string) (*BumpConfig, error) { func getBumpConfig(cfg_name string) (*BumpConfig, error) {
cfg, err := ini.Load(cfg_name) cfg, err := ini.Load(cfg_name)
if err != nil { if err != nil {
log.Fatalf("Error loading config: %v", err) return nil, fmt.Errorf("error loading config: %w", err)
} }
sec, err := cfg.GetSection("bumpversion") sec, err := cfg.GetSection("bumpversion")
@@ -70,6 +70,7 @@ func bumpVersion(bc *BumpConfig, part string) (string, error) {
// Создадим карту групп по именам // Создадим карту групп по именам
groupNames := re.SubexpNames() groupNames := re.SubexpNames()
var major, minor, patch int var major, minor, patch int
var hasMajor, hasMinor, hasPatch bool
for i, name := range groupNames { for i, name := range groupNames {
switch name { switch name {
case "major": case "major":
@@ -77,18 +78,24 @@ func bumpVersion(bc *BumpConfig, part string) (string, error) {
if err != nil { if err != nil {
return "", err return "", err
} }
hasMajor = true
case "minor": case "minor":
minor, err = strconv.Atoi(matches[i]) minor, err = strconv.Atoi(matches[i])
if err != nil { if err != nil {
return "", err return "", err
} }
hasMinor = true
case "patch": case "patch":
patch, err = strconv.Atoi(matches[i]) patch, err = strconv.Atoi(matches[i])
if err != nil { if err != nil {
return "", err return "", err
} }
hasPatch = true
} }
} }
if !hasMajor || !hasMinor || !hasPatch {
return "", fmt.Errorf("parse pattern must contain major, minor, and patch groups")
}
switch part { switch part {
case "major": case "major":
major++ major++
@@ -143,39 +150,45 @@ func updateConfigFile(configPath string, newVersion string) error {
// resolveFlag проверяет два логических флага: positive и negative. // resolveFlag проверяет два логических флага: positive и negative.
// Если оба заданы как true, вызывается ошибка; если задан negative, возвращается false; // Если оба заданы как true, вызывается ошибка; если задан negative, возвращается false;
// если задан positive, возвращается true; иначе возвращается defaultValue. // если задан positive, возвращается true; иначе возвращается defaultValue.
func resolveFlag(positive, negative *bool, defaultValue bool) bool { func resolveFlag(positive, negative *bool, defaultValue bool) (bool, error) {
if *positive && *negative { if *positive && *negative {
// Если оба флага заданы, это противоречивое состояние. return false, fmt.Errorf("conflicting flags: both positive and negative are set")
// Здесь можно завершить программу с ошибкой или выбрать приоритет.
// Например, завершим выполнение:
panic("conflicting flags: both positive and negative are set")
} }
if *negative { if *negative {
return false return false, nil
} }
if *positive { if *positive {
return true return true, nil
} }
return defaultValue return defaultValue, nil
} }
// Версия приложения // Версия приложения
const ( const AppName = "BumpVersion"
AppName = "BumpVersion"
var (
AppVersion = "0.1.3" AppVersion = "0.1.3"
AppCommit = "unknown"
) )
func versionString() string {
if AppCommit == "" || AppCommit == "unknown" {
return AppVersion
}
return fmt.Sprintf("%s (%s)", AppVersion, AppCommit)
}
func main() { func main() {
const cfg_name = ".bumpversion.cfg" const cfg_name = ".bumpversion.cfg"
args := os.Args[1:] args := os.Args[1:]
// Проверяем аргументы командной строки // Проверяем аргументы командной строки
if len(args) > 0 && strings.ToLower(args[0]) == "--version" { if len(args) > 0 && strings.ToLower(args[0]) == "--version" {
fmt.Printf("%s version %s\n", AppName, AppVersion) fmt.Printf("%s version %s\n", AppName, versionString())
return return
} }
// Печатаем название и версию при старте // Печатаем название и версию при старте
fmt.Printf("Starting %s version %s\n", AppName, AppVersion) fmt.Printf("Starting %s version %s\n", AppName, versionString())
bc, err := getBumpConfig(cfg_name) bc, err := getBumpConfig(cfg_name)
if err != nil { if err != nil {
@@ -198,8 +211,14 @@ func main() {
} }
// Разрешаем флаги: // Разрешаем флаги:
shouldCommit := resolveFlag(commit, noCommit, bc.Commit) shouldCommit, err := resolveFlag(commit, noCommit, bc.Commit)
shouldTag := resolveFlag(tag, noTag, bc.Tag) if err != nil {
log.Fatalf("Error resolving commit flags: %v", err)
}
shouldTag, err := resolveFlag(tag, noTag, bc.Tag)
if err != nil {
log.Fatalf("Error resolving tag flags: %v", err)
}
newVersion, err := bumpVersion(bc, *part) newVersion, err := bumpVersion(bc, *part)
if err != nil { if err != nil {