dependabot-npm_and_yarn 0.213.0 → 0.215.0

Sign up to get free protection for your applications and to get access to all the features.
@@ -16,29 +16,82 @@ module Dependabot
16
16
  6
17
17
  end
18
18
 
19
- # Run any number of yarn commands while ensuring that `enableScripts` is
20
- # set to false. Yarn commands should _not_ be ran outside of this helper
21
- # to ensure that postinstall scripts are never executed, as they could
22
- # contain malicious code.
23
- def self.run_yarn_commands(*commands)
24
- # We never want to execute postinstall scripts
25
- SharedHelpers.run_shell_command("yarn config set enableScripts false")
19
+ def self.fetch_yarnrc_yml_value(key, default_value)
20
+ if File.exist?(".yarnrc.yml") && (yarnrc = YAML.load_file(".yarnrc.yml"))
21
+ yarnrc.fetch(key, default_value)
22
+ else
23
+ default_value
24
+ end
25
+ end
26
+
27
+ def self.yarn_berry?(yarn_lock)
28
+ yaml = YAML.safe_load(yarn_lock.content)
29
+ yaml.key?("__metadata")
30
+ rescue StandardError
31
+ false
32
+ end
33
+
34
+ def self.yarn_major_version
35
+ output = SharedHelpers.run_shell_command("yarn --version")
36
+ Version.new(output).major
37
+ end
38
+
39
+ def self.yarn_zero_install?
40
+ File.exist?(".pnp.cjs")
41
+ end
42
+
43
+ def self.yarn_offline_cache?
44
+ yarn_cache_dir = fetch_yarnrc_yml_value("cacheFolder", ".yarn/cache")
45
+ File.exist?(yarn_cache_dir) && (fetch_yarnrc_yml_value("nodeLinker", "") == "node-modules")
46
+ end
47
+
48
+ def self.yarn_berry_args
49
+ if yarn_major_version == 2
50
+ ""
51
+ elsif yarn_major_version >= 3 && (yarn_zero_install? || yarn_offline_cache?)
52
+ "--mode=skip-build"
53
+ else
54
+ # We only want this mode if the cache is not being updated/managed
55
+ # as this improperly leaves old versions in the cache
56
+ "--mode=update-lockfile"
57
+ end
58
+ end
59
+
60
+ def self.setup_yarn_berry
61
+ # Always disable immutable installs so yarn's CI detection doesn't prevent updates.
62
+ SharedHelpers.run_shell_command("yarn config set enableImmutableInstalls false")
63
+ # We never want to execute postinstall scripts, either set this config or mode=skip-build must be set
64
+ if yarn_major_version == 2 || !yarn_zero_install?
65
+ SharedHelpers.run_shell_command("yarn config set enableScripts false")
66
+ end
26
67
  if (http_proxy = ENV.fetch("HTTP_PROXY", false))
27
68
  SharedHelpers.run_shell_command("yarn config set httpProxy #{http_proxy}")
28
69
  end
29
70
  if (https_proxy = ENV.fetch("HTTPS_PROXY", false))
30
71
  SharedHelpers.run_shell_command("yarn config set httpsProxy #{https_proxy}")
31
72
  end
32
- if (ca_file_path = ENV.fetch("NODE_EXTRA_CA_CERTS", false))
33
- output = SharedHelpers.run_shell_command("yarn --version")
34
- major_version = Version.new(output).major
35
- if major_version >= 4
36
- SharedHelpers.run_shell_command("yarn config set httpsCaFilePath #{ca_file_path}")
37
- else
38
- SharedHelpers.run_shell_command("yarn config set caFilePath #{ca_file_path}")
39
- end
73
+ return unless (ca_file_path = ENV.fetch("NODE_EXTRA_CA_CERTS", false))
74
+
75
+ if yarn_major_version >= 4
76
+ SharedHelpers.run_shell_command("yarn config set httpsCaFilePath #{ca_file_path}")
77
+ else
78
+ SharedHelpers.run_shell_command("yarn config set caFilePath #{ca_file_path}")
40
79
  end
41
- commands.each { |cmd| SharedHelpers.run_shell_command(cmd) }
80
+ end
81
+
82
+ # Run any number of yarn commands while ensuring that `enableScripts` is
83
+ # set to false. Yarn commands should _not_ be ran outside of this helper
84
+ # to ensure that postinstall scripts are never executed, as they could
85
+ # contain malicious code.
86
+ def self.run_yarn_commands(*commands)
87
+ setup_yarn_berry
88
+ commands.each { |cmd, fingerprint| SharedHelpers.run_shell_command(cmd, fingerprint: fingerprint) }
89
+ end
90
+
91
+ # Run a single yarn command returning stdout/stderr
92
+ def self.run_yarn_command(command, fingerprint: nil)
93
+ setup_yarn_berry
94
+ SharedHelpers.run_shell_command(command, fingerprint: fingerprint)
42
95
  end
43
96
 
44
97
  def self.dependencies_with_all_versions_metadata(dependency_set)
@@ -14,14 +14,14 @@ module Dependabot
14
14
  File.join(__dir__, "../../../helpers")
15
15
  end
16
16
 
17
- def self.npm8_subdependency_update_command(dependency_names)
17
+ def self.run_npm8_subdependency_update_command(dependency_names)
18
18
  # NOTE: npm options
19
19
  # - `--force` ignores checks for platform (os, cpu) and engines
20
20
  # - `--dry-run=false` the updater sets a global .npmrc with dry-run: true to
21
21
  # work around an issue in npm 6, we don't want that here
22
22
  # - `--ignore-scripts` disables prepare and prepack scripts which are run
23
23
  # when installing git dependencies
24
- [
24
+ command = [
25
25
  "npm",
26
26
  "update",
27
27
  *dependency_names,
@@ -31,6 +31,19 @@ module Dependabot
31
31
  "--ignore-scripts",
32
32
  "--package-lock-only"
33
33
  ].join(" ")
34
+
35
+ fingerprint = [
36
+ "npm",
37
+ "update",
38
+ "<dependency_names>",
39
+ "--force",
40
+ "--dry-run",
41
+ "false",
42
+ "--ignore-scripts",
43
+ "--package-lock-only"
44
+ ].join(" ")
45
+
46
+ SharedHelpers.run_shell_command(command, fingerprint: fingerprint)
34
47
  end
35
48
  end
36
49
  end
@@ -16,7 +16,12 @@ module Dependabot
16
16
  def write_temporary_dependency_files
17
17
  write_lock_files
18
18
 
19
- File.write(".npmrc", npmrc_content)
19
+ if Helpers.yarn_berry?(yarn_locks.first)
20
+ File.write(".yarnrc.yml", yarnrc_yml_content) if yarnrc_yml_file
21
+ else
22
+ File.write(".npmrc", npmrc_content) unless Helpers.yarn_berry?(yarn_locks.first)
23
+ File.write(".yarnrc", yarnrc_content) if yarnrc_specifies_private_reg?
24
+ end
20
25
 
21
26
  package_files.each do |file|
22
27
  path = file.name
@@ -69,6 +74,24 @@ module Dependabot
69
74
  end
70
75
  end
71
76
 
77
+ def yarnrc_specifies_private_reg?
78
+ return false unless yarnrc_file
79
+
80
+ regex = UpdateChecker::RegistryFinder::YARN_GLOBAL_REGISTRY_REGEX
81
+ yarnrc_global_registry =
82
+ yarnrc_file.content.
83
+ lines.find { |line| line.match?(regex) }&.
84
+ match(regex)&.
85
+ named_captures&.
86
+ fetch("registry")
87
+
88
+ return false unless yarnrc_global_registry
89
+
90
+ UpdateChecker::RegistryFinder::CENTRAL_REGISTRIES.none? do |r|
91
+ r.include?(URI(yarnrc_global_registry).host)
92
+ end
93
+ end
94
+
72
95
  # Duplicated in NpmLockfileUpdater
73
96
  # Remove the dependency we want to update from the lockfile and let
74
97
  # yarn find the latest resolvable version and fix the lockfile
@@ -88,6 +111,25 @@ module Dependabot
88
111
  dependency_files: dependency_files
89
112
  ).npmrc_content
90
113
  end
114
+
115
+ def yarnrc_file
116
+ dependency_files.find { |f| f.name == ".yarnrc" }
117
+ end
118
+
119
+ def yarnrc_content
120
+ NpmAndYarn::FileUpdater::NpmrcBuilder.new(
121
+ credentials: credentials,
122
+ dependency_files: dependency_files
123
+ ).yarnrc_content
124
+ end
125
+
126
+ def yarnrc_yml_file
127
+ dependency_files.find { |f| f.name.end_with?(".yarnrc.yml") }
128
+ end
129
+
130
+ def yarnrc_yml_content
131
+ yarnrc_yml_file.content
132
+ end
91
133
  end
92
134
  end
93
135
  end
@@ -130,10 +130,10 @@ module Dependabot
130
130
  end
131
131
 
132
132
  def filter_lower_versions(versions_array)
133
- return versions_array unless dependency.version && version_class.correct?(dependency.version)
133
+ return versions_array unless dependency.numeric_version
134
134
 
135
135
  versions_array.
136
- select { |version, _| version > version_class.new(dependency.version) }
136
+ select { |version, _| version > dependency.numeric_version }
137
137
  end
138
138
 
139
139
  def version_from_dist_tags
@@ -159,13 +159,10 @@ module Dependabot
159
159
  wants_latest_dist_tag?(latest) ? latest : nil
160
160
  end
161
161
 
162
- # rubocop:disable Metrics/PerceivedComplexity
163
162
  def related_to_current_pre?(version)
164
- current_version = dependency.version
165
- if current_version &&
166
- version_class.correct?(current_version) &&
167
- version_class.new(current_version).prerelease? &&
168
- version_class.new(current_version).release == version.release
163
+ current_version = dependency.numeric_version
164
+ if current_version&.prerelease? &&
165
+ current_version&.release == version.release
169
166
  return true
170
167
  end
171
168
 
@@ -181,7 +178,6 @@ module Dependabot
181
178
  false
182
179
  end
183
180
  end
184
- # rubocop:enable Metrics/PerceivedComplexity
185
181
 
186
182
  def specified_dist_tag_requirement?
187
183
  dependency.requirements.any? do |req|
@@ -204,10 +200,9 @@ module Dependabot
204
200
  end
205
201
 
206
202
  def current_version_greater_than?(version)
207
- return false unless dependency.version
208
- return false unless version_class.correct?(dependency.version)
203
+ return false unless dependency.numeric_version
209
204
 
210
- version_class.new(dependency.version) > version
205
+ dependency.numeric_version > version
211
206
  end
212
207
 
213
208
  def current_requirement_greater_than?(version)
@@ -292,7 +287,6 @@ module Dependabot
292
287
  url: dependency_url,
293
288
  headers: registry_auth_headers
294
289
  )
295
-
296
290
  return response unless response.status == 500
297
291
  return response unless registry_auth_headers["Authorization"]
298
292
 
@@ -12,6 +12,7 @@ module Dependabot
12
12
  https://registry.npmjs.org
13
13
  http://registry.npmjs.org
14
14
  https://registry.yarnpkg.com
15
+ http://registry.yarnpkg.com
15
16
  ).freeze
16
17
  NPM_AUTH_TOKEN_REGEX = %r{//(?<registry>.*)/:_authToken=(?<token>.*)$}
17
18
  NPM_GLOBAL_REGISTRY_REGEX = /^registry\s*=\s*['"]?(?<registry>.*?)['"]?$/
@@ -145,10 +146,13 @@ module Dependabot
145
146
  npmrc_file.content.scan(NPM_AUTH_TOKEN_REGEX) do
146
147
  next if Regexp.last_match[:registry].include?("${")
147
148
 
149
+ registry = Regexp.last_match[:registry]
150
+ token = Regexp.last_match[:token]&.strip
151
+
148
152
  registries << {
149
153
  "type" => "npm_registry",
150
- "registry" => Regexp.last_match[:registry],
151
- "token" => Regexp.last_match[:token]&.strip
154
+ "registry" => registry.gsub(/\s+/, "%20"),
155
+ "token" => token
152
156
  }
153
157
  end
154
158
 
@@ -157,7 +161,8 @@ module Dependabot
157
161
 
158
162
  registry = Regexp.last_match[:registry].strip.
159
163
  sub(%r{/+$}, "").
160
- sub(%r{^.*?//}, "")
164
+ sub(%r{^.*?//}, "").
165
+ gsub(/\s+/, "%20")
161
166
  next if registries.map { |r| r["registry"] }.include?(registry)
162
167
 
163
168
  registries << {
@@ -179,7 +184,8 @@ module Dependabot
179
184
 
180
185
  registry = Regexp.last_match[:registry].strip.
181
186
  sub(%r{/+$}, "").
182
- sub(%r{^.*?//}, "")
187
+ sub(%r{^.*?//}, "").
188
+ gsub(/\s+/, "%20")
183
189
  registries << {
184
190
  "type" => "npm_registry",
185
191
  "registry" => registry,
@@ -19,19 +19,21 @@ module Dependabot
19
19
  class UpdateChecker
20
20
  class SubdependencyVersionResolver
21
21
  def initialize(dependency:, credentials:, dependency_files:,
22
- ignored_versions:, latest_allowable_version:)
22
+ ignored_versions:, latest_allowable_version:, repo_contents_path:)
23
23
  @dependency = dependency
24
24
  @credentials = credentials
25
25
  @dependency_files = dependency_files
26
26
  @ignored_versions = ignored_versions
27
27
  @latest_allowable_version = latest_allowable_version
28
+ @repo_contents_path = repo_contents_path
28
29
  end
29
30
 
30
31
  def latest_resolvable_version
31
32
  raise "Not a subdependency!" if dependency.requirements.any?
32
33
  return if bundled_dependency?
33
34
 
34
- SharedHelpers.in_a_temporary_directory do
35
+ base_dir = dependency_files.first.directory
36
+ SharedHelpers.in_a_temporary_repo_directory(base_dir, repo_contents_path) do
35
37
  dependency_files_builder.write_temporary_dependency_files
36
38
 
37
39
  updated_lockfiles = filtered_lockfiles.map do |lockfile|
@@ -53,13 +55,13 @@ module Dependabot
53
55
  private
54
56
 
55
57
  attr_reader :dependency, :credentials, :dependency_files,
56
- :ignored_versions, :latest_allowable_version
58
+ :ignored_versions, :latest_allowable_version, :repo_contents_path
57
59
 
58
60
  def update_subdependency_in_lockfile(lockfile)
59
61
  lockfile_name = Pathname.new(lockfile.name).basename.to_s
60
62
  path = Pathname.new(lockfile.name).dirname.to_s
61
63
 
62
- updated_files = if lockfile.name.end_with?("yarn.lock") && yarn_berry?(lockfile)
64
+ updated_files = if lockfile.name.end_with?("yarn.lock") && Helpers.yarn_berry?(lockfile)
63
65
  run_yarn_berry_updater(path, lockfile_name)
64
66
  elsif lockfile.name.end_with?("yarn.lock")
65
67
  run_yarn_updater(path, lockfile_name)
@@ -70,15 +72,6 @@ module Dependabot
70
72
  updated_files.fetch(lockfile_name)
71
73
  end
72
74
 
73
- def yarn_berry?(yarn_lock)
74
- return false unless Experiments.enabled?(:yarn_berry)
75
-
76
- yaml = YAML.safe_load(yarn_lock.content)
77
- yaml.key?("__metadata")
78
- rescue StandardError
79
- false
80
- end
81
-
82
75
  def version_from_updated_lockfiles(updated_lockfiles)
83
76
  updated_files = dependency_files -
84
77
  dependency_files_builder.yarn_locks -
@@ -123,8 +116,9 @@ module Dependabot
123
116
  def run_yarn_berry_updater(path, lockfile_name)
124
117
  SharedHelpers.with_git_configured(credentials: credentials) do
125
118
  Dir.chdir(path) do
126
- Helpers.run_yarn_commands(
127
- "yarn up -R #{dependency.name}"
119
+ Helpers.run_yarn_command(
120
+ "yarn up -R #{dependency.name} #{Helpers.yarn_berry_args}".strip,
121
+ fingerprint: "yarn up -R <dependency_name> #{Helpers.yarn_berry_args}".strip
128
122
  )
129
123
  { lockfile_name => File.read(lockfile_name) }
130
124
  end
@@ -137,7 +131,7 @@ module Dependabot
137
131
  npm_version = Dependabot::NpmAndYarn::Helpers.npm_version(lockfile_content)
138
132
 
139
133
  if npm_version == "npm8"
140
- SharedHelpers.run_shell_command(NativeHelpers.npm8_subdependency_update_command([dependency.name]))
134
+ NativeHelpers.run_npm8_subdependency_update_command([dependency.name])
141
135
  { lockfile_name => File.read(lockfile_name) }
142
136
  else
143
137
  SharedHelpers.run_helper_subprocess(
@@ -38,6 +38,15 @@ module Dependabot
38
38
  "(?<required_dep>[^"]+)"
39
39
  /x
40
40
 
41
+ # Error message from yarn add:
42
+ # YN0060: │ eve-roster@workspace:. provides jest (p8d618) \
43
+ # with version 29.3.0, which doesn't satisfy \
44
+ # what ts-jest requests\n
45
+ YARN_BERRY_PEER_DEP_ERROR_REGEX =
46
+ /
47
+ YN0060:\s|\s.+\sprovides\s(?<required_dep>.+?)\s\((?<info_hash>\w+)\).+what\s(?<requiring_dep>.+?)\srequests
48
+ /x
49
+
41
50
  # Error message from npm install:
42
51
  # react-dom@15.2.0 requires a peer of react@^15.2.0 \
43
52
  # but none is installed. You must install peer dependencies yourself.
@@ -62,7 +71,7 @@ module Dependabot
62
71
  /x
63
72
 
64
73
  def initialize(dependency:, credentials:, dependency_files:,
65
- latest_allowable_version:, latest_version_finder:)
74
+ latest_allowable_version:, latest_version_finder:, repo_contents_path:)
66
75
  @dependency = dependency
67
76
  @credentials = credentials
68
77
  @dependency_files = dependency_files
@@ -70,6 +79,7 @@ module Dependabot
70
79
 
71
80
  @latest_version_finder = {}
72
81
  @latest_version_finder[dependency] = latest_version_finder
82
+ @repo_contents_path = repo_contents_path
73
83
  end
74
84
 
75
85
  def latest_resolvable_version
@@ -135,7 +145,7 @@ module Dependabot
135
145
  private
136
146
 
137
147
  attr_reader :dependency, :credentials, :dependency_files,
138
- :latest_allowable_version
148
+ :latest_allowable_version, :repo_contents_path
139
149
 
140
150
  def latest_version_finder(dep)
141
151
  @latest_version_finder[dep] ||=
@@ -307,30 +317,15 @@ module Dependabot
307
317
  # TODO: Add all of the error handling that the FileUpdater does
308
318
  # here (since problematic repos will be resolved here before they're
309
319
  # seen by the FileUpdater)
310
- SharedHelpers.in_a_temporary_directory do
320
+ base_dir = dependency_files.first.directory
321
+ SharedHelpers.in_a_temporary_repo_directory(base_dir, repo_contents_path) do
311
322
  dependency_files_builder.write_temporary_dependency_files
312
323
 
313
324
  filtered_package_files.flat_map do |file|
314
325
  path = Pathname.new(file.name).dirname
315
326
  run_checker(path: path, version: version)
316
327
  rescue SharedHelpers::HelperSubprocessFailed => e
317
- errors = []
318
- if e.message.match?(NPM6_PEER_DEP_ERROR_REGEX)
319
- e.message.scan(NPM6_PEER_DEP_ERROR_REGEX) do
320
- errors << Regexp.last_match.named_captures
321
- end
322
- elsif e.message.match?(NPM8_PEER_DEP_ERROR_REGEX)
323
- e.message.scan(NPM8_PEER_DEP_ERROR_REGEX) do
324
- errors << Regexp.last_match.named_captures
325
- end
326
- elsif e.message.match?(YARN_PEER_DEP_ERROR_REGEX)
327
- e.message.scan(YARN_PEER_DEP_ERROR_REGEX) do
328
- errors << Regexp.last_match.named_captures
329
- end
330
- else
331
- raise
332
- end
333
- errors
328
+ handle_peer_dependency_errors(e)
334
329
  end.compact
335
330
  end
336
331
  rescue SharedHelpers::HelperSubprocessFailed
@@ -340,6 +335,30 @@ module Dependabot
340
335
  []
341
336
  end
342
337
 
338
+ def handle_peer_dependency_errors(error)
339
+ errors = []
340
+ if error.message.match?(NPM6_PEER_DEP_ERROR_REGEX)
341
+ error.message.scan(NPM6_PEER_DEP_ERROR_REGEX) do
342
+ errors << Regexp.last_match.named_captures
343
+ end
344
+ elsif error.message.match?(NPM8_PEER_DEP_ERROR_REGEX)
345
+ error.message.scan(NPM8_PEER_DEP_ERROR_REGEX) do
346
+ errors << Regexp.last_match.named_captures
347
+ end
348
+ elsif error.message.match?(YARN_PEER_DEP_ERROR_REGEX)
349
+ error.message.scan(YARN_PEER_DEP_ERROR_REGEX) do
350
+ errors << Regexp.last_match.named_captures
351
+ end
352
+ elsif error.message.match?(YARN_BERRY_PEER_DEP_ERROR_REGEX)
353
+ error.message.scan(YARN_BERRY_PEER_DEP_ERROR_REGEX) do
354
+ errors << Regexp.last_match.named_captures
355
+ end
356
+ else
357
+ raise
358
+ end
359
+ errors
360
+ end
361
+
343
362
  def unmet_peer_dependencies
344
363
  peer_dependency_errors.
345
364
  map { |captures| error_details_from_captures(captures) }
@@ -351,13 +370,14 @@ module Dependabot
351
370
  end
352
371
 
353
372
  def error_details_from_captures(captures)
373
+ required_dep_captures = captures.fetch("required_dep")
374
+ requiring_dep_captures = captures.fetch("requiring_dep")
375
+ return {} unless required_dep_captures && requiring_dep_captures
376
+
354
377
  {
355
- requirement_name:
356
- captures.fetch("required_dep").sub(/@[^@]+$/, ""),
357
- requirement_version:
358
- captures.fetch("required_dep").split("@").last.delete('"'),
359
- requiring_dep_name:
360
- captures.fetch("requiring_dep").sub(/@[^@]+$/, "")
378
+ requirement_name: required_dep_captures.sub(/@[^@]+$/, ""),
379
+ requirement_version: required_dep_captures.split("@").last.delete('"'),
380
+ requiring_dep_name: requiring_dep_captures.sub(/@[^@]+$/, "")
361
381
  }
362
382
  end
363
383
 
@@ -468,13 +488,37 @@ module Dependabot
468
488
  def run_checker(path:, version:)
469
489
  # If there are both yarn lockfiles and npm lockfiles only run the
470
490
  # yarn updater
471
- if lockfiles_for_path(lockfiles: dependency_files_builder.yarn_locks, path: path).any?
491
+ lockfiles = lockfiles_for_path(lockfiles: dependency_files_builder.yarn_locks, path: path)
492
+ if lockfiles.any?
493
+ return run_yarn_berry_checker(path: path, version: version) if Helpers.yarn_berry?(lockfiles.first)
494
+
472
495
  return run_yarn_checker(path: path, version: version)
473
496
  end
474
497
 
475
498
  run_npm_checker(path: path, version: version)
476
499
  end
477
500
 
501
+ def run_yarn_berry_checker(path:, version:)
502
+ # This method mimics calling a native helper in order to comply with the caller's expectations
503
+ # Specifically we add the dependency at the specified updated version
504
+ # then check the output of the add command for Peer Dependency errors (Denoted by YN0060)
505
+ # If we find peer dependency issues, we raise HelperSubprocessFailed as
506
+ # the native helpers do.
507
+ SharedHelpers.with_git_configured(credentials: credentials) do
508
+ Dir.chdir(path) do
509
+ output = Helpers.run_yarn_command(
510
+ "yarn add #{dependency.name}@#{version} #{Helpers.yarn_berry_args}".strip
511
+ )
512
+ if output.include?("YN0060")
513
+ raise SharedHelpers::HelperSubprocessFailed.new(
514
+ message: output,
515
+ error_context: {}
516
+ )
517
+ end
518
+ end
519
+ end
520
+ end
521
+
478
522
  def run_yarn_checker(path:, version:)
479
523
  SharedHelpers.with_git_configured(credentials: credentials) do
480
524
  Dir.chdir(path) do
@@ -22,7 +22,7 @@ module Dependabot
22
22
  dependency.version &&
23
23
  version_class.correct?(dependency.version) &&
24
24
  vulnerable_versions.any? &&
25
- !vulnerable_versions.include?(version_class.new(dependency.version))
25
+ !vulnerable_versions.include?(current_version)
26
26
 
27
27
  super
28
28
  end
@@ -279,9 +279,7 @@ module Dependabot
279
279
 
280
280
  def latest_version_for_git_dependency
281
281
  @latest_version_for_git_dependency ||=
282
- if git_branch_or_ref_in_latest_release?
283
- latest_released_version
284
- elsif version_class.correct?(dependency.version)
282
+ if version_class.correct?(dependency.version)
285
283
  latest_git_version_details[:version] &&
286
284
  version_class.new(latest_git_version_details[:version])
287
285
  else
@@ -294,26 +292,9 @@ module Dependabot
294
292
  latest_version_finder.latest_version_from_registry
295
293
  end
296
294
 
297
- def should_switch_source_from_git_to_registry?
298
- return false unless git_dependency?
299
- return false unless git_branch_or_ref_in_latest_release?
300
- return false if latest_version_for_git_dependency.nil?
301
-
302
- version_class.correct?(latest_version_for_git_dependency)
303
- end
304
-
305
- def git_branch_or_ref_in_latest_release?
306
- return false unless latest_released_version
307
-
308
- return @git_branch_or_ref_in_latest_release if defined?(@git_branch_or_ref_in_latest_release)
309
-
310
- @git_branch_or_ref_in_latest_release ||=
311
- git_commit_checker.branch_or_ref_in_release?(latest_released_version)
312
- end
313
-
314
295
  def latest_version_details
315
296
  @latest_version_details ||=
316
- if git_dependency? && !should_switch_source_from_git_to_registry?
297
+ if git_dependency?
317
298
  latest_git_version_details
318
299
  else
319
300
  { version: latest_released_version }
@@ -339,7 +320,8 @@ module Dependabot
339
320
  credentials: credentials,
340
321
  dependency_files: dependency_files,
341
322
  latest_allowable_version: latest_version,
342
- latest_version_finder: latest_version_finder
323
+ latest_version_finder: latest_version_finder,
324
+ repo_contents_path: repo_contents_path
343
325
  )
344
326
  end
345
327
 
@@ -350,7 +332,8 @@ module Dependabot
350
332
  credentials: credentials,
351
333
  dependency_files: dependency_files,
352
334
  ignored_versions: ignored_versions,
353
- latest_allowable_version: latest_version
335
+ latest_allowable_version: latest_version,
336
+ repo_contents_path: repo_contents_path
354
337
  )
355
338
  end
356
339
 
@@ -387,9 +370,6 @@ module Dependabot
387
370
  # Never need to update source, unless a git_dependency
388
371
  return dependency_source_details unless git_dependency?
389
372
 
390
- # Source becomes `nil` if switching to default rubygems
391
- return nil if should_switch_source_from_git_to_registry?
392
-
393
373
  # Update the git tag if updating a pinned version
394
374
  if git_commit_checker.pinned_ref_looks_like_version? &&
395
375
  !git_commit_checker.local_tag_for_latest_version.nil?
@@ -24,3 +24,5 @@ Dependabot::Dependency.register_production_check(
24
24
  groups.include?("dependencies")
25
25
  end
26
26
  )
27
+
28
+ Dependabot::Utils.register_always_clone("npm_and_yarn")