Application
This commit is contained in:
208
src/main.go
Normal file
208
src/main.go
Normal file
@@ -0,0 +1,208 @@
|
||||
package main
|
||||
|
||||
import (
|
||||
"flag"
|
||||
"fmt"
|
||||
"log"
|
||||
"os"
|
||||
"os/exec"
|
||||
"regexp"
|
||||
"strconv"
|
||||
"strings"
|
||||
|
||||
"github.com/go-ini/ini"
|
||||
)
|
||||
|
||||
type BumpConfig struct {
|
||||
CurrentVersion string
|
||||
Commit bool
|
||||
Tag bool
|
||||
TagName string
|
||||
Parse string
|
||||
Serialize string
|
||||
Message string
|
||||
FilePaths []string
|
||||
}
|
||||
|
||||
func loadConfig(configPath string) (*ini.File, error) {
|
||||
return ini.Load(configPath)
|
||||
}
|
||||
|
||||
func getBumpConfig(cfg *ini.File) (*BumpConfig, error) {
|
||||
sec, err := cfg.GetSection("bumpversion")
|
||||
if err != nil {
|
||||
return nil, fmt.Errorf("missing [bumpversion] section: %w", err)
|
||||
}
|
||||
bc := &BumpConfig{
|
||||
CurrentVersion: sec.Key("current_version").String(),
|
||||
Commit: sec.Key("commit").MustBool(false),
|
||||
Tag: sec.Key("tag").MustBool(false),
|
||||
TagName: sec.Key("tag_name").String(),
|
||||
Parse: sec.Key("parse").String(),
|
||||
Serialize: strings.TrimSpace(sec.Key("serialize").String()),
|
||||
Message: sec.Key("message").String(),
|
||||
}
|
||||
// Получим список файлов для обновления из секций, начинающихся с "bumpversion:file:"
|
||||
for _, s := range cfg.Sections() {
|
||||
if strings.HasPrefix(s.Name(), "bumpversion:file:") {
|
||||
// Имя файла после последнего двоеточия:
|
||||
parts := strings.SplitN(s.Name(), ":", 3)
|
||||
if len(parts) == 3 {
|
||||
filePath := strings.TrimSpace(parts[2])
|
||||
bc.FilePaths = append(bc.FilePaths, filePath)
|
||||
}
|
||||
}
|
||||
}
|
||||
return bc, nil
|
||||
}
|
||||
|
||||
// bumpVersion парсит current_version, увеличивает нужную часть и возвращает новую версию.
|
||||
func bumpVersion(bc *BumpConfig, part string) (string, error) {
|
||||
re, err := regexp.Compile(bc.Parse)
|
||||
if err != nil {
|
||||
return "", fmt.Errorf("failed to compile parse regex: %w", err)
|
||||
}
|
||||
matches := re.FindStringSubmatch(bc.CurrentVersion)
|
||||
if matches == nil {
|
||||
return "", fmt.Errorf("current version %s does not match parse pattern", bc.CurrentVersion)
|
||||
}
|
||||
// Создадим карту групп по именам
|
||||
groupNames := re.SubexpNames()
|
||||
var major, minor, patch int
|
||||
for i, name := range groupNames {
|
||||
switch name {
|
||||
case "major":
|
||||
major, err = strconv.Atoi(matches[i])
|
||||
if err != nil {
|
||||
return "", err
|
||||
}
|
||||
case "minor":
|
||||
minor, err = strconv.Atoi(matches[i])
|
||||
if err != nil {
|
||||
return "", err
|
||||
}
|
||||
case "patch":
|
||||
patch, err = strconv.Atoi(matches[i])
|
||||
if err != nil {
|
||||
return "", err
|
||||
}
|
||||
}
|
||||
}
|
||||
switch part {
|
||||
case "major":
|
||||
major++
|
||||
minor = 0
|
||||
patch = 0
|
||||
case "minor":
|
||||
minor++
|
||||
patch = 0
|
||||
case "patch":
|
||||
patch++
|
||||
default:
|
||||
return "", fmt.Errorf("unknown bump part: %s", part)
|
||||
}
|
||||
newVersion := bc.Serialize
|
||||
newVersion = strings.ReplaceAll(newVersion, "{major}", fmt.Sprintf("%d", major))
|
||||
newVersion = strings.ReplaceAll(newVersion, "{minor}", fmt.Sprintf("%d", minor))
|
||||
newVersion = strings.ReplaceAll(newVersion, "{patch}", fmt.Sprintf("%d", patch))
|
||||
return newVersion, nil
|
||||
}
|
||||
|
||||
func updateFiles(filePaths []string, oldVersion, newVersion string) {
|
||||
for _, path := range filePaths {
|
||||
data, err := os.ReadFile(path)
|
||||
if err != nil {
|
||||
log.Printf("Unable to read file %s: %v", path, err)
|
||||
continue
|
||||
}
|
||||
newData := strings.ReplaceAll(string(data), oldVersion, newVersion)
|
||||
if err := os.WriteFile(path, []byte(newData), 0644); err != nil {
|
||||
log.Printf("Unable to write file %s: %v", path, err)
|
||||
} else {
|
||||
log.Printf("Updated file: %s", path)
|
||||
}
|
||||
}
|
||||
}
|
||||
|
||||
func gitCommitAndTag(currentVersion, newVersion string, bc *BumpConfig) error {
|
||||
commitMsg := strings.ReplaceAll(bc.Message, "{current_version}", currentVersion)
|
||||
commitMsg = strings.ReplaceAll(commitMsg, "{new_version}", newVersion)
|
||||
if bc.Commit {
|
||||
if err := exec.Command("git", "add", ".").Run(); err != nil {
|
||||
return fmt.Errorf("git add error: %w", err)
|
||||
}
|
||||
if err := exec.Command("git", "commit", "-m", commitMsg).Run(); err != nil {
|
||||
return fmt.Errorf("git commit error: %w", err)
|
||||
}
|
||||
log.Printf("Committed with message: %s", commitMsg)
|
||||
}
|
||||
if bc.Tag {
|
||||
tagName := strings.ReplaceAll(bc.TagName, "{new_version}", newVersion)
|
||||
if err := exec.Command("git", "tag", tagName).Run(); err != nil {
|
||||
return fmt.Errorf("git tag error: %w", err)
|
||||
}
|
||||
log.Printf("Created git tag: %s", tagName)
|
||||
}
|
||||
return nil
|
||||
}
|
||||
|
||||
func updateConfigFile(configPath string, newVersion string) error {
|
||||
cfg, err := ini.Load(configPath)
|
||||
if err != nil {
|
||||
return err
|
||||
}
|
||||
cfg.Section("bumpversion").Key("current_version").SetValue(newVersion)
|
||||
return cfg.SaveTo(configPath)
|
||||
}
|
||||
|
||||
// Версия приложения
|
||||
const (
|
||||
AppName = "BumpVersion"
|
||||
AppVersion = "0.1.0"
|
||||
)
|
||||
|
||||
func main() {
|
||||
// Проверяем аргументы командной строки
|
||||
args := os.Args[1:]
|
||||
if len(args) > 0 && strings.ToLower(args[0]) == "--version" {
|
||||
fmt.Printf("%s version %s\n", AppName, AppVersion)
|
||||
return
|
||||
}
|
||||
|
||||
// Печатаем название и версию при старте
|
||||
fmt.Printf("Starting %s version %s\n", AppName, AppVersion)
|
||||
|
||||
part := flag.String("part", "patch", "Part to bump: major, minor, patch")
|
||||
configPath := flag.String("config", ".bumpversion.cfg", "Path to config file")
|
||||
flag.Parse()
|
||||
|
||||
cfgFile, err := loadConfig(*configPath)
|
||||
if err != nil {
|
||||
log.Fatalf("Error loading config: %v", err)
|
||||
}
|
||||
|
||||
bc, err := getBumpConfig(cfgFile)
|
||||
if err != nil {
|
||||
log.Fatalf("Error reading bumpversion configuration: %v", err)
|
||||
}
|
||||
|
||||
fmt.Printf("Current version: %s\n", bc.CurrentVersion)
|
||||
newVersion, err := bumpVersion(bc, *part)
|
||||
if err != nil {
|
||||
log.Fatalf("Error bumping version: %v", err)
|
||||
}
|
||||
fmt.Printf("New version: %s\n", newVersion)
|
||||
|
||||
// Обновляем файлы, указанные в конфигурации
|
||||
updateFiles(bc.FilePaths, bc.CurrentVersion, newVersion)
|
||||
|
||||
// Выполняем git commit и tag, если требуется
|
||||
if err := gitCommitAndTag(bc.CurrentVersion, newVersion, bc); err != nil {
|
||||
log.Printf("Git commit/tag error: %v", err)
|
||||
}
|
||||
|
||||
// Обновляем конфигурационный файл
|
||||
if err := updateConfigFile(*configPath, newVersion); err != nil {
|
||||
log.Printf("Error updating config file: %v", err)
|
||||
}
|
||||
}
|
||||
Reference in New Issue
Block a user