dependabot-common 0.108.18 → 0.108.19
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
CHANGED
|
@@ -1,7 +1,7 @@
|
|
|
1
1
|
---
|
|
2
2
|
SHA256:
|
|
3
|
-
metadata.gz:
|
|
4
|
-
data.tar.gz:
|
|
3
|
+
metadata.gz: 9c8b59378241405894c2ce121aa7ed05e619caf957a927bf17cabb734b05f165
|
|
4
|
+
data.tar.gz: 3da383889459a00bf61b175c0f7a8a20fc4b95b703d1bb3eb562043d3a824a54
|
|
5
5
|
SHA512:
|
|
6
|
-
metadata.gz:
|
|
7
|
-
data.tar.gz:
|
|
6
|
+
metadata.gz: 4df19d351139d8accd5c8afdf768bdfe4e61432c0d2afd7b69441dfa13006cac6915b44c556d81cf34682c35964a362a66a203f55bedb884b5e1c97f1e0742c4
|
|
7
|
+
data.tar.gz: c0f8720394c1e3059d4cdad5a22b764d8adb41549f9882901356ce97c0be097d2660634bf514124b92ded45094c556776d744c4af6399809c13b78d56f8b2d5f
|
|
@@ -12,24 +12,7 @@ module Dependabot
|
|
|
12
12
|
class MessageBuilder
|
|
13
13
|
require_relative "message_builder/issue_linker"
|
|
14
14
|
require_relative "message_builder/link_and_mention_sanitizer"
|
|
15
|
-
|
|
16
|
-
ANGULAR_PREFIXES = %w(build chore ci docs feat fix perf refactor style
|
|
17
|
-
test).freeze
|
|
18
|
-
ESLINT_PREFIXES = %w(Breaking Build Chore Docs Fix New Update
|
|
19
|
-
Upgrade).freeze
|
|
20
|
-
GITMOJI_PREFIXES = %w(alien ambulance apple arrow_down arrow_up art beers
|
|
21
|
-
bento bookmark boom bug building_construction bulb
|
|
22
|
-
busts_in_silhouette camera_flash card_file_box
|
|
23
|
-
chart_with_upwards_trend checkered_flag
|
|
24
|
-
children_crossing clown_face construction
|
|
25
|
-
construction_worker egg fire globe_with_meridians
|
|
26
|
-
green_apple green_heart hankey heavy_minus_sign
|
|
27
|
-
heavy_plus_sign iphone lipstick lock loud_sound memo
|
|
28
|
-
mute ok_hand package page_facing_up pencil2 penguin
|
|
29
|
-
pushpin recycle rewind robot rocket rotating_light
|
|
30
|
-
see_no_evil sparkles speech_balloon tada truck
|
|
31
|
-
twisted_rightwards_arrows whale wheelchair
|
|
32
|
-
white_check_mark wrench zap).freeze
|
|
15
|
+
require_relative "pr_name_prefixer"
|
|
33
16
|
|
|
34
17
|
attr_reader :source, :dependencies, :files, :credentials,
|
|
35
18
|
:pr_message_footer, :signoff_details, :vulnerabilities_fixed,
|
|
@@ -49,9 +32,11 @@ module Dependabot
|
|
|
49
32
|
end
|
|
50
33
|
|
|
51
34
|
def pr_name
|
|
52
|
-
|
|
35
|
+
pr_name = pr_name_prefixer.pr_name_prefix
|
|
36
|
+
pr_name += library? ? library_pr_name : application_pr_name
|
|
37
|
+
return pr_name if files.first.directory == "/"
|
|
53
38
|
|
|
54
|
-
|
|
39
|
+
pr_name + " in #{files.first.directory}"
|
|
55
40
|
end
|
|
56
41
|
|
|
57
42
|
def pr_message
|
|
@@ -68,53 +53,11 @@ module Dependabot
|
|
|
68
53
|
|
|
69
54
|
private
|
|
70
55
|
|
|
71
|
-
def commit_subject
|
|
72
|
-
subject = pr_name.gsub("⬆️", ":arrow_up:").gsub("🔒", ":lock:")
|
|
73
|
-
return subject unless subject.length > 72
|
|
74
|
-
|
|
75
|
-
subject = subject.gsub(/ from [^\s]*? to [^\s]*/, "")
|
|
76
|
-
return subject unless subject.length > 72
|
|
77
|
-
|
|
78
|
-
subject.split(" in ").first
|
|
79
|
-
end
|
|
80
|
-
|
|
81
|
-
def commit_message_intro
|
|
82
|
-
return requirement_commit_message_intro if library?
|
|
83
|
-
|
|
84
|
-
version_commit_message_intro
|
|
85
|
-
end
|
|
86
|
-
|
|
87
|
-
def prefixed_pr_message_footer
|
|
88
|
-
return "" unless pr_message_footer
|
|
89
|
-
|
|
90
|
-
"\n\n#{pr_message_footer}"
|
|
91
|
-
end
|
|
92
|
-
|
|
93
|
-
def message_trailers
|
|
94
|
-
return unless on_behalf_of_message || signoff_message
|
|
95
|
-
|
|
96
|
-
[on_behalf_of_message, signoff_message].compact.join("\n")
|
|
97
|
-
end
|
|
98
|
-
|
|
99
|
-
def signoff_message
|
|
100
|
-
return unless signoff_details.is_a?(Hash)
|
|
101
|
-
return unless signoff_details[:name] && signoff_details[:email]
|
|
102
|
-
|
|
103
|
-
"Signed-off-by: #{signoff_details[:name]} <#{signoff_details[:email]}>"
|
|
104
|
-
end
|
|
105
|
-
|
|
106
|
-
def on_behalf_of_message
|
|
107
|
-
return unless signoff_details.is_a?(Hash)
|
|
108
|
-
return unless signoff_details[:org_name] && signoff_details[:org_email]
|
|
109
|
-
|
|
110
|
-
"On-behalf-of: @#{signoff_details[:org_name]} "\
|
|
111
|
-
"<#{signoff_details[:org_email]}>"
|
|
112
|
-
end
|
|
113
|
-
|
|
114
56
|
def library_pr_name
|
|
115
|
-
pr_name =
|
|
57
|
+
pr_name = "update "
|
|
58
|
+
pr_name = pr_name.capitalize if pr_name_prefixer.capitalize_first_word?
|
|
116
59
|
|
|
117
|
-
pr_name
|
|
60
|
+
pr_name +
|
|
118
61
|
if dependencies.count == 1
|
|
119
62
|
"#{dependencies.first.display_name} requirement "\
|
|
120
63
|
"from #{old_library_requirement(dependencies.first)} "\
|
|
@@ -123,17 +66,14 @@ module Dependabot
|
|
|
123
66
|
names = dependencies.map(&:name)
|
|
124
67
|
"requirements for #{names[0..-2].join(', ')} and #{names[-1]}"
|
|
125
68
|
end
|
|
126
|
-
|
|
127
|
-
return pr_name if files.first.directory == "/"
|
|
128
|
-
|
|
129
|
-
pr_name + " in #{files.first.directory}"
|
|
130
69
|
end
|
|
131
70
|
|
|
132
71
|
# rubocop:disable Metrics/AbcSize
|
|
133
72
|
def application_pr_name
|
|
134
|
-
pr_name =
|
|
73
|
+
pr_name = "bump "
|
|
74
|
+
pr_name = pr_name.capitalize if pr_name_prefixer.capitalize_first_word?
|
|
135
75
|
|
|
136
|
-
pr_name
|
|
76
|
+
pr_name +
|
|
137
77
|
if dependencies.count == 1
|
|
138
78
|
dependency = dependencies.first
|
|
139
79
|
"#{dependency.display_name} from #{previous_version(dependency)} "\
|
|
@@ -151,95 +91,54 @@ module Dependabot
|
|
|
151
91
|
names = dependencies.map(&:name)
|
|
152
92
|
"#{names[0..-2].join(', ')} and #{names[-1]}"
|
|
153
93
|
end
|
|
154
|
-
|
|
155
|
-
return pr_name if files.first.directory == "/"
|
|
156
|
-
|
|
157
|
-
pr_name + " in #{files.first.directory}"
|
|
158
94
|
end
|
|
159
95
|
# rubocop:enable Metrics/AbcSize
|
|
160
96
|
|
|
161
97
|
def pr_name_prefix
|
|
162
|
-
|
|
163
|
-
prefix += security_prefix if includes_security_fixes?
|
|
164
|
-
prefix = prefix.gsub("⬆️ 🔒", "⬆️🔒")
|
|
165
|
-
prefix + pr_name_first_word
|
|
166
|
-
end
|
|
167
|
-
|
|
168
|
-
def commit_prefix
|
|
169
|
-
# If there is a previous Dependabot commit, and it used a known style,
|
|
170
|
-
# use that as our model for subsequent commits
|
|
171
|
-
case last_dependabot_commit_style
|
|
172
|
-
when :gitmoji then "⬆️ "
|
|
173
|
-
when :conventional_prefix then "#{last_dependabot_commit_prefix}: "
|
|
174
|
-
when :conventional_prefix_with_scope
|
|
175
|
-
"#{last_dependabot_commit_prefix}(#{scope}): "
|
|
176
|
-
else
|
|
177
|
-
# Otherwise we need to detect the user's preferred style from the
|
|
178
|
-
# existing commits on their repo
|
|
179
|
-
build_commit_prefix_from_previous_commits
|
|
180
|
-
end
|
|
98
|
+
pr_name_prefixer.pr_name_prefix
|
|
181
99
|
end
|
|
182
100
|
|
|
183
|
-
def
|
|
184
|
-
|
|
101
|
+
def commit_subject
|
|
102
|
+
subject = pr_name.gsub("⬆️", ":arrow_up:").gsub("🔒", ":lock:")
|
|
103
|
+
return subject unless subject.length > 72
|
|
185
104
|
|
|
186
|
-
|
|
187
|
-
|
|
105
|
+
subject = subject.gsub(/ from [^\s]*? to [^\s]*/, "")
|
|
106
|
+
return subject unless subject.length > 72
|
|
188
107
|
|
|
189
|
-
|
|
190
|
-
first_word = library? ? "update " : "bump "
|
|
191
|
-
capitalize_first_word? ? first_word.capitalize : first_word
|
|
108
|
+
subject.split(" in ").first
|
|
192
109
|
end
|
|
193
110
|
|
|
194
|
-
def
|
|
195
|
-
|
|
196
|
-
when :gitmoji then true
|
|
197
|
-
when :conventional_prefix, :conventional_prefix_with_scope
|
|
198
|
-
last_dependabot_commit_message.match?(/: (\[Security\] )?(B|U)/)
|
|
199
|
-
else
|
|
200
|
-
if using_angular_commit_messages? || using_eslint_commit_messages?
|
|
201
|
-
prefixes = ANGULAR_PREFIXES + ESLINT_PREFIXES
|
|
202
|
-
semantic_msgs = recent_commit_messages.select do |message|
|
|
203
|
-
prefixes.any? { |pre| message.match?(/#{pre}[:(]/i) }
|
|
204
|
-
end
|
|
205
|
-
|
|
206
|
-
return true if semantic_msgs.all? { |m| m.match?(/:\s+\[?[A-Z]/) }
|
|
207
|
-
return false if semantic_msgs.all? { |m| m.match?(/:\s+\[?[a-z]/) }
|
|
208
|
-
end
|
|
111
|
+
def commit_message_intro
|
|
112
|
+
return requirement_commit_message_intro if library?
|
|
209
113
|
|
|
210
|
-
|
|
211
|
-
end
|
|
114
|
+
version_commit_message_intro
|
|
212
115
|
end
|
|
213
116
|
|
|
214
|
-
def
|
|
215
|
-
|
|
216
|
-
"#{angular_commit_prefix}(#{scope}): "
|
|
217
|
-
elsif using_eslint_commit_messages?
|
|
218
|
-
# https://eslint.org/docs/developer-guide/contributing/pull-requests
|
|
219
|
-
"Upgrade: "
|
|
220
|
-
elsif using_gitmoji_commit_messages?
|
|
221
|
-
"⬆️ "
|
|
222
|
-
elsif using_prefixed_commit_messages?
|
|
223
|
-
"build(#{scope}): "
|
|
224
|
-
end
|
|
225
|
-
end
|
|
117
|
+
def prefixed_pr_message_footer
|
|
118
|
+
return "" unless pr_message_footer
|
|
226
119
|
|
|
227
|
-
|
|
228
|
-
dependencies.any?(&:production?) ? "deps" : "deps-dev"
|
|
120
|
+
"\n\n#{pr_message_footer}"
|
|
229
121
|
end
|
|
230
122
|
|
|
231
|
-
def
|
|
232
|
-
return unless
|
|
123
|
+
def message_trailers
|
|
124
|
+
return unless on_behalf_of_message || signoff_message
|
|
125
|
+
|
|
126
|
+
[on_behalf_of_message, signoff_message].compact.join("\n")
|
|
127
|
+
end
|
|
233
128
|
|
|
234
|
-
|
|
235
|
-
return
|
|
236
|
-
return unless
|
|
129
|
+
def signoff_message
|
|
130
|
+
return unless signoff_details.is_a?(Hash)
|
|
131
|
+
return unless signoff_details[:name] && signoff_details[:email]
|
|
237
132
|
|
|
238
|
-
:
|
|
133
|
+
"Signed-off-by: #{signoff_details[:name]} <#{signoff_details[:email]}>"
|
|
239
134
|
end
|
|
240
135
|
|
|
241
|
-
def
|
|
242
|
-
|
|
136
|
+
def on_behalf_of_message
|
|
137
|
+
return unless signoff_details.is_a?(Hash)
|
|
138
|
+
return unless signoff_details[:org_name] && signoff_details[:org_email]
|
|
139
|
+
|
|
140
|
+
"On-behalf-of: @#{signoff_details[:org_name]} "\
|
|
141
|
+
"<#{signoff_details[:org_email]}>"
|
|
243
142
|
end
|
|
244
143
|
|
|
245
144
|
def requirement_commit_message_intro
|
|
@@ -619,6 +518,16 @@ module Dependabot
|
|
|
619
518
|
new(dependency: dependency, credentials: credentials)
|
|
620
519
|
end
|
|
621
520
|
|
|
521
|
+
def pr_name_prefixer
|
|
522
|
+
@pr_name_prefixer ||=
|
|
523
|
+
PrNamePrefixer.new(
|
|
524
|
+
source: source,
|
|
525
|
+
dependencies: dependencies,
|
|
526
|
+
credentials: credentials,
|
|
527
|
+
security_fix: vulnerabilities_fixed.values.flatten.any?
|
|
528
|
+
)
|
|
529
|
+
end
|
|
530
|
+
|
|
622
531
|
def previous_version(dependency)
|
|
623
532
|
if dependency.previous_version.match?(/^[0-9a-f]{40}$/)
|
|
624
533
|
return previous_ref(dependency) if ref_changed?(dependency)
|
|
@@ -753,191 +662,6 @@ module Dependabot
|
|
|
753
662
|
Gem::Version.correct?(dependency.version)
|
|
754
663
|
end
|
|
755
664
|
|
|
756
|
-
def includes_security_fixes?
|
|
757
|
-
vulnerabilities_fixed.values.flatten.any?
|
|
758
|
-
end
|
|
759
|
-
|
|
760
|
-
def using_angular_commit_messages?
|
|
761
|
-
return false if recent_commit_messages.none?
|
|
762
|
-
|
|
763
|
-
angular_messages = recent_commit_messages.select do |message|
|
|
764
|
-
ANGULAR_PREFIXES.any? { |pre| message.match?(/#{pre}[:(]/i) }
|
|
765
|
-
end
|
|
766
|
-
|
|
767
|
-
# Definitely not using Angular commits if < 30% match angular commits
|
|
768
|
-
if angular_messages.count.to_f / recent_commit_messages.count < 0.3
|
|
769
|
-
return false
|
|
770
|
-
end
|
|
771
|
-
|
|
772
|
-
eslint_only_pres = ESLINT_PREFIXES.map(&:downcase) - ANGULAR_PREFIXES
|
|
773
|
-
angular_only_pres = ANGULAR_PREFIXES - ESLINT_PREFIXES.map(&:downcase)
|
|
774
|
-
|
|
775
|
-
uses_eslint_only_pres =
|
|
776
|
-
recent_commit_messages.
|
|
777
|
-
any? { |m| eslint_only_pres.any? { |pre| m.match?(/#{pre}[:(]/i) } }
|
|
778
|
-
|
|
779
|
-
uses_angular_only_pres =
|
|
780
|
-
recent_commit_messages.
|
|
781
|
-
any? { |m| angular_only_pres.any? { |pre| m.match?(/#{pre}[:(]/i) } }
|
|
782
|
-
|
|
783
|
-
# If using any angular-only prefixes, return true
|
|
784
|
-
# (i.e., we assume Angular over ESLint when both are present)
|
|
785
|
-
return true if uses_angular_only_pres
|
|
786
|
-
return false if uses_eslint_only_pres
|
|
787
|
-
|
|
788
|
-
true
|
|
789
|
-
end
|
|
790
|
-
|
|
791
|
-
def using_eslint_commit_messages?
|
|
792
|
-
return false if recent_commit_messages.none?
|
|
793
|
-
|
|
794
|
-
semantic_messages = recent_commit_messages.select do |message|
|
|
795
|
-
ESLINT_PREFIXES.any? { |pre| message.start_with?(/#{pre}[:(]/) }
|
|
796
|
-
end
|
|
797
|
-
|
|
798
|
-
semantic_messages.count.to_f / recent_commit_messages.count > 0.3
|
|
799
|
-
end
|
|
800
|
-
|
|
801
|
-
def using_prefixed_commit_messages?
|
|
802
|
-
return false if using_gitmoji_commit_messages?
|
|
803
|
-
return false if recent_commit_messages.none?
|
|
804
|
-
|
|
805
|
-
prefixed_messages = recent_commit_messages.select do |message|
|
|
806
|
-
message.start_with?(/[a-z][^\s]+:/)
|
|
807
|
-
end
|
|
808
|
-
|
|
809
|
-
prefixed_messages.count.to_f / recent_commit_messages.count > 0.3
|
|
810
|
-
end
|
|
811
|
-
|
|
812
|
-
def angular_commit_prefix
|
|
813
|
-
raise "Not using angular commits!" unless using_angular_commit_messages?
|
|
814
|
-
|
|
815
|
-
recent_commits_using_chore =
|
|
816
|
-
recent_commit_messages.
|
|
817
|
-
any? { |msg| msg.start_with?("chore", "Chore") }
|
|
818
|
-
|
|
819
|
-
recent_commits_using_build =
|
|
820
|
-
recent_commit_messages.
|
|
821
|
-
any? { |msg| msg.start_with?("build", "Build") }
|
|
822
|
-
|
|
823
|
-
commit_prefix =
|
|
824
|
-
if recent_commits_using_chore && !recent_commits_using_build
|
|
825
|
-
"chore"
|
|
826
|
-
else
|
|
827
|
-
"build"
|
|
828
|
-
end
|
|
829
|
-
|
|
830
|
-
if capitalize_angular_commit_prefix?
|
|
831
|
-
commit_prefix = commit_prefix.capitalize
|
|
832
|
-
end
|
|
833
|
-
|
|
834
|
-
commit_prefix
|
|
835
|
-
end
|
|
836
|
-
|
|
837
|
-
def capitalize_angular_commit_prefix?
|
|
838
|
-
semantic_messages = recent_commit_messages.select do |message|
|
|
839
|
-
ANGULAR_PREFIXES.any? { |pre| message.match?(/#{pre}[:(]/i) }
|
|
840
|
-
end
|
|
841
|
-
|
|
842
|
-
if semantic_messages.none?
|
|
843
|
-
return last_dependabot_commit_message&.start_with?(/[A-Z]/)
|
|
844
|
-
end
|
|
845
|
-
|
|
846
|
-
capitalized_msgs = semantic_messages.
|
|
847
|
-
select { |m| m.start_with?(/[A-Z]/) }
|
|
848
|
-
capitalized_msgs.count.to_f / semantic_messages.count > 0.5
|
|
849
|
-
end
|
|
850
|
-
|
|
851
|
-
def using_gitmoji_commit_messages?
|
|
852
|
-
return false unless recent_commit_messages.any?
|
|
853
|
-
|
|
854
|
-
gitmoji_messages =
|
|
855
|
-
recent_commit_messages.
|
|
856
|
-
select { |m| GITMOJI_PREFIXES.any? { |pre| m.match?(/:#{pre}:/i) } }
|
|
857
|
-
|
|
858
|
-
gitmoji_messages.count / recent_commit_messages.count.to_f > 0.3
|
|
859
|
-
end
|
|
860
|
-
|
|
861
|
-
def recent_commit_messages
|
|
862
|
-
case source.provider
|
|
863
|
-
when "github" then recent_github_commit_messages
|
|
864
|
-
when "gitlab" then recent_gitlab_commit_messages
|
|
865
|
-
else raise "Unsupported provider: #{source.provider}"
|
|
866
|
-
end
|
|
867
|
-
end
|
|
868
|
-
|
|
869
|
-
def recent_github_commit_messages
|
|
870
|
-
recent_github_commits.
|
|
871
|
-
reject { |c| c.author&.type == "Bot" }.
|
|
872
|
-
reject { |c| c.commit&.message&.start_with?("Merge") }.
|
|
873
|
-
map(&:commit).
|
|
874
|
-
map(&:message).
|
|
875
|
-
compact.
|
|
876
|
-
map(&:strip)
|
|
877
|
-
end
|
|
878
|
-
|
|
879
|
-
def recent_gitlab_commit_messages
|
|
880
|
-
@recent_gitlab_commit_messages ||=
|
|
881
|
-
gitlab_client_for_source.commits(source.repo)
|
|
882
|
-
|
|
883
|
-
@recent_gitlab_commit_messages.
|
|
884
|
-
reject { |c| c.author_email == "support@dependabot.com" }.
|
|
885
|
-
reject { |c| c.message&.start_with?("merge !") }.
|
|
886
|
-
map(&:message).
|
|
887
|
-
compact.
|
|
888
|
-
map(&:strip)
|
|
889
|
-
end
|
|
890
|
-
|
|
891
|
-
def last_dependabot_commit_message
|
|
892
|
-
case source.provider
|
|
893
|
-
when "github" then last_github_dependabot_commit_message
|
|
894
|
-
when "gitlab" then last_gitlab_dependabot_commit_message
|
|
895
|
-
else raise "Unsupported provider: #{source.provider}"
|
|
896
|
-
end
|
|
897
|
-
end
|
|
898
|
-
|
|
899
|
-
def last_github_dependabot_commit_message
|
|
900
|
-
recent_github_commits.
|
|
901
|
-
reject { |c| c.commit&.message&.start_with?("Merge") }.
|
|
902
|
-
find { |c| c.commit.author&.name&.include?("dependabot") }&.
|
|
903
|
-
commit&.
|
|
904
|
-
message&.
|
|
905
|
-
strip
|
|
906
|
-
end
|
|
907
|
-
|
|
908
|
-
def recent_github_commits
|
|
909
|
-
@recent_github_commits ||=
|
|
910
|
-
github_client_for_source.commits(source.repo, per_page: 100)
|
|
911
|
-
rescue Octokit::Conflict
|
|
912
|
-
@recent_github_commits ||= []
|
|
913
|
-
end
|
|
914
|
-
|
|
915
|
-
def last_gitlab_dependabot_commit_message
|
|
916
|
-
@recent_gitlab_commit_messages ||=
|
|
917
|
-
gitlab_client_for_source.commits(source.repo)
|
|
918
|
-
|
|
919
|
-
@recent_gitlab_commit_messages.
|
|
920
|
-
find { |c| c.author_email == "support@dependabot.com" }&.
|
|
921
|
-
message&.
|
|
922
|
-
strip
|
|
923
|
-
end
|
|
924
|
-
|
|
925
|
-
def github_client_for_source
|
|
926
|
-
@github_client_for_source ||=
|
|
927
|
-
Dependabot::Clients::GithubWithRetries.for_source(
|
|
928
|
-
source: source,
|
|
929
|
-
credentials: credentials
|
|
930
|
-
)
|
|
931
|
-
end
|
|
932
|
-
|
|
933
|
-
def gitlab_client_for_source
|
|
934
|
-
@gitlab_client_for_source ||=
|
|
935
|
-
Dependabot::Clients::GitlabWithRetries.for_source(
|
|
936
|
-
source: source,
|
|
937
|
-
credentials: credentials
|
|
938
|
-
)
|
|
939
|
-
end
|
|
940
|
-
|
|
941
665
|
def package_manager
|
|
942
666
|
@package_manager ||= dependencies.first.package_manager
|
|
943
667
|
end
|
|
@@ -0,0 +1,307 @@
|
|
|
1
|
+
# frozen_string_literal: true
|
|
2
|
+
|
|
3
|
+
require "dependabot/clients/github_with_retries"
|
|
4
|
+
require "dependabot/clients/gitlab_with_retries"
|
|
5
|
+
require "dependabot/pull_request_creator"
|
|
6
|
+
|
|
7
|
+
module Dependabot
|
|
8
|
+
class PullRequestCreator
|
|
9
|
+
class PrNamePrefixer
|
|
10
|
+
ANGULAR_PREFIXES = %w(build chore ci docs feat fix perf refactor style
|
|
11
|
+
test).freeze
|
|
12
|
+
ESLINT_PREFIXES = %w(Breaking Build Chore Docs Fix New Update
|
|
13
|
+
Upgrade).freeze
|
|
14
|
+
GITMOJI_PREFIXES = %w(alien ambulance apple arrow_down arrow_up art beers
|
|
15
|
+
bento bookmark boom bug building_construction bulb
|
|
16
|
+
busts_in_silhouette camera_flash card_file_box
|
|
17
|
+
chart_with_upwards_trend checkered_flag
|
|
18
|
+
children_crossing clown_face construction
|
|
19
|
+
construction_worker egg fire globe_with_meridians
|
|
20
|
+
green_apple green_heart hankey heavy_minus_sign
|
|
21
|
+
heavy_plus_sign iphone lipstick lock loud_sound memo
|
|
22
|
+
mute ok_hand package page_facing_up pencil2 penguin
|
|
23
|
+
pushpin recycle rewind robot rocket rotating_light
|
|
24
|
+
see_no_evil sparkles speech_balloon tada truck
|
|
25
|
+
twisted_rightwards_arrows whale wheelchair
|
|
26
|
+
white_check_mark wrench zap).freeze
|
|
27
|
+
|
|
28
|
+
def initialize(source:, dependencies:, credentials:, security_fix: false)
|
|
29
|
+
@dependencies = dependencies
|
|
30
|
+
@source = source
|
|
31
|
+
@credentials = credentials
|
|
32
|
+
@security_fix = security_fix
|
|
33
|
+
end
|
|
34
|
+
|
|
35
|
+
def pr_name_prefix
|
|
36
|
+
prefix = commit_prefix.to_s
|
|
37
|
+
prefix += security_prefix if security_fix?
|
|
38
|
+
prefix.gsub("⬆️ 🔒", "⬆️🔒")
|
|
39
|
+
end
|
|
40
|
+
|
|
41
|
+
def capitalize_first_word?
|
|
42
|
+
case last_dependabot_commit_style
|
|
43
|
+
when :gitmoji then true
|
|
44
|
+
when :conventional_prefix, :conventional_prefix_with_scope
|
|
45
|
+
last_dependabot_commit_message.match?(/: (\[Security\] )?(B|U)/)
|
|
46
|
+
else
|
|
47
|
+
if using_angular_commit_messages? || using_eslint_commit_messages?
|
|
48
|
+
prefixes = ANGULAR_PREFIXES + ESLINT_PREFIXES
|
|
49
|
+
semantic_msgs = recent_commit_messages.select do |message|
|
|
50
|
+
prefixes.any? { |pre| message.match?(/#{pre}[:(]/i) }
|
|
51
|
+
end
|
|
52
|
+
|
|
53
|
+
return true if semantic_msgs.all? { |m| m.match?(/:\s+\[?[A-Z]/) }
|
|
54
|
+
return false if semantic_msgs.all? { |m| m.match?(/:\s+\[?[a-z]/) }
|
|
55
|
+
end
|
|
56
|
+
|
|
57
|
+
!commit_prefix&.match(/\A[a-z]/)
|
|
58
|
+
end
|
|
59
|
+
end
|
|
60
|
+
|
|
61
|
+
private
|
|
62
|
+
|
|
63
|
+
attr_reader :source, :dependencies, :credentials
|
|
64
|
+
|
|
65
|
+
def security_fix?
|
|
66
|
+
@security_fix
|
|
67
|
+
end
|
|
68
|
+
|
|
69
|
+
def commit_prefix
|
|
70
|
+
# If there is a previous Dependabot commit, and it used a known style,
|
|
71
|
+
# use that as our model for subsequent commits
|
|
72
|
+
case last_dependabot_commit_style
|
|
73
|
+
when :gitmoji then "⬆️ "
|
|
74
|
+
when :conventional_prefix then "#{last_dependabot_commit_prefix}: "
|
|
75
|
+
when :conventional_prefix_with_scope
|
|
76
|
+
"#{last_dependabot_commit_prefix}(#{scope}): "
|
|
77
|
+
else
|
|
78
|
+
# Otherwise we need to detect the user's preferred style from the
|
|
79
|
+
# existing commits on their repo
|
|
80
|
+
build_commit_prefix_from_previous_commits
|
|
81
|
+
end
|
|
82
|
+
end
|
|
83
|
+
|
|
84
|
+
def security_prefix
|
|
85
|
+
return "🔒 " if commit_prefix == "⬆️ "
|
|
86
|
+
|
|
87
|
+
capitalize_first_word? ? "[Security] " : "[security] "
|
|
88
|
+
end
|
|
89
|
+
|
|
90
|
+
def build_commit_prefix_from_previous_commits
|
|
91
|
+
if using_angular_commit_messages?
|
|
92
|
+
"#{angular_commit_prefix}(#{scope}): "
|
|
93
|
+
elsif using_eslint_commit_messages?
|
|
94
|
+
# https://eslint.org/docs/developer-guide/contributing/pull-requests
|
|
95
|
+
"Upgrade: "
|
|
96
|
+
elsif using_gitmoji_commit_messages?
|
|
97
|
+
"⬆️ "
|
|
98
|
+
elsif using_prefixed_commit_messages?
|
|
99
|
+
"build(#{scope}): "
|
|
100
|
+
end
|
|
101
|
+
end
|
|
102
|
+
|
|
103
|
+
def scope
|
|
104
|
+
dependencies.any?(&:production?) ? "deps" : "deps-dev"
|
|
105
|
+
end
|
|
106
|
+
|
|
107
|
+
def last_dependabot_commit_style
|
|
108
|
+
return unless (msg = last_dependabot_commit_message)
|
|
109
|
+
|
|
110
|
+
return :gitmoji if msg.start_with?("⬆️")
|
|
111
|
+
return :conventional_prefix if msg.match?(/\A(chore|build|upgrade):/i)
|
|
112
|
+
return unless msg.match?(/\A(chore|build|upgrade)\(/i)
|
|
113
|
+
|
|
114
|
+
:conventional_prefix_with_scope
|
|
115
|
+
end
|
|
116
|
+
|
|
117
|
+
def last_dependabot_commit_prefix
|
|
118
|
+
last_dependabot_commit_message&.split(/[:(]/)&.first
|
|
119
|
+
end
|
|
120
|
+
|
|
121
|
+
def using_angular_commit_messages?
|
|
122
|
+
return false if recent_commit_messages.none?
|
|
123
|
+
|
|
124
|
+
angular_messages = recent_commit_messages.select do |message|
|
|
125
|
+
ANGULAR_PREFIXES.any? { |pre| message.match?(/#{pre}[:(]/i) }
|
|
126
|
+
end
|
|
127
|
+
|
|
128
|
+
# Definitely not using Angular commits if < 30% match angular commits
|
|
129
|
+
if angular_messages.count.to_f / recent_commit_messages.count < 0.3
|
|
130
|
+
return false
|
|
131
|
+
end
|
|
132
|
+
|
|
133
|
+
eslint_only_pres = ESLINT_PREFIXES.map(&:downcase) - ANGULAR_PREFIXES
|
|
134
|
+
angular_only_pres = ANGULAR_PREFIXES - ESLINT_PREFIXES.map(&:downcase)
|
|
135
|
+
|
|
136
|
+
uses_eslint_only_pres =
|
|
137
|
+
recent_commit_messages.
|
|
138
|
+
any? { |m| eslint_only_pres.any? { |pre| m.match?(/#{pre}[:(]/i) } }
|
|
139
|
+
|
|
140
|
+
uses_angular_only_pres =
|
|
141
|
+
recent_commit_messages.
|
|
142
|
+
any? { |m| angular_only_pres.any? { |pre| m.match?(/#{pre}[:(]/i) } }
|
|
143
|
+
|
|
144
|
+
# If using any angular-only prefixes, return true
|
|
145
|
+
# (i.e., we assume Angular over ESLint when both are present)
|
|
146
|
+
return true if uses_angular_only_pres
|
|
147
|
+
return false if uses_eslint_only_pres
|
|
148
|
+
|
|
149
|
+
true
|
|
150
|
+
end
|
|
151
|
+
|
|
152
|
+
def using_eslint_commit_messages?
|
|
153
|
+
return false if recent_commit_messages.none?
|
|
154
|
+
|
|
155
|
+
semantic_messages = recent_commit_messages.select do |message|
|
|
156
|
+
ESLINT_PREFIXES.any? { |pre| message.start_with?(/#{pre}[:(]/) }
|
|
157
|
+
end
|
|
158
|
+
|
|
159
|
+
semantic_messages.count.to_f / recent_commit_messages.count > 0.3
|
|
160
|
+
end
|
|
161
|
+
|
|
162
|
+
def using_prefixed_commit_messages?
|
|
163
|
+
return false if using_gitmoji_commit_messages?
|
|
164
|
+
return false if recent_commit_messages.none?
|
|
165
|
+
|
|
166
|
+
prefixed_messages = recent_commit_messages.select do |message|
|
|
167
|
+
message.start_with?(/[a-z][^\s]+:/)
|
|
168
|
+
end
|
|
169
|
+
|
|
170
|
+
prefixed_messages.count.to_f / recent_commit_messages.count > 0.3
|
|
171
|
+
end
|
|
172
|
+
|
|
173
|
+
def angular_commit_prefix
|
|
174
|
+
raise "Not using angular commits!" unless using_angular_commit_messages?
|
|
175
|
+
|
|
176
|
+
recent_commits_using_chore =
|
|
177
|
+
recent_commit_messages.
|
|
178
|
+
any? { |msg| msg.start_with?("chore", "Chore") }
|
|
179
|
+
|
|
180
|
+
recent_commits_using_build =
|
|
181
|
+
recent_commit_messages.
|
|
182
|
+
any? { |msg| msg.start_with?("build", "Build") }
|
|
183
|
+
|
|
184
|
+
commit_prefix =
|
|
185
|
+
if recent_commits_using_chore && !recent_commits_using_build
|
|
186
|
+
"chore"
|
|
187
|
+
else
|
|
188
|
+
"build"
|
|
189
|
+
end
|
|
190
|
+
|
|
191
|
+
if capitalize_angular_commit_prefix?
|
|
192
|
+
commit_prefix = commit_prefix.capitalize
|
|
193
|
+
end
|
|
194
|
+
|
|
195
|
+
commit_prefix
|
|
196
|
+
end
|
|
197
|
+
|
|
198
|
+
def capitalize_angular_commit_prefix?
|
|
199
|
+
semantic_messages = recent_commit_messages.select do |message|
|
|
200
|
+
ANGULAR_PREFIXES.any? { |pre| message.match?(/#{pre}[:(]/i) }
|
|
201
|
+
end
|
|
202
|
+
|
|
203
|
+
if semantic_messages.none?
|
|
204
|
+
return last_dependabot_commit_message&.start_with?(/[A-Z]/)
|
|
205
|
+
end
|
|
206
|
+
|
|
207
|
+
capitalized_msgs = semantic_messages.
|
|
208
|
+
select { |m| m.start_with?(/[A-Z]/) }
|
|
209
|
+
capitalized_msgs.count.to_f / semantic_messages.count > 0.5
|
|
210
|
+
end
|
|
211
|
+
|
|
212
|
+
def using_gitmoji_commit_messages?
|
|
213
|
+
return false unless recent_commit_messages.any?
|
|
214
|
+
|
|
215
|
+
gitmoji_messages =
|
|
216
|
+
recent_commit_messages.
|
|
217
|
+
select { |m| GITMOJI_PREFIXES.any? { |pre| m.match?(/:#{pre}:/i) } }
|
|
218
|
+
|
|
219
|
+
gitmoji_messages.count / recent_commit_messages.count.to_f > 0.3
|
|
220
|
+
end
|
|
221
|
+
|
|
222
|
+
def recent_commit_messages
|
|
223
|
+
case source.provider
|
|
224
|
+
when "github" then recent_github_commit_messages
|
|
225
|
+
when "gitlab" then recent_gitlab_commit_messages
|
|
226
|
+
else raise "Unsupported provider: #{source.provider}"
|
|
227
|
+
end
|
|
228
|
+
end
|
|
229
|
+
|
|
230
|
+
def recent_github_commit_messages
|
|
231
|
+
recent_github_commits.
|
|
232
|
+
reject { |c| c.author&.type == "Bot" }.
|
|
233
|
+
reject { |c| c.commit&.message&.start_with?("Merge") }.
|
|
234
|
+
map(&:commit).
|
|
235
|
+
map(&:message).
|
|
236
|
+
compact.
|
|
237
|
+
map(&:strip)
|
|
238
|
+
end
|
|
239
|
+
|
|
240
|
+
def recent_gitlab_commit_messages
|
|
241
|
+
@recent_gitlab_commit_messages ||=
|
|
242
|
+
gitlab_client_for_source.commits(source.repo)
|
|
243
|
+
|
|
244
|
+
@recent_gitlab_commit_messages.
|
|
245
|
+
reject { |c| c.author_email == "support@dependabot.com" }.
|
|
246
|
+
reject { |c| c.message&.start_with?("merge !") }.
|
|
247
|
+
map(&:message).
|
|
248
|
+
compact.
|
|
249
|
+
map(&:strip)
|
|
250
|
+
end
|
|
251
|
+
|
|
252
|
+
def last_dependabot_commit_message
|
|
253
|
+
case source.provider
|
|
254
|
+
when "github" then last_github_dependabot_commit_message
|
|
255
|
+
when "gitlab" then last_gitlab_dependabot_commit_message
|
|
256
|
+
else raise "Unsupported provider: #{source.provider}"
|
|
257
|
+
end
|
|
258
|
+
end
|
|
259
|
+
|
|
260
|
+
def last_github_dependabot_commit_message
|
|
261
|
+
recent_github_commits.
|
|
262
|
+
reject { |c| c.commit&.message&.start_with?("Merge") }.
|
|
263
|
+
find { |c| c.commit.author&.name&.include?("dependabot") }&.
|
|
264
|
+
commit&.
|
|
265
|
+
message&.
|
|
266
|
+
strip
|
|
267
|
+
end
|
|
268
|
+
|
|
269
|
+
def recent_github_commits
|
|
270
|
+
@recent_github_commits ||=
|
|
271
|
+
github_client_for_source.commits(source.repo, per_page: 100)
|
|
272
|
+
rescue Octokit::Conflict
|
|
273
|
+
@recent_github_commits ||= []
|
|
274
|
+
end
|
|
275
|
+
|
|
276
|
+
def last_gitlab_dependabot_commit_message
|
|
277
|
+
@recent_gitlab_commit_messages ||=
|
|
278
|
+
gitlab_client_for_source.commits(source.repo)
|
|
279
|
+
|
|
280
|
+
@recent_gitlab_commit_messages.
|
|
281
|
+
find { |c| c.author_email == "support@dependabot.com" }&.
|
|
282
|
+
message&.
|
|
283
|
+
strip
|
|
284
|
+
end
|
|
285
|
+
|
|
286
|
+
def github_client_for_source
|
|
287
|
+
@github_client_for_source ||=
|
|
288
|
+
Dependabot::Clients::GithubWithRetries.for_source(
|
|
289
|
+
source: source,
|
|
290
|
+
credentials: credentials
|
|
291
|
+
)
|
|
292
|
+
end
|
|
293
|
+
|
|
294
|
+
def gitlab_client_for_source
|
|
295
|
+
@gitlab_client_for_source ||=
|
|
296
|
+
Dependabot::Clients::GitlabWithRetries.for_source(
|
|
297
|
+
source: source,
|
|
298
|
+
credentials: credentials
|
|
299
|
+
)
|
|
300
|
+
end
|
|
301
|
+
|
|
302
|
+
def package_manager
|
|
303
|
+
@package_manager ||= dependencies.first.package_manager
|
|
304
|
+
end
|
|
305
|
+
end
|
|
306
|
+
end
|
|
307
|
+
end
|
data/lib/dependabot/version.rb
CHANGED
metadata
CHANGED
|
@@ -1,14 +1,14 @@
|
|
|
1
1
|
--- !ruby/object:Gem::Specification
|
|
2
2
|
name: dependabot-common
|
|
3
3
|
version: !ruby/object:Gem::Version
|
|
4
|
-
version: 0.108.
|
|
4
|
+
version: 0.108.19
|
|
5
5
|
platform: ruby
|
|
6
6
|
authors:
|
|
7
7
|
- Dependabot
|
|
8
8
|
autorequire:
|
|
9
9
|
bindir: bin
|
|
10
10
|
cert_chain: []
|
|
11
|
-
date: 2019-06-
|
|
11
|
+
date: 2019-06-18 00:00:00.000000000 Z
|
|
12
12
|
dependencies:
|
|
13
13
|
- !ruby/object:Gem::Dependency
|
|
14
14
|
name: aws-sdk-ecr
|
|
@@ -346,6 +346,7 @@ files:
|
|
|
346
346
|
- lib/dependabot/pull_request_creator/message_builder.rb
|
|
347
347
|
- lib/dependabot/pull_request_creator/message_builder/issue_linker.rb
|
|
348
348
|
- lib/dependabot/pull_request_creator/message_builder/link_and_mention_sanitizer.rb
|
|
349
|
+
- lib/dependabot/pull_request_creator/pr_name_prefixer.rb
|
|
349
350
|
- lib/dependabot/pull_request_updater.rb
|
|
350
351
|
- lib/dependabot/pull_request_updater/github.rb
|
|
351
352
|
- lib/dependabot/security_advisory.rb
|