github.com/haya14busa/reviewdog@v0.0.0-20180723114510-ffb00ef78fd3/gitlab_mr_diff.go (about) 1 package reviewdog 2 3 import ( 4 "context" 5 "fmt" 6 "os/exec" 7 "strings" 8 9 gitlab "github.com/xanzy/go-gitlab" 10 ) 11 12 var _ DiffService = &GitLabMergeRequestDiff{} 13 14 // GitLabMergeRequestDiff is a diff service for GitLab MergeRequest. 15 type GitLabMergeRequestDiff struct { 16 cli *gitlab.Client 17 pr int 18 sha string 19 projects string 20 21 // wd is working directory relative to root of repository. 22 wd string 23 } 24 25 // NewGitLabMergeRequestDiff returns a new GitLabMergeRequestDiff service. 26 // itLabMergeRequestDiff service needs git command in $PATH. 27 func NewGitLabMergeRequestDiff(cli *gitlab.Client, owner, repo string, pr int, sha string) (*GitLabMergeRequestDiff, error) { 28 workDir, err := gitRelWorkdir() 29 if err != nil { 30 return nil, fmt.Errorf("GitLabMergeRequestCommitCommenter needs 'git' command: %v", err) 31 } 32 return &GitLabMergeRequestDiff{ 33 cli: cli, 34 pr: pr, 35 sha: sha, 36 projects: owner + "/" + repo, 37 wd: workDir, 38 }, nil 39 } 40 41 // Diff returns a diff of MergeRequest. It runs `git diff` locally instead of 42 // diff_url of GitLab Merge Request because diff of diff_url is not suited for 43 // comment API in a sense that diff of diff_url is equivalent to 44 // `git diff --no-renames`, we want diff which is equivalent to 45 // `git diff --find-renames`. 46 func (g *GitLabMergeRequestDiff) Diff(ctx context.Context) ([]byte, error) { 47 mr, _, err := g.cli.MergeRequests.GetMergeRequest(g.projects, g.pr, nil) 48 if err != nil { 49 return nil, err 50 } 51 targetBranch, _, err := g.cli.Branches.GetBranch(mr.TargetProjectID, mr.TargetBranch, nil) 52 if err != nil { 53 return nil, err 54 } 55 return g.gitDiff(ctx, g.sha, targetBranch.Commit.ID) 56 } 57 58 func (g *GitLabMergeRequestDiff) gitDiff(_ context.Context, baseSha string, targetSha string) ([]byte, error) { 59 b, err := exec.Command("git", "merge-base", targetSha, baseSha).Output() 60 if err != nil { 61 return nil, fmt.Errorf("failed to get merge-base commit: %v", err) 62 } 63 mergeBase := strings.Trim(string(b), "\n") 64 relArg := fmt.Sprintf("--relative=%s", g.wd) 65 bytes, err := exec.Command("git", "diff", relArg, "--find-renames", mergeBase, baseSha).Output() 66 if err != nil { 67 return nil, fmt.Errorf("failed to run git diff: %v", err) 68 } 69 return bytes, nil 70 } 71 72 // Strip returns 1 as a strip of git diff. 73 func (g *GitLabMergeRequestDiff) Strip() int { 74 return 1 75 }