bundler 2.2.3 → 2.3.5

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 (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
@@ -85,6 +85,10 @@ module Gem
85
85
  dependencies - development_dependencies
86
86
  end
87
87
 
88
+ def deleted_gem?
89
+ !default_gem? && !File.directory?(full_gem_path)
90
+ end
91
+
88
92
  private
89
93
 
90
94
  def dependencies_to_gemfile(dependencies, group = nil)
@@ -105,7 +109,7 @@ module Gem
105
109
  end
106
110
 
107
111
  class Dependency
108
- attr_accessor :source, :groups, :all_sources
112
+ attr_accessor :source, :groups
109
113
 
110
114
  alias_method :eql?, :==
111
115
 
@@ -116,7 +120,7 @@ module Gem
116
120
  end
117
121
 
118
122
  def to_yaml_properties
119
- instance_variables.reject {|p| ["@source", "@groups", "@all_sources"].include?(p.to_s) }
123
+ instance_variables.reject {|p| ["@source", "@groups"].include?(p.to_s) }
120
124
  end
121
125
 
122
126
  def to_lock
@@ -134,6 +138,8 @@ module Gem
134
138
  class Requirement
135
139
  module OrderIndependentComparison
136
140
  def ==(other)
141
+ return unless Gem::Requirement === other
142
+
137
143
  if _requirements_sorted? && other._requirements_sorted?
138
144
  super
139
145
  else
@@ -158,20 +164,52 @@ module Gem
158
164
  end
159
165
  end
160
166
 
167
+ if Gem::Requirement.new("~> 2.0").hash == Gem::Requirement.new("~> 2.0.0").hash
168
+ class Requirement
169
+ module CorrectHashForLambdaOperator
170
+ def hash
171
+ if requirements.any? {|r| r.first == "~>" }
172
+ requirements.map {|r| r.first == "~>" ? [r[0], r[1].to_s] : r }.sort.hash
173
+ else
174
+ super
175
+ end
176
+ end
177
+ end
178
+
179
+ prepend CorrectHashForLambdaOperator
180
+ end
181
+ end
182
+
183
+ require "rubygems/platform"
184
+
161
185
  class Platform
162
186
  JAVA = Gem::Platform.new("java") unless defined?(JAVA)
163
187
  MSWIN = Gem::Platform.new("mswin32") unless defined?(MSWIN)
164
188
  MSWIN64 = Gem::Platform.new("mswin64") unless defined?(MSWIN64)
165
189
  MINGW = Gem::Platform.new("x86-mingw32") unless defined?(MINGW)
166
190
  X64_MINGW = Gem::Platform.new("x64-mingw32") unless defined?(X64_MINGW)
191
+ end
167
192
 
168
- undef_method :hash if method_defined? :hash
169
- def hash
170
- @cpu.hash ^ @os.hash ^ @version.hash
171
- end
193
+ Platform.singleton_class.module_eval do
194
+ unless Platform.singleton_methods.include?(:match_spec?)
195
+ def match_spec?(spec)
196
+ match_gem?(spec.platform, spec.name)
197
+ end
172
198
 
173
- undef_method :eql? if method_defined? :eql?
174
- alias_method :eql?, :==
199
+ def match_gem?(platform, gem_name)
200
+ match_platforms?(platform, Gem.platforms)
201
+ end
202
+
203
+ private
204
+
205
+ def match_platforms?(platform, platforms)
206
+ platforms.any? do |local_platform|
207
+ platform.nil? ||
208
+ local_platform == platform ||
209
+ (local_platform != Gem::Platform::RUBY && local_platform =~ platform)
210
+ end
211
+ end
212
+ end
175
213
  end
176
214
 
177
215
  require "rubygems/util"
@@ -8,13 +8,68 @@ module Bundler
8
8
  # Bundler needs to install gems regardless of binstub overwriting
9
9
  end
10
10
 
11
+ def install
12
+ pre_install_checks
13
+
14
+ run_pre_install_hooks
15
+
16
+ spec.loaded_from = spec_file
17
+
18
+ # Completely remove any previous gem files
19
+ strict_rm_rf gem_dir
20
+ strict_rm_rf spec.extension_dir
21
+
22
+ SharedHelpers.filesystem_access(gem_dir, :create) do
23
+ FileUtils.mkdir_p gem_dir, :mode => 0o755
24
+ end
25
+
26
+ extract_files
27
+
28
+ build_extensions
29
+ write_build_info_file
30
+ run_post_build_hooks
31
+
32
+ generate_bin
33
+ generate_plugins
34
+
35
+ write_spec
36
+
37
+ SharedHelpers.filesystem_access("#{gem_home}/cache", :write) do
38
+ write_cache_file
39
+ end
40
+
41
+ say spec.post_install_message unless spec.post_install_message.nil?
42
+
43
+ run_post_install_hooks
44
+
45
+ spec
46
+ end
47
+
48
+ def generate_plugins
49
+ return unless Gem::Installer.instance_methods(false).include?(:generate_plugins)
50
+
51
+ latest = Gem::Specification.stubs_for(spec.name).first
52
+ return if latest && latest.version > spec.version
53
+
54
+ ensure_writable_dir @plugins_dir
55
+
56
+ if spec.plugins.empty?
57
+ remove_plugins_for(spec, @plugins_dir)
58
+ else
59
+ regenerate_plugins_for(spec, @plugins_dir)
60
+ end
61
+ end
62
+
11
63
  def pre_install_checks
12
64
  super && validate_bundler_checksum(options[:bundler_expected_checksum])
13
65
  end
14
66
 
15
67
  def build_extensions
16
68
  extension_cache_path = options[:bundler_extension_cache_path]
17
- return super unless extension_cache_path && extension_dir = spec.extension_dir
69
+ unless extension_cache_path && extension_dir = spec.extension_dir
70
+ require "shellwords" unless Bundler.rubygems.provides?(">= 3.2.25")
71
+ return super
72
+ end
18
73
 
19
74
  extension_dir = Pathname.new(extension_dir)
20
75
  build_complete = SharedHelpers.filesystem_access(extension_cache_path.join("gem.build_complete"), :read, &:file?)
@@ -24,6 +79,7 @@ module Bundler
24
79
  FileUtils.cp_r extension_cache_path, spec.extension_dir
25
80
  end
26
81
  else
82
+ require "shellwords" # compensate missing require in rubygems before version 3.2.25
27
83
  super
28
84
  if extension_dir.directory? # not made for gems without extensions
29
85
  SharedHelpers.filesystem_access(extension_cache_path.parent, &:mkpath)
@@ -36,6 +92,17 @@ module Bundler
36
92
 
37
93
  private
38
94
 
95
+ def strict_rm_rf(dir)
96
+ # FileUtils.rm_rf should probably rise in case of permission issues like
97
+ # `rm -rf` does. However, it fails to delete the folder silently due to
98
+ # https://github.com/ruby/fileutils/issues/57. It should probably be fixed
99
+ # inside `fileutils` but for now I`m checking whether the folder was
100
+ # removed after it completes, and raising otherwise.
101
+ FileUtils.rm_rf dir
102
+
103
+ raise PermissionError.new(dir, :delete) if File.directory?(dir)
104
+ end
105
+
39
106
  def validate_bundler_checksum(checksum)
40
107
  return true if Bundler.settings[:disable_checksum_validation]
41
108
  return true unless checksum
@@ -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