package git import ( "fmt" "path/filepath" "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) 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 }