merge_requests.rb 5.17 KB
Newer Older
1
module API
Valeriy Sizov's avatar
Valeriy Sizov committed
2
  # MergeRequest API
3 4
  class MergeRequests < Grape::API
    before { authenticate! }
5
    before { Thread.current[:current_user] = current_user }
6

Hiroyuki Sato's avatar
Hiroyuki Sato committed
7
    resource :projects do
8
      helpers do
9 10 11
        def handle_merge_request_errors!(errors)
          if errors[:project_access].any?
            error!(errors[:project_access], 422)
12 13
          elsif errors[:branch_conflict].any?
            error!(errors[:branch_conflict], 422)
14
          end
15
          not_found!
16
        end
Izaak Alpert's avatar
Izaak Alpert committed
17 18 19 20 21 22 23 24

        def not_fork?(target_project_id, user_project)
          target_project_id.nil? || target_project_id == user_project.id.to_s
        end

        def target_matches_fork(target_project_id,user_project)
          user_project.forked? && user_project.forked_from_project.id.to_s == target_project_id
        end
25 26
      end

Valeriy Sizov's avatar
Valeriy Sizov committed
27
      # List merge requests
28
      #
Valeriy Sizov's avatar
Valeriy Sizov committed
29
      # Parameters:
30
      #   id (required) - The ID of a project
Valeriy Sizov's avatar
Valeriy Sizov committed
31 32
      #
      # Example:
33
      #   GET /projects/:id/merge_requests
Valeriy Sizov's avatar
Valeriy Sizov committed
34
      #
35
      get ":id/merge_requests" do
36
        authorize! :read_merge_request, user_project
37

Valeriy Sizov's avatar
Valeriy Sizov committed
38
        present paginate(user_project.merge_requests), with: Entities::MergeRequest
39
      end
40

Valeriy Sizov's avatar
Valeriy Sizov committed
41
      # Show MR
42
      #
Valeriy Sizov's avatar
Valeriy Sizov committed
43
      # Parameters:
44
      #   id (required)               - The ID of a project
Valeriy Sizov's avatar
Valeriy Sizov committed
45
      #   merge_request_id (required) - The ID of MR
46
      #
Valeriy Sizov's avatar
Valeriy Sizov committed
47
      # Example:
48
      #   GET /projects/:id/merge_request/:merge_request_id
Valeriy Sizov's avatar
Valeriy Sizov committed
49
      #
50
      get ":id/merge_request/:merge_request_id" do
51
        merge_request = user_project.merge_requests.find(params[:merge_request_id])
52

53
        authorize! :read_merge_request, merge_request
54

55
        present merge_request, with: Entities::MergeRequest
56 57
      end

Valeriy Sizov's avatar
Valeriy Sizov committed
58 59 60 61
      # Create MR
      #
      # Parameters:
      #
62
      #   id (required)            - The ID of a project - this will be the source of the merge request
Valeriy Sizov's avatar
Valeriy Sizov committed
63 64
      #   source_branch (required) - The source branch
      #   target_branch (required) - The target branch
65
      #   target_project           - The target project of the merge request defaults to the :id of the project
Valeriy Sizov's avatar
Valeriy Sizov committed
66 67
      #   assignee_id              - Assignee user ID
      #   title (required)         - Title of MR
68
      #
Valeriy Sizov's avatar
Valeriy Sizov committed
69
      # Example:
70
      #   POST /projects/:id/merge_requests
Valeriy Sizov's avatar
Valeriy Sizov committed
71
      #
72
      post ":id/merge_requests" do
Valeriy Sizov's avatar
Valeriy Sizov committed
73
        authorize! :write_merge_request, user_project
74
        required_attributes! [:source_branch, :target_branch, :title]
75
        attrs = attributes_for_keys [:source_branch, :target_branch, :assignee_id, :title, :target_project_id]
76
        merge_request = user_project.merge_requests.new(attrs)
Valeriy Sizov's avatar
Valeriy Sizov committed
77
        merge_request.author = current_user
78
        merge_request.source_project = user_project
Izaak Alpert's avatar
Izaak Alpert committed
79
        target_project_id = attrs[:target_project_id]
Izaak Alpert's avatar
Izaak Alpert committed
80
        if not_fork?(target_project_id, user_project)
81
          merge_request.target_project = user_project
Izaak Alpert's avatar
Izaak Alpert committed
82 83 84 85 86 87
        else
          if target_matches_fork(target_project_id,user_project)
            merge_request.target_project = Project.find_by_id(attrs[:target_project_id])
          else
            render_api_error!('(Bad Request) Specified target project that is not the source project, or the source fork of the project.', 400)
          end
88
        end
Izaak Alpert's avatar
Izaak Alpert committed
89

Valeriy Sizov's avatar
Valeriy Sizov committed
90 91 92 93
        if merge_request.save
          merge_request.reload_code
          present merge_request, with: Entities::MergeRequest
        else
94
          handle_merge_request_errors! merge_request.errors
Valeriy Sizov's avatar
Valeriy Sizov committed
95
        end
96 97
      end

Valeriy Sizov's avatar
Valeriy Sizov committed
98 99 100
      # Update MR
      #
      # Parameters:
101
      #   id (required)               - The ID of a project
Valeriy Sizov's avatar
Valeriy Sizov committed
102 103 104 105 106
      #   merge_request_id (required) - ID of MR
      #   source_branch               - The source branch
      #   target_branch               - The target branch
      #   assignee_id                 - Assignee user ID
      #   title                       - Title of MR
107
      #   state_event                 - Status of MR. (close|reopen|merge)
Valeriy Sizov's avatar
Valeriy Sizov committed
108
      # Example:
109
      #   PUT /projects/:id/merge_request/:merge_request_id
Valeriy Sizov's avatar
Valeriy Sizov committed
110
      #
111
      put ":id/merge_request/:merge_request_id" do
112
        attrs = attributes_for_keys [:source_branch, :target_branch, :assignee_id, :title, :state_event]
113
        merge_request = user_project.merge_requests.find(params[:merge_request_id])
114

115
        authorize! :modify_merge_request, merge_request
116

117 118 119 120 121
        if merge_request.update_attributes attrs
          merge_request.reload_code
          merge_request.mark_as_unchecked
          present merge_request, with: Entities::MergeRequest
        else
122
          handle_merge_request_errors! merge_request.errors
123
        end
124 125
      end

Valeriy Sizov's avatar
Valeriy Sizov committed
126 127 128
      # Post comment to merge request
      #
      # Parameters:
129
      #   id (required) - The ID of a project
Valeriy Sizov's avatar
Valeriy Sizov committed
130 131
      #   merge_request_id (required) - ID of MR
      #   note (required) - Text of comment
132
      # Examples:
133
      #   POST /projects/:id/merge_request/:merge_request_id/comments
Valeriy Sizov's avatar
Valeriy Sizov committed
134
      #
135
      post ":id/merge_request/:merge_request_id/comments" do
136
        required_attributes! [:note]
137

138 139 140
        merge_request = user_project.merge_requests.find(params[:merge_request_id])
        note = merge_request.notes.new(note: params[:note], project_id: user_project.id)
        note.author = current_user
Valeriy Sizov's avatar
Valeriy Sizov committed
141

142
        if note.save
143
          present note, with: Entities::MRNote
144 145 146 147 148
        else
          not_found!
        end
      end

149 150 151
    end
  end
end