grafana-backuper/pkg/git/commit.go

123 lines
2.3 KiB
Go

package git
import (
"errors"
"fmt"
"path/filepath"
"strings"
"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 {
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
}
}
type Commit struct {
Author *object.Signature
Committer *object.Signature
Content []byte
Filename string
KeyFile string
project *Project
signKey *openpgp.Entity
}
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 {
return err
}
if _, err := c.project.worktree.Add(c.Filename); err != nil {
return err
}
commitOpts := git.CommitOptions{Author: c.Author}
if c.Committer != nil {
commitOpts.Committer = c.Committer
}
if c.signKey != nil {
commitOpts.SignKey = c.signKey
}
_, err := c.project.worktree.Commit(msg, &commitOpts)
if err != nil {
return err
}
return nil
}
func (c *Commit) Exists(uid string, id uint) bool {
commitIter, err := c.project.repository.Log(&git.LogOptions{})
if err != nil {
return false
}
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
}
func (c *Commit) addContent() error {
file, err := c.project.worktree.Filesystem.Create(c.Filename)
if err != nil {
return err
}
defer file.Close()
_, err = file.Write(c.Content)
return err
}