Module: Utils

Instance Method Summary collapse

Instance Method Details

#diff_strings(a, b) ⇒ Object

Creates a git-format diff of the two strings by writing them to temp files



124
125
126
127
128
129
130
# File 'lib/wcc/utils.rb', line 124

def diff_strings(a, b)
  File.write('a.tmp', a)
  File.write('b.tmp', b)
  diff = `git diff --no-index a.tmp b.tmp`
  File.delete('a.tmp', 'b.tmp')
  diff
end

#each_addition_in_diff(passed_diff = nil, &block) ⇒ Object



69
70
71
# File 'lib/wcc/utils.rb', line 69

def each_addition_in_diff(passed_diff = nil, &block)
  each_line_in_diff(passed_diff, type: :addition, &block)
end

#each_file_in_diff(passed_diff = nil) ⇒ Object



60
61
62
63
64
65
66
67
# File 'lib/wcc/utils.rb', line 60

def each_file_in_diff(passed_diff = nil)
  diffs = passed_diff ? [passed_diff] : parsed_diffs
  diffs&.flat_map do |diff|
    diff.files.flat_map do |file|
      yield(file, diff)
    end
  end
end

#each_line_in_diff(passed_diff = nil, type: nil) ⇒ Object



73
74
75
76
77
78
79
80
81
82
# File 'lib/wcc/utils.rb', line 73

def each_line_in_diff(passed_diff = nil, type: nil)
  each_file_in_diff(passed_diff) do |file, diff|
    file.hunks.flat_map do |hunk|
      lines = hunk.lines
      lines = lines.select { |l| l.public_send("#{type}?") } if type
      lines = lines.map { |l| yield(l, hunk, file, diff) } if block_given?
      lines
    end
  end
end

#find_file_in_diff(filename) ⇒ Object



35
36
37
38
39
40
# File 'lib/wcc/utils.rb', line 35

def find_file_in_diff(filename)
  each_file_in_diff do |file, _diff|
    return file if file.b_path == filename
  end
  nil
end

#find_in_diff(regex) ⇒ Object

Finds lines in the overall diff matching the given regex, and executes a block for each matched line. The results of the yield block are returned as an array.



45
46
47
48
49
50
51
52
53
54
55
56
57
58
# File 'lib/wcc/utils.rb', line 45

def find_in_diff(regex)
  each_file_in_diff do |file, diff|
    file.hunks.flat_map do |hunk|
      lines = hunk.lines.select { |l| l.addition? && l.content =~ regex }
      if block_given?
        lines =
          lines.map do |l|
            yield(l.content.match(regex), l, hunk, file, diff)
          end
      end
      lines
    end
  end
end


132
133
134
# File 'lib/wcc/utils.rb', line 132

def format_links_as_markdown(line)
  line.gsub(/\[?(https?\:\/\/[^\s\]]+)\]?/i, '[\1](\1)')
end

#issue(message, severity: 'message', file: nil, line: nil) ⇒ Object

Adds a message to the Danger report with the given serverity - ‘message’, ‘warn’, or ‘fail



138
139
140
141
142
143
144
145
146
147
# File 'lib/wcc/utils.rb', line 138

def issue(message, severity: 'message', file: nil, line: nil)
  case severity
  when 'message'
    plugin.message(message, file: file, line: line)
  when 'warn'
    plugin.warn(message, file: file, line: line)
  else
    plugin.fail(message, file: file, line: line)
  end
end

#loggerObject



13
14
15
16
17
18
19
20
# File 'lib/wcc/utils.rb', line 13

def logger
  return @logger if @logger

  @logger = Logger.new(STDERR)
  @logger.level = ENV['DANGER_LOG_LEVEL'] ||
    (plugin.verbose ? Logger::INFO : Logger::ERROR)
  @logger
end

#parsed_diffsObject

All the diffs in the PR parsed into GitDiff objects



23
24
25
26
27
28
29
30
31
32
33
# File 'lib/wcc/utils.rb', line 23

def parsed_diffs
  @parsed_diffs ||=
    plugin.git.diff&.map do |d|
      begin
        GitDiff.from_string(d.patch)
      rescue StandardError
        logger.fatal "Error parsing patch:\n#{d.patch}"
        raise
      end
    end
end

#pluginObject



7
8
9
10
11
# File 'lib/wcc/utils.rb', line 7

def plugin
  # individual check classes usually set the '@plugin' variable,
  # otherwise this mixin was included on the plugin itself.
  @plugin || self
end

#run(command) ⇒ Object



84
85
86
87
88
89
# File 'lib/wcc/utils.rb', line 84

def run(command)
  logger.info "Executing command '#{command}'"
  result = `#{command}`
  logger.debug result
  result
end

#run_and_diff(command = nil) ⇒ Object

Runs a command twice - once on the merge base, and once on the current working directory. Then, returns the git diff of the printed results.



93
94
95
96
97
98
99
100
101
102
103
104
105
106
107
108
109
110
# File 'lib/wcc/utils.rb', line 93

def run_and_diff(command = nil)
  unless command || block_given?
    raise ArgumentError('Must give command or block')
  end

  logger.info "Executing diff: '#{command}'"
  with_revision(plugin.github.base_commit) do |dir|
    initial = nil
    Dir.chdir(dir) do
      initial = command ? `#{command}` : yield
    end
    final = command ? `#{command}` : yield

    diff = diff_strings(initial, final)
    logger.debug diff
    diff
  end
end

#with_revision(revision) ⇒ Object

Executes a block after checking out the specified revision into a temp directory.



114
115
116
117
118
119
120
121
# File 'lib/wcc/utils.rb', line 114

def with_revision(revision)
  Dir.mktmpdir do |dir|
    logger.debug "Checking out revision #{revision} into #{dir}"
    system "git --work-tree=#{dir} checkout #{revision.strip} -- ."

    yield(dir)
  end
end