Class: Danger::DangerConflictChecker

Inherits:
Plugin
  • Object
show all
Defined in:
lib/conflict_checker/plugin.rb

Overview

Check and warn the conflict between PRs.

Examples:

Get information about the conflict between PRs.

conflict_checker.check_conflict

Warn in PR comment about the conflict between PRs.

conflict_checker.check_conflict_and_comment

See Also:

  • justice3120/danger-conflict_checker

Instance Method Summary collapse

Constructor Details

#initialize(dangerfile) ⇒ DangerConflictChecker

Returns a new instance of DangerConflictChecker.



19
20
21
# File 'lib/conflict_checker/plugin.rb', line 19

def initialize(dangerfile)
  super(dangerfile)
end

Instance Method Details

#check_conflictArray<Hash>

Get information about the conflict between PRs

Returns:

  • (Array<Hash>)


26
27
28
29
30
31
32
33
34
35
36
37
38
39
40
41
42
43
44
45
46
47
48
49
50
51
52
53
54
55
56
57
58
59
60
61
62
63
64
65
66
67
68
69
70
71
72
73
74
75
76
77
78
79
80
81
82
# File 'lib/conflict_checker/plugin.rb', line 26

def check_conflict()
  check_results = []

  repo_name = github.pr_json[:base][:repo][:full_name]

  pull_requests = github.api.pull_requests(repo_name).select do |pr|
    pr[:id] != github.pr_json[:id] && pr[:base][:label] == github.pr_json[:base][:label]
  end

  return if pull_requests.empty?

  g = Git.open(Dir.pwd)

  pull_requests.each do |pr|
    result = {
      pull_request: pr,
      mergeable: true,
      conflicts: []
    }

    uuid = SecureRandom.uuid

    r = g.add_remote(uuid, pr[:head][:repo][:ssh_url])
    r.fetch()

    branch1 = github.pr_json[:head][:ref]
    branch2 = "#{uuid}/#{pr[:head][:ref]}"

    base = `git merge-base #{branch1} #{branch2}`.chomp

    Tempfile.open('tmp') do |f|
      patch = `git format-patch #{base}..#{branch2} --stdout`.chomp
      f.sync = true
      f.puts patch
      out, s = Open3.capture2e("git apply --check #{f.path}")

      out.each_line do |line|

        if 'patch failed' == line.split(':')[1].strip
          conflict = {
            file: line.split(':')[2].strip,
            line: line.split(':')[3].strip.to_i
          }
          result[:conflicts] << conflict
        end
      end

      result[:mergeable] = result[:conflicts].empty?
    end

    g.remove_remote(uuid)

    check_results << result
  end

  check_results
end

#check_conflict_and_commentArray<Hash>

Warn in PR comment about the conflict between PRs

Returns:

  • (Array<Hash>)


88
89
90
91
92
93
94
95
96
97
98
99
100
101
102
103
104
# File 'lib/conflict_checker/plugin.rb', line 88

def check_conflict_and_comment()
  results = check_conflict()

  results.each do |result|
    message = "<p>This PR conflicts with <a href=\"#{result[:pull_request][:html_url]}\">##{result[:pull_request][:number]}</a>.</p>"
    table = '<table><thead><tr><th width="100%">File</th><th>Line</th></tr></thead><tbody>' + result[:conflicts].map do |conflict|
      file = conflict[:file]
      line = conflict[:line]
      line_link = "#{result[:pull_request][:head][:repo][:html_url]}/blob/#{result[:pull_request][:head][:ref]}/#{file}#L#{line}"
      "<tr><td>#{file}</td><td><a href=\"#{line_link}\">#L#{line}</a></td></tr>"
    end.join('') + '</tbody></table>'
    puts (message + table)
    warn("<div>" + message + table + "</div>")
  end

  results
end