grafana-backuper/pkg/git/commit.go

124 lines
2.3 KiB
Go
Raw Normal View History

2024-06-23 16:25:55 +02:00
package git
import (
"errors"
"fmt"
"path/filepath"
"strings"
2024-06-23 16:25:55 +02:00
"time"
"github.com/ProtonMail/go-crypto/openpgp"
"github.com/go-git/go-git/v5"
"github.com/go-git/go-git/v5/plumbing/object"
)
type CommitOption func(*Commit)
func WithAuthor(name, email string) CommitOption {
return func(c *Commit) {
c.Author = &object.Signature{
Name: name,
Email: email,
When: time.Now(),
}
}
}
func WithCommitter(name, email string) CommitOption {
return func(c *Commit) {
c.Committer = &object.Signature{
Name: name,
Email: email,
When: time.Now(),
}
}
}
func WithFileContent(content []byte, filename, folder string) CommitOption {
2024-06-23 16:25:55 +02:00
return func(c *Commit) {
c.Content = content
c.Filename = filepath.Join(folder, fmt.Sprintf("%s.json", filename))
}
}
func WithSigner(signKey SignKey) CommitOption {
return func(c *Commit) {
c.signKey = signKey.entity
2024-06-23 16:25:55 +02:00
}
}
type Commit struct {
Author *object.Signature
Committer *object.Signature
Content []byte
Filename string
KeyFile string
2024-06-23 16:25:55 +02:00
project *Project
signKey *openpgp.Entity
2024-06-23 16:25:55 +02:00
}
func (p *Project) NewCommit(options ...CommitOption) *Commit {
commit := &Commit{project: p}
for _, option := range options {
option(commit)
}
return commit
}
func (c *Commit) Create(msg string) error {
if err := c.addContent(); err != nil {
2024-06-23 16:25:55 +02:00
return err
}
if _, err := c.project.worktree.Add(c.Filename); err != nil {
2024-06-23 16:25:55 +02:00
return err
}
commitOpts := git.CommitOptions{Author: c.Author}
2024-06-23 16:25:55 +02:00
if c.Committer != nil {
commitOpts.Committer = c.Committer
2024-06-23 16:25:55 +02:00
}
if c.signKey != nil {
commitOpts.SignKey = c.signKey
2024-06-23 16:25:55 +02:00
}
_, err := c.project.worktree.Commit(msg, &commitOpts)
if err != nil {
2024-06-23 16:25:55 +02:00
return err
}
return nil
}
2024-06-23 16:25:55 +02:00
func (c *Commit) Exists(uid string, id uint) bool {
commitIter, err := c.project.repository.Log(&git.LogOptions{})
if err != nil {
return false
2024-06-23 16:25:55 +02:00
}
err = commitIter.ForEach(func(commit *object.Commit) error {
if strings.Contains(commit.Message, fmt.Sprintf("Update %s", uid)) &&
strings.Contains(commit.Message, fmt.Sprintf("version %d", id)) {
return errors.New("version already committed")
}
return nil
})
return err != nil
2024-06-23 16:25:55 +02:00
}
func (c *Commit) addContent() error {
file, err := c.project.worktree.Filesystem.Create(c.Filename)
2024-06-23 16:25:55 +02:00
if err != nil {
return err
}
defer file.Close()
2024-06-23 16:25:55 +02:00
_, err = file.Write(c.Content)
return err
2024-06-23 16:25:55 +02:00
}