|
| 1 | +module Hooks |
| 2 | + # Transfers merge request changes to reviewboard |
| 3 | + class Reviewboard |
| 4 | + def initialize(reviewboard, gitlab, git, options = {}) |
| 5 | + @reviewboard = reviewboard |
| 6 | + @gitlab = gitlab |
| 7 | + @git = git |
| 8 | + @options = options |
| 9 | + end |
| 10 | + |
| 11 | + def process(merge_request) |
| 12 | + attr = merge_request.fetch('object_attributes') |
| 13 | + |
| 14 | + return unless label_matches?(attr) |
| 15 | + |
| 16 | + review_id = review_id_from_comments( |
| 17 | + attr.fetch('source_project_id'), |
| 18 | + attr.fetch('id') |
| 19 | + ) |
| 20 | + |
| 21 | + unless review_id.nil? |
| 22 | + review = @reviewboard.review_request(review_id) |
| 23 | + return if review.fetch('commit_id') == attr.fetch('last_commit').fetch('id') |
| 24 | + end |
| 25 | + |
| 26 | + @git.create_diff( |
| 27 | + attr.fetch('source').fetch('ssh_url'), |
| 28 | + attr.fetch('target_branch'), |
| 29 | + attr.fetch('source_branch') |
| 30 | + ) do |file| |
| 31 | + if review_id.nil? |
| 32 | + review_id = create_review_request(merge_request, file) |
| 33 | + @gitlab.create_merge_request_comment( |
| 34 | + attr.fetch('source_project_id'), |
| 35 | + attr.fetch('id'), |
| 36 | + "REVIEW_ID: #{review_id}" |
| 37 | + ) |
| 38 | + else |
| 39 | + update_review_request(review_id, merge_request, file) |
| 40 | + end |
| 41 | + end |
| 42 | + |
| 43 | + @gitlab.create_merge_request_comment( |
| 44 | + attr.fetch('source_project_id'), |
| 45 | + attr.fetch('id'), |
| 46 | + @reviewboard.last_diff_uri(review_id) |
| 47 | + ) |
| 48 | + end |
| 49 | + |
| 50 | + def label_matches?(attr) |
| 51 | + return true unless @options.key?(:label) |
| 52 | + |
| 53 | + @gitlab.merge_request( |
| 54 | + attr.fetch('source_project_id'), |
| 55 | + attr.fetch('id') |
| 56 | + ).labels.include?(@options[:label]) |
| 57 | + end |
| 58 | + |
| 59 | + def update_review_request(review_id, merge_request, file) |
| 60 | + attr = merge_request.fetch('object_attributes') |
| 61 | + |
| 62 | + @reviewboard.sync_review_request( |
| 63 | + review_id: review_id, |
| 64 | + draft_params: |
| 65 | + { |
| 66 | + public: true, |
| 67 | + commit_id: attr.fetch('last_commit').fetch('id') |
| 68 | + }, |
| 69 | + diff: file |
| 70 | + ) |
| 71 | + end |
| 72 | + |
| 73 | + def create_review_request(merge_request, file) |
| 74 | + attr = merge_request.fetch('object_attributes') |
| 75 | + repo = attr.fetch('source') |
| 76 | + |
| 77 | + @reviewboard.sync_review_request( |
| 78 | + create_params: |
| 79 | + { |
| 80 | + repository: repo.fetch('name'), |
| 81 | + submit_as: merge_request.fetch('user').fetch('username') |
| 82 | + }, |
| 83 | + draft_params: |
| 84 | + { |
| 85 | + branch: attr.fetch('source_branch'), |
| 86 | + summary: attr.fetch('title'), |
| 87 | + description: attr.fetch('url'), |
| 88 | + public: true, |
| 89 | + commit_id: attr.fetch('last_commit').fetch('id') |
| 90 | + }, |
| 91 | + diff: file |
| 92 | + ) |
| 93 | + end |
| 94 | + |
| 95 | + def review_id_from_comments(pid, mid) |
| 96 | + @gitlab.merge_request_comments(pid, mid).each do |comment| |
| 97 | + return $1.to_i if /REVIEW_ID: (\d+)/.match(comment.note) |
| 98 | + end |
| 99 | + nil |
| 100 | + end |
| 101 | + end |
| 102 | +end |
0 commit comments