diff --git a/repository/mocks.go b/repository/mocks.go index 3bd1b66..17afd92 100644 --- a/repository/mocks.go +++ b/repository/mocks.go @@ -103,6 +103,37 @@ func CreateTestRepository(tmp_path string, repo string, file string, content str return cleanup, err } +func CreateCommitOnTestRepository(tmpPath string, repo string, file string, content string) ([]byte, error) { + testPath := path.Join(tmpPath, repo+".git") + gitPath, err := exec.LookPath("git") + if err != nil { + return nil, err + } + err = ioutil.WriteFile(path.Join(testPath, file), []byte(content), 0644) + if err != nil { + return nil, err + } + cmd := exec.Command(gitPath, "add", ".") + cmd.Dir = testPath + err = cmd.Run() + if err != nil { + return nil, err + } + cmd = exec.Command(gitPath, "commit", "-m", content, "--allow-empty-message") + cmd.Dir = testPath + err = cmd.Run() + if err != nil { + return nil, err + } + cmd = exec.Command(gitPath, "log", "--pretty=format:%H", "-1") + cmd.Dir = testPath + out, err := cmd.Output() + if err !=nil { + return nil, err + } + return out, nil +} + func CreateBranchesOnTestRepository(tmp_path string, repo string, file string, content string, branches ...string) error { testPath := path.Join(tmp_path, repo+".git") gitPath, err := exec.LookPath("git") @@ -182,3 +213,13 @@ func (r *MockContentRetriever) GetBranch(repo string) ([]map[string]string, erro } return r.Refs, nil } + +func (r *MockContentRetriever) GetDiff(repo, previousCommit, lastCommit string) ([]byte, error) { + if r.LookPathError != nil { + return nil, r.LookPathError + } + if r.OutputError != nil { + return nil, r.OutputError + } + return r.ResultContents, nil +} diff --git a/repository/repository.go b/repository/repository.go index 6cf6b6a..eaaa657 100644 --- a/repository/repository.go +++ b/repository/repository.go @@ -251,6 +251,7 @@ type ContentRetriever interface { GetTree(repo, ref, path string) ([]map[string]string, error) GetForEachRef(repo, pattern string) ([]map[string]string, error) GetBranch(repo string) ([]map[string]string, error) + GetDiff(repo, lastCommit, previousCommit string) ([]byte, error) } var Retriever ContentRetriever @@ -411,6 +412,25 @@ func (*GitContentRetriever) GetBranch(repo string) ([]map[string]string, error) return branches, err } +func (*GitContentRetriever) GetDiff(repo, previousCommit, lastCommit string) ([]byte, error) { + gitPath, err := exec.LookPath("git") + if err != nil { + return nil, fmt.Errorf("Error when trying to obtain diff with commits %s and %s of repository %s (%s).", lastCommit, previousCommit, repo, err) + } + cwd := barePath(repo) + repoExists, err := exists(cwd) + if err != nil || !repoExists { + return nil, fmt.Errorf("Error when trying to obtain diff with commits %s and %s of repository %s (Repository does not exist).", lastCommit, previousCommit, repo) + } + cmd := exec.Command(gitPath, "diff", previousCommit, lastCommit) + cmd.Dir = cwd + out, err := cmd.CombinedOutput() + if err != nil { + return nil, fmt.Errorf("Error when trying to obtain diff with commits %s and %s of repository %s (%s).", lastCommit, previousCommit, repo, err) + } + return out, nil +} + func retriever() ContentRetriever { if Retriever == nil { Retriever = &GitContentRetriever{} @@ -441,3 +461,7 @@ func GetForEachRef(repo, pattern string) ([]map[string]string, error) { func GetBranch(repo string) ([]map[string]string, error) { return retriever().GetBranch(repo) } + +func GetDiff(repo, previousCommit, lastCommit string) ([]byte, error) { + return retriever().GetDiff(repo, previousCommit, lastCommit) +} diff --git a/repository/repository_test.go b/repository/repository_test.go index 90a0029..1364289 100644 --- a/repository/repository_test.go +++ b/repository/repository_test.go @@ -876,3 +876,67 @@ func (s *S) TestGetBranchIntegrationEmptySubject(c *gocheck.C) { c.Assert(branches[1]["authorEmail"], gocheck.Equals, "") c.Assert(branches[1]["subject"], gocheck.Equals, "") } + +func (s *S) TestGetDiffIntegration(c *gocheck.C) { + oldBare := bare + bare = "/tmp" + repo := "gandalf-test-repo" + file := "README" + content := "Just a regular readme." + object1 := "You should read this README" + object2 := "Seriously, read this file!" + cleanUp, errCreate := CreateTestRepository(bare, repo, file, content) + defer func() { + cleanUp() + bare = oldBare + }() + c.Assert(errCreate, gocheck.IsNil) + firstCommit, err := CreateCommitOnTestRepository(bare, repo, file, object1) + c.Assert(err, gocheck.IsNil) + secondCommit, err := CreateCommitOnTestRepository(bare, repo, file, object2) + c.Assert(err, gocheck.IsNil) + diff, err := GetDiff(repo, string(firstCommit), string(secondCommit)) + c.Assert(err, gocheck.IsNil) + c.Assert(string(diff), gocheck.Matches, `(?s).*-You should read this README.*\+Seriously, read this file!.*`) +} + +func (s *S) TestGetDiffIntegrationWhenInvalidRepo(c *gocheck.C) { + oldBare := bare + bare = "/tmp" + repo := "gandalf-test-repo" + file := "README" + content := "Just a regular readme." + object1 := "You should read this README" + object2 := "Seriously, read this file!" + cleanUp, errCreate := CreateTestRepository(bare, repo, file, content) + defer func() { + cleanUp() + bare = oldBare + }() + c.Assert(errCreate, gocheck.IsNil) + firstCommit, err := CreateCommitOnTestRepository(bare, repo, file, object1) + c.Assert(err, gocheck.IsNil) + secondCommit, err := CreateCommitOnTestRepository(bare, repo, file, object2) + c.Assert(err, gocheck.IsNil) + _, err = GetDiff("invalid-repo", string(firstCommit), string(secondCommit)) + c.Assert(err.Error(), gocheck.Equals, fmt.Sprintf("Error when trying to obtain diff with commits %s and %s of repository invalid-repo (Repository does not exist).", secondCommit, firstCommit)) +} + +func (s *S) TestGetDiffIntegrationWhenInvalidCommit(c *gocheck.C) { + oldBare := bare + bare = "/tmp" + repo := "gandalf-test-repo" + file := "README" + content := "Just a regular readme." + object1 := "You should read this README" + cleanUp, errCreate := CreateTestRepository(bare, repo, file, content) + defer func() { + cleanUp() + bare = oldBare + }() + c.Assert(errCreate, gocheck.IsNil) + firstCommit, err := CreateCommitOnTestRepository(bare, repo, file, object1) + c.Assert(err, gocheck.IsNil) + _, err = GetDiff(repo, "12beu23eu23923ey32eiyeg2ye", string(firstCommit)) + c.Assert(err.Error(), gocheck.Equals, fmt.Sprintf("Error when trying to obtain diff with commits %s and 12beu23eu23923ey32eiyeg2ye of repository %s (exit status 128).", firstCommit, repo)) +}