changelog generator & diff tool stormlightlabs.github.io/git-storm/
changelog changeset markdown golang git
at main 3.9 kB view raw
1package testutils 2 3import ( 4 "os" 5 "path/filepath" 6 "testing" 7 "time" 8 9 "github.com/go-git/go-git/v6" 10 "github.com/go-git/go-git/v6/plumbing" 11 "github.com/go-git/go-git/v6/plumbing/object" 12) 13 14// SetupTestRepo creates a git repository in a temporary directory with sample 15// commits. The repository contains multiple commits with different types of 16// changes to support testing diff algorithms, changelog generation, and git log 17// parsing. 18func SetupTestRepo(t *testing.T) *git.Repository { 19 t.Helper() 20 dir := t.TempDir() 21 22 repo, err := git.PlainInit(dir, false) 23 if err != nil { 24 t.Fatalf("failed to init repo: %v", err) 25 } 26 27 w, err := repo.Worktree() 28 if err != nil { 29 t.Fatalf("failed to get worktree: %v", err) 30 } 31 32 commits := []struct { 33 name, content, message string 34 }{ 35 {"README.md", "# Project\n\nInitial version", "chore: initial commit"}, 36 {"a.txt", "hello world", "feat: add hello world"}, 37 {"b.txt", "fixed bug", "fix: patch file"}, 38 {"a.txt", "hello world\ngoodbye world", "feat: add goodbye"}, 39 {"c.txt", "new feature\nwith multiple lines\nof content", "feat: add multi-line file"}, 40 {"b.txt", "fixed bug\nwith proper handling", "fix: improve error handling"}, 41 } 42 43 for _, c := range commits { 44 path := filepath.Join(dir, c.name) 45 if err := os.WriteFile(path, []byte(c.content), 0644); err != nil { 46 t.Fatalf("failed to write file %s: %v", c.name, err) 47 } 48 if _, err := w.Add(c.name); err != nil { 49 t.Fatalf("failed to add file %s: %v", c.name, err) 50 } 51 if _, err := w.Commit(c.message, &git.CommitOptions{ 52 Author: &object.Signature{ 53 Name: "Test Author", 54 Email: "test@example.com", 55 When: time.Now(), 56 }, 57 }); err != nil { 58 t.Fatalf("commit failed: %v", err) 59 } 60 } 61 return repo 62} 63 64// CreateTag creates a lightweight tag at the current HEAD of the repository. 65func CreateTag(t *testing.T, repo *git.Repository, tagName string) { 66 t.Helper() 67 head, err := repo.Head() 68 if err != nil { 69 t.Fatalf("failed to get HEAD: %v", err) 70 } 71 72 _, err = repo.CreateTag(tagName, head.Hash(), nil) 73 if err != nil { 74 t.Fatalf("failed to create tag %s: %v", tagName, err) 75 } 76} 77 78// CreateTagAtCommit creates a lightweight tag at a specific commit hash. 79func CreateTagAtCommit(t *testing.T, repo *git.Repository, tagName, commitHash string) error { 80 t.Helper() 81 hash, err := repo.ResolveRevision(plumbing.Revision(commitHash)) 82 if err != nil { 83 return err 84 } 85 86 _, err = repo.CreateTag(tagName, *hash, nil) 87 return err 88} 89 90// GetCommitHistory returns all commits in the repository from HEAD backwards. 91func GetCommitHistory(t *testing.T, repo *git.Repository) []*object.Commit { 92 t.Helper() 93 head, err := repo.Head() 94 if err != nil { 95 t.Fatalf("failed to get HEAD: %v", err) 96 } 97 98 commitIter, err := repo.Log(&git.LogOptions{From: head.Hash()}) 99 if err != nil { 100 t.Fatalf("failed to get commit log: %v", err) 101 } 102 103 var commits []*object.Commit 104 err = commitIter.ForEach(func(c *object.Commit) error { 105 commits = append(commits, c) 106 return nil 107 }) 108 if err != nil { 109 t.Fatalf("failed to iterate commits: %v", err) 110 } 111 112 return commits 113} 114 115// AddCommit adds a new commit to the repository with the given file changes. 116func AddCommit(t *testing.T, repo *git.Repository, filename, content, message string) { 117 t.Helper() 118 w, err := repo.Worktree() 119 if err != nil { 120 t.Fatalf("failed to get worktree: %v", err) 121 } 122 123 path := filepath.Join(w.Filesystem.Root(), filename) 124 if err := os.WriteFile(path, []byte(content), 0644); err != nil { 125 t.Fatalf("failed to write file %s: %v", filename, err) 126 } 127 128 if _, err := w.Add(filename); err != nil { 129 t.Fatalf("failed to add file %s: %v", filename, err) 130 } 131 132 if _, err := w.Commit(message, &git.CommitOptions{ 133 Author: &object.Signature{ 134 Name: "Test Author", 135 Email: "test@example.com", 136 When: time.Now(), 137 }, 138 }); err != nil { 139 t.Fatalf("commit failed: %v", err) 140 } 141}