Skip to content
This repository has been archived by the owner on Dec 10, 2024. It is now read-only.

refactor: add api call for merge request diff #1796

Merged
merged 1 commit into from
Sep 25, 2023
Merged
Show file tree
Hide file tree
Changes from all commits
Commits
File filter

Filter by extension

Filter by extension

Conversations
Failed to load comments.
Loading
Jump to
Jump to file
Failed to load files.
Loading
Diff view
Diff view
148 changes: 95 additions & 53 deletions merge_requests.go
Original file line number Diff line number Diff line change
Expand Up @@ -36,59 +36,50 @@ type MergeRequestsService struct {
//
// GitLab API docs: https://docs.gitlab.com/ee/api/merge_requests.html
type MergeRequest struct {
ID int `json:"id"`
IID int `json:"iid"`
TargetBranch string `json:"target_branch"`
SourceBranch string `json:"source_branch"`
ProjectID int `json:"project_id"`
Title string `json:"title"`
State string `json:"state"`
CreatedAt *time.Time `json:"created_at"`
UpdatedAt *time.Time `json:"updated_at"`
Upvotes int `json:"upvotes"`
Downvotes int `json:"downvotes"`
Author *BasicUser `json:"author"`
Assignee *BasicUser `json:"assignee"`
Assignees []*BasicUser `json:"assignees"`
Reviewers []*BasicUser `json:"reviewers"`
SourceProjectID int `json:"source_project_id"`
TargetProjectID int `json:"target_project_id"`
Labels Labels `json:"labels"`
LabelDetails []*LabelDetails `json:"label_details"`
Description string `json:"description"`
Draft bool `json:"draft"`
WorkInProgress bool `json:"work_in_progress"`
Milestone *Milestone `json:"milestone"`
MergeWhenPipelineSucceeds bool `json:"merge_when_pipeline_succeeds"`
DetailedMergeStatus string `json:"detailed_merge_status"`
MergeError string `json:"merge_error"`
MergedBy *BasicUser `json:"merged_by"`
MergedAt *time.Time `json:"merged_at"`
ClosedBy *BasicUser `json:"closed_by"`
ClosedAt *time.Time `json:"closed_at"`
Subscribed bool `json:"subscribed"`
SHA string `json:"sha"`
MergeCommitSHA string `json:"merge_commit_sha"`
SquashCommitSHA string `json:"squash_commit_sha"`
UserNotesCount int `json:"user_notes_count"`
ChangesCount string `json:"changes_count"`
ShouldRemoveSourceBranch bool `json:"should_remove_source_branch"`
ForceRemoveSourceBranch bool `json:"force_remove_source_branch"`
AllowCollaboration bool `json:"allow_collaboration"`
WebURL string `json:"web_url"`
References *IssueReferences `json:"references"`
DiscussionLocked bool `json:"discussion_locked"`
Changes []struct {
OldPath string `json:"old_path"`
NewPath string `json:"new_path"`
AMode string `json:"a_mode"`
BMode string `json:"b_mode"`
Diff string `json:"diff"`
NewFile bool `json:"new_file"`
RenamedFile bool `json:"renamed_file"`
DeletedFile bool `json:"deleted_file"`
} `json:"changes"`
User struct {
ID int `json:"id"`
IID int `json:"iid"`
TargetBranch string `json:"target_branch"`
SourceBranch string `json:"source_branch"`
ProjectID int `json:"project_id"`
Title string `json:"title"`
State string `json:"state"`
CreatedAt *time.Time `json:"created_at"`
UpdatedAt *time.Time `json:"updated_at"`
Upvotes int `json:"upvotes"`
Downvotes int `json:"downvotes"`
Author *BasicUser `json:"author"`
Assignee *BasicUser `json:"assignee"`
Assignees []*BasicUser `json:"assignees"`
Reviewers []*BasicUser `json:"reviewers"`
SourceProjectID int `json:"source_project_id"`
TargetProjectID int `json:"target_project_id"`
Labels Labels `json:"labels"`
LabelDetails []*LabelDetails `json:"label_details"`
Description string `json:"description"`
Draft bool `json:"draft"`
WorkInProgress bool `json:"work_in_progress"`
Milestone *Milestone `json:"milestone"`
MergeWhenPipelineSucceeds bool `json:"merge_when_pipeline_succeeds"`
DetailedMergeStatus string `json:"detailed_merge_status"`
MergeError string `json:"merge_error"`
MergedBy *BasicUser `json:"merged_by"`
MergedAt *time.Time `json:"merged_at"`
ClosedBy *BasicUser `json:"closed_by"`
ClosedAt *time.Time `json:"closed_at"`
Subscribed bool `json:"subscribed"`
SHA string `json:"sha"`
MergeCommitSHA string `json:"merge_commit_sha"`
SquashCommitSHA string `json:"squash_commit_sha"`
UserNotesCount int `json:"user_notes_count"`
ChangesCount string `json:"changes_count"`
ShouldRemoveSourceBranch bool `json:"should_remove_source_branch"`
ForceRemoveSourceBranch bool `json:"force_remove_source_branch"`
AllowCollaboration bool `json:"allow_collaboration"`
WebURL string `json:"web_url"`
References *IssueReferences `json:"references"`
DiscussionLocked bool `json:"discussion_locked"`
Changes []*MergeRequestDiff `json:"changes"`
User struct {
CanMerge bool `json:"can_merge"`
} `json:"user"`
TimeStats *TimeStats `json:"time_stats"`
Expand Down Expand Up @@ -152,6 +143,21 @@ func (m *MergeRequest) UnmarshalJSON(data []byte) error {
return json.Unmarshal(data, (*alias)(m))
}

// MergeRequestDiff represents Gitlab merge request diff.
//
// Gitlab API docs:
// https://docs.gitlab.com/ee/api/merge_requests.html#list-merge-request-diffs
type MergeRequestDiff struct {
OldPath string `json:"old_path"`
NewPath string `json:"new_path"`
AMode string `json:"a_mode"`
BMode string `json:"b_mode"`
Diff string `json:"diff"`
NewFile bool `json:"new_file"`
RenamedFile bool `json:"renamed_file"`
DeletedFile bool `json:"deleted_file"`
}

// MergeRequestDiffVersion represents Gitlab merge request version.
//
// Gitlab API docs:
Expand Down Expand Up @@ -461,6 +467,9 @@ type GetMergeRequestChangesOptions struct {
// GetMergeRequestChanges shows information about the merge request including
// its files and changes.
//
// Deprecated: This endpoint has been replaced by
// MergeRequestsService.ListMergeRequesDiffs()
//
// GitLab API docs:
// https://docs.gitlab.com/ee/api/merge_requests.html#get-single-merge-request-changes
func (s *MergeRequestsService) GetMergeRequestChanges(pid interface{}, mergeRequest int, opt *GetMergeRequestChangesOptions, options ...RequestOptionFunc) (*MergeRequest, *Response, error) {
Expand All @@ -484,6 +493,39 @@ func (s *MergeRequestsService) GetMergeRequestChanges(pid interface{}, mergeRequ
return m, resp, nil
}

// ListMergeRequesDiffsOptions represents the available ListMergeRequesDiffs()
// options.
//
// GitLab API docs:
// https://docs.gitlab.com/ee/api/merge_requests.html#list-merge-request-diffs
type ListMergeRequesDiffsOptions ListOptions

// ListMergeRequesDiffs List diffs of the files changed in a merge request
//
// GitLab API docs:
// https://docs.gitlab.com/ee/api/merge_requests.html#list-merge-request-diffs
func (s *MergeRequestsService) ListMergeRequesDiffs(pid interface{}, mergeRequest int, opt *ListMergeRequesDiffsOptions, options ...RequestOptionFunc) ([]*MergeRequestDiff, *Response, error) {
project, err := parseID(pid)
if err != nil {
return nil, nil, err
}

u := fmt.Sprintf("/projects/%s/merge_requests/%d/diffs", PathEscape(project), mergeRequest)

req, err := s.client.NewRequest(http.MethodGet, u, opt, options)
if err != nil {
return nil, nil, err
}

var m []*MergeRequestDiff
resp, err := s.client.Do(req, &m)
if err != nil {
return nil, resp, err
}

return m, resp, nil
}

// GetMergeRequestParticipants gets a list of merge request participants.
//
// GitLab API docs:
Expand Down
46 changes: 46 additions & 0 deletions merge_requests_test.go
Original file line number Diff line number Diff line change
Expand Up @@ -260,6 +260,52 @@ func TestGetIssuesClosedOnMerge_Jira(t *testing.T) {
assert.Equal(t, "Title of this issue", issues[0].Title)
}

func TestListMergeRequesDiffs(t *testing.T) {
mux, client := setup(t)

mux.HandleFunc("/api/v4/projects/1/merge_requests/1/diffs", func(w http.ResponseWriter, r *http.Request) {
testMethod(t, r, http.MethodGet)
mustWriteHTTPResponse(t, w, "testdata/list_merge_request_diff.json")
})

opts := &ListMergeRequesDiffsOptions{
Page: 1,
PerPage: 2,
}

diffs, _, err := client.MergeRequests.ListMergeRequesDiffs(1, 1, opts)
if err != nil {
t.Errorf("MergeRequests.ListMergeRequesDiffs returned error: %v", err)
}

want := []*MergeRequestDiff{
{
OldPath: "README",
NewPath: "README",
AMode: "100644",
BMode: "100644",
Diff: "@@ -1 +1 @@ -Title +README",
NewFile: false,
RenamedFile: false,
DeletedFile: false,
},
{
OldPath: "VERSION",
NewPath: "VERSION",
AMode: "100644",
BMode: "100644",
Diff: "@@ -1.9.7 +1.9.8",
NewFile: false,
RenamedFile: false,
DeletedFile: false,
},
}

if !reflect.DeepEqual(want, diffs) {
t.Errorf("MergeRequests.ListMergeRequesDiffs returned %+v, want %+v", diffs, want)
}
}

func TestIntSliceOrString(t *testing.T) {
t.Run("any", func(t *testing.T) {
opts := &ListMergeRequestsOptions{}
Expand Down
22 changes: 22 additions & 0 deletions testdata/list_merge_request_diff.json
Original file line number Diff line number Diff line change
@@ -0,0 +1,22 @@
[
{
"old_path": "README",
"new_path": "README",
"a_mode": "100644",
"b_mode": "100644",
"diff": "@@ -1 +1 @@ -Title +README",
"new_file": false,
"renamed_file": false,
"deleted_file": false
},
{
"old_path": "VERSION",
"new_path": "VERSION",
"a_mode": "100644",
"b_mode": "100644",
"diff": "@@ -1.9.7 +1.9.8",
"new_file": false,
"renamed_file": false,
"deleted_file": false
}
]