1package git
2
3import (
4 "os"
5 "path/filepath"
6 "testing"
7 "time"
8
9 gogit "github.com/go-git/go-git/v5"
10 "github.com/go-git/go-git/v5/plumbing"
11 "github.com/go-git/go-git/v5/plumbing/object"
12 "github.com/stretchr/testify/require"
13)
14
15type RepoSuite struct {
16 t *testing.T
17 tempDir string
18 repo *GitRepo
19 baseTime time.Time
20}
21
22func NewRepoSuite(t *testing.T) *RepoSuite {
23 tempDir, err := os.MkdirTemp("", "git-test-*")
24 require.NoError(t, err)
25
26 return &RepoSuite{
27 t: t,
28 tempDir: tempDir,
29 baseTime: time.Date(2024, 1, 1, 0, 0, 0, 0, time.UTC),
30 }
31}
32
33func (h *RepoSuite) cleanup() {
34 if h.tempDir != "" {
35 os.RemoveAll(h.tempDir)
36 }
37}
38
39func (h *RepoSuite) init() *GitRepo {
40 repoPath := filepath.Join(h.tempDir, "test-repo")
41
42 // initialize repository
43 r, err := gogit.PlainInit(repoPath, false)
44 require.NoError(h.t, err)
45
46 // configure git user
47 cfg, err := r.Config()
48 require.NoError(h.t, err)
49 cfg.User.Name = "Test User"
50 cfg.User.Email = "test@example.com"
51 err = r.SetConfig(cfg)
52 require.NoError(h.t, err)
53
54 // create initial commit with a file
55 w, err := r.Worktree()
56 require.NoError(h.t, err)
57
58 // create initial file
59 initialFile := filepath.Join(repoPath, "README.md")
60 err = os.WriteFile(initialFile, []byte("# Test Repository\n\nInitial content.\n"), 0644)
61 require.NoError(h.t, err)
62
63 _, err = w.Add("README.md")
64 require.NoError(h.t, err)
65
66 _, err = w.Commit("Initial commit", &gogit.CommitOptions{
67 Author: &object.Signature{
68 Name: "Test User",
69 Email: "test@example.com",
70 When: h.baseTime,
71 },
72 })
73 require.NoError(h.t, err)
74
75 gitRepo, err := PlainOpen(repoPath)
76 require.NoError(h.t, err)
77
78 h.repo = gitRepo
79 return gitRepo
80}
81
82func (h *RepoSuite) commitFile(filename, content, message string) plumbing.Hash {
83 filePath := filepath.Join(h.repo.path, filename)
84 dir := filepath.Dir(filePath)
85
86 err := os.MkdirAll(dir, 0755)
87 require.NoError(h.t, err)
88
89 err = os.WriteFile(filePath, []byte(content), 0644)
90 require.NoError(h.t, err)
91
92 w, err := h.repo.r.Worktree()
93 require.NoError(h.t, err)
94
95 _, err = w.Add(filename)
96 require.NoError(h.t, err)
97
98 hash, err := w.Commit(message, &gogit.CommitOptions{
99 Author: &object.Signature{
100 Name: "Test User",
101 Email: "test@example.com",
102 },
103 })
104 require.NoError(h.t, err)
105
106 return hash
107}
108
109func (h *RepoSuite) createAnnotatedTag(name string, commit plumbing.Hash, taggerName, taggerEmail, message string, when time.Time) {
110 _, err := h.repo.r.CreateTag(name, commit, &gogit.CreateTagOptions{
111 Tagger: &object.Signature{
112 Name: taggerName,
113 Email: taggerEmail,
114 When: when,
115 },
116 Message: message,
117 })
118 require.NoError(h.t, err)
119}
120
121func (h *RepoSuite) createLightweightTag(name string, commit plumbing.Hash) {
122 ref := plumbing.NewReferenceFromStrings("refs/tags/"+name, commit.String())
123 err := h.repo.r.Storer.SetReference(ref)
124 require.NoError(h.t, err)
125}
126
127func (h *RepoSuite) createBranch(name string, commit plumbing.Hash) {
128 ref := plumbing.NewReferenceFromStrings("refs/heads/"+name, commit.String())
129 err := h.repo.r.Storer.SetReference(ref)
130 require.NoError(h.t, err)
131}
132
133func (h *RepoSuite) checkoutBranch(name string) {
134 w, err := h.repo.r.Worktree()
135 require.NoError(h.t, err)
136
137 err = w.Checkout(&gogit.CheckoutOptions{
138 Branch: plumbing.NewBranchReferenceName(name),
139 })
140 require.NoError(h.t, err)
141}