github.com/mistwind/reviewdog@v0.0.0-20230322024206-9cfa11856d58/service/gitlab/gitlab_push_commits_diff.go (about) 1 package gitlab 2 3 import ( 4 "context" 5 "fmt" 6 "log" 7 "os/exec" 8 9 "github.com/xanzy/go-gitlab" 10 11 "github.com/mistwind/reviewdog" 12 "github.com/mistwind/reviewdog/service/serviceutil" 13 ) 14 15 var _ reviewdog.DiffService = &PushCommitsDiff{} 16 17 // PushCommitsDiff is a diff service for GitLab Push Commits. 18 type PushCommitsDiff struct { 19 cli *gitlab.Client 20 sha string 21 beforeSHA string 22 projects string 23 24 // wd is working directory relative to root of repository. 25 wd string 26 } 27 28 // NewGitLabPushCommitsDiff returns a new PushCommitsDiff service. 29 // itLabPushCommitsDiff service needs git command in $PATH. 30 func NewGitLabPushCommitsDiff(cli *gitlab.Client, owner, repo string, sha string, beforeSHA string) (*PushCommitsDiff, error) { 31 workDir, err := serviceutil.GitRelWorkdir() 32 if err != nil { 33 return nil, fmt.Errorf("PushCommitsDiff needs 'git' command: %w", err) 34 } 35 return &PushCommitsDiff{ 36 cli: cli, 37 sha: sha, 38 beforeSHA: beforeSHA, 39 projects: owner + "/" + repo, 40 wd: workDir, 41 }, nil 42 } 43 44 // NewGitLabPushCommitsDiffWithProjectID returns a new PushCommitsDiff service. 45 // itLabPushCommitsDiff service needs git command in $PATH. 46 func NewGitLabPushCommitsDiffWithProjectID(cli *gitlab.Client, projectID string, sha string, beforeSHA string) (*PushCommitsDiff, error) { 47 workDir, err := serviceutil.GitRelWorkdir() 48 if err != nil { 49 return nil, fmt.Errorf("PushCommitsDiff needs 'git' command: %w", err) 50 } 51 return &PushCommitsDiff{ 52 cli: cli, 53 sha: sha, 54 beforeSHA: beforeSHA, 55 projects: projectID, 56 wd: workDir, 57 }, nil 58 } 59 60 // Diff returns a diff of PushCommits. It runs `git diff` locally instead of 61 // diff_url of GitLab Merge Request because diff of diff_url is not suited for 62 // comment API in a sense that diff of diff_url is equivalent to 63 // `git diff --no-renames`, we want diff which is equivalent to 64 // `git diff --find-renames`. 65 // git diff old new 66 func (g *PushCommitsDiff) Diff(ctx context.Context) ([]byte, error) { 67 b, err := g.gitDiff(ctx, g.beforeSHA, g.sha) 68 log.Printf("reviewdog: [gitlab-push-commit-report] PushCommitsDiff: %s\n", string(b)) 69 return b, err 70 } 71 72 func (g *PushCommitsDiff) gitDiff(_ context.Context, baseSha, targetSha string) ([]byte, error) { 73 bytes, err := exec.Command("git", "diff", "--find-renames", baseSha, targetSha).Output() 74 if err != nil { 75 return nil, fmt.Errorf("failed to run git diff: %w", err) 76 } 77 return bytes, nil 78 } 79 80 // Strip returns 1 as a strip of git diff. 81 func (g *PushCommitsDiff) Strip() int { 82 return 1 83 }