bundler 2.2.11 → 2.3.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.
Files changed (174) hide show
  1. checksums.yaml +4 -4
  2. data/CHANGELOG.md +414 -5
  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 +1 -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 +24 -5
  12. data/lib/bundler/cli/exec.rb +1 -6
  13. data/lib/bundler/cli/gem.rb +130 -26
  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/platform.rb +1 -1
  22. data/lib/bundler/cli/remove.rb +1 -2
  23. data/lib/bundler/cli/update.rb +17 -8
  24. data/lib/bundler/cli.rb +41 -55
  25. data/lib/bundler/compact_index_client/cache.rb +0 -9
  26. data/lib/bundler/compact_index_client/updater.rb +10 -11
  27. data/lib/bundler/compact_index_client.rb +2 -8
  28. data/lib/bundler/current_ruby.rb +5 -4
  29. data/lib/bundler/definition.rb +147 -290
  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/env.rb +1 -1
  35. data/lib/bundler/environment_preserver.rb +4 -1
  36. data/lib/bundler/errors.rb +19 -3
  37. data/lib/bundler/feature_flag.rb +0 -4
  38. data/lib/bundler/fetcher/compact_index.rb +10 -15
  39. data/lib/bundler/fetcher/downloader.rb +9 -6
  40. data/lib/bundler/fetcher/index.rb +0 -27
  41. data/lib/bundler/fetcher.rb +10 -16
  42. data/lib/bundler/friendly_errors.rb +5 -32
  43. data/lib/bundler/gem_helper.rb +21 -16
  44. data/lib/bundler/index.rb +2 -7
  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 +14 -9
  50. data/lib/bundler/installer.rb +8 -17
  51. data/lib/bundler/lazy_specification.rb +23 -2
  52. data/lib/bundler/lockfile_generator.rb +1 -1
  53. data/lib/bundler/lockfile_parser.rb +16 -45
  54. data/lib/bundler/man/bundle-add.1 +10 -2
  55. data/lib/bundler/man/bundle-add.1.ronn +7 -1
  56. data/lib/bundler/man/bundle-binstubs.1 +1 -1
  57. data/lib/bundler/man/bundle-cache.1 +1 -1
  58. data/lib/bundler/man/bundle-check.1 +1 -1
  59. data/lib/bundler/man/bundle-clean.1 +1 -1
  60. data/lib/bundler/man/bundle-config.1 +23 -15
  61. data/lib/bundler/man/bundle-config.1.ronn +24 -17
  62. data/lib/bundler/man/bundle-doctor.1 +1 -1
  63. data/lib/bundler/man/bundle-exec.1 +1 -1
  64. data/lib/bundler/man/bundle-gem.1 +14 -1
  65. data/lib/bundler/man/bundle-gem.1.ronn +16 -0
  66. data/lib/bundler/man/bundle-info.1 +1 -1
  67. data/lib/bundler/man/bundle-init.1 +1 -1
  68. data/lib/bundler/man/bundle-inject.1 +1 -1
  69. data/lib/bundler/man/bundle-install.1 +2 -2
  70. data/lib/bundler/man/bundle-install.1.ronn +2 -2
  71. data/lib/bundler/man/bundle-list.1 +1 -1
  72. data/lib/bundler/man/bundle-lock.1 +1 -1
  73. data/lib/bundler/man/bundle-open.1 +1 -1
  74. data/lib/bundler/man/bundle-outdated.1 +1 -1
  75. data/lib/bundler/man/bundle-platform.1 +1 -1
  76. data/lib/bundler/man/bundle-pristine.1 +1 -1
  77. data/lib/bundler/man/bundle-remove.1 +1 -1
  78. data/lib/bundler/man/bundle-show.1 +1 -1
  79. data/lib/bundler/man/bundle-update.1 +5 -5
  80. data/lib/bundler/man/bundle-update.1.ronn +5 -4
  81. data/lib/bundler/man/bundle-viz.1 +1 -1
  82. data/lib/bundler/man/bundle.1 +1 -1
  83. data/lib/bundler/man/gemfile.5 +28 -2
  84. data/lib/bundler/man/gemfile.5.ronn +9 -1
  85. data/lib/bundler/plugin/api/source.rb +22 -0
  86. data/lib/bundler/plugin/index.rb +4 -1
  87. data/lib/bundler/plugin/installer.rb +10 -10
  88. data/lib/bundler/plugin/source_list.rb +4 -0
  89. data/lib/bundler/plugin.rb +28 -8
  90. data/lib/bundler/process_lock.rb +1 -1
  91. data/lib/bundler/psyched_yaml.rb +1 -13
  92. data/lib/bundler/remote_specification.rb +7 -0
  93. data/lib/bundler/resolver/spec_group.rb +1 -25
  94. data/lib/bundler/resolver.rb +55 -147
  95. data/lib/bundler/retry.rb +1 -1
  96. data/lib/bundler/ruby_version.rb +1 -1
  97. data/lib/bundler/rubygems_ext.rb +30 -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 +96 -20
  103. data/lib/bundler/setup.rb +2 -2
  104. data/lib/bundler/shared_helpers.rb +4 -19
  105. data/lib/bundler/source/git/git_proxy.rb +8 -6
  106. data/lib/bundler/source/git.rb +22 -4
  107. data/lib/bundler/source/metadata.rb +1 -5
  108. data/lib/bundler/source/path/installer.rb +1 -1
  109. data/lib/bundler/source/path.rb +3 -1
  110. data/lib/bundler/source/rubygems.rb +111 -106
  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 -60
  114. data/lib/bundler/source_map.rb +58 -0
  115. data/lib/bundler/spec_set.rb +17 -31
  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/Gemfile.tt +5 -2
  121. data/lib/bundler/templates/newgem/README.md.tt +5 -3
  122. data/lib/bundler/templates/newgem/Rakefile.tt +15 -2
  123. data/lib/bundler/templates/newgem/github/workflows/main.yml.tt +15 -6
  124. data/lib/bundler/templates/newgem/newgem.gemspec.tt +18 -16
  125. data/lib/bundler/templates/newgem/sig/newgem.rbs.tt +8 -0
  126. data/lib/bundler/templates/newgem/standard.yml.tt +3 -0
  127. data/lib/bundler/templates/newgem/test/minitest/{newgem_test.rb.tt → test_newgem.rb.tt} +1 -1
  128. data/lib/bundler/ui/shell.rb +1 -1
  129. data/lib/bundler/vendor/.document +1 -0
  130. data/lib/bundler/vendor/connection_pool/LICENSE +20 -0
  131. data/lib/bundler/vendor/connection_pool/lib/connection_pool/timed_stack.rb +19 -21
  132. data/lib/bundler/vendor/connection_pool/lib/connection_pool/version.rb +1 -1
  133. data/lib/bundler/vendor/connection_pool/lib/connection_pool/wrapper.rb +57 -0
  134. data/lib/bundler/vendor/connection_pool/lib/connection_pool.rb +39 -74
  135. data/lib/bundler/vendor/fileutils/LICENSE.txt +22 -0
  136. data/lib/bundler/vendor/molinillo/LICENSE +9 -0
  137. data/lib/bundler/vendor/molinillo/lib/molinillo/dependency_graph.rb +2 -2
  138. data/lib/bundler/vendor/molinillo/lib/molinillo/modules/specification_provider.rb +1 -1
  139. data/lib/bundler/vendor/net-http-persistent/README.rdoc +82 -0
  140. data/lib/bundler/vendor/thor/LICENSE.md +20 -0
  141. data/lib/bundler/vendor/thor/lib/thor/actions/file_manipulation.rb +5 -5
  142. data/lib/bundler/vendor/thor/lib/thor/actions/inject_into_file.rb +1 -2
  143. data/lib/bundler/vendor/thor/lib/thor/actions.rb +6 -2
  144. data/lib/bundler/vendor/thor/lib/thor/core_ext/hash_with_indifferent_access.rb +6 -0
  145. data/lib/bundler/vendor/thor/lib/thor/error.rb +9 -4
  146. data/lib/bundler/vendor/thor/lib/thor/parser/options.rb +19 -1
  147. data/lib/bundler/vendor/thor/lib/thor/shell/basic.rb +22 -4
  148. data/lib/bundler/vendor/thor/lib/thor/shell.rb +1 -1
  149. data/lib/bundler/vendor/thor/lib/thor/util.rb +1 -1
  150. data/lib/bundler/vendor/thor/lib/thor/version.rb +1 -1
  151. data/lib/bundler/vendor/tmpdir/lib/tmpdir.rb +1 -1
  152. data/lib/bundler/vendor/tsort/LICENSE.txt +22 -0
  153. data/lib/bundler/vendor/tsort/lib/tsort.rb +453 -0
  154. data/lib/bundler/vendor/uri/LICENSE.txt +22 -0
  155. data/lib/bundler/vendor/uri/lib/uri/common.rb +17 -80
  156. data/lib/bundler/vendor/uri/lib/uri/ftp.rb +0 -1
  157. data/lib/bundler/vendor/uri/lib/uri/generic.rb +5 -6
  158. data/lib/bundler/vendor/uri/lib/uri/http.rb +0 -1
  159. data/lib/bundler/vendor/uri/lib/uri/https.rb +0 -1
  160. data/lib/bundler/vendor/uri/lib/uri/ldap.rb +1 -1
  161. data/lib/bundler/vendor/uri/lib/uri/mailto.rb +0 -1
  162. data/lib/bundler/vendor/uri/lib/uri/rfc2396_parser.rb +1 -14
  163. data/lib/bundler/vendor/uri/lib/uri/rfc3986_parser.rb +1 -12
  164. data/lib/bundler/vendor/uri/lib/uri/version.rb +1 -1
  165. data/lib/bundler/vendor/uri/lib/uri/ws.rb +84 -0
  166. data/lib/bundler/vendor/uri/lib/uri/wss.rb +22 -0
  167. data/lib/bundler/vendor/uri/lib/uri.rb +0 -1
  168. data/lib/bundler/vendored_tsort.rb +4 -0
  169. data/lib/bundler/version.rb +1 -1
  170. data/lib/bundler/worker.rb +19 -4
  171. data/lib/bundler.rb +28 -31
  172. metadata +27 -9
  173. data/lib/bundler/gemdeps.rb +0 -29
  174. data/lib/bundler/vendor/connection_pool/lib/connection_pool/monotonic_time.rb +0 -66
@@ -12,32 +12,30 @@ module Bundler
12
12
  EXT_LOCK = Monitor.new
13
13
  end
14
14
 
15
- def self.version
16
- @version ||= Gem::Version.new(Gem::VERSION)
17
- end
18
-
19
- def self.provides?(req_str)
20
- Gem::Requirement.new(req_str).satisfied_by?(version)
21
- end
22
-
23
15
  def initialize
24
16
  @replaced_methods = {}
25
17
  backport_ext_builder_monitor
26
18
  end
27
19
 
28
20
  def version
29
- self.class.version
21
+ @version ||= Gem.rubygems_version
30
22
  end
31
23
 
32
24
  def provides?(req_str)
33
- self.class.provides?(req_str)
25
+ Gem::Requirement.new(req_str).satisfied_by?(version)
26
+ end
27
+
28
+ def supports_bundler_trampolining?
29
+ provides?(">= 3.3.0.a")
34
30
  end
35
31
 
36
32
  def build_args
33
+ require "rubygems/command"
37
34
  Gem::Command.build_args
38
35
  end
39
36
 
40
37
  def build_args=(args)
38
+ require "rubygems/command"
41
39
  Gem::Command.build_args = args
42
40
  end
43
41
 
@@ -84,16 +82,12 @@ module Bundler
84
82
  def spec_missing_extensions?(spec, default = true)
85
83
  return spec.missing_extensions? if spec.respond_to?(:missing_extensions?)
86
84
 
87
- return false if spec_default_gem?(spec)
85
+ return false if spec.default_gem?
88
86
  return false if spec.extensions.empty?
89
87
 
90
88
  default
91
89
  end
92
90
 
93
- def spec_default_gem?(spec)
94
- spec.respond_to?(:default_gem?) && spec.default_gem?
95
- end
96
-
97
91
  def spec_matches_for_glob(spec, glob)
98
92
  return spec.matches_for_glob(glob) if spec.respond_to?(:matches_for_glob)
99
93
 
@@ -117,7 +111,7 @@ module Bundler
117
111
  Bundler.ui.error "#{e.class}: #{e.message}"
118
112
  Bundler.ui.trace e
119
113
  raise
120
- rescue YamlLibrarySyntaxError => e
114
+ rescue ::Psych::SyntaxError => e
121
115
  raise YamlSyntaxError.new(e, "Your RubyGems configuration, which is " \
122
116
  "usually located in ~/.gemrc, contains invalid YAML syntax.")
123
117
  end
@@ -144,19 +138,6 @@ module Bundler
144
138
  end
145
139
  end
146
140
 
147
- def sources=(val)
148
- # Gem.configuration creates a new Gem::ConfigFile, which by default will read ~/.gemrc
149
- # If that file exists, its settings (including sources) will overwrite the values we
150
- # are about to set here. In order to avoid that, we force memoizing the config file now.
151
- configuration
152
-
153
- Gem.sources = val
154
- end
155
-
156
- def sources
157
- Gem.sources
158
- end
159
-
160
141
  def gem_dir
161
142
  Gem.dir
162
143
  end
@@ -234,18 +215,6 @@ module Bundler
234
215
  EXT_LOCK
235
216
  end
236
217
 
237
- def with_build_args(args)
238
- ext_lock.synchronize do
239
- old_args = build_args
240
- begin
241
- self.build_args = args
242
- yield
243
- ensure
244
- self.build_args = old_args
245
- end
246
- end
247
- end
248
-
249
218
  def spec_from_gem(path, policy = nil)
250
219
  require "rubygems/security"
251
220
  require_relative "psyched_yaml"
@@ -502,14 +471,15 @@ module Bundler
502
471
  end
503
472
 
504
473
  def fetch_specs(remote, name)
474
+ require "rubygems/remote_fetcher"
505
475
  path = remote.uri.to_s + "#{name}.#{Gem.marshal_version}.gz"
506
476
  fetcher = gem_remote_fetcher
507
477
  fetcher.headers = { "X-Gemfile-Source" => remote.original_uri.to_s } if remote.original_uri
508
478
  string = fetcher.fetch_path(path)
509
479
  Bundler.load_marshal(string)
510
- rescue Gem::RemoteFetcher::FetchError => e
480
+ rescue Gem::RemoteFetcher::FetchError
511
481
  # it's okay for prerelease to fail
512
- raise e unless name == "prerelease_specs"
482
+ raise unless name == "prerelease_specs"
513
483
  end
514
484
 
515
485
  def fetch_all_remote_specs(remote)
@@ -519,20 +489,41 @@ module Bundler
519
489
  specs.concat(pres)
520
490
  end
521
491
 
522
- def download_gem(spec, uri, path)
492
+ def download_gem(spec, uri, cache_dir)
493
+ require "rubygems/remote_fetcher"
523
494
  uri = Bundler.settings.mirror_for(uri)
524
495
  fetcher = gem_remote_fetcher
525
496
  fetcher.headers = { "X-Gemfile-Source" => spec.remote.original_uri.to_s } if spec.remote.original_uri
526
497
  Bundler::Retry.new("download gem from #{uri}").attempts do
527
- fetcher.download(spec, uri, path)
498
+ gem_file_name = spec.file_name
499
+ local_gem_path = File.join cache_dir, gem_file_name
500
+ return if File.exist? local_gem_path
501
+
502
+ begin
503
+ remote_gem_path = uri + "gems/#{gem_file_name}"
504
+ remote_gem_path = remote_gem_path.to_s if provides?("< 3.2.0.rc.1")
505
+
506
+ SharedHelpers.filesystem_access(local_gem_path) do
507
+ fetcher.cache_update_path remote_gem_path, local_gem_path
508
+ end
509
+ rescue Gem::RemoteFetcher::FetchError
510
+ raise if spec.original_platform == spec.platform
511
+
512
+ original_gem_file_name = "#{spec.original_name}.gem"
513
+ raise if gem_file_name == original_gem_file_name
514
+
515
+ gem_file_name = original_gem_file_name
516
+ retry
517
+ end
528
518
  end
519
+ rescue Gem::RemoteFetcher::FetchError => e
520
+ raise Bundler::HTTPError, "Could not download gem from #{uri} due to underlying error <#{e.message}>"
529
521
  end
530
522
 
531
523
  def gem_remote_fetcher
532
- require "resolv"
524
+ require "rubygems/remote_fetcher"
533
525
  proxy = configuration[:http_proxy]
534
- dns = Resolv::DNS.new
535
- Gem::RemoteFetcher.new(proxy, dns)
526
+ Gem::RemoteFetcher.new(proxy)
536
527
  end
537
528
 
538
529
  def gem_from_path(path, policy = nil)
@@ -551,10 +542,6 @@ module Bundler
551
542
  Gem::REPOSITORY_SUBDIRECTORIES
552
543
  end
553
544
 
554
- def install_with_build_args(args)
555
- yield
556
- end
557
-
558
545
  def path_separator
559
546
  Gem.path_separator
560
547
  end
@@ -584,6 +571,10 @@ module Bundler
584
571
  end
585
572
  end
586
573
 
574
+ def find_bundler(version)
575
+ find_name("bundler").find {|s| s.version.to_s == version }
576
+ end
577
+
587
578
  def find_name(name)
588
579
  Gem::Specification.stubs_for(name).map(&:to_spec)
589
580
  end
@@ -597,14 +588,6 @@ module Bundler
597
588
  Gem::Specification.send(:default_stubs, "*.gemspec")
598
589
  end
599
590
  end
600
-
601
- def use_gemdeps(gemfile)
602
- ENV["BUNDLE_GEMFILE"] ||= File.expand_path(gemfile)
603
- require_relative "gemdeps"
604
- runtime = Bundler.setup
605
- activated_spec_names = runtime.requested_specs.map(&:to_spec).sort_by(&:name)
606
- [Gemdeps.new(runtime), activated_spec_names]
607
- end
608
591
  end
609
592
 
610
593
  def self.rubygems
@@ -12,22 +12,16 @@ module Bundler
12
12
  def setup(*groups)
13
13
  @definition.ensure_equivalent_gemfile_and_lockfile if Bundler.frozen_bundle?
14
14
 
15
- groups.map!(&:to_sym)
16
-
17
15
  # Has to happen first
18
16
  clean_load_path
19
17
 
20
- specs = groups.any? ? @definition.specs_for(groups) : requested_specs
18
+ specs = @definition.specs_for(groups)
21
19
 
22
20
  SharedHelpers.set_bundle_environment
23
21
  Bundler.rubygems.replace_entrypoints(specs)
24
22
 
25
23
  # Activate the specs
26
24
  load_paths = specs.map do |spec|
27
- unless spec.loaded_from
28
- raise GemNotFound, "#{spec.full_name} is missing. Run `bundle install` to get it."
29
- end
30
-
31
25
  check_for_activated_spec!(spec)
32
26
 
33
27
  Bundler.rubygems.mark_loaded(spec)
@@ -106,7 +100,7 @@ module Bundler
106
100
 
107
101
  alias_method :gems, :specs
108
102
 
109
- def cache(custom_path = nil)
103
+ def cache(custom_path = nil, local = false)
110
104
  cache_path = Bundler.app_cache(custom_path)
111
105
  SharedHelpers.filesystem_access(cache_path) do |p|
112
106
  FileUtils.mkdir_p(p)
@@ -114,7 +108,20 @@ module Bundler
114
108
 
115
109
  Bundler.ui.info "Updating files in #{Bundler.settings.app_cache_path}"
116
110
 
117
- specs_to_cache = Bundler.settings[:cache_all_platforms] ? @definition.resolve.materialized_for_all_platforms : specs
111
+ specs_to_cache = if Bundler.settings[:cache_all_platforms]
112
+ @definition.resolve.materialized_for_all_platforms
113
+ else
114
+ begin
115
+ specs
116
+ rescue GemNotFound
117
+ if local
118
+ Bundler.ui.warn "Some gems seem to be missing from your #{Bundler.settings.app_cache_path} directory."
119
+ end
120
+
121
+ raise
122
+ end
123
+ end
124
+
118
125
  specs_to_cache.each do |spec|
119
126
  next if spec.name == "bundler"
120
127
  next if spec.source.is_a?(Source::Gemspec)
@@ -258,7 +265,7 @@ module Bundler
258
265
 
259
266
  return if manuals.empty?
260
267
  Bundler::SharedHelpers.set_env "MANPATH", manuals.concat(
261
- ENV["MANPATH"].to_s.split(File::PATH_SEPARATOR)
268
+ ENV["MANPATH"] ? ENV["MANPATH"].to_s.split(File::PATH_SEPARATOR) : [""]
262
269
  ).uniq.join(File::PATH_SEPARATOR)
263
270
  end
264
271
 
@@ -284,7 +291,7 @@ module Bundler
284
291
  return unless activated_spec = Bundler.rubygems.loaded_specs(spec.name)
285
292
  return if activated_spec.version == spec.version
286
293
 
287
- suggestion = if Bundler.rubygems.spec_default_gem?(activated_spec)
294
+ suggestion = if activated_spec.default_gem?
288
295
  "Since #{spec.name} is a default gem, you can either remove your dependency on it" \
289
296
  " or try updating to a newer version of bundler that supports #{spec.name} as a default gem."
290
297
  else
@@ -0,0 +1,168 @@
1
+ # frozen_string_literal: true
2
+
3
+ module Bundler
4
+ #
5
+ # This class handles installing and switching to the version of bundler needed
6
+ # by an application.
7
+ #
8
+ class SelfManager
9
+ def restart_with_locked_bundler_if_needed
10
+ return unless needs_switching? && installed?
11
+
12
+ restart_with(lockfile_version)
13
+ end
14
+
15
+ def install_locked_bundler_and_restart_with_it_if_needed
16
+ return unless needs_switching?
17
+
18
+ Bundler.ui.info \
19
+ "Bundler #{current_version} is running, but your lockfile was generated with #{lockfile_version}. " \
20
+ "Installing Bundler #{lockfile_version} and restarting using that version."
21
+
22
+ install_and_restart_with(lockfile_version)
23
+ end
24
+
25
+ def update_bundler_and_restart_with_it_if_needed(target)
26
+ return unless autoswitching_applies?
27
+
28
+ spec = resolve_update_version_from(target)
29
+ return unless spec
30
+
31
+ version = spec.version
32
+
33
+ Bundler.ui.info "Updating bundler to #{version}."
34
+
35
+ install(spec)
36
+
37
+ restart_with(version)
38
+ end
39
+
40
+ private
41
+
42
+ def install_and_restart_with(version)
43
+ requirement = Gem::Requirement.new(version)
44
+ spec = find_latest_matching_spec(requirement)
45
+
46
+ if spec.nil?
47
+ Bundler.ui.warn "Your lockfile is locked to a version of bundler (#{lockfile_version}) that doesn't exist at https://rubygems.org/. Going on using #{current_version}"
48
+ return
49
+ end
50
+
51
+ install(spec)
52
+ rescue StandardError => e
53
+ Bundler.ui.trace e
54
+ Bundler.ui.warn "There was an error installing the locked bundler version (#{lockfile_version}), rerun with the `--verbose` flag for more details. Going on using bundler #{current_version}."
55
+ else
56
+ restart_with(version)
57
+ end
58
+
59
+ def install(spec)
60
+ spec.source.install(spec)
61
+ end
62
+
63
+ def restart_with(version)
64
+ configured_gem_home = ENV["GEM_HOME"]
65
+ configured_gem_path = ENV["GEM_PATH"]
66
+
67
+ cmd = [$PROGRAM_NAME, *ARGV]
68
+ cmd.unshift(Gem.ruby) unless File.executable?($PROGRAM_NAME)
69
+
70
+ Bundler.with_original_env do
71
+ Kernel.exec(
72
+ { "GEM_HOME" => configured_gem_home, "GEM_PATH" => configured_gem_path, "BUNDLER_VERSION" => version.to_s },
73
+ *cmd
74
+ )
75
+ end
76
+ end
77
+
78
+ def needs_switching?
79
+ autoswitching_applies? &&
80
+ released?(lockfile_version) &&
81
+ !running?(lockfile_version) &&
82
+ !updating?
83
+ end
84
+
85
+ def autoswitching_applies?
86
+ ENV["BUNDLER_VERSION"].nil? &&
87
+ Bundler.rubygems.supports_bundler_trampolining? &&
88
+ SharedHelpers.in_bundle? &&
89
+ lockfile_version
90
+ end
91
+
92
+ def resolve_update_version_from(target)
93
+ requirement = Gem::Requirement.new(target)
94
+ update_candidate = find_latest_matching_spec(requirement)
95
+
96
+ if update_candidate.nil?
97
+ raise InvalidOption, "The `bundle update --bundler` target version (#{target}) does not exist"
98
+ end
99
+
100
+ resolved_version = update_candidate.version
101
+ needs_update = requirement.specific? ? !running?(resolved_version) : running_older_than?(resolved_version)
102
+
103
+ return unless needs_update
104
+
105
+ update_candidate
106
+ end
107
+
108
+ def local_specs
109
+ @local_specs ||= Bundler::Source::Rubygems.new("allow_local" => true).specs.select {|spec| spec.name == "bundler" }
110
+ end
111
+
112
+ def remote_specs
113
+ @remote_specs ||= begin
114
+ source = Bundler::Source::Rubygems.new("remotes" => "https://rubygems.org")
115
+ source.remote!
116
+ source.add_dependency_names("bundler")
117
+ source.specs
118
+ end
119
+ end
120
+
121
+ def find_latest_matching_spec(requirement)
122
+ local_result = find_latest_matching_spec_from_collection(local_specs, requirement)
123
+ return local_result if local_result && requirement.specific?
124
+
125
+ remote_result = find_latest_matching_spec_from_collection(remote_specs, requirement)
126
+ return remote_result if local_result.nil?
127
+
128
+ [local_result, remote_result].max
129
+ end
130
+
131
+ def find_latest_matching_spec_from_collection(specs, requirement)
132
+ specs.sort.reverse_each.find {|spec| requirement.satisfied_by?(spec.version) }
133
+ end
134
+
135
+ def running?(version)
136
+ version == current_version
137
+ end
138
+
139
+ def running_older_than?(version)
140
+ current_version < version
141
+ end
142
+
143
+ def released?(version)
144
+ !version.to_s.end_with?(".dev")
145
+ end
146
+
147
+ def updating?
148
+ "update".start_with?(ARGV.first || " ") && ARGV[1..-1].any? {|a| a.start_with?("--bundler") }
149
+ end
150
+
151
+ def installed?
152
+ Bundler.configure
153
+
154
+ Bundler.rubygems.find_bundler(lockfile_version.to_s)
155
+ end
156
+
157
+ def current_version
158
+ @current_version ||= Gem::Version.new(Bundler::VERSION)
159
+ end
160
+
161
+ def lockfile_version
162
+ return @lockfile_version if defined?(@lockfile_version)
163
+
164
+ parsed_version = Bundler::LockfileParser.bundled_with
165
+ @lockfile_version = parsed_version ? Gem::Version.new(parsed_version) : nil
166
+ end
167
+ end
168
+ end
@@ -13,27 +13,28 @@ module Bundler
13
13
  auto_install
14
14
  cache_all
15
15
  cache_all_platforms
16
+ clean
16
17
  default_install_uses_path
17
18
  deployment
18
- deployment_means_frozen
19
19
  disable_checksum_validation
20
20
  disable_exec_load
21
21
  disable_local_branch_check
22
22
  disable_local_revision_check
23
- disable_multisource
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