dependabot-common 0.119.1 → 0.119.6

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: 55d06a3a88c37d000b5380d1b1dcc12179e035967017f61ec7f310279836656a
4
- data.tar.gz: 3bdff5a073acdb9d4440319bf3120d20687417ec3b6f4287ec7358f349baaa0a
3
+ metadata.gz: ce4dd778f67c7a4f612edfbe2f1ef0bae78566f7c50a46212f0244745cf07da1
4
+ data.tar.gz: 46f644e4de54337eb399265827d754e6ba82477603e046f42c6d79924b32cb86
5
5
  SHA512:
6
- metadata.gz: 127a52768582e1e2e179ce49b95229d05b6b6d0c50a4991c131297cfc2ba126e2f82afb786dbd6da3222f567020f51da7273de336e489a88e703571c825f481d
7
- data.tar.gz: cef7b76143722481b5c9a034104e211493489fe5815d73ea83dd2f2db0415211d36b8b87ec865f0dd3e01549057eba986e52888621ca31d791ca32e25de38d5e
6
+ metadata.gz: 73958fe712b9b38885ec5591114943367adec8cdb77af7efd9a7069261512b2b50b77d7c578335bf87e5f89bef934102c099dd1ec4353ecd075e0924a56d74d8
7
+ data.tar.gz: 54e51527b3f98b0e2b722b1c2617344d4601fde8272986b02c60edc8e9b1525ccb1ea093efb18a02c259279f75cf3e7ce41d9d6e01641ccc3b675335c930026b
@@ -28,6 +28,7 @@ module Dependabot
28
28
  def initialize(source, credentials)
29
29
  @source = source
30
30
  @credentials = credentials
31
+ @auth_header = auth_header_for(credentials&.fetch("token", nil))
31
32
  end
32
33
 
33
34
  def fetch_commit(_repo, branch)
@@ -180,8 +181,9 @@ module Dependabot
180
181
  def get(url)
181
182
  response = Excon.get(
182
183
  url,
183
- user: credentials&.fetch("username"),
184
- password: credentials&.fetch("password"),
184
+ headers: auth_header,
185
+ user: credentials&.fetch("username", nil),
186
+ password: credentials&.fetch("password", nil),
185
187
  idempotent: true,
186
188
  **SharedHelpers.excon_defaults
187
189
  )
@@ -193,12 +195,14 @@ module Dependabot
193
195
  def post(url, json)
194
196
  response = Excon.post(
195
197
  url,
196
- headers: {
197
- "Content-Type" => "application/json"
198
- },
198
+ headers: auth_header.merge(
199
+ {
200
+ "Content-Type" => "application/json"
201
+ }
202
+ ),
199
203
  body: json,
200
- user: credentials&.fetch("username"),
201
- password: credentials&.fetch("password"),
204
+ user: credentials&.fetch("username", nil),
205
+ password: credentials&.fetch("password", nil),
202
206
  idempotent: true,
203
207
  **SharedHelpers.excon_defaults
204
208
  )
@@ -209,6 +213,21 @@ module Dependabot
209
213
 
210
214
  private
211
215
 
216
+ def auth_header_for(token)
217
+ return {} unless token
218
+
219
+ if token.include?(":")
220
+ encoded_token = Base64.encode64(token).delete("\n")
221
+ { "Authorization" => "Basic #{encoded_token}" }
222
+ elsif Base64.decode64(token).ascii_only? &&
223
+ Base64.decode64(token).include?(":")
224
+ { "Authorization" => "Basic #{token.delete("\n")}" }
225
+ else
226
+ { "Authorization" => "Bearer #{token}" }
227
+ end
228
+ end
229
+
230
+ attr_reader :auth_header
212
231
  attr_reader :credentials
213
232
  attr_reader :source
214
233
  end
@@ -60,7 +60,6 @@ module Dependabot
60
60
  dependencies.find { |d| d.name&.downcase == name&.downcase }
61
61
  end
62
62
 
63
- # rubocop:disable Metrics/PerceivedComplexity
64
63
  def combined_dependency(old_dep, new_dep)
65
64
  package_manager = old_dep.package_manager
66
65
  v_cls = Utils.version_class_for_package_manager(package_manager)
@@ -89,8 +88,6 @@ module Dependabot
89
88
  subdependency_metadata: subdependency_metadata
90
89
  )
91
90
  end
92
-
93
- # rubocop:enable Metrics/PerceivedComplexity
94
91
  end
95
92
  end
96
93
  end
@@ -86,6 +86,7 @@ module Dependabot
86
86
  raise Dependabot::GitDependencyReferenceNotFound, dependency.name
87
87
  end
88
88
 
89
+ # rubocop:disable Metrics/PerceivedComplexity
89
90
  def local_tag_for_latest_version
90
91
  tags =
91
92
  local_tags.
@@ -114,6 +115,7 @@ module Dependabot
114
115
  tag_sha: tag.tag_sha
115
116
  }
116
117
  end
118
+ # rubocop:enable Metrics/PerceivedComplexity
117
119
 
118
120
  def git_repo_reachable?
119
121
  local_upload_pack
@@ -143,6 +143,7 @@ module Dependabot
143
143
  select_best_changelog(files)
144
144
  end
145
145
 
146
+ # rubocop:disable Metrics/PerceivedComplexity
146
147
  def select_best_changelog(files)
147
148
  CHANGELOG_NAMES.each do |name|
148
149
  candidates = files.select { |f| f.name =~ /#{name}/i }
@@ -163,6 +164,7 @@ module Dependabot
163
164
 
164
165
  nil
165
166
  end
167
+ # rubocop:enable Metrics/PerceivedComplexity
166
168
 
167
169
  def tag_for_new_version
168
170
  @tag_for_new_version ||=
@@ -21,7 +21,6 @@ module Dependabot
21
21
  !old_version_changelog_line.nil?
22
22
  end
23
23
 
24
- # rubocop:disable Metrics/PerceivedComplexity
25
24
  def pruned_text
26
25
  changelog_lines = changelog_text.split("\n")
27
26
 
@@ -51,7 +50,6 @@ module Dependabot
51
50
 
52
51
  changelog_lines.slice(slice_range).join("\n").sub(/\n*\z/, "")
53
52
  end
54
- # rubocop:enable Metrics/PerceivedComplexity
55
53
 
56
54
  private
57
55
 
@@ -116,7 +116,6 @@ module Dependabot
116
116
  gsub(",", "-and-")
117
117
  end
118
118
 
119
- # rubocop:disable Metrics/PerceivedComplexity
120
119
  def new_version(dependency)
121
120
  # Version looks like a git SHA and we could be updating to a specific
122
121
  # ref in which case we return that otherwise we return a shorthand sha
@@ -135,7 +134,6 @@ module Dependabot
135
134
  dependency.version
136
135
  end
137
136
  end
138
- # rubocop:enable Metrics/PerceivedComplexity
139
137
 
140
138
  def previous_ref(dependency)
141
139
  previous_refs = dependency.previous_requirements.map do |r|
@@ -51,6 +51,7 @@ module Dependabot
51
51
  @require_up_to_date_base
52
52
  end
53
53
 
54
+ # rubocop:disable Metrics/PerceivedComplexity
54
55
  def branch_exists?(name)
55
56
  git_metadata_fetcher.ref_names.include?(name)
56
57
  rescue Dependabot::GitDependenciesNotReachable => e
@@ -66,6 +67,7 @@ module Dependabot
66
67
  retrying = true
67
68
  retry
68
69
  end
70
+ # rubocop:enable Metrics/PerceivedComplexity
69
71
 
70
72
  def unmerged_pull_request_exists?
71
73
  pull_requests_for_branch.reject(&:merged).any?
@@ -113,6 +113,7 @@ module Dependabot
113
113
  end.min
114
114
  end
115
115
 
116
+ # rubocop:disable Metrics/PerceivedComplexity
116
117
  def version(dep)
117
118
  return dep.version if version_class.correct?(dep.version)
118
119
 
@@ -127,7 +128,9 @@ module Dependabot
127
128
 
128
129
  version_from_ref
129
130
  end
131
+ # rubocop:enable Metrics/PerceivedComplexity
130
132
 
133
+ # rubocop:disable Metrics/PerceivedComplexity
131
134
  def previous_version(dep)
132
135
  version_str = dep.previous_version
133
136
  return version_str if version_class.correct?(version_str)
@@ -144,6 +147,7 @@ module Dependabot
144
147
 
145
148
  version_from_ref
146
149
  end
150
+ # rubocop:enable Metrics/PerceivedComplexity
147
151
 
148
152
  def create_default_dependencies_label_if_required
149
153
  return if custom_labels
@@ -10,6 +10,7 @@ require "dependabot/pull_request_creator"
10
10
  module Dependabot
11
11
  class PullRequestCreator
12
12
  class MessageBuilder
13
+ require_relative "message_builder/metadata_presenter"
13
14
  require_relative "message_builder/issue_linker"
14
15
  require_relative "message_builder/link_and_mention_sanitizer"
15
16
  require_relative "pr_name_prefixer"
@@ -312,240 +313,38 @@ module Dependabot
312
313
  end.join
313
314
  end
314
315
 
315
- def metadata_cascades_for_dep(dep)
316
- break_tag = source_provider_supports_html? ? "\n<br />" : "\n\n"
317
-
318
- msg = ""
319
- msg += vulnerabilities_cascade(dep)
320
- msg += release_cascade(dep)
321
- msg += changelog_cascade(dep)
322
- msg += upgrade_guide_cascade(dep)
323
- msg += commits_cascade(dep)
324
- msg += maintainer_changes_cascade(dep)
325
- msg += break_tag unless msg == ""
326
- "\n" + sanitize_links_and_mentions(msg, unsafe: true)
327
- end
328
-
329
- def vulnerabilities_cascade(dep)
330
- fixed_vulns = vulnerabilities_fixed[dep.name]
331
- return "" unless fixed_vulns&.any?
332
-
333
- msg = ""
334
- fixed_vulns.each { |v| msg += serialized_vulnerability_details(v) }
335
- msg = sanitize_template_tags(msg)
336
- msg = sanitize_links_and_mentions(msg)
337
-
338
- build_details_tag(summary: "Vulnerabilities fixed", body: msg)
339
- end
340
-
341
- def release_cascade(dep)
342
- return "" unless releases_text(dep) && releases_url(dep)
343
-
344
- msg = "*Sourced from [#{dep.display_name}'s releases]"\
345
- "(#{releases_url(dep)}).*\n\n"
346
- msg +=
347
- begin
348
- release_note_lines = releases_text(dep).split("\n").first(50)
349
- release_note_lines = release_note_lines.map { |line| "> #{line}\n" }
350
- if release_note_lines.count == 50
351
- release_note_lines << truncated_line
352
- end
353
- release_note_lines.join
354
- end
355
- msg = link_issues(text: msg, dependency: dep)
356
- msg = fix_relative_links(
357
- text: msg,
358
- base_url: source_url(dep) + "/blob/HEAD/"
359
- )
360
- msg = sanitize_template_tags(msg)
361
- msg = sanitize_links_and_mentions(msg)
362
-
363
- build_details_tag(summary: "Release notes", body: msg)
364
- end
365
-
366
- def changelog_cascade(dep)
367
- return "" unless changelog_url(dep) && changelog_text(dep)
368
-
369
- msg = "*Sourced from "\
370
- "[#{dep.display_name}'s changelog](#{changelog_url(dep)}).*\n\n"
371
- msg +=
372
- begin
373
- changelog_lines = changelog_text(dep).split("\n").first(50)
374
- changelog_lines = changelog_lines.map { |line| "> #{line}\n" }
375
- changelog_lines << truncated_line if changelog_lines.count == 50
376
- changelog_lines.join
377
- end
378
- msg = link_issues(text: msg, dependency: dep)
379
- msg = fix_relative_links(text: msg, base_url: changelog_url(dep))
380
- msg = sanitize_template_tags(msg)
381
- msg = sanitize_links_and_mentions(msg)
382
-
383
- build_details_tag(summary: "Changelog", body: msg)
384
- end
385
-
386
- def upgrade_guide_cascade(dep)
387
- return "" unless upgrade_url(dep) && upgrade_text(dep)
388
-
389
- msg = "*Sourced from "\
390
- "[#{dep.display_name}'s upgrade guide]"\
391
- "(#{upgrade_url(dep)}).*\n\n"
392
- msg +=
393
- begin
394
- upgrade_lines = upgrade_text(dep).split("\n").first(50)
395
- upgrade_lines = upgrade_lines.map { |line| "> #{line}\n" }
396
- upgrade_lines << truncated_line if upgrade_lines.count == 50
397
- upgrade_lines.join
398
- end
399
- msg = link_issues(text: msg, dependency: dep)
400
- msg = fix_relative_links(text: msg, base_url: upgrade_url(dep))
401
- msg = sanitize_template_tags(msg)
402
- msg = sanitize_links_and_mentions(msg)
403
-
404
- build_details_tag(summary: "Upgrade guide", body: msg)
405
- end
406
-
407
- def commits_cascade(dep)
408
- return "" unless commits_url(dep) && commits(dep)
409
-
410
- msg = ""
411
-
412
- commits(dep).reverse.first(10).each do |commit|
413
- title = commit[:message].strip.split("\n").first
414
- title = title.slice(0..76) + "..." if title && title.length > 80
415
- title = title&.gsub(/(?<=[^\w.-])([_*`~])/, '\\1')
416
- sha = commit[:sha][0, 7]
417
- msg += "- [`#{sha}`](#{commit[:html_url]}) #{title}\n"
418
- end
419
-
420
- msg = msg.gsub(/\<.*?\>/) { |tag| "\\#{tag}" }
421
-
422
- msg +=
423
- if commits(dep).count > 10
424
- "- Additional commits viewable in "\
425
- "[compare view](#{commits_url(dep)})\n"
426
- else
427
- "- See full diff in [compare view](#{commits_url(dep)})\n"
428
- end
429
- msg = link_issues(text: msg, dependency: dep)
430
- msg = sanitize_links_and_mentions(msg)
431
-
432
- build_details_tag(summary: "Commits", body: msg)
433
- end
434
-
435
- def maintainer_changes_cascade(dep)
436
- return "" unless maintainer_changes(dep)
437
-
438
- build_details_tag(
439
- summary: "Maintainer changes",
440
- body: sanitize_links_and_mentions(maintainer_changes(dep)) + "\n"
441
- )
442
- end
443
-
444
- def build_details_tag(summary:, body:)
445
- # Azure DevOps does not support <details> tag (https://developercommunity.visualstudio.com/content/problem/608769/add-support-for-in-markdown.html)
446
- # CodeCommit does not support the <details> tag (no url available)
447
- if source_provider_supports_html?
448
- msg = "<details>\n<summary>#{summary}</summary>\n\n"
449
- msg += body
450
- msg + "</details>\n"
451
- else
452
- "\n\##{summary}\n\n#{body}"
453
- end
454
- end
455
-
456
- def source_provider_supports_html?
457
- !%w(azure codecommit).include?(source.provider)
458
- end
459
-
460
- def serialized_vulnerability_details(details)
461
- msg = vulnerability_source_line(details)
462
-
463
- if details["title"]
464
- msg += "> **#{details['title'].lines.map(&:strip).join(' ')}**\n"
465
- end
466
-
467
- if (description = details["description"])
468
- description.strip.lines.first(20).each { |line| msg += "> #{line}" }
469
- msg += truncated_line if description.strip.lines.count > 20
470
- end
471
-
472
- msg += "\n" unless msg.end_with?("\n")
473
- msg += "> \n"
474
- msg += vulnerability_version_range_lines(details)
475
- msg + "\n"
476
- end
477
-
478
- def vulnerability_source_line(details)
479
- if details["source_url"] && details["source_name"]
480
- "*Sourced from [#{details['source_name']}]"\
481
- "(#{details['source_url']}).*\n\n"
482
- elsif details["source_name"]
483
- "*Sourced from #{details['source_name']}.*\n\n"
484
- else
485
- ""
486
- end
487
- end
488
-
489
- def vulnerability_version_range_lines(details)
490
- msg = ""
491
- %w(patched_versions unaffected_versions affected_versions).each do |tp|
492
- type = tp.split("_").first.capitalize
493
- next unless details[tp]
494
-
495
- versions_string = details[tp].any? ? details[tp].join("; ") : "none"
496
- versions_string = versions_string.gsub(/(?<!\\)~/, '\~')
497
- msg += "> #{type} versions: #{versions_string}\n"
498
- end
499
- msg
500
- end
501
-
502
- def truncated_line
503
- # Tables can spill out of truncated details, so we close them
504
- "></tr></table> ... (truncated)\n"
505
- end
506
-
507
- def releases_url(dependency)
508
- metadata_finder(dependency).releases_url
509
- end
510
-
511
- def releases_text(dependency)
512
- metadata_finder(dependency).releases_text
316
+ def metadata_cascades_for_dep(dependency)
317
+ MetadataPresenter.new(
318
+ dependency: dependency,
319
+ source: source,
320
+ metadata_finder: metadata_finder(dependency),
321
+ vulnerabilities_fixed: vulnerabilities_fixed[dependency.name],
322
+ github_redirection_service: github_redirection_service
323
+ ).to_s
513
324
  end
514
325
 
515
326
  def changelog_url(dependency)
516
327
  metadata_finder(dependency).changelog_url
517
328
  end
518
329
 
519
- def changelog_text(dependency)
520
- metadata_finder(dependency).changelog_text
521
- end
522
-
523
- def upgrade_url(dependency)
524
- metadata_finder(dependency).upgrade_guide_url
525
- end
526
-
527
- def upgrade_text(dependency)
528
- metadata_finder(dependency).upgrade_guide_text
529
- end
530
-
531
330
  def commits_url(dependency)
532
331
  metadata_finder(dependency).commits_url
533
332
  end
534
333
 
535
- def commits(dependency)
536
- metadata_finder(dependency).commits
334
+ def homepage_url(dependency)
335
+ metadata_finder(dependency).homepage_url
537
336
  end
538
337
 
539
- def maintainer_changes(dependency)
540
- metadata_finder(dependency).maintainer_changes
338
+ def releases_url(dependency)
339
+ metadata_finder(dependency).releases_url
541
340
  end
542
341
 
543
342
  def source_url(dependency)
544
343
  metadata_finder(dependency).source_url
545
344
  end
546
345
 
547
- def homepage_url(dependency)
548
- metadata_finder(dependency).homepage_url
346
+ def upgrade_url(dependency)
347
+ metadata_finder(dependency).upgrade_guide_url
549
348
  end
550
349
 
551
350
  def metadata_finder(dependency)
@@ -567,7 +366,6 @@ module Dependabot
567
366
  )
568
367
  end
569
368
 
570
- # rubocop:disable Metrics/PerceivedComplexity
571
369
  def previous_version(dependency)
572
370
  # If we don't have a previous version, we *may* still be able to figure
573
371
  # one out if a ref was provided and has been changed (in which case the
@@ -590,7 +388,6 @@ module Dependabot
590
388
  dependency.previous_version
591
389
  end
592
390
  end
593
- # rubocop:enable Metrics/PerceivedComplexity
594
391
 
595
392
  def new_version(dependency)
596
393
  if dependency.version.match?(/^[0-9a-f]{40}$/)
@@ -658,48 +455,6 @@ module Dependabot
658
455
  raise "No new requirement!"
659
456
  end
660
457
 
661
- def link_issues(text:, dependency:)
662
- IssueLinker.
663
- new(source_url: source_url(dependency)).
664
- link_issues(text: text)
665
- end
666
-
667
- def fix_relative_links(text:, base_url:)
668
- text.gsub(/\[.*?\]\([^)]+\)/) do |link|
669
- next link if link.include?("://")
670
-
671
- relative_path = link.match(/\((.*?)\)/).captures.last
672
- base = base_url.split("://").last.gsub(%r{[^/]*$}, "")
673
- path = File.join(base, relative_path)
674
- absolute_path =
675
- base_url.sub(
676
- %r{(?<=://).*$},
677
- Pathname.new(path).cleanpath.to_s
678
- )
679
- link.gsub(relative_path, absolute_path)
680
- end
681
- end
682
-
683
- def sanitize_links_and_mentions(text, unsafe: false)
684
- return text unless source.provider == "github"
685
-
686
- LinkAndMentionSanitizer.
687
- new(github_redirection_service: github_redirection_service).
688
- sanitize_links_and_mentions(text: text, unsafe: unsafe)
689
- end
690
-
691
- def sanitize_template_tags(text)
692
- text.gsub(/\<.*?\>/) do |tag|
693
- tag_contents = tag.match(/\<(.*?)\>/).captures.first.strip
694
-
695
- # Unclosed calls to template overflow out of the blockquote block,
696
- # wrecking the rest of our PRs. Other tags don't share this problem.
697
- next "\\#{tag}" if tag_contents.start_with?("template")
698
-
699
- tag
700
- end
701
- end
702
-
703
458
  def ref_changed?(dependency)
704
459
  previous_ref(dependency) != new_ref(dependency)
705
460
  end
@@ -58,7 +58,6 @@ module Dependabot
58
58
  end
59
59
  end
60
60
 
61
- # rubocop:disable Metrics/PerceivedComplexity
62
61
  def sanitize_links(doc)
63
62
  doc.walk do |node|
64
63
  if node.type == :link && node.url.match?(GITHUB_REF_REGEX)
@@ -81,7 +80,6 @@ module Dependabot
81
80
  end
82
81
  end
83
82
  end
84
- # rubocop:enable Metrics/PerceivedComplexity
85
83
 
86
84
  def replace_github_host(text)
87
85
  text.gsub(
@@ -0,0 +1,270 @@
1
+ # frozen_string_literal: true
2
+
3
+ require "dependabot/pull_request_creator/message_builder"
4
+
5
+ module Dependabot
6
+ class PullRequestCreator
7
+ class MessageBuilder
8
+ class MetadataPresenter
9
+ extend Forwardable
10
+
11
+ attr_reader :dependency, :source, :metadata_finder,
12
+ :vulnerabilities_fixed, :github_redirection_service
13
+
14
+ def_delegators :metadata_finder,
15
+ :changelog_url,
16
+ :changelog_text,
17
+ :commits_url,
18
+ :commits,
19
+ :maintainer_changes,
20
+ :releases_url,
21
+ :releases_text,
22
+ :source_url,
23
+ :upgrade_guide_url,
24
+ :upgrade_guide_text
25
+
26
+ def initialize(dependency:, source:, metadata_finder:,
27
+ vulnerabilities_fixed:, github_redirection_service:)
28
+ @dependency = dependency
29
+ @source = source
30
+ @metadata_finder = metadata_finder
31
+ @vulnerabilities_fixed = vulnerabilities_fixed
32
+ @github_redirection_service = github_redirection_service
33
+ end
34
+
35
+ def to_s
36
+ msg = ""
37
+ msg += vulnerabilities_cascade
38
+ msg += release_cascade
39
+ msg += changelog_cascade
40
+ msg += upgrade_guide_cascade
41
+ msg += commits_cascade
42
+ msg += maintainer_changes_cascade
43
+ msg += break_tag unless msg == ""
44
+ "\n" + sanitize_links_and_mentions(msg, unsafe: true)
45
+ end
46
+
47
+ private
48
+
49
+ def vulnerabilities_cascade
50
+ return "" unless vulnerabilities_fixed&.any?
51
+
52
+ msg = ""
53
+ vulnerabilities_fixed.each do |v|
54
+ msg += serialized_vulnerability_details(v)
55
+ end
56
+
57
+ msg = sanitize_template_tags(msg)
58
+ msg = sanitize_links_and_mentions(msg)
59
+
60
+ build_details_tag(summary: "Vulnerabilities fixed", body: msg)
61
+ end
62
+
63
+ def release_cascade
64
+ return "" unless releases_text && releases_url
65
+
66
+ msg = "*Sourced from [#{dependency.display_name}'s releases]"\
67
+ "(#{releases_url}).*\n\n"
68
+ msg += quote_and_truncate(releases_text)
69
+ msg = link_issues(text: msg)
70
+ msg = fix_relative_links(
71
+ text: msg,
72
+ base_url: source_url + "/blob/HEAD/"
73
+ )
74
+ msg = sanitize_template_tags(msg)
75
+ msg = sanitize_links_and_mentions(msg)
76
+
77
+ build_details_tag(summary: "Release notes", body: msg)
78
+ end
79
+
80
+ def changelog_cascade
81
+ return "" unless changelog_url && changelog_text
82
+
83
+ msg = "*Sourced from "\
84
+ "[#{dependency.display_name}'s changelog]"\
85
+ "(#{changelog_url}).*\n\n"
86
+ msg += quote_and_truncate(changelog_text)
87
+ msg = link_issues(text: msg)
88
+ msg = fix_relative_links(text: msg, base_url: changelog_url)
89
+ msg = sanitize_template_tags(msg)
90
+ msg = sanitize_links_and_mentions(msg)
91
+
92
+ build_details_tag(summary: "Changelog", body: msg)
93
+ end
94
+
95
+ def upgrade_guide_cascade
96
+ return "" unless upgrade_guide_url && upgrade_guide_text
97
+
98
+ msg = "*Sourced from "\
99
+ "[#{dependency.display_name}'s upgrade guide]"\
100
+ "(#{upgrade_guide_url}).*\n\n"
101
+ msg += quote_and_truncate(upgrade_guide_text)
102
+ msg = link_issues(text: msg)
103
+ msg = fix_relative_links(text: msg, base_url: upgrade_guide_url)
104
+ msg = sanitize_template_tags(msg)
105
+ msg = sanitize_links_and_mentions(msg)
106
+
107
+ build_details_tag(summary: "Upgrade guide", body: msg)
108
+ end
109
+
110
+ def commits_cascade
111
+ return "" unless commits_url && commits
112
+
113
+ msg = ""
114
+
115
+ commits.reverse.first(10).each do |commit|
116
+ title = commit[:message].strip.split("\n").first
117
+ title = title.slice(0..76) + "..." if title && title.length > 80
118
+ title = title&.gsub(/(?<=[^\w.-])([_*`~])/, '\\1')
119
+ sha = commit[:sha][0, 7]
120
+ msg += "- [`#{sha}`](#{commit[:html_url]}) #{title}\n"
121
+ end
122
+
123
+ msg = msg.gsub(/\<.*?\>/) { |tag| "\\#{tag}" }
124
+
125
+ msg +=
126
+ if commits.count > 10
127
+ "- Additional commits viewable in "\
128
+ "[compare view](#{commits_url})\n"
129
+ else
130
+ "- See full diff in [compare view](#{commits_url})\n"
131
+ end
132
+ msg = link_issues(text: msg)
133
+ msg = sanitize_links_and_mentions(msg)
134
+
135
+ build_details_tag(summary: "Commits", body: msg)
136
+ end
137
+
138
+ def maintainer_changes_cascade
139
+ return "" unless maintainer_changes
140
+
141
+ build_details_tag(
142
+ summary: "Maintainer changes",
143
+ body: sanitize_links_and_mentions(maintainer_changes) + "\n"
144
+ )
145
+ end
146
+
147
+ def build_details_tag(summary:, body:)
148
+ # Azure DevOps does not support <details> tag (https://developercommunity.visualstudio.com/content/problem/608769/add-support-for-in-markdown.html)
149
+ # CodeCommit does not support the <details> tag (no url available)
150
+ if source_provider_supports_html?
151
+ msg = "<details>\n<summary>#{summary}</summary>\n\n"
152
+ msg += body
153
+ msg + "</details>\n"
154
+ else
155
+ "\n\##{summary}\n\n#{body}"
156
+ end
157
+ end
158
+
159
+ def serialized_vulnerability_details(details)
160
+ msg = vulnerability_source_line(details)
161
+
162
+ if details["title"]
163
+ msg += "> **#{details['title'].lines.map(&:strip).join(' ')}**\n"
164
+ end
165
+
166
+ if (description = details["description"])
167
+ description.strip.lines.first(20).each { |line| msg += "> #{line}" }
168
+ msg += truncated_line if description.strip.lines.count > 20
169
+ end
170
+
171
+ msg += "\n" unless msg.end_with?("\n")
172
+ msg += "> \n"
173
+ msg += vulnerability_version_range_lines(details)
174
+ msg + "\n"
175
+ end
176
+
177
+ def vulnerability_source_line(details)
178
+ if details["source_url"] && details["source_name"]
179
+ "*Sourced from [#{details['source_name']}]"\
180
+ "(#{details['source_url']}).*\n\n"
181
+ elsif details["source_name"]
182
+ "*Sourced from #{details['source_name']}.*\n\n"
183
+ else
184
+ ""
185
+ end
186
+ end
187
+
188
+ def vulnerability_version_range_lines(details)
189
+ msg = ""
190
+ %w(
191
+ patched_versions
192
+ unaffected_versions
193
+ affected_versions
194
+ ).each do |tp|
195
+ type = tp.split("_").first.capitalize
196
+ next unless details[tp]
197
+
198
+ versions_string = details[tp].any? ? details[tp].join("; ") : "none"
199
+ versions_string = versions_string.gsub(/(?<!\\)~/, '\~')
200
+ msg += "> #{type} versions: #{versions_string}\n"
201
+ end
202
+ msg
203
+ end
204
+
205
+ def link_issues(text:)
206
+ IssueLinker.
207
+ new(source_url: source_url).
208
+ link_issues(text: text)
209
+ end
210
+
211
+ def fix_relative_links(text:, base_url:)
212
+ text.gsub(/\[.*?\]\([^)]+\)/) do |link|
213
+ next link if link.include?("://")
214
+
215
+ relative_path = link.match(/\((.*?)\)/).captures.last
216
+ base = base_url.split("://").last.gsub(%r{[^/]*$}, "")
217
+ path = File.join(base, relative_path)
218
+ absolute_path =
219
+ base_url.sub(
220
+ %r{(?<=://).*$},
221
+ Pathname.new(path).cleanpath.to_s
222
+ )
223
+ link.gsub(relative_path, absolute_path)
224
+ end
225
+ end
226
+
227
+ def quote_and_truncate(text, limit: 50)
228
+ lines = text.split("\n")
229
+ lines.first(limit).tap do |limited_lines|
230
+ limited_lines.map! { |line| "> #{line}\n" }
231
+ limited_lines << truncated_line if lines.count > limit
232
+ end.join
233
+ end
234
+
235
+ def truncated_line
236
+ # Tables can spill out of truncated details, so we close them
237
+ "></tr></table> \n ... (truncated)\n"
238
+ end
239
+
240
+ def break_tag
241
+ source_provider_supports_html? ? "\n<br />" : "\n\n"
242
+ end
243
+
244
+ def source_provider_supports_html?
245
+ !%w(azure codecommit).include?(source.provider)
246
+ end
247
+
248
+ def sanitize_links_and_mentions(text, unsafe: false)
249
+ return text unless source.provider == "github"
250
+
251
+ LinkAndMentionSanitizer.
252
+ new(github_redirection_service: github_redirection_service).
253
+ sanitize_links_and_mentions(text: text, unsafe: unsafe)
254
+ end
255
+
256
+ def sanitize_template_tags(text)
257
+ text.gsub(/\<.*?\>/) do |tag|
258
+ tag_contents = tag.match(/\<(.*?)\>/).captures.first.strip
259
+
260
+ # Unclosed calls to template overflow out of the blockquote block,
261
+ # wrecking the rest of our PRs. Other tags don't share this problem.
262
+ next "\\#{tag}" if tag_contents.start_with?("template")
263
+
264
+ tag
265
+ end
266
+ end
267
+ end
268
+ end
269
+ end
270
+ end
@@ -172,6 +172,7 @@ module Dependabot
172
172
  last_dependabot_commit_message&.split(/[:(]/)&.first
173
173
  end
174
174
 
175
+ # rubocop:disable Metrics/PerceivedComplexity
175
176
  def using_angular_commit_messages?
176
177
  return false if recent_commit_messages.none?
177
178
 
@@ -202,6 +203,7 @@ module Dependabot
202
203
 
203
204
  true
204
205
  end
206
+ # rubocop:enable Metrics/PerceivedComplexity
205
207
 
206
208
  def using_eslint_commit_messages?
207
209
  return false if recent_commit_messages.none?
@@ -178,6 +178,7 @@ module Dependabot
178
178
  )
179
179
  end
180
180
 
181
+ # rubocop:disable Metrics/PerceivedComplexity
181
182
  def self.configure_git_credentials(credentials)
182
183
  # Then add a file-based credential store that loads a file in this repo.
183
184
  # Under the hood this uses git credential-store, but it's invoked through
@@ -221,6 +222,7 @@ module Dependabot
221
222
  # Save the file
222
223
  File.write("git.store", git_store_content)
223
224
  end
225
+ # rubocop:enable Metrics/PerceivedComplexity
224
226
 
225
227
  def self.reset_git_repo(path)
226
228
  Dir.chdir(path) do
@@ -1,5 +1,5 @@
1
1
  # frozen_string_literal: true
2
2
 
3
3
  module Dependabot
4
- VERSION = "0.119.1"
4
+ VERSION = "0.119.6"
5
5
  end
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.119.1
4
+ version: 0.119.6
5
5
  platform: ruby
6
6
  authors:
7
7
  - Dependabot
8
8
  autorequire:
9
9
  bindir: bin
10
10
  cert_chain: []
11
- date: 2020-08-28 00:00:00.000000000 Z
11
+ date: 2020-09-21 00:00:00.000000000 Z
12
12
  dependencies:
13
13
  - !ruby/object:Gem::Dependency
14
14
  name: aws-sdk-codecommit
@@ -292,14 +292,14 @@ dependencies:
292
292
  requirements:
293
293
  - - "~>"
294
294
  - !ruby/object:Gem::Version
295
- version: 0.88.0
295
+ version: 0.90.0
296
296
  type: :development
297
297
  prerelease: false
298
298
  version_requirements: !ruby/object:Gem::Requirement
299
299
  requirements:
300
300
  - - "~>"
301
301
  - !ruby/object:Gem::Version
302
- version: 0.88.0
302
+ version: 0.90.0
303
303
  - !ruby/object:Gem::Dependency
304
304
  name: vcr
305
305
  requirement: !ruby/object:Gem::Requirement
@@ -376,6 +376,7 @@ files:
376
376
  - lib/dependabot/pull_request_creator/message_builder.rb
377
377
  - lib/dependabot/pull_request_creator/message_builder/issue_linker.rb
378
378
  - lib/dependabot/pull_request_creator/message_builder/link_and_mention_sanitizer.rb
379
+ - lib/dependabot/pull_request_creator/message_builder/metadata_presenter.rb
379
380
  - lib/dependabot/pull_request_creator/pr_name_prefixer.rb
380
381
  - lib/dependabot/pull_request_updater.rb
381
382
  - lib/dependabot/pull_request_updater/github.rb