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  }