dependabot-common 0.212.0 → 0.213.0

Sign up to get free protection for your applications and to get access to all the features.
@@ -1,20 +1,23 @@
1
1
  # frozen_string_literal: true
2
2
 
3
+ require "digest"
4
+
3
5
  require "dependabot/metadata_finders"
4
6
  require "dependabot/pull_request_creator"
5
7
 
6
8
  module Dependabot
7
9
  class PullRequestCreator
8
10
  class BranchNamer
9
- attr_reader :dependencies, :files, :target_branch, :separator, :prefix
11
+ attr_reader :dependencies, :files, :target_branch, :separator, :prefix, :max_length
10
12
 
11
13
  def initialize(dependencies:, files:, target_branch:, separator: "/",
12
- prefix: "dependabot")
14
+ prefix: "dependabot", max_length: nil)
13
15
  @dependencies = dependencies
14
16
  @files = files
15
17
  @target_branch = target_branch
16
18
  @separator = separator
17
19
  @prefix = prefix
20
+ @max_length = max_length
18
21
  end
19
22
 
20
23
  def new_branch_name
@@ -37,7 +40,15 @@ module Dependabot
37
40
  end
38
41
 
39
42
  # Some users need branch names without slashes
40
- sanitize_ref(File.join(prefixes, @name).gsub("/", separator))
43
+ sanitized_name = sanitize_ref(File.join(prefixes, @name).gsub("/", separator))
44
+
45
+ # Shorten the ref in case users refs have length limits
46
+ if @max_length && (sanitized_name.length > @max_length)
47
+ sha = Digest::SHA1.hexdigest(sanitized_name)[0, @max_length]
48
+ sanitized_name[[@max_length - sha.size, 0].max..] = sha
49
+ end
50
+
51
+ sanitized_name
41
52
  end
42
53
 
43
54
  private
@@ -181,7 +192,7 @@ module Dependabot
181
192
 
182
193
  def sanitize_ref(ref)
183
194
  # This isn't a complete implementation of git's ref validation, but it
184
- # covers most cases that crop up. Its list of allowed charactersr is a
195
+ # covers most cases that crop up. Its list of allowed characters is a
185
196
  # bit stricter than git's, but that's for cosmetic reasons.
186
197
  ref.
187
198
  # Remove forbidden characters (those not already replaced elsewhere)
@@ -5,7 +5,7 @@ require "dependabot/pull_request_creator"
5
5
  module Dependabot
6
6
  class PullRequestCreator
7
7
  class Labeler
8
- DEPENDENCIES_LABEL_REGEX = %r{^[^/]*dependenc[^/]+$}i.freeze
8
+ DEPENDENCIES_LABEL_REGEX = %r{^[^/]*dependenc[^/]+$}i
9
9
  DEFAULT_DEPENDENCIES_LABEL = "dependencies"
10
10
  DEFAULT_SECURITY_LABEL = "security"
11
11
 
@@ -271,7 +271,7 @@ module Dependabot
271
271
  end
272
272
 
273
273
  def fetch_azure_labels
274
- langauge_name =
274
+ language_name =
275
275
  self.class.label_details_for_package_manager(package_manager).
276
276
  fetch(:name)
277
277
 
@@ -279,7 +279,7 @@ module Dependabot
279
279
  *@labels,
280
280
  DEFAULT_DEPENDENCIES_LABEL,
281
281
  DEFAULT_SECURITY_LABEL,
282
- langauge_name
282
+ language_name
283
283
  ].uniq
284
284
  end
285
285
 
@@ -374,16 +374,16 @@ module Dependabot
374
374
  end
375
375
 
376
376
  def create_gitlab_language_label
377
- langauge_name =
377
+ language_name =
378
378
  self.class.label_details_for_package_manager(package_manager).
379
379
  fetch(:name)
380
380
  gitlab_client_for_source.create_label(
381
381
  source.repo,
382
- langauge_name,
382
+ language_name,
383
383
  "#" + self.class.label_details_for_package_manager(package_manager).
384
384
  fetch(:colour)
385
385
  )
386
- @labels = [*@labels, langauge_name].uniq
386
+ @labels = [*@labels, language_name].uniq
387
387
  end
388
388
 
389
389
  def github_client_for_source
@@ -6,15 +6,15 @@ module Dependabot
6
6
  class PullRequestCreator
7
7
  class MessageBuilder
8
8
  class IssueLinker
9
- REPO_REGEX = %r{(?<repo>[\w.-]+/(?:(?!\.git|\.\s)[\w.-])+)}.freeze
10
- TAG_REGEX = /(?<tag>(?:\#|GH-)\d+)/i.freeze
9
+ REPO_REGEX = %r{(?<repo>[\w.-]+/(?:(?!\.git|\.\s)[\w.-])+)}
10
+ TAG_REGEX = /(?<tag>(?:\#|GH-)\d+)/i
11
11
  ISSUE_LINK_REGEXS = [
12
12
  /
13
13
  (?:(?<=[^A-Za-z0-9\[\\]|^)\\*#{TAG_REGEX}(?=[^A-Za-z0-9\-]|$))|
14
14
  (?:(?<=\s|^)#{REPO_REGEX}#{TAG_REGEX}(?=[^A-Za-z0-9\-]|$))
15
- /x.freeze,
16
- /\[#{TAG_REGEX}\](?=[^A-Za-z0-9\-\(])/.freeze,
17
- /\[(?<tag>(?:\#|GH-)?\d+)\]\(\)/i.freeze
15
+ /x,
16
+ /\[#{TAG_REGEX}\](?=[^A-Za-z0-9\-\(])/,
17
+ /\[(?<tag>(?:\#|GH-)?\d+)\]\(\)/i
18
18
  ].freeze
19
19
 
20
20
  attr_reader :source_url
@@ -8,17 +8,19 @@ module Dependabot
8
8
  class PullRequestCreator
9
9
  class MessageBuilder
10
10
  class LinkAndMentionSanitizer
11
- GITHUB_USERNAME = /[a-z0-9]+(-[a-z0-9]+)*/i.freeze
11
+ GITHUB_USERNAME = /[a-z0-9]+(-[a-z0-9]+)*/i
12
12
  GITHUB_REF_REGEX = %r{
13
13
  (?:https?://)?
14
14
  github\.com/(?<repo>#{GITHUB_USERNAME}/[^/\s]+)/
15
15
  (?:issue|pull)s?/(?<number>\d+)
16
- }x.freeze
17
- MENTION_REGEX = %r{(?<![A-Za-z0-9`~])@#{GITHUB_USERNAME}/?}.freeze
16
+ }x
17
+ # [^/\s#]+ means one or more characters not matching (^) the class /, whitespace (\s), or #
18
+ GITHUB_NWO_REGEX = %r{(?<repo>#{GITHUB_USERNAME}/[^/\s#]+)#(?<number>\d+)}
19
+ MENTION_REGEX = %r{(?<![A-Za-z0-9`~])@#{GITHUB_USERNAME}/?}
18
20
  # regex to match a team mention on github
19
- TEAM_MENTION_REGEX = %r{(?<![A-Za-z0-9`~])@(?<org>#{GITHUB_USERNAME})/(?<team>#{GITHUB_USERNAME})/?}.freeze
21
+ TEAM_MENTION_REGEX = %r{(?<![A-Za-z0-9`~])@(?<org>#{GITHUB_USERNAME})/(?<team>#{GITHUB_USERNAME})/?}
20
22
  # End of string
21
- EOS_REGEX = /\z/.freeze
23
+ EOS_REGEX = /\z/
22
24
  COMMONMARKER_OPTIONS = %i(
23
25
  GITHUB_PRE_LANG FULL_INFO_STRING
24
26
  ).freeze
@@ -40,6 +42,7 @@ module Dependabot
40
42
  sanitize_team_mentions(doc)
41
43
  sanitize_mentions(doc)
42
44
  sanitize_links(doc)
45
+ sanitize_nwo_text(doc)
43
46
 
44
47
  mode = unsafe ? :UNSAFE : :DEFAULT
45
48
  doc.to_html(([mode] + COMMONMARKER_OPTIONS), COMMONMARKER_EXTENSIONS)
@@ -109,6 +112,25 @@ module Dependabot
109
112
  end
110
113
  end
111
114
 
115
+ def sanitize_nwo_text(doc)
116
+ doc.walk do |node|
117
+ if node.type == :text &&
118
+ node.string_content.match?(GITHUB_NWO_REGEX) &&
119
+ !parent_node_link?(node)
120
+ replace_nwo_node(node)
121
+ end
122
+ end
123
+ end
124
+
125
+ def replace_nwo_node(node)
126
+ match = node.string_content.match(GITHUB_NWO_REGEX)
127
+ repo = match.named_captures.fetch("repo")
128
+ number = match.named_captures.fetch("number")
129
+ new_node = build_nwo_text_node("#{repo}##{number}")
130
+ node.insert_before(new_node)
131
+ node.delete
132
+ end
133
+
112
134
  def replace_github_host(text)
113
135
  text.gsub(
114
136
  /(www\.)?github.com/, github_redirection_service || "github.com"
@@ -171,6 +193,12 @@ module Dependabot
171
193
  [code_node]
172
194
  end
173
195
 
196
+ def build_nwo_text_node(text)
197
+ code_node = CommonMarker::Node.new(:code)
198
+ code_node.string_content = text
199
+ code_node
200
+ end
201
+
174
202
  def create_link_node(url, text)
175
203
  link_node = CommonMarker::Node.new(:link)
176
204
  code_node = CommonMarker::Node.new(:code)
@@ -153,7 +153,7 @@ module Dependabot
153
153
  msg += body
154
154
  msg + "</details>\n"
155
155
  else
156
- "\n\##{summary}\n\n#{body}"
156
+ "\n##{summary}\n\n#{body}"
157
157
  end
158
158
  end
159
159
 
@@ -245,8 +245,6 @@ module Dependabot
245
245
  end
246
246
 
247
247
  def sanitize_links_and_mentions(text, unsafe: false)
248
- return text unless source.provider == "github"
249
-
250
248
  LinkAndMentionSanitizer.
251
249
  new(github_redirection_service: github_redirection_service).
252
250
  sanitize_links_and_mentions(text: text, unsafe: unsafe)
@@ -3,6 +3,7 @@
3
3
  require "pathname"
4
4
  require "dependabot/clients/github_with_retries"
5
5
  require "dependabot/clients/gitlab_with_retries"
6
+ require "dependabot/logger"
6
7
  require "dependabot/metadata_finders"
7
8
  require "dependabot/pull_request_creator"
8
9
  require "dependabot/pull_request_creator/message"
@@ -38,7 +39,12 @@ module Dependabot
38
39
  end
39
40
 
40
41
  def pr_name
41
- pr_name = pr_name_prefixer.pr_name_prefix
42
+ begin
43
+ pr_name = pr_name_prefixer.pr_name_prefix
44
+ rescue StandardError => e
45
+ Dependabot.logger.error("Error while generating PR name: #{e.message}")
46
+ pr_name = ""
47
+ end
42
48
  pr_name += library? ? library_pr_name : application_pr_name
43
49
  return pr_name if files.first.directory == "/"
44
50
 
@@ -48,6 +54,9 @@ module Dependabot
48
54
  def pr_message
49
55
  suffixed_pr_message_header + commit_message_intro + \
50
56
  metadata_cascades + prefixed_pr_message_footer
57
+ rescue StandardError => e
58
+ Dependabot.logger.error("Error while generating PR message: #{e.message}")
59
+ suffixed_pr_message_header + prefixed_pr_message_footer
51
60
  end
52
61
 
53
62
  def commit_message
@@ -56,6 +65,11 @@ module Dependabot
56
65
  message += metadata_links
57
66
  message += "\n\n" + message_trailers if message_trailers
58
67
  message
68
+ rescue StandardError => e
69
+ Dependabot.logger.error("Error while generating commit message: #{e.message}")
70
+ message = commit_subject
71
+ message += "\n\n" + message_trailers if message_trailers
72
+ message
59
73
  end
60
74
 
61
75
  def message
@@ -78,11 +92,16 @@ module Dependabot
78
92
  "#{from_version_msg(old_library_requirement(dependencies.first))}" \
79
93
  "to #{new_library_requirement(dependencies.first)}"
80
94
  else
81
- names = dependencies.map(&:name)
82
- "requirements for #{names[0..-2].join(', ')} and #{names[-1]}"
95
+ names = dependencies.map(&:name).uniq
96
+ if names.count == 1
97
+ "requirements for #{names.first}"
98
+ else
99
+ "requirements for #{names[0..-2].join(', ')} and #{names[-1]}"
100
+ end
83
101
  end
84
102
  end
85
103
 
104
+ # rubocop:disable Metrics/AbcSize
86
105
  def application_pr_name
87
106
  pr_name = "bump "
88
107
  pr_name = pr_name.capitalize if pr_name_prefixer.capitalize_first_word?
@@ -104,10 +123,15 @@ module Dependabot
104
123
  "#{from_version_msg(previous_version(dependency))}" \
105
124
  "to #{new_version(dependency)}"
106
125
  else
107
- names = dependencies.map(&:name)
108
- "#{names[0..-2].join(', ')} and #{names[-1]}"
126
+ names = dependencies.map(&:name).uniq
127
+ if names.count == 1
128
+ names.first
129
+ else
130
+ "#{names[0..-2].join(', ')} and #{names[-1]}"
131
+ end
109
132
  end
110
133
  end
134
+ # rubocop:enable Metrics/AbcSize
111
135
 
112
136
  def pr_name_prefix
113
137
  pr_name_prefixer.pr_name_prefix
@@ -192,11 +216,17 @@ module Dependabot
192
216
  end
193
217
 
194
218
  # rubocop:disable Metrics/PerceivedComplexity
219
+ # rubocop:disable Metrics/AbcSize
195
220
  def version_commit_message_intro
196
221
  return multidependency_property_intro if dependencies.count > 1 && updating_a_property?
197
222
 
198
223
  return dependency_set_intro if dependencies.count > 1 && updating_a_dependency_set?
199
224
 
225
+ return transitive_removed_dependency_intro if dependencies.count > 1 && removing_a_transitive_dependency?
226
+
227
+ return transitive_multidependency_intro if dependencies.count > 1 &&
228
+ updating_top_level_and_transitive_dependencies?
229
+
200
230
  return multidependency_intro if dependencies.count > 1
201
231
 
202
232
  dependency = dependencies.first
@@ -216,6 +246,7 @@ module Dependabot
216
246
  end
217
247
 
218
248
  # rubocop:enable Metrics/PerceivedComplexity
249
+ # rubocop:enable Metrics/AbcSize
219
250
 
220
251
  def multidependency_property_intro
221
252
  dependency = dependencies.first
@@ -239,6 +270,38 @@ module Dependabot
239
270
  "dependencies needed to be updated together."
240
271
  end
241
272
 
273
+ def transitive_multidependency_intro
274
+ dependency = dependencies.first
275
+
276
+ msg = "Bumps #{dependency_links[0]} to #{new_version(dependency)}"
277
+
278
+ msg += if dependencies.count > 2
279
+ " and updates ancestor dependencies #{dependency_links[0..-2].join(', ')} " \
280
+ "and #{dependency_links[-1]}. "
281
+ else
282
+ " and updates ancestor dependency #{dependency_links[1]}. "
283
+ end
284
+
285
+ msg += "These dependencies need to be updated together.\n"
286
+
287
+ msg
288
+ end
289
+
290
+ def transitive_removed_dependency_intro
291
+ msg = "Removes #{dependency_links[0]}. It's no longer used after updating"
292
+
293
+ msg += if dependencies.count > 2
294
+ " ancestor dependencies #{dependency_links[0..-2].join(', ')} " \
295
+ "and #{dependency_links[-1]}. "
296
+ else
297
+ " ancestor dependency #{dependency_links[1]}. "
298
+ end
299
+
300
+ msg += "These dependencies need to be updated together.\n"
301
+
302
+ msg
303
+ end
304
+
242
305
  def from_version_msg(previous_version)
243
306
  return "" unless previous_version
244
307
 
@@ -257,6 +320,15 @@ module Dependabot
257
320
  any? { |r| r.dig(:metadata, :dependency_set) }
258
321
  end
259
322
 
323
+ def removing_a_transitive_dependency?
324
+ dependencies.any?(&:removed?)
325
+ end
326
+
327
+ def updating_top_level_and_transitive_dependencies?
328
+ dependencies.any?(&:top_level?) &&
329
+ dependencies.any? { |dep| !dep.top_level? }
330
+ end
331
+
260
332
  def property_name
261
333
  @property_name ||= dependencies.first.requirements.
262
334
  find { |r| r.dig(:metadata, :property_name) }&.
@@ -318,7 +390,7 @@ module Dependabot
318
390
 
319
391
  dependencies.map do |dep|
320
392
  msg = if dep.removed?
321
- "\nRemoves `#{dep.display_name}`"
393
+ "\nRemoves `#{dep.display_name}`\n"
322
394
  else
323
395
  "\nUpdates `#{dep.display_name}` " \
324
396
  "#{from_version_msg(previous_version(dep))}" \
@@ -43,11 +43,12 @@ module Dependabot
43
43
  end
44
44
 
45
45
  def capitalize_first_word?
46
- return !commit_message_options[:prefix]&.strip&.match?(/\A[a-z]/) if commit_message_options.key?(:prefix)
47
-
48
46
  return capitalise_first_word_from_last_dependabot_commit_style if last_dependabot_commit_style
49
47
 
50
48
  capitalise_first_word_from_previous_commits
49
+ rescue StandardError
50
+ # ignoring failure due to network call to find out if the PR should be capitalized
51
+ false
51
52
  end
52
53
 
53
54
  private
@@ -48,7 +48,7 @@ module Dependabot
48
48
  :custom_labels, :author_details, :signature_key,
49
49
  :commit_message_options, :vulnerabilities_fixed,
50
50
  :reviewers, :assignees, :milestone, :branch_name_separator,
51
- :branch_name_prefix, :github_redirection_service,
51
+ :branch_name_prefix, :branch_name_max_length, :github_redirection_service,
52
52
  :custom_headers, :provider_metadata
53
53
 
54
54
  def initialize(source:, base_commit:, dependencies:, files:, credentials:,
@@ -57,7 +57,8 @@ module Dependabot
57
57
  commit_message_options: {}, vulnerabilities_fixed: {},
58
58
  reviewers: nil, assignees: nil, milestone: nil,
59
59
  branch_name_separator: "/", branch_name_prefix: "dependabot",
60
- label_language: false, automerge_candidate: false,
60
+ branch_name_max_length: nil, label_language: false,
61
+ automerge_candidate: false,
61
62
  github_redirection_service: DEFAULT_GITHUB_REDIRECTION_SERVICE,
62
63
  custom_headers: nil, require_up_to_date_base: false,
63
64
  provider_metadata: {}, message: nil)
@@ -78,6 +79,7 @@ module Dependabot
78
79
  @vulnerabilities_fixed = vulnerabilities_fixed
79
80
  @branch_name_separator = branch_name_separator
80
81
  @branch_name_prefix = branch_name_prefix
82
+ @branch_name_max_length = branch_name_max_length
81
83
  @label_language = label_language
82
84
  @automerge_candidate = automerge_candidate
83
85
  @github_redirection_service = github_redirection_service
@@ -232,7 +234,8 @@ module Dependabot
232
234
  files: files,
233
235
  target_branch: source.branch,
234
236
  separator: branch_name_separator,
235
- prefix: branch_name_prefix
237
+ prefix: branch_name_prefix,
238
+ max_length: branch_name_max_length
236
239
  )
237
240
  end
238
241
 
@@ -53,7 +53,7 @@ module Dependabot
53
53
  end
54
54
 
55
55
  # Currently the PR diff in ADO shows difference in commits instead of actual diff in files.
56
- # This workaround is done to get the target branch commit history on the source branch alongwith file changes
56
+ # This workaround puts the target branch commit history on the source branch along with the file changes.
57
57
  def update_source_branch
58
58
  # 1) Push the file changes to a newly created temporary branch (from base commit)
59
59
  new_commit = create_temp_branch
@@ -182,28 +182,31 @@ module Dependabot
182
182
  end
183
183
 
184
184
  def commit_message
185
- # Take the commit message from the old commit
186
- commit_being_updated.message
185
+ fallback_message =
186
+ "#{pull_request.title}" \
187
+ "\n\n" \
188
+ "Dependabot couldn't find the original pull request head commit, " \
189
+ "#{old_commit}."
190
+
191
+ # Take the commit message from the old commit. If the old commit can't
192
+ # be found, use the PR title as the commit message.
193
+ commit_being_updated&.message || fallback_message
187
194
  end
188
195
 
189
196
  def commit_being_updated
190
- @commit_being_updated ||=
197
+ return @commit_being_updated if defined?(@commit_being_updated)
198
+
199
+ @commit_being_updated =
191
200
  if pull_request.commits == 1
192
201
  github_client_for_source.
193
202
  git_commit(source.repo, pull_request.head.sha)
194
203
  else
195
- author_name = author_details&.fetch(:name, nil) || "dependabot"
196
204
  commits =
197
205
  github_client_for_source.
198
- pull_request_commits(source.repo, pull_request_number).
199
- reverse
200
-
201
- commit =
202
- commits.find { |c| c.sha == old_commit } ||
203
- commits.find { |c| c.commit.author.name.include?(author_name) } ||
204
- commits.first
206
+ pull_request_commits(source.repo, pull_request_number)
205
207
 
206
- commit.commit
208
+ commit = commits.find { |c| c.sha == old_commit }
209
+ commit&.commit
207
210
  end
208
211
  end
209
212
 
@@ -69,7 +69,8 @@ module Dependabot
69
69
  old_commit: old_commit,
70
70
  files: files,
71
71
  credentials: credentials,
72
- pull_request_number: pull_request_number
72
+ pull_request_number: pull_request_number,
73
+ author_details: author_details
73
74
  )
74
75
  end
75
76
  end
@@ -7,7 +7,7 @@ module Dependabot
7
7
  (?:\.com)[/:]
8
8
  (?<repo>[\w.-]+/(?:(?!\.git|\.\s)[\w.-])+)
9
9
  (?:(?:/tree|/blob)/(?<branch>[^/]+)/(?<directory>.*)[\#|/])?
10
- }x.freeze
10
+ }x
11
11
 
12
12
  GITHUB_ENTERPRISE_SOURCE = %r{
13
13
  (?<protocol>(http://|https://|git://|ssh://))*
@@ -16,27 +16,27 @@ module Dependabot
16
16
  [/:]
17
17
  (?<repo>[\w.-]+/(?:(?!\.git|\.\s)[\w.-])+)
18
18
  (?:(?:/tree|/blob)/(?<branch>[^/]+)/(?<directory>.*)[\#|/])?
19
- }x.freeze
19
+ }x
20
20
 
21
21
  GITLAB_SOURCE = %r{
22
22
  (?<provider>gitlab)
23
23
  (?:\.com)[/:]
24
- (?<repo>(?!\.git|/tree|/blob)[\w./-]+?)(?:\.git)?
25
- (?:(?:/tree|/blob)/(?<branch>[^/]+)/(?<directory>.*)[\#|/].*)?$
26
- }x.freeze
24
+ (?<repo>[^/]+/(?:(?!\.git)[^/])+((?!/tree|/blob/|/-)/[^/]+)?)
25
+ (?:(?:/tree|/blob)/(?<branch>[^/]+)/(?<directory>.*)[\#|/].*)?
26
+ }x
27
27
 
28
28
  BITBUCKET_SOURCE = %r{
29
29
  (?<provider>bitbucket)
30
30
  (?:\.org)[/:]
31
31
  (?<repo>[\w.-]+/(?:(?!\.git|\.\s)[\w.-])+)
32
32
  (?:(?:/src)/(?<branch>[^/]+)/(?<directory>.*)[\#|/])?
33
- }x.freeze
33
+ }x
34
34
 
35
35
  AZURE_SOURCE = %r{
36
36
  (?<provider>azure)
37
37
  (?:\.com)[/:]
38
38
  (?<repo>[\w.-]+/([\w.-]+/)?(?:_git/)(?:(?!\.git|\.\s)[\w.-])+)
39
- }x.freeze
39
+ }x
40
40
 
41
41
  CODECOMMIT_SOURCE = %r{
42
42
  (?<protocol>(http://|https://|git://|ssh://))
@@ -48,7 +48,7 @@ module Dependabot
48
48
  (?:/)?(?<directory>[^?]*)?
49
49
  [?]?
50
50
  (?<ref>.*)?
51
- }x.freeze
51
+ }x
52
52
 
53
53
  SOURCE_REGEX = /
54
54
  (?:#{GITHUB_SOURCE})|
@@ -56,7 +56,7 @@ module Dependabot
56
56
  (?:#{BITBUCKET_SOURCE})|
57
57
  (?:#{AZURE_SOURCE})|
58
58
  (?:#{CODECOMMIT_SOURCE})
59
- /x.freeze
59
+ /x
60
60
 
61
61
  IGNORED_PROVIDER_HOSTS = %w(gitbox.apache.org svn.apache.org fuchsia.googlesource.com).freeze
62
62
 
@@ -120,7 +120,7 @@ module Dependabot
120
120
  Utils.requirement_class_for_package_manager(dependency.package_manager)
121
121
  end
122
122
 
123
- # For some langauges, the manifest file may be constructed such that
123
+ # For some languages, the manifest file may be constructed such that
124
124
  # Dependabot has no way to update it (e.g., if it fetches its versions
125
125
  # from a web API). This method is overridden in those cases.
126
126
  def requirements_unlocked_or_can_be?
@@ -1,5 +1,5 @@
1
1
  # frozen_string_literal: true
2
2
 
3
3
  module Dependabot
4
- VERSION = "0.212.0"
4
+ VERSION = "0.213.0"
5
5
  end