github.com/adevinta/maiao@v0.0.0-20240318133227-b6f9656b5e07/pkg/git/repo_test.go (about) 1 package git 2 3 import ( 4 "bytes" 5 "os" 6 "os/exec" 7 "path/filepath" 8 "strings" 9 "testing" 10 11 "github.com/adevinta/maiao/pkg/log" 12 "github.com/adevinta/maiao/pkg/system" 13 "github.com/sirupsen/logrus" 14 "github.com/spf13/afero" 15 "github.com/stretchr/testify/assert" 16 "github.com/stretchr/testify/require" 17 ) 18 19 func TestFindGitDir(t *testing.T) { 20 t.Cleanup(system.Reset) 21 system.DefaultFileSystem = afero.NewMemMapFs() 22 23 require.NoError(t, system.DefaultFileSystem.MkdirAll("/some/path/to/repository/.git", 0700)) 24 fd, err := system.DefaultFileSystem.Create("/some/path/to/something/else/.git") 25 require.NoError(t, err) 26 fd.Close() 27 28 dir, err := FindGitDir("/some/path/to/repository/.git") 29 assert.NoError(t, err) 30 assert.Equal(t, "/some/path/to/repository/.git", dir) 31 32 dir, err = FindGitDir("/some/path/to/repository/.git/something/else") 33 assert.NoError(t, err) 34 assert.Equal(t, "/some/path/to/repository/.git", dir) 35 36 dir, err = FindGitDir("/some/path/to/repository/something/else") 37 assert.NoError(t, err) 38 assert.Equal(t, "/some/path/to/repository/.git", dir) 39 40 dir, err = FindGitDir("/some/path/to/something/else/.git") 41 assert.Error(t, err) 42 assert.Equal(t, "", dir) 43 44 } 45 46 func TestFindGitDirWithWorkDir(t *testing.T) { 47 repo, err := os.MkdirTemp("", "maiao-worktree-test-git-dir-repo") 48 require.NoError(t, err) 49 worktree, err := os.MkdirTemp("", "maiao-worktree-test-git-dir-worktree") 50 require.NoError(t, err) 51 t.Cleanup(func() { 52 os.RemoveAll(repo) 53 os.RemoveAll(worktree) 54 }) 55 cmd(t, "git", "-C", repo, "init") 56 cmd(t, "git", "-C", repo, "commit", "--allow-empty", "-m", "initial commit") 57 // Use show toplevel as tempfiles on mac may be in /var/folders/... while mounted volumes are in /private/var/folders/... 58 // Internally, when creating worktrees, git uses the toplevel to point to the worktree dir 59 // Hint it to do the same 60 repoGitDir, err := FindGitDir(cmdOutput(t, "git", "-C", repo, "rev-parse", "--show-toplevel")) 61 assert.NoError(t, err) 62 cmd(t, "git", "-C", repo, "worktree", "add", worktree) 63 worktreeGitDir, err := FindGitDir(worktree) 64 assert.NoError(t, err) 65 66 if !strings.HasPrefix(worktreeGitDir, filepath.Join(repoGitDir, "worktrees")) { 67 assert.Failf(t, "Unexpected prefix", "worktree git dir '%s' should be included in the repo git dir '%s'", worktreeGitDir, filepath.Join(repoGitDir, ".git", "worktrees")) 68 } 69 } 70 71 func cmd(t testing.TB, cmd string, args ...string) { 72 c := exec.Command(cmd, args...) 73 c.Stdout = os.Stdout 74 c.Stderr = os.Stderr 75 if err := c.Run(); err != nil { 76 t.Errorf("failed to run command %s: %s", strings.Join(append([]string{cmd}, args...), " "), err.Error()) 77 t.FailNow() 78 } 79 } 80 81 func cmdOutput(t testing.TB, cmd string, args ...string) string { 82 c := exec.Command(cmd, args...) 83 b := bytes.NewBuffer(nil) 84 c.Stdout = b 85 c.Stderr = os.Stderr 86 if err := c.Run(); err != nil { 87 t.Errorf("failed to run command %s: %s", strings.Join(append([]string{cmd}, args...), " "), err.Error()) 88 t.FailNow() 89 } 90 return strings.Trim(b.String(), " \n") 91 } 92 93 func commitFile(t *testing.T, dir, path, content, message string) string { 94 fd, err := os.Create(filepath.Join(dir, path)) 95 assert.NoError(t, err) 96 fd.Write([]byte(content)) 97 cmd(t, "git", "-C", dir, "add", path) 98 cmd(t, "git", "-C", dir, "commit", "-m", message) 99 return cmdOutput(t, "git", "-C", dir, "rev-parse", "HEAD") 100 } 101 102 // func TestRepo(t *testing.T) { 103 // t.Run("in a standard directory", func(t *testing.T) { 104 // r, err := PlainOpen("../..") 105 // assert.NoError(t, err) 106 // assert.NotNil(t, r) 107 // assert.Equal(t, "../../.git", r.CommonGitDir()) 108 // t.Run("head is retrievable", func(t *testing.T) { 109 // head, err := r.Head() 110 // assert.NoError(t, err) 111 // assert.NotNil(t, head) 112 // assert.Equal(t, cmdOutput(t, "git", "rev-parse", "--symbolic-full-name", "HEAD"), head.Name().String()) 113 // }) 114 // }) 115 // t.Run("inside a worktree", func(t *testing.T) { 116 // branch := uuid.New().String() 117 // wt := "tests/worktree-tests/" + branch 118 // cmd(t, "git", "-C", "..", "worktree", "add", wt, "-B", branch) 119 // defer func() { 120 // cmd(t, "rm", "-rf", "../"+wt) 121 // cmd(t, "git", "-C", "../..", "worktree", "prune") 122 // cmd(t, "git", "branch", "-D", branch) 123 // }() 124 125 // r, err := PlainOpen("../" + wt + "/") 126 127 // assert.NoError(t, err) 128 // assert.NotNil(t, r) 129 // abs, _ := filepath.Abs("../../.git") 130 // assert.Equal(t, abs, r.CommonGitDir()) 131 // t.Run("head is retrievable", func(t *testing.T) { 132 // t.Skip("gopkg.in/src-d/go-git.v4 does not support working in git worktrees") 133 // head, err := r.Head() 134 // assert.NoError(t, err) 135 // assert.NotNil(t, head) 136 // assert.Equal(t, branch, head.Name()) 137 // }) 138 // }) 139 // } 140 141 // func TestMergeBase(t *testing.T) { 142 // dir, err := ioutil.TempDir("", t.Name()) 143 // assert.NoError(t, err) 144 // fmt.Println(dir) 145 // defer os.RemoveAll(dir) 146 // cmd(t, "git", "init", dir) 147 // cmd(t, "git", "-C", dir, "config", "commit.gpgsign", "false") 148 // commitFile(t, dir, "README.md", strings.Join(faker.Hacker().Phrases(), "\n\n"), faker.Hacker().SaySomethingSmart()) 149 // c1 := commitFile(t, dir, "file1", strings.Join(faker.Hacker().Phrases(), "\n\n"), faker.Hacker().SaySomethingSmart()) 150 // cmd(t, "git", "-C", dir, "checkout", "-b", "old-branch") 151 // commitFile(t, dir, "file1", strings.Join(faker.Hacker().Phrases(), "\n\n"), faker.Hacker().SaySomethingSmart()) 152 // cmd(t, "git", "-C", dir, "checkout", "-b", "new-branch", c1) 153 // commitFile(t, dir, "file1", strings.Join(faker.Hacker().Phrases(), "\n\n"), faker.Hacker().SaySomethingSmart()) 154 // repo, err := PlainOpen(dir) 155 // assert.NoError(t, err) 156 // assert.Equal(t, c1, repo.MergeBase("old-branch", "new-branch")) 157 // assert.Equal(t, "", repo.MergeBase("old-branch", "some-branch")) 158 // } 159 160 // get all logs when running tests 161 func init() { 162 log.Logger.SetLevel(logrus.DebugLevel) 163 }