danger 6.3.2 → 7.0.0
This diff represents the content of publicly available package versions that have been released to one of the supported registries. The information contained in this diff is provided for informational purposes only and reflects changes between package versions as they appear in their respective public registries.
- checksums.yaml +4 -4
- data/lib/danger/commands/local.rb +3 -0
- data/lib/danger/commands/pr.rb +1 -0
- data/lib/danger/comment_generators/bitbucket_server_message_group.md.erb +12 -0
- data/lib/danger/danger_core/dangerfile.rb +5 -1
- data/lib/danger/danger_core/message_aggregator.rb +46 -9
- data/lib/danger/danger_core/message_group.rb +27 -1
- data/lib/danger/danger_core/messages/violation.rb +1 -1
- data/lib/danger/danger_core/plugins/dangerfile_git_plugin.rb +3 -3
- data/lib/danger/helpers/comments_helper.rb +28 -3
- data/lib/danger/helpers/emoji_mapper.rb +11 -2
- data/lib/danger/helpers/message_groups_array_helper.rb +31 -0
- data/lib/danger/request_sources/bitbucket_cloud.rb +46 -0
- data/lib/danger/request_sources/bitbucket_cloud_api.rb +19 -7
- data/lib/danger/version.rb +1 -1
- metadata +14 -6
checksums.yaml
CHANGED
@@ -1,7 +1,7 @@
|
|
1
1
|
---
|
2
2
|
SHA256:
|
3
|
-
metadata.gz:
|
4
|
-
data.tar.gz:
|
3
|
+
metadata.gz: bac82d5de5c00b56576cd95681444543eb4b540f6bb6767ac1d407fb13150fbc
|
4
|
+
data.tar.gz: 032b2993f97a2c8c56b4d8f69690c7bbd7bbf6738e3631af54a0ea657811939f
|
5
5
|
SHA512:
|
6
|
-
metadata.gz:
|
7
|
-
data.tar.gz:
|
6
|
+
metadata.gz: 74fa60f6fc40846e32837a0b8234b119f6132ff4a629abd705480a8c4ebee1bbb78ed19ad940fc63d8d08b427e238bea3edb2d67286d23ceef48ac8a7c9e0dd3
|
7
|
+
data.tar.gz: 7072368e374403c31ea5240b8004942c9e28f00806f4acb1d65fafe850d291b8a893f06a3b1a294a325e374fc594e732c43343cd50c36ea99ee5d52ffe281c0a
|
@@ -66,12 +66,15 @@ module Danger
|
|
66
66
|
|
67
67
|
private
|
68
68
|
|
69
|
+
# this method is a duplicate of Commands::PR#configure_octokit
|
70
|
+
# - worth a refactor sometime?
|
69
71
|
def configure_octokit(cache_dir)
|
70
72
|
# setup caching for Github calls to hitting the API rate limit too quickly
|
71
73
|
cache_file = File.join(cache_dir, "danger_local_cache")
|
72
74
|
cache = HTTPCache.new(cache_file, clear_cache: @clear_http_cache)
|
73
75
|
Octokit.middleware = Faraday::RackBuilder.new do |builder|
|
74
76
|
builder.use Faraday::HttpCache, store: cache, serializer: Marshal, shared_cache: false
|
77
|
+
builder.use Octokit::Middleware::FollowRedirects
|
75
78
|
builder.use Octokit::Response::RaiseError
|
76
79
|
builder.adapter Faraday.default_adapter
|
77
80
|
end
|
data/lib/danger/commands/pr.rb
CHANGED
@@ -83,6 +83,7 @@ module Danger
|
|
83
83
|
end
|
84
84
|
Octokit.middleware = Faraday::RackBuilder.new do |builder|
|
85
85
|
builder.use Faraday::HttpCache, store: cache, serializer: Marshal, shared_cache: false
|
86
|
+
builder.use Octokit::Middleware::FollowRedirects
|
86
87
|
builder.use Octokit::Response::RaiseError
|
87
88
|
builder.adapter Faraday.default_adapter
|
88
89
|
end
|
@@ -0,0 +1,12 @@
|
|
1
|
+
<%- @message_group.messages.each do |message| -%>
|
2
|
+
<%- next if message.type == :markdown -%>
|
3
|
+
<%= @emoji_mapper.from_type(message.type) -%> <%= message.message %>
|
4
|
+
|
5
|
+
<%- end -%>
|
6
|
+
<%- @resolved.each do |message| -%>
|
7
|
+
<%= @emoji_mapper.map("white_check_mark") %> <%= message %>
|
8
|
+
<%- end -%>
|
9
|
+
|
10
|
+
<%= @message_group.markdowns.map(&:message).join("\n\n") %>
|
11
|
+
|
12
|
+
Generated by :no_entry_sign: [Danger](https://danger.systems/ "generated_by_<%= @danger_id %>")
|
@@ -2,6 +2,7 @@
|
|
2
2
|
|
3
3
|
require "danger/danger_core/dangerfile_dsl"
|
4
4
|
require "danger/danger_core/standard_error"
|
5
|
+
require "danger/danger_core/message_aggregator"
|
5
6
|
|
6
7
|
require "danger/danger_core/plugins/dangerfile_messaging_plugin"
|
7
8
|
require "danger/danger_core/plugins/dangerfile_danger_plugin"
|
@@ -251,7 +252,10 @@ module Danger
|
|
251
252
|
}
|
252
253
|
|
253
254
|
if env.request_source.respond_to?(:update_pr_by_line!) && ENV["DANGER_MESSAGE_AGGREGATION"]
|
254
|
-
env.request_source.update_pr_by_line!(
|
255
|
+
env.request_source.update_pr_by_line!(message_groups: MessageAggregator.aggregate(**report),
|
256
|
+
new_comment: new_comment,
|
257
|
+
remove_previous_comments: remove_previous_comments,
|
258
|
+
danger_id: report[:danger_id])
|
255
259
|
else
|
256
260
|
env.request_source.update_pull_request!(
|
257
261
|
**report,
|
@@ -1,12 +1,49 @@
|
|
1
|
-
|
2
|
-
|
3
|
-
|
4
|
-
|
1
|
+
# frozen_string_literal: true
|
2
|
+
require "danger/danger_core/message_group"
|
3
|
+
require "danger/helpers/message_groups_array_helper"
|
4
|
+
|
5
|
+
module Danger
|
6
|
+
class MessageAggregator
|
7
|
+
def self.aggregate(*args)
|
8
|
+
new(*args).aggregate
|
9
|
+
end
|
10
|
+
|
11
|
+
def initialize(warnings: [],
|
12
|
+
errors: [],
|
13
|
+
messages: [],
|
14
|
+
markdowns: [],
|
15
|
+
danger_id: "danger")
|
16
|
+
@messages = warnings + errors + messages + markdowns
|
17
|
+
@danger_id = danger_id
|
18
|
+
end
|
19
|
+
|
20
|
+
# aggregates the messages into an array of MessageGroups
|
21
|
+
# @return [[MessageGroup]]
|
22
|
+
def aggregate
|
23
|
+
# oookay I took some shortcuts with this one.
|
24
|
+
# first, sort messages by file and line
|
25
|
+
@messages.sort! { |a, b| a.compare_by_file_and_line(b) }
|
26
|
+
|
27
|
+
# now create an initial empty message group
|
28
|
+
first_group = MessageGroup.new(file: nil,
|
29
|
+
line: nil)
|
30
|
+
@message_groups = @messages.reduce([first_group]) do |groups, msg|
|
31
|
+
# We get to take a shortcut because we sorted the messages earlier - only
|
32
|
+
# have to see if we can append msg to the last group in the list
|
33
|
+
if groups.last << msg
|
34
|
+
# we appended it, so return groups unchanged
|
35
|
+
groups
|
36
|
+
else
|
37
|
+
# have to create a new group since msg wasn't appended to the other
|
38
|
+
# group
|
39
|
+
new_group = MessageGroup.new(file: msg.file,
|
40
|
+
line: msg.line)
|
41
|
+
new_group << msg
|
42
|
+
groups << new_group
|
43
|
+
end
|
44
|
+
end
|
5
45
|
|
6
|
-
|
7
|
-
|
8
|
-
messages: [],
|
9
|
-
markdowns: [],
|
10
|
-
danger_id: "danger")
|
46
|
+
@message_groups.extend(Helpers::MessageGroupsArrayHelper)
|
47
|
+
end
|
11
48
|
end
|
12
49
|
end
|
@@ -28,7 +28,18 @@ module Danger
|
|
28
28
|
# @param message [Markdown, Violation] the message to add
|
29
29
|
def <<(message)
|
30
30
|
# TODO: insertion sort
|
31
|
-
|
31
|
+
return nil unless same_line?(message)
|
32
|
+
|
33
|
+
inserted = false
|
34
|
+
messages.each.with_index do |other, idx|
|
35
|
+
if (message <=> other) == -1
|
36
|
+
inserted = true
|
37
|
+
messages.insert(idx, message)
|
38
|
+
break
|
39
|
+
end
|
40
|
+
end
|
41
|
+
messages << message unless inserted
|
42
|
+
messages
|
32
43
|
end
|
33
44
|
|
34
45
|
# The list of messages in this group. This list will be sorted in decreasing
|
@@ -38,5 +49,20 @@ module Danger
|
|
38
49
|
end
|
39
50
|
|
40
51
|
attr_reader :file, :line
|
52
|
+
|
53
|
+
# @return a hash of statistics. Currently only :warnings_count and
|
54
|
+
# :errors_count
|
55
|
+
def stats
|
56
|
+
stats = { warnings_count: 0, errors_count: 0 }
|
57
|
+
messages.each do |msg|
|
58
|
+
stats[:warnings_count] += 1 if msg.type == :warning
|
59
|
+
stats[:errors_count] += 1 if msg.type == :error
|
60
|
+
end
|
61
|
+
stats
|
62
|
+
end
|
63
|
+
|
64
|
+
def markdowns
|
65
|
+
messages.select { |x| x.type == :markdown }
|
66
|
+
end
|
41
67
|
end
|
42
68
|
end
|
@@ -136,14 +136,14 @@ module Danger
|
|
136
136
|
# @return [Hash] with keys `:insertions`, `:deletions` giving line counts, and `:before`, `:after` giving file contents, or nil if the file has no changes or does not exist
|
137
137
|
#
|
138
138
|
def info_for_file(file)
|
139
|
-
return nil unless modified_files.include?(file)
|
139
|
+
return nil unless modified_files.include?(file) || added_files.include?(file) || deleted_files.include?(file)
|
140
140
|
stats = @git.diff.stats[:files][file]
|
141
141
|
diff = @git.diff[file]
|
142
142
|
{
|
143
143
|
insertions: stats[:insertions],
|
144
144
|
deletions: stats[:deletions],
|
145
|
-
before: diff.blob(:src).contents,
|
146
|
-
after: diff.blob(:dst).contents
|
145
|
+
before: added_files.include?(file) || deleted_files.include?(file) ? nil : diff.blob(:src).contents,
|
146
|
+
after: added_files.include?(file) || deleted_files.include?(file) ? nil : diff.blob(:dst).contents
|
147
147
|
}
|
148
148
|
end
|
149
149
|
|
@@ -76,7 +76,7 @@ module Danger
|
|
76
76
|
}
|
77
77
|
end
|
78
78
|
|
79
|
-
def apply_template(tables: [], markdowns: [], danger_id: "danger", template: "github")
|
79
|
+
def apply_template(tables: [], markdowns: [], danger_id: "danger", template: "github", request_source: template)
|
80
80
|
require "erb"
|
81
81
|
|
82
82
|
md_template = File.join(Danger.gem_path, "lib/danger/comment_generators/#{template}.md.erb")
|
@@ -86,7 +86,7 @@ module Danger
|
|
86
86
|
@tables = tables
|
87
87
|
@markdowns = markdowns.map(&:message)
|
88
88
|
@danger_id = danger_id
|
89
|
-
@emoji_mapper = EmojiMapper.new(
|
89
|
+
@emoji_mapper = EmojiMapper.new(request_source.sub("_inline",""))
|
90
90
|
|
91
91
|
return ERB.new(File.read(md_template), 0, "-").result(binding)
|
92
92
|
end
|
@@ -104,7 +104,32 @@ module Danger
|
|
104
104
|
)
|
105
105
|
end
|
106
106
|
|
107
|
-
|
107
|
+
# resolved is essentially reserved for future use - eventually we might
|
108
|
+
# have some nice generic resolved-thing going :)
|
109
|
+
def generate_message_group_comment(message_group:,
|
110
|
+
danger_id: "danger",
|
111
|
+
resolved: [],
|
112
|
+
template: "github")
|
113
|
+
# cheating a bit - I don't want to alter the apply_template API
|
114
|
+
# so just sneak around behind its back setting some instance variables
|
115
|
+
# to get them to show up in the template
|
116
|
+
@message_group = message_group
|
117
|
+
@resolved = resolved
|
118
|
+
request_source_name = template.sub("_message_group", "")
|
119
|
+
|
120
|
+
|
121
|
+
apply_template(danger_id: danger_id,
|
122
|
+
markdowns: message_group.markdowns,
|
123
|
+
template: template,
|
124
|
+
request_source: request_source_name)
|
125
|
+
.sub(/\A\n*/, "")
|
126
|
+
end
|
127
|
+
|
128
|
+
def generate_inline_comment_body(emoji,
|
129
|
+
message,
|
130
|
+
danger_id: "danger",
|
131
|
+
resolved: [],
|
132
|
+
template: "github")
|
108
133
|
apply_template(
|
109
134
|
tables: [{ content: [message], resolved: resolved, emoji: emoji }],
|
110
135
|
danger_id: danger_id,
|
@@ -15,16 +15,25 @@ module Danger
|
|
15
15
|
}
|
16
16
|
}.freeze
|
17
17
|
|
18
|
+
TYPE_TO_EMOJI = {
|
19
|
+
error: "no_entry_sign",
|
20
|
+
warning: "warning",
|
21
|
+
message: "book",
|
22
|
+
}.freeze
|
23
|
+
|
18
24
|
def initialize(template)
|
19
|
-
template.sub!('_inline', '')
|
20
25
|
@template = DATA.has_key?(template) ? template : "github"
|
21
26
|
end
|
22
27
|
|
23
28
|
def map(emoji)
|
24
|
-
emoji
|
29
|
+
emoji&.delete! ":"
|
25
30
|
DATA[template][emoji]
|
26
31
|
end
|
27
32
|
|
33
|
+
def from_type(type)
|
34
|
+
map(TYPE_TO_EMOJI[type])
|
35
|
+
end
|
36
|
+
|
28
37
|
private
|
29
38
|
|
30
39
|
attr_reader :template
|
@@ -0,0 +1,31 @@
|
|
1
|
+
module Danger
|
2
|
+
module Helpers
|
3
|
+
module MessageGroupsArrayHelper
|
4
|
+
FakeArray = Struct.new(:count) do
|
5
|
+
def empty?
|
6
|
+
count.zero?
|
7
|
+
end
|
8
|
+
end
|
9
|
+
|
10
|
+
def fake_warnings_array
|
11
|
+
FakeArray.new(counts[:warnings])
|
12
|
+
end
|
13
|
+
|
14
|
+
def fake_errors_array
|
15
|
+
FakeArray.new(counts[:errors])
|
16
|
+
end
|
17
|
+
|
18
|
+
def counts
|
19
|
+
return @counts if @counts
|
20
|
+
|
21
|
+
@counts = { warnings: 0, errors: 0 }
|
22
|
+
each do |message_group, counts|
|
23
|
+
group_stats = message_group.stats
|
24
|
+
@counts[:warnings] += group_stats[:warnings_count]
|
25
|
+
@counts[:errors] += group_stats[:errors_count]
|
26
|
+
end
|
27
|
+
@counts
|
28
|
+
end
|
29
|
+
end
|
30
|
+
end
|
31
|
+
end
|
@@ -2,6 +2,7 @@
|
|
2
2
|
|
3
3
|
require "danger/helpers/comments_helper"
|
4
4
|
require "danger/request_sources/bitbucket_cloud_api"
|
5
|
+
require "danger/danger_core/message_group"
|
5
6
|
|
6
7
|
module Danger
|
7
8
|
module RequestSources
|
@@ -12,6 +13,7 @@ module Danger
|
|
12
13
|
def self.env_vars
|
13
14
|
[
|
14
15
|
"DANGER_BITBUCKETCLOUD_USERNAME",
|
16
|
+
"DANGER_BITBUCKETCLOUD_UUID",
|
15
17
|
"DANGER_BITBUCKETCLOUD_PASSWORD"
|
16
18
|
]
|
17
19
|
end
|
@@ -90,6 +92,50 @@ module Danger
|
|
90
92
|
@api.post_comment(comment)
|
91
93
|
end
|
92
94
|
|
95
|
+
def update_pr_by_line!(message_groups:,
|
96
|
+
danger_id: "danger",
|
97
|
+
new_comment: false,
|
98
|
+
remove_previous_comments: false)
|
99
|
+
if !new_comment || remove_previous_comments
|
100
|
+
delete_old_comments(danger_id: danger_id)
|
101
|
+
end
|
102
|
+
|
103
|
+
summary_body = generate_description(warnings: message_groups.fake_warnings_array,
|
104
|
+
errors: message_groups.fake_errors_array,
|
105
|
+
template: "bitbucket_server")
|
106
|
+
summary_body += "\n\n"
|
107
|
+
|
108
|
+
|
109
|
+
# this isn't the most elegant thing in the world, but we need the group
|
110
|
+
# with file: nil, line: nil so we can combine its info in with the
|
111
|
+
# summary_body
|
112
|
+
summary_group = message_groups.first
|
113
|
+
if summary_group && summary_group.file.nil? && summary_group.line.nil?
|
114
|
+
# remove summary_group from message_groups so it doesn't get a
|
115
|
+
# duplicate comment posted in the message_groups loop below
|
116
|
+
message_groups.shift
|
117
|
+
else
|
118
|
+
summary_group = MessageGroup.new(file: nil, line: nil)
|
119
|
+
end
|
120
|
+
|
121
|
+
summary_body += generate_message_group_comment(
|
122
|
+
message_group: summary_group,
|
123
|
+
danger_id: danger_id,
|
124
|
+
template: "bitbucket_server_message_group"
|
125
|
+
)
|
126
|
+
|
127
|
+
@api.post_comment(summary_body)
|
128
|
+
|
129
|
+
message_groups.each do |message_group|
|
130
|
+
body = generate_message_group_comment(message_group: message_group,
|
131
|
+
danger_id: danger_id,
|
132
|
+
template: "bitbucket_server_message_group")
|
133
|
+
@api.post_comment(body,
|
134
|
+
file: message_group.file,
|
135
|
+
line: message_group.line)
|
136
|
+
end
|
137
|
+
end
|
138
|
+
|
93
139
|
def update_inline_comments_for_kind!(kind, messages, danger_id: "danger")
|
94
140
|
emoji = { warnings: "warning", errors: "no_entry_sign", messages: "book" }[kind]
|
95
141
|
|
@@ -6,8 +6,10 @@ module Danger
|
|
6
6
|
module RequestSources
|
7
7
|
class BitbucketCloudAPI
|
8
8
|
attr_accessor :host, :project, :slug, :access_token, :pull_request_id
|
9
|
+
attr_reader :my_uuid
|
9
10
|
|
10
11
|
def initialize(repo_slug, pull_request_id, branch_name, environment)
|
12
|
+
initialize_my_uuid(environment["DANGER_BITBUCKETCLOUD_UUID"])
|
11
13
|
@username = environment["DANGER_BITBUCKETCLOUD_USERNAME"]
|
12
14
|
@password = environment["DANGER_BITBUCKETCLOUD_PASSWORD"]
|
13
15
|
self.project, self.slug = repo_slug.split("/")
|
@@ -16,6 +18,17 @@ module Danger
|
|
16
18
|
self.host = "https://bitbucket.org/"
|
17
19
|
end
|
18
20
|
|
21
|
+
def initialize_my_uuid(uuid)
|
22
|
+
return if uuid.nil?
|
23
|
+
return @my_uuid = uuid if uuid.empty?
|
24
|
+
|
25
|
+
if uuid.start_with?("{") && uuid.end_with?("}")
|
26
|
+
@my_uuid = uuid
|
27
|
+
else
|
28
|
+
@my_uuid = "{#{uuid}}"
|
29
|
+
end
|
30
|
+
end
|
31
|
+
|
19
32
|
def inspect
|
20
33
|
inspected = super
|
21
34
|
|
@@ -27,12 +40,9 @@ module Danger
|
|
27
40
|
end
|
28
41
|
|
29
42
|
def credentials_given?
|
30
|
-
@
|
31
|
-
|
32
|
-
|
33
|
-
def my_uuid
|
34
|
-
uri = URI("https://api.bitbucket.org/2.0/users/#{@username}")
|
35
|
-
@my_uuid ||= fetch_json(uri)[:uuid]
|
43
|
+
@my_uuid && !@my_uuid.empty? &&
|
44
|
+
@username && !@username.empty? &&
|
45
|
+
@password && !@password.empty?
|
36
46
|
end
|
37
47
|
|
38
48
|
def pull_request(*)
|
@@ -157,7 +167,9 @@ module Danger
|
|
157
167
|
end
|
158
168
|
|
159
169
|
def credentials_not_available
|
160
|
-
"Credentials not available. Provide DANGER_BITBUCKETCLOUD_USERNAME
|
170
|
+
"Credentials not available. Provide DANGER_BITBUCKETCLOUD_USERNAME, " \
|
171
|
+
"DANGER_BITBUCKETCLOUD_UUID, and DANGER_BITBUCKETCLOUD_PASSWORD " \
|
172
|
+
"as environment variables."
|
161
173
|
end
|
162
174
|
|
163
175
|
def error_fetching_json(url, status_code)
|
data/lib/danger/version.rb
CHANGED
metadata
CHANGED
@@ -1,7 +1,7 @@
|
|
1
1
|
--- !ruby/object:Gem::Specification
|
2
2
|
name: danger
|
3
3
|
version: !ruby/object:Gem::Version
|
4
|
-
version:
|
4
|
+
version: 7.0.0
|
5
5
|
platform: ruby
|
6
6
|
authors:
|
7
7
|
- Orta Therox
|
@@ -9,7 +9,7 @@ authors:
|
|
9
9
|
autorequire:
|
10
10
|
bindir: bin
|
11
11
|
cert_chain: []
|
12
|
-
date: 2020-
|
12
|
+
date: 2020-04-16 00:00:00.000000000 Z
|
13
13
|
dependencies:
|
14
14
|
- !ruby/object:Gem::Dependency
|
15
15
|
name: claide
|
@@ -71,16 +71,22 @@ dependencies:
|
|
71
71
|
name: faraday
|
72
72
|
requirement: !ruby/object:Gem::Requirement
|
73
73
|
requirements:
|
74
|
-
- - "
|
74
|
+
- - ">="
|
75
75
|
- !ruby/object:Gem::Version
|
76
|
-
version:
|
76
|
+
version: 0.9.0
|
77
|
+
- - "<"
|
78
|
+
- !ruby/object:Gem::Version
|
79
|
+
version: '2.0'
|
77
80
|
type: :runtime
|
78
81
|
prerelease: false
|
79
82
|
version_requirements: !ruby/object:Gem::Requirement
|
80
83
|
requirements:
|
81
|
-
- - "
|
84
|
+
- - ">="
|
82
85
|
- !ruby/object:Gem::Version
|
83
|
-
version:
|
86
|
+
version: 0.9.0
|
87
|
+
- - "<"
|
88
|
+
- !ruby/object:Gem::Version
|
89
|
+
version: '2.0'
|
84
90
|
- !ruby/object:Gem::Dependency
|
85
91
|
name: faraday-http-cache
|
86
92
|
requirement: !ruby/object:Gem::Requirement
|
@@ -250,6 +256,7 @@ files:
|
|
250
256
|
- lib/danger/commands/systems.rb
|
251
257
|
- lib/danger/comment_generators/bitbucket_server.md.erb
|
252
258
|
- lib/danger/comment_generators/bitbucket_server_inline.md.erb
|
259
|
+
- lib/danger/comment_generators/bitbucket_server_message_group.md.erb
|
253
260
|
- lib/danger/comment_generators/github.md.erb
|
254
261
|
- lib/danger/comment_generators/github_inline.md.erb
|
255
262
|
- lib/danger/comment_generators/gitlab.md.erb
|
@@ -283,6 +290,7 @@ files:
|
|
283
290
|
- lib/danger/helpers/comments_parsing_helper.rb
|
284
291
|
- lib/danger/helpers/emoji_mapper.rb
|
285
292
|
- lib/danger/helpers/find_max_num_violations.rb
|
293
|
+
- lib/danger/helpers/message_groups_array_helper.rb
|
286
294
|
- lib/danger/plugin_support/gems_resolver.rb
|
287
295
|
- lib/danger/plugin_support/plugin.rb
|
288
296
|
- lib/danger/plugin_support/plugin_file_resolver.rb
|