13
14
15
16
17
18
19
20
21
22
23
24
25
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
|
# File 'lib/ace/review/molecules/diff_scope.rb', line 13
def self.select(diff, patterns = nil, groups: nil)
patterns = patterns.transform_keys(&:to_s) if patterns.is_a?(Hash)
groups = groups.map { |group| group.is_a?(Hash) ? group.transform_keys(&:to_s) : group } if groups.is_a?(Array)
valid_groups = groups.nil? || (groups.is_a?(Array) && groups.all? { |group| valid_patterns?(group) && !group.nil? })
unless valid_patterns?(patterns) && valid_groups
return {success: false, error: "Review file patterns/groups must contain include/exclude arrays of glob strings"}
end
blocks = Atoms::DiffBoundaryFinder.parse(diff)
unless blocks.any? && blocks.map { |block| block[:content] }.join == diff
return {success: false, error: "Cannot account for every PR diff block; review input is incomplete"}
end
filters = [patterns, *Array(groups)].compact
selected, excluded = blocks.partition { |block| selected_block?(block, filters) }
if selected.empty?
return {success: false, error: "Review scope contains no changed files"}
end
{
success: true,
diff: selected.map { |block| block[:content] }.join,
manifest: {
raw_sha256: Digest::SHA256.hexdigest(diff),
selected_sha256: Digest::SHA256.hexdigest(selected.map { |block| block[:content] }.join),
selected_files: selected.map { |block| block[:path] },
excluded_files: excluded.map { |block| block[:path] },
binary_files: binary_paths(blocks),
renames: selected.filter_map do |block|
{from: block[:old_path], to: block[:path]} if block[:old_path] != block[:path]
end,
received_diff_accounted_for: true,
file_pattern_groups: filters
}
}
rescue ArgumentError => e
{success: false, error: "Cannot account for every PR diff block: #{e.message}"}
end
|