bundler 2.2.3 → 2.3.5

Sign up to get free protection for your applications and to get access to all the features.
Files changed (183) hide show
  1. checksums.yaml +4 -4
  2. data/CHANGELOG.md +503 -7
  3. data/README.md +1 -1
  4. data/bundler.gemspec +2 -3
  5. data/exe/bundle +7 -8
  6. data/lib/bundler/.document +1 -0
  7. data/lib/bundler/build_metadata.rb +2 -2
  8. data/lib/bundler/cli/cache.rb +2 -1
  9. data/lib/bundler/cli/check.rb +4 -2
  10. data/lib/bundler/cli/common.rb +15 -2
  11. data/lib/bundler/cli/doctor.rb +15 -4
  12. data/lib/bundler/cli/exec.rb +1 -6
  13. data/lib/bundler/cli/gem.rb +132 -24
  14. data/lib/bundler/cli/info.rb +16 -4
  15. data/lib/bundler/cli/install.rb +12 -27
  16. data/lib/bundler/cli/issue.rb +4 -3
  17. data/lib/bundler/cli/list.rb +7 -1
  18. data/lib/bundler/cli/lock.rb +5 -1
  19. data/lib/bundler/cli/open.rb +1 -2
  20. data/lib/bundler/cli/outdated.rb +10 -11
  21. data/lib/bundler/cli/remove.rb +1 -2
  22. data/lib/bundler/cli/update.rb +17 -8
  23. data/lib/bundler/cli.rb +44 -60
  24. data/lib/bundler/compact_index_client/cache.rb +0 -9
  25. data/lib/bundler/compact_index_client/updater.rb +10 -19
  26. data/lib/bundler/compact_index_client.rb +2 -8
  27. data/lib/bundler/current_ruby.rb +5 -4
  28. data/lib/bundler/definition.rb +158 -316
  29. data/lib/bundler/dep_proxy.rb +15 -8
  30. data/lib/bundler/dependency.rb +5 -7
  31. data/lib/bundler/digest.rb +71 -0
  32. data/lib/bundler/dsl.rb +67 -66
  33. data/lib/bundler/endpoint_specification.rb +21 -11
  34. data/lib/bundler/environment_preserver.rb +4 -1
  35. data/lib/bundler/errors.rb +19 -3
  36. data/lib/bundler/feature_flag.rb +0 -5
  37. data/lib/bundler/fetcher/compact_index.rb +10 -15
  38. data/lib/bundler/fetcher/downloader.rb +9 -6
  39. data/lib/bundler/fetcher/index.rb +0 -27
  40. data/lib/bundler/fetcher.rb +10 -17
  41. data/lib/bundler/friendly_errors.rb +5 -32
  42. data/lib/bundler/gem_helper.rb +28 -21
  43. data/lib/bundler/gem_version_promoter.rb +2 -2
  44. data/lib/bundler/index.rb +8 -12
  45. data/lib/bundler/injector.rb +12 -3
  46. data/lib/bundler/inline.rb +2 -1
  47. data/lib/bundler/installer/gem_installer.rb +4 -22
  48. data/lib/bundler/installer/parallel_installer.rb +36 -15
  49. data/lib/bundler/installer/standalone.rb +29 -9
  50. data/lib/bundler/installer.rb +8 -34
  51. data/lib/bundler/lazy_specification.rb +32 -20
  52. data/lib/bundler/lockfile_generator.rb +1 -1
  53. data/lib/bundler/lockfile_parser.rb +16 -45
  54. data/{man → lib/bundler/man}/bundle-add.1 +10 -2
  55. data/lib/bundler/man/bundle-add.1.ronn +7 -1
  56. data/{man → lib/bundler/man}/bundle-binstubs.1 +1 -1
  57. data/{man → lib/bundler/man}/bundle-cache.1 +1 -1
  58. data/{man → lib/bundler/man}/bundle-check.1 +1 -1
  59. data/{man → lib/bundler/man}/bundle-clean.1 +1 -1
  60. data/{man → lib/bundler/man}/bundle-config.1 +27 -19
  61. data/lib/bundler/man/bundle-config.1.ronn +33 -25
  62. data/{man → lib/bundler/man}/bundle-doctor.1 +1 -1
  63. data/{man → lib/bundler/man}/bundle-exec.1 +1 -1
  64. data/{man → lib/bundler/man}/bundle-gem.1 +14 -1
  65. data/lib/bundler/man/bundle-gem.1.ronn +16 -0
  66. data/{man → lib/bundler/man}/bundle-info.1 +1 -1
  67. data/{man → lib/bundler/man}/bundle-init.1 +1 -1
  68. data/{man → lib/bundler/man}/bundle-inject.1 +1 -1
  69. data/{man → lib/bundler/man}/bundle-install.1 +2 -2
  70. data/lib/bundler/man/bundle-install.1.ronn +2 -2
  71. data/{man → lib/bundler/man}/bundle-list.1 +1 -1
  72. data/{man → lib/bundler/man}/bundle-lock.1 +1 -1
  73. data/{man → lib/bundler/man}/bundle-open.1 +1 -1
  74. data/{man → lib/bundler/man}/bundle-outdated.1 +1 -1
  75. data/{man → lib/bundler/man}/bundle-platform.1 +1 -1
  76. data/{man → lib/bundler/man}/bundle-pristine.1 +1 -1
  77. data/{man → lib/bundler/man}/bundle-remove.1 +1 -1
  78. data/{man → lib/bundler/man}/bundle-show.1 +1 -1
  79. data/{man → lib/bundler/man}/bundle-update.1 +5 -5
  80. data/lib/bundler/man/bundle-update.1.ronn +5 -4
  81. data/{man → lib/bundler/man}/bundle-viz.1 +1 -1
  82. data/{man → lib/bundler/man}/bundle.1 +1 -1
  83. data/{man → lib/bundler/man}/gemfile.5 +28 -2
  84. data/lib/bundler/man/gemfile.5.ronn +9 -1
  85. data/{man → lib/bundler/man}/index.txt +0 -0
  86. data/lib/bundler/plugin/api/source.rb +22 -0
  87. data/lib/bundler/plugin/index.rb +4 -1
  88. data/lib/bundler/plugin/installer.rb +10 -10
  89. data/lib/bundler/plugin/source_list.rb +4 -0
  90. data/lib/bundler/plugin.rb +28 -8
  91. data/lib/bundler/process_lock.rb +1 -1
  92. data/lib/bundler/psyched_yaml.rb +1 -13
  93. data/lib/bundler/resolver/spec_group.rb +36 -48
  94. data/lib/bundler/resolver.rb +97 -151
  95. data/lib/bundler/retry.rb +1 -1
  96. data/lib/bundler/ruby_version.rb +1 -1
  97. data/lib/bundler/rubygems_ext.rb +46 -8
  98. data/lib/bundler/rubygems_gem_installer.rb +68 -1
  99. data/lib/bundler/rubygems_integration.rb +43 -60
  100. data/lib/bundler/runtime.rb +18 -11
  101. data/lib/bundler/self_manager.rb +168 -0
  102. data/lib/bundler/settings.rb +97 -21
  103. data/lib/bundler/setup.rb +2 -2
  104. data/lib/bundler/shared_helpers.rb +6 -21
  105. data/lib/bundler/source/git/git_proxy.rb +60 -53
  106. data/lib/bundler/source/git.rb +38 -18
  107. data/lib/bundler/source/metadata.rb +1 -5
  108. data/lib/bundler/source/path/installer.rb +3 -1
  109. data/lib/bundler/source/path.rb +3 -1
  110. data/lib/bundler/source/rubygems.rb +113 -100
  111. data/lib/bundler/source/rubygems_aggregate.rb +68 -0
  112. data/lib/bundler/source.rb +21 -0
  113. data/lib/bundler/source_list.rb +100 -62
  114. data/lib/bundler/source_map.rb +58 -0
  115. data/lib/bundler/spec_set.rb +21 -34
  116. data/lib/bundler/stub_specification.rb +8 -0
  117. data/lib/bundler/templates/Executable.bundler +7 -7
  118. data/lib/bundler/templates/Gemfile +0 -2
  119. data/lib/bundler/templates/gems.rb +0 -3
  120. data/lib/bundler/templates/newgem/CHANGELOG.md.tt +5 -0
  121. data/lib/bundler/templates/newgem/Gemfile.tt +5 -2
  122. data/lib/bundler/templates/newgem/README.md.tt +5 -3
  123. data/lib/bundler/templates/newgem/Rakefile.tt +15 -2
  124. data/lib/bundler/templates/newgem/github/workflows/main.yml.tt +15 -6
  125. data/lib/bundler/templates/newgem/newgem.gemspec.tt +18 -16
  126. data/lib/bundler/templates/newgem/rubocop.yml.tt +3 -0
  127. data/lib/bundler/templates/newgem/sig/newgem.rbs.tt +8 -0
  128. data/lib/bundler/templates/newgem/standard.yml.tt +2 -0
  129. data/lib/bundler/templates/newgem/test/minitest/{newgem_test.rb.tt → test_newgem.rb.tt} +1 -1
  130. data/lib/bundler/ui/shell.rb +1 -1
  131. data/lib/bundler/vendor/.document +1 -0
  132. data/lib/bundler/vendor/connection_pool/LICENSE +20 -0
  133. data/lib/bundler/vendor/connection_pool/lib/connection_pool/timed_stack.rb +19 -21
  134. data/lib/bundler/vendor/connection_pool/lib/connection_pool/version.rb +1 -1
  135. data/lib/bundler/vendor/connection_pool/lib/connection_pool/wrapper.rb +57 -0
  136. data/lib/bundler/vendor/connection_pool/lib/connection_pool.rb +39 -74
  137. data/lib/bundler/vendor/fileutils/LICENSE.txt +22 -0
  138. data/lib/bundler/vendor/molinillo/LICENSE +9 -0
  139. data/lib/bundler/vendor/molinillo/lib/molinillo/delegates/specification_provider.rb +7 -0
  140. data/lib/bundler/vendor/molinillo/lib/molinillo/dependency_graph/vertex.rb +11 -5
  141. data/lib/bundler/vendor/molinillo/lib/molinillo/dependency_graph.rb +2 -3
  142. data/lib/bundler/vendor/molinillo/lib/molinillo/errors.rb +2 -2
  143. data/lib/bundler/vendor/molinillo/lib/molinillo/modules/specification_provider.rb +12 -1
  144. data/lib/bundler/vendor/molinillo/lib/molinillo/resolution.rb +11 -7
  145. data/lib/bundler/vendor/net-http-persistent/README.rdoc +82 -0
  146. data/lib/bundler/vendor/thor/LICENSE.md +20 -0
  147. data/lib/bundler/vendor/thor/lib/thor/actions/file_manipulation.rb +9 -7
  148. data/lib/bundler/vendor/thor/lib/thor/actions/inject_into_file.rb +1 -2
  149. data/lib/bundler/vendor/thor/lib/thor/actions.rb +7 -3
  150. data/lib/bundler/vendor/thor/lib/thor/core_ext/hash_with_indifferent_access.rb +6 -0
  151. data/lib/bundler/vendor/thor/lib/thor/error.rb +10 -5
  152. data/lib/bundler/vendor/thor/lib/thor/parser/arguments.rb +5 -1
  153. data/lib/bundler/vendor/thor/lib/thor/parser/options.rb +28 -9
  154. data/lib/bundler/vendor/thor/lib/thor/shell/basic.rb +27 -6
  155. data/lib/bundler/vendor/thor/lib/thor/shell/color.rb +5 -1
  156. data/lib/bundler/vendor/thor/lib/thor/shell.rb +1 -1
  157. data/lib/bundler/vendor/thor/lib/thor/util.rb +1 -1
  158. data/lib/bundler/vendor/thor/lib/thor/version.rb +1 -1
  159. data/lib/bundler/vendor/thor/lib/thor.rb +5 -6
  160. data/lib/bundler/vendor/tmpdir/lib/tmpdir.rb +1 -1
  161. data/lib/bundler/vendor/tsort/LICENSE.txt +22 -0
  162. data/lib/bundler/vendor/tsort/lib/tsort.rb +453 -0
  163. data/lib/bundler/vendor/uri/LICENSE.txt +22 -0
  164. data/lib/bundler/vendor/uri/lib/uri/common.rb +17 -80
  165. data/lib/bundler/vendor/uri/lib/uri/ftp.rb +0 -1
  166. data/lib/bundler/vendor/uri/lib/uri/generic.rb +5 -6
  167. data/lib/bundler/vendor/uri/lib/uri/http.rb +0 -1
  168. data/lib/bundler/vendor/uri/lib/uri/https.rb +0 -1
  169. data/lib/bundler/vendor/uri/lib/uri/ldap.rb +1 -1
  170. data/lib/bundler/vendor/uri/lib/uri/mailto.rb +0 -1
  171. data/lib/bundler/vendor/uri/lib/uri/rfc2396_parser.rb +1 -14
  172. data/lib/bundler/vendor/uri/lib/uri/rfc3986_parser.rb +1 -12
  173. data/lib/bundler/vendor/uri/lib/uri/version.rb +1 -1
  174. data/lib/bundler/vendor/uri/lib/uri/ws.rb +84 -0
  175. data/lib/bundler/vendor/uri/lib/uri/wss.rb +22 -0
  176. data/lib/bundler/vendor/uri/lib/uri.rb +0 -1
  177. data/lib/bundler/vendored_tsort.rb +4 -0
  178. data/lib/bundler/version.rb +1 -1
  179. data/lib/bundler/worker.rb +19 -4
  180. data/lib/bundler.rb +29 -33
  181. metadata +54 -35
  182. data/lib/bundler/gemdeps.rb +0 -29
  183. data/lib/bundler/vendor/connection_pool/lib/connection_pool/monotonic_time.rb +0 -66
@@ -7,33 +7,34 @@ module Bundler
7
7
  autoload :Validator, File.expand_path("settings/validator", __dir__)
8
8
 
9
9
  BOOL_KEYS = %w[
10
- allow_bundler_dependency_conflicts
11
10
  allow_deployment_source_credential_changes
12
11
  allow_offline_install
13
12
  auto_clean_without_path
14
13
  auto_install
15
14
  cache_all
16
15
  cache_all_platforms
16
+ clean
17
17
  default_install_uses_path
18
18
  deployment
19
- deployment_means_frozen
20
19
  disable_checksum_validation
21
20
  disable_exec_load
22
21
  disable_local_branch_check
23
- disable_multisource
22
+ disable_local_revision_check
24
23
  disable_shared_gems
25
24
  disable_version_check
26
25
  force_ruby_platform
27
26
  forget_cli_options
28
27
  frozen
28
+ gem.changelog
29
29
  gem.coc
30
30
  gem.mit
31
+ git.allow_insecure
31
32
  global_gem_cache
32
33
  ignore_messages
33
34
  init_gems_rb
35
+ inline
34
36
  no_install
35
37
  no_prune
36
- only_update_to_newer_versions
37
38
  path_relative_to_cwd
38
39
  path.system
39
40
  plugins
@@ -43,7 +44,6 @@ module Bundler
43
44
  silence_deprecations
44
45
  silence_root_warning
45
46
  suppress_install_using_messages
46
- unlock_source_unlocks_spec
47
47
  update_requires_all_flag
48
48
  use_gem_version_promoter_for_major_updates
49
49
  ].freeze
@@ -61,6 +61,22 @@ module Bundler
61
61
  without
62
62
  ].freeze
63
63
 
64
+ STRING_KEYS = %w[
65
+ bin
66
+ cache_path
67
+ console
68
+ gem.ci
69
+ gem.github_username
70
+ gem.linter
71
+ gem.rubocop
72
+ gem.test
73
+ gemfile
74
+ path
75
+ shebang
76
+ system_bindir
77
+ trust-policy
78
+ ].freeze
79
+
64
80
  DEFAULT_CONFIG = {
65
81
  "BUNDLE_SILENCE_DEPRECATIONS" => false,
66
82
  "BUNDLE_DISABLE_VERSION_CHECK" => true,
@@ -126,8 +142,8 @@ module Bundler
126
142
  keys = @temporary.keys | @global_config.keys | @local_config.keys | @env_config.keys
127
143
 
128
144
  keys.map do |key|
129
- key.sub(/^BUNDLE_/, "").gsub(/__/, ".").downcase
130
- end
145
+ key.sub(/^BUNDLE_/, "").gsub(/___/, "-").gsub(/__/, ".").downcase
146
+ end.sort
131
147
  end
132
148
 
133
149
  def local_overrides
@@ -173,29 +189,37 @@ module Bundler
173
189
  locations = []
174
190
 
175
191
  if value = @temporary[key]
176
- locations << "Set for the current command: #{converted_value(value, exposed_key).inspect}"
192
+ locations << "Set for the current command: #{printable_value(value, exposed_key).inspect}"
177
193
  end
178
194
 
179
195
  if value = @local_config[key]
180
- locations << "Set for your local app (#{local_config_file}): #{converted_value(value, exposed_key).inspect}"
196
+ locations << "Set for your local app (#{local_config_file}): #{printable_value(value, exposed_key).inspect}"
181
197
  end
182
198
 
183
199
  if value = @env_config[key]
184
- locations << "Set via #{key}: #{converted_value(value, exposed_key).inspect}"
200
+ locations << "Set via #{key}: #{printable_value(value, exposed_key).inspect}"
185
201
  end
186
202
 
187
203
  if value = @global_config[key]
188
- locations << "Set for the current user (#{global_config_file}): #{converted_value(value, exposed_key).inspect}"
204
+ locations << "Set for the current user (#{global_config_file}): #{printable_value(value, exposed_key).inspect}"
189
205
  end
190
206
 
191
207
  return ["You have not configured a value for `#{exposed_key}`"] if locations.empty?
192
208
  locations
193
209
  end
194
210
 
211
+ def processor_count
212
+ require "etc"
213
+ Etc.nprocessors
214
+ rescue StandardError
215
+ 1
216
+ end
217
+
195
218
  # for legacy reasons, in Bundler 2, we do not respect :disable_shared_gems
196
219
  def path
197
220
  configs.each do |_level, settings|
198
221
  path = value_for("path", settings)
222
+ path = "vendor/bundle" if value_for("deployment", settings) && path.nil?
199
223
  path_system = value_for("path.system", settings)
200
224
  disabled_shared_gems = value_for("disable_shared_gems", settings)
201
225
  next if path.nil? && path_system.nil? && disabled_shared_gems.nil?
@@ -277,9 +301,7 @@ module Bundler
277
301
  end
278
302
 
279
303
  def key_for(key)
280
- key = Settings.normalize_uri(key).to_s if key.is_a?(String) && /https?:/ =~ key
281
- key = key.to_s.gsub(".", "__").upcase
282
- "BUNDLE_#{key}"
304
+ self.class.key_for(key)
283
305
  end
284
306
 
285
307
  private
@@ -314,6 +336,10 @@ module Bundler
314
336
  BOOL_KEYS.include?(name.to_s) || BOOL_KEYS.include?(parent_setting_for(name.to_s))
315
337
  end
316
338
 
339
+ def is_string(name)
340
+ STRING_KEYS.include?(name.to_s) || name.to_s.start_with?("local.") || name.to_s.start_with?("mirror.") || name.to_s.start_with?("build.")
341
+ end
342
+
317
343
  def to_bool(value)
318
344
  case value
319
345
  when nil, /\A(false|f|no|n|0|)\z/i, false
@@ -331,6 +357,14 @@ module Bundler
331
357
  ARRAY_KEYS.include?(key.to_s)
332
358
  end
333
359
 
360
+ def is_credential(key)
361
+ key == "gem.push_key"
362
+ end
363
+
364
+ def is_userinfo(value)
365
+ value.include?(":")
366
+ end
367
+
334
368
  def to_array(value)
335
369
  return [] unless value
336
370
  value.split(":").map(&:to_sym)
@@ -377,15 +411,38 @@ module Bundler
377
411
  end
378
412
  end
379
413
 
414
+ def printable_value(value, key)
415
+ converted = converted_value(value, key)
416
+ return converted unless converted.is_a?(String)
417
+
418
+ if is_string(key)
419
+ converted
420
+ elsif is_credential(key)
421
+ "[REDACTED]"
422
+ elsif is_userinfo(converted)
423
+ username, pass = converted.split(":", 2)
424
+
425
+ if pass == "x-oauth-basic"
426
+ username = "[REDACTED]"
427
+ else
428
+ pass = "[REDACTED]"
429
+ end
430
+
431
+ [username, pass].join(":")
432
+ else
433
+ converted
434
+ end
435
+ end
436
+
380
437
  def global_config_file
381
438
  if ENV["BUNDLE_CONFIG"] && !ENV["BUNDLE_CONFIG"].empty?
382
439
  Pathname.new(ENV["BUNDLE_CONFIG"])
383
- else
384
- begin
385
- Bundler.user_bundle_path("config")
386
- rescue PermissionError, GenericSystemCallError
387
- nil
388
- end
440
+ elsif ENV["BUNDLE_USER_CONFIG"] && !ENV["BUNDLE_USER_CONFIG"].empty?
441
+ Pathname.new(ENV["BUNDLE_USER_CONFIG"])
442
+ elsif ENV["BUNDLE_USER_HOME"] && !ENV["BUNDLE_USER_HOME"].empty?
443
+ Pathname.new(ENV["BUNDLE_USER_HOME"]).join("config")
444
+ elsif Bundler.rubygems.user_home && !Bundler.rubygems.user_home.empty?
445
+ Pathname.new(Bundler.rubygems.user_home).join(".bundle/config")
389
446
  end
390
447
  end
391
448
 
@@ -399,7 +456,20 @@ module Bundler
399
456
  valid_file = file.exist? && !file.size.zero?
400
457
  return {} unless valid_file
401
458
  require_relative "yaml_serializer"
402
- YAMLSerializer.load file.read
459
+ YAMLSerializer.load(file.read).inject({}) do |config, (k, v)|
460
+ new_k = k
461
+
462
+ if k.include?("-")
463
+ Bundler.ui.warn "Your #{file} config includes `#{k}`, which contains the dash character (`-`).\n" \
464
+ "This is deprecated, because configuration through `ENV` should be possible, but `ENV` keys cannot include dashes.\n" \
465
+ "Please edit #{file} and replace any dashes in configuration keys with a triple underscore (`___`)."
466
+
467
+ new_k = k.gsub("-", "___")
468
+ end
469
+
470
+ config[new_k] = v
471
+ config
472
+ end
403
473
  end
404
474
  end
405
475
 
@@ -416,6 +486,12 @@ module Bundler
416
486
  \z
417
487
  /ix.freeze
418
488
 
489
+ def self.key_for(key)
490
+ key = normalize_uri(key).to_s if key.is_a?(String) && /https?:/ =~ key
491
+ key = key.to_s.gsub(".", "__").gsub("-", "___").upcase
492
+ "BUNDLE_#{key}"
493
+ end
494
+
419
495
  # TODO: duplicates Rubygems#normalize_uri
420
496
  # TODO: is this the correct place to validate mirror URIs?
421
497
  def self.normalize_uri(uri)
data/lib/bundler/setup.rb CHANGED
@@ -9,10 +9,10 @@ if Bundler::SharedHelpers.in_bundle?
9
9
  begin
10
10
  Bundler.ui.silence { Bundler.setup }
11
11
  rescue Bundler::BundlerError => e
12
- Bundler.ui.warn "\e[31m#{e.message}\e[0m"
12
+ Bundler.ui.error e.message
13
13
  Bundler.ui.warn e.backtrace.join("\n") if ENV["DEBUG"]
14
14
  if e.is_a?(Bundler::GemNotFound)
15
- Bundler.ui.warn "\e[33mRun `bundle install` to install missing gems.\e[0m"
15
+ Bundler.ui.warn "Run `bundle install` to install missing gems."
16
16
  end
17
17
  exit e.status_code
18
18
  end
@@ -109,7 +109,7 @@ module Bundler
109
109
  raise VirtualProtocolError.new
110
110
  rescue Errno::ENOSPC
111
111
  raise NoSpaceOnDeviceError.new(path, action)
112
- rescue *[const_get_safely(:ENOTSUP, Errno)].compact
112
+ rescue Errno::ENOTSUP
113
113
  raise OperationNotSupportedError.new(path, action)
114
114
  rescue Errno::EEXIST, Errno::ENOENT
115
115
  raise
@@ -117,13 +117,6 @@ module Bundler
117
117
  raise GenericSystemCallError.new(e, "There was an error accessing `#{path}`.")
118
118
  end
119
119
 
120
- def const_get_safely(constant_name, namespace)
121
- const_in_namespace = namespace.constants.include?(constant_name.to_s) ||
122
- namespace.constants.include?(constant_name.to_sym)
123
- return nil unless const_in_namespace
124
- namespace.const_get(constant_name)
125
- end
126
-
127
120
  def major_deprecation(major_version, message, print_caller_location: false)
128
121
  if print_caller_location
129
122
  caller_location = caller_locations(2, 2).first
@@ -152,13 +145,6 @@ module Bundler
152
145
  Bundler.ui.warn message
153
146
  end
154
147
 
155
- def trap(signal, override = false, &block)
156
- prior = Signal.trap(signal) do
157
- block.call
158
- prior.call unless override
159
- end
160
- end
161
-
162
148
  def ensure_same_dependencies(spec, old_deps, new_deps)
163
149
  new_deps = new_deps.reject {|d| d.type == :development }
164
150
  old_deps = old_deps.reject {|d| d.type == :development }
@@ -194,11 +180,11 @@ module Bundler
194
180
  return @md5_available if defined?(@md5_available)
195
181
  @md5_available = begin
196
182
  require "openssl"
197
- OpenSSL::Digest.digest("MD5", "")
183
+ ::OpenSSL::Digest.digest("MD5", "")
198
184
  true
199
185
  rescue LoadError
200
186
  true
201
- rescue OpenSSL::Digest::DigestError
187
+ rescue ::OpenSSL::Digest::DigestError
202
188
  false
203
189
  end
204
190
  end
@@ -253,7 +239,7 @@ module Bundler
253
239
  current = File.expand_path(SharedHelpers.pwd).tap{|x| x.untaint if RUBY_VERSION < "2.7" }
254
240
 
255
241
  until !File.directory?(current) || current == previous
256
- if ENV["BUNDLE_SPEC_RUN"]
242
+ if ENV["BUNDLER_SPEC_RUN"]
257
243
  # avoid stepping above the tmp directory when testing
258
244
  gemspec = if ENV["GEM_COMMAND"]
259
245
  # for Ruby Core
@@ -327,12 +313,11 @@ module Bundler
327
313
  end
328
314
 
329
315
  def clean_load_path
330
- bundler_lib = bundler_ruby_lib
331
-
332
316
  loaded_gem_paths = Bundler.rubygems.loaded_gem_paths
333
317
 
334
318
  $LOAD_PATH.reject! do |p|
335
- next if resolve_path(p).start_with?(bundler_lib)
319
+ resolved_path = resolve_path(p)
320
+ next if $LOADED_FEATURES.any? {|lf| lf.start_with?(resolved_path) }
336
321
  loaded_gem_paths.delete(p)
337
322
  end
338
323
  $LOAD_PATH.uniq!
@@ -1,7 +1,5 @@
1
1
  # frozen_string_literal: true
2
2
 
3
- require "shellwords"
4
-
5
3
  module Bundler
6
4
  class Source
7
5
  class Git
@@ -17,7 +15,7 @@ module Bundler
17
15
  class GitNotAllowedError < GitError
18
16
  def initialize(command)
19
17
  msg = String.new
20
- msg << "Bundler is trying to run a `git #{command}` at runtime. You probably need to run `bundle install`. However, "
18
+ msg << "Bundler is trying to run `#{command}` at runtime. You probably need to run `bundle install`. However, "
21
19
  msg << "this error message could probably be more useful. Please submit a ticket at https://github.com/rubygems/rubygems/issues/new?labels=Bundler&template=bundler-related-issue.md "
22
20
  msg << "with steps to reproduce as well as the following\n\nCALLER: #{caller.join("\n")}"
23
21
  super msg
@@ -27,11 +25,11 @@ module Bundler
27
25
  class GitCommandError < GitError
28
26
  attr_reader :command
29
27
 
30
- def initialize(command, path, destination_path, extra_info = nil)
28
+ def initialize(command, path, extra_info = nil)
31
29
  @command = command
32
30
 
33
31
  msg = String.new
34
- msg << "Git error: command `git #{command}` in directory #{destination_path} has failed."
32
+ msg << "Git error: command `#{command}` in directory #{path} has failed."
35
33
  msg << "\n#{extra_info}" if extra_info
36
34
  msg << "\nIf this error persists you could try removing the cache directory '#{path}'" if path.exist?
37
35
  super msg
@@ -39,9 +37,9 @@ module Bundler
39
37
  end
40
38
 
41
39
  class MissingGitRevisionError < GitCommandError
42
- def initialize(command, path, destination_path, ref, repo)
40
+ def initialize(command, destination_path, ref, repo)
43
41
  msg = "Revision #{ref} does not exist in the repository #{repo}. Maybe you misspelled it?"
44
- super command, path, destination_path, msg
42
+ super command, destination_path, msg
45
43
  end
46
44
  end
47
45
 
@@ -58,7 +56,6 @@ module Bundler
58
56
  @ref = ref
59
57
  @revision = revision
60
58
  @git = git
61
- raise GitNotInstalledError.new if allow? && !Bundler.git_present?
62
59
  end
63
60
 
64
61
  def revision
@@ -67,13 +64,13 @@ module Bundler
67
64
 
68
65
  def branch
69
66
  @branch ||= allowed_with_path do
70
- git("rev-parse --abbrev-ref HEAD", :dir => path).strip
67
+ git("rev-parse", "--abbrev-ref", "HEAD", :dir => path).strip
71
68
  end
72
69
  end
73
70
 
74
71
  def contains?(commit)
75
72
  allowed_with_path do
76
- result, status = git_null("branch --contains #{commit}", :dir => path)
73
+ result, status = git_null("branch", "--contains", commit, :dir => path)
77
74
  status.success? && result =~ /^\* (.*)$/
78
75
  end
79
76
  end
@@ -88,20 +85,22 @@ module Bundler
88
85
 
89
86
  def checkout
90
87
  return if path.exist? && has_revision_cached?
91
- extra_ref = "#{Shellwords.shellescape(ref)}:#{Shellwords.shellescape(ref)}" if ref && ref.start_with?("refs/")
88
+ extra_ref = "#{ref}:#{ref}" if ref && ref.start_with?("refs/")
92
89
 
93
90
  Bundler.ui.info "Fetching #{URICredentialsFilter.credential_filtered_uri(uri)}"
94
91
 
92
+ configured_uri = configured_uri_for(uri).to_s
93
+
95
94
  unless path.exist?
96
95
  SharedHelpers.filesystem_access(path.dirname) do |p|
97
96
  FileUtils.mkdir_p(p)
98
97
  end
99
- git_retry %(clone #{uri_escaped_with_configured_credentials} "#{path}" --bare --no-hardlinks --quiet)
98
+ git_retry "clone", "--bare", "--no-hardlinks", "--quiet", "--", configured_uri, path.to_s
100
99
  return unless extra_ref
101
100
  end
102
101
 
103
102
  with_path do
104
- git_retry %(fetch --force --quiet --tags #{uri_escaped_with_configured_credentials} "refs/heads/*:refs/heads/*" #{extra_ref}), :dir => path
103
+ git_retry(*["fetch", "--force", "--quiet", "--tags", "--", configured_uri, "refs/heads/*:refs/heads/*", extra_ref].compact, :dir => path)
105
104
  end
106
105
  end
107
106
 
@@ -115,7 +114,7 @@ module Bundler
115
114
  SharedHelpers.filesystem_access(destination) do |p|
116
115
  FileUtils.rm_rf(p)
117
116
  end
118
- git_retry %(clone --no-checkout --quiet "#{path}" "#{destination}")
117
+ git_retry "clone", "--no-checkout", "--quiet", path.to_s, destination.to_s
119
118
  File.chmod(((File.stat(destination).mode | 0o777) & ~File.umask), destination)
120
119
  rescue Errno::EEXIST => e
121
120
  file_path = e.message[%r{.*?((?:[a-zA-Z]:)?/.*)}, 1]
@@ -125,56 +124,59 @@ module Bundler
125
124
  end
126
125
  end
127
126
  # method 2
128
- git_retry %(fetch --force --quiet --tags "#{path}"), :dir => destination
127
+ git_retry "fetch", "--force", "--quiet", "--tags", path.to_s, :dir => destination
129
128
 
130
129
  begin
131
- git "reset --hard #{@revision}", :dir => destination
130
+ git "reset", "--hard", @revision, :dir => destination
132
131
  rescue GitCommandError => e
133
- raise MissingGitRevisionError.new(e.command, path, destination, @revision, URICredentialsFilter.credential_filtered_uri(uri))
132
+ raise MissingGitRevisionError.new(e.command, destination, @revision, URICredentialsFilter.credential_filtered_uri(uri))
134
133
  end
135
134
 
136
135
  if submodules
137
- git_retry "submodule update --init --recursive", :dir => destination
136
+ git_retry "submodule", "update", "--init", "--recursive", :dir => destination
138
137
  elsif Gem::Version.create(version) >= Gem::Version.create("2.9.0")
139
138
  inner_command = "git -C $toplevel submodule deinit --force $sm_path"
140
- inner_command = inner_command.gsub("$") { '\$' } unless Bundler::WINDOWS
141
- git_retry "submodule foreach --quiet \"#{inner_command}\"", :dir => destination
139
+ git_retry "submodule", "foreach", "--quiet", inner_command, :dir => destination
142
140
  end
143
141
  end
144
142
 
145
143
  private
146
144
 
147
- def git_null(command, dir: SharedHelpers.pwd)
145
+ def git_null(*command, dir: nil)
148
146
  check_allowed(command)
149
147
 
150
148
  out, status = SharedHelpers.with_clean_git_env do
151
- capture_and_ignore_stderr("git #{command}", :chdir => dir.to_s)
149
+ capture_and_ignore_stderr(*capture3_args_for(command, dir))
152
150
  end
153
151
 
154
152
  [URICredentialsFilter.credential_filtered_string(out, uri), status]
155
153
  end
156
154
 
157
- def git_retry(command, dir: SharedHelpers.pwd)
158
- Bundler::Retry.new("`git #{URICredentialsFilter.credential_filtered_string(command, uri)}`", GitNotAllowedError).attempts do
159
- git(command, :dir => dir)
155
+ def git_retry(*command, dir: nil)
156
+ command_with_no_credentials = check_allowed(command)
157
+
158
+ Bundler::Retry.new("`#{command_with_no_credentials}` at #{dir || SharedHelpers.pwd}").attempts do
159
+ git(*command, :dir => dir)
160
160
  end
161
161
  end
162
162
 
163
- def git(command, dir: SharedHelpers.pwd)
163
+ def git(*command, dir: nil)
164
164
  command_with_no_credentials = check_allowed(command)
165
165
 
166
166
  out, status = SharedHelpers.with_clean_git_env do
167
- capture_and_filter_stderr(uri, "git #{command}", :chdir => dir.to_s)
167
+ capture_and_filter_stderr(*capture3_args_for(command, dir))
168
168
  end
169
169
 
170
- raise GitCommandError.new(command_with_no_credentials, path, dir) unless status.success?
170
+ filtered_out = URICredentialsFilter.credential_filtered_string(out, uri)
171
+
172
+ raise GitCommandError.new(command_with_no_credentials, dir || SharedHelpers.pwd, filtered_out) unless status.success?
171
173
 
172
- URICredentialsFilter.credential_filtered_string(out, uri)
174
+ filtered_out
173
175
  end
174
176
 
175
177
  def has_revision_cached?
176
178
  return unless @revision
177
- with_path { git("cat-file -e #{@revision}", :dir => path) }
179
+ with_path { git("cat-file", "-e", @revision, :dir => path) }
178
180
  true
179
181
  rescue GitError
180
182
  false
@@ -186,24 +188,10 @@ module Bundler
186
188
 
187
189
  def find_local_revision
188
190
  allowed_with_path do
189
- git("rev-parse --verify #{Shellwords.shellescape(ref)}", :dir => path).strip
191
+ git("rev-parse", "--verify", ref || "HEAD", :dir => path).strip
190
192
  end
191
193
  rescue GitCommandError => e
192
- raise MissingGitRevisionError.new(e.command, path, path, ref, URICredentialsFilter.credential_filtered_uri(uri))
193
- end
194
-
195
- # Escape the URI for git commands
196
- def uri_escaped_with_configured_credentials
197
- remote = configured_uri_for(uri)
198
- if Bundler::WINDOWS
199
- # Windows quoting requires double quotes only, with double quotes
200
- # inside the string escaped by being doubled.
201
- '"' + remote.gsub('"') { '""' } + '"'
202
- else
203
- # Bash requires single quoted strings, with the single quotes escaped
204
- # by ending the string, escaping the quote, and restarting the string.
205
- "'" + remote.gsub("'") { "'\\''" } + "'"
206
- end
194
+ raise MissingGitRevisionError.new(e.command, path, ref, URICredentialsFilter.credential_filtered_uri(uri))
207
195
  end
208
196
 
209
197
  # Adds credentials to the URI as Fetcher#configured_uri_for does
@@ -219,7 +207,11 @@ module Bundler
219
207
  end
220
208
 
221
209
  def allow?
222
- @git ? @git.allow_git_ops? : true
210
+ allowed = @git ? @git.allow_git_ops? : true
211
+
212
+ raise GitNotInstalledError.new if allowed && !Bundler.git_present?
213
+
214
+ allowed
223
215
  end
224
216
 
225
217
  def with_path(&blk)
@@ -233,23 +225,38 @@ module Bundler
233
225
  end
234
226
 
235
227
  def check_allowed(command)
236
- command_with_no_credentials = URICredentialsFilter.credential_filtered_string(command, uri)
228
+ require "shellwords"
229
+ command_with_no_credentials = URICredentialsFilter.credential_filtered_string("git #{command.shelljoin}", uri)
237
230
  raise GitNotAllowedError.new(command_with_no_credentials) unless allow?
238
231
  command_with_no_credentials
239
232
  end
240
233
 
241
- def capture_and_filter_stderr(uri, cmd, chdir: SharedHelpers.pwd)
234
+ def capture_and_filter_stderr(*cmd)
242
235
  require "open3"
243
- return_value, captured_err, status = Open3.capture3(cmd, :chdir => chdir)
244
- Bundler.ui.warn URICredentialsFilter.credential_filtered_string(captured_err, uri) if uri && !captured_err.empty?
236
+ return_value, captured_err, status = Open3.capture3(*cmd)
237
+ Bundler.ui.warn URICredentialsFilter.credential_filtered_string(captured_err, uri) unless captured_err.empty?
245
238
  [return_value, status]
246
239
  end
247
240
 
248
- def capture_and_ignore_stderr(cmd, chdir: SharedHelpers.pwd)
241
+ def capture_and_ignore_stderr(*cmd)
249
242
  require "open3"
250
- return_value, _, status = Open3.capture3(cmd, :chdir => chdir)
243
+ return_value, _, status = Open3.capture3(*cmd)
251
244
  [return_value, status]
252
245
  end
246
+
247
+ def capture3_args_for(cmd, dir)
248
+ return ["git", *cmd] unless dir
249
+
250
+ if Bundler.feature_flag.bundler_3_mode? || supports_minus_c?
251
+ ["git", "-C", dir.to_s, *cmd]
252
+ else
253
+ ["git", *cmd, { :chdir => dir.to_s }]
254
+ end
255
+ end
256
+
257
+ def supports_minus_c?
258
+ @supports_minus_c ||= Gem::Version.new(version) >= Gem::Version.new("1.8.5")
259
+ end
253
260
  end
254
261
  end
255
262
  end