diff --git a/src/git.go b/src/git.go index 9d3fee5..554789d 100644 --- a/src/git.go +++ b/src/git.go @@ -11,42 +11,101 @@ import ( "github.com/go-git/go-git/v5/plumbing/object" ) +// getenvDefault возвращает значение из окружения по ключу, или заданное +// по умолчанию +func getenvDefault(k, def string) string { + if v := os.Getenv(k); v != "" { + return v + } + return def +} + +// normalizePath возвращает нормализованный путь +func normalizePath(p string) string { + p = strings.TrimSpace(p) + p = strings.TrimPrefix(p, "./") + return p +} + // gitCommit выполняет коммит с внесёнными изменениями -func gitCommit(bc *BumpConfig, newVersion string) { +func gitCommit(bc *BumpConfig, newVersion string, configPath string) { // Открываем локальный репозиторий (предполагается, что он существует в папке ".") repo, err := git.PlainOpen(".") if err != nil { log.Fatalf("Repository open error: %v", err) } - // Получаем рабочее дерево + // получаем рабочее дерево worktree, err := repo.Worktree() if err != nil { log.Fatalf("Work directory open error: %v", err) } - // Добавляем все изменения в индекс (или конкретные файлы, если нужно) - _, err = worktree.Add(".") + // создаём список файлов, которые должны быть включены в коммит + targets := make([]string, 0, len(bc.FilePaths)+1) + targets = append(targets, bc.FilePaths...) + targets = append(targets, configPath) + + // проверяем на наличие изменений + status, err := worktree.Status() if err != nil { - log.Fatalf("Changes append error: %v", err) + log.Fatalf("Status error: %v", err) } - // Формируем сообщение коммита - commitMsg := strings.ReplaceAll(bc.Message, "{current_version}", bc.CurrentVersion) - commitMsg = strings.ReplaceAll(commitMsg, "{new_version}", newVersion) - commit, err := worktree.Commit(commitMsg, &git.CommitOptions{ - Author: &object.Signature{ - Name: os.Getenv("GIT_USERNAME"), - Email: os.Getenv("GIT_EMAIL"), - When: time.Now(), - }, + changed := false + for _, p := range targets { + if p == "" { + continue + } + p = normalizePath(p) + + // пропускаем отсутствующие файлы тихо + if _, err := os.Stat(p); err != nil { + if os.IsNotExist(err) { + log.Printf("Skip missing file: %s", p) + continue + } + log.Fatalf("Stat error for %s: %v", p, err) + } + + st := status[p] + if st.Worktree != git.Unmodified { + if _, err := worktree.Add(p); err != nil { + log.Fatalf("Add %s error: %v", p, err) + } + changed = true + continue + } + } + + if !changed { + log.Printf("No changes detected in configured files; skipping commit.") + return + } + + // формируем сообщение коммита + commitMsg := strings. + NewReplacer( + "{current_version}", bc.CurrentVersion, + "{new_version}", newVersion, + ).Replace(bc.Message) + + author := &object.Signature{ + Name: getenvDefault("GIT_USERNAME", "bumpversion"), + Email: getenvDefault("GIT_EMAIL", "bumpversion@deploy"), + When: time.Now().UTC(), + } + + hash, err := worktree.Commit(commitMsg, &git.CommitOptions{ + Author: author, + Committer: author, }) if err != nil { log.Fatalf("Commit error: %v", err) } // Получаем объект коммита (по его хэшу) - commitObj, err := repo.CommitObject(commit) + commitObj, err := repo.CommitObject(hash) if err != nil { log.Fatalf("Commit object error: %v", err) } diff --git a/src/main.go b/src/main.go index afc8f96..9301a27 100644 --- a/src/main.go +++ b/src/main.go @@ -162,7 +162,7 @@ func resolveFlag(positive, negative *bool, defaultValue bool) bool { // Версия приложения const ( AppName = "BumpVersion" - AppVersion = "0.1.2" + AppVersion = "0.1.3" ) func main() { @@ -220,7 +220,7 @@ func main() { // Выполняем git commit и tag, если требуется if shouldCommit { - gitCommit(bc, newVersion) + gitCommit(bc, newVersion, cfg_name) } // Выполняем git commit и tag, если требуется