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
@@ -22,7 +22,7 @@ module Bundler
22
22
  @uri = options["uri"] || ""
23
23
  @safe_uri = URICredentialsFilter.credential_filtered_uri(@uri)
24
24
  @branch = options["branch"]
25
- @ref = options["ref"] || options["branch"] || options["tag"] || "master"
25
+ @ref = options["ref"] || options["branch"] || options["tag"]
26
26
  @submodules = options["submodules"]
27
27
  @name = options["name"]
28
28
  @version = options["version"].to_s.strip.gsub("-", ".pre.")
@@ -42,7 +42,7 @@ module Bundler
42
42
  %w[ref branch tag submodules].each do |opt|
43
43
  out << " #{opt}: #{options[opt]}\n" if options[opt]
44
44
  end
45
- out << " glob: #{@glob}\n" unless @glob == DEFAULT_GLOB
45
+ out << " glob: #{@glob}\n" unless default_glob?
46
46
  out << " specs:\n"
47
47
  end
48
48
 
@@ -60,25 +60,35 @@ module Bundler
60
60
  alias_method :==, :eql?
61
61
 
62
62
  def to_s
63
- at = if local?
64
- path
65
- elsif user_ref = options["ref"]
66
- if ref =~ /\A[a-z0-9]{4,}\z/i
67
- shortref_for_display(user_ref)
63
+ begin
64
+ at = if local?
65
+ path
66
+ elsif user_ref = options["ref"]
67
+ if ref =~ /\A[a-z0-9]{4,}\z/i
68
+ shortref_for_display(user_ref)
69
+ else
70
+ user_ref
71
+ end
72
+ elsif ref
73
+ ref
68
74
  else
69
- user_ref
75
+ git_proxy.branch
70
76
  end
71
- else
72
- ref
77
+
78
+ rev = "at #{at}@#{shortref_for_display(revision)}"
79
+ rescue GitError
80
+ ""
73
81
  end
74
82
 
75
- rev = begin
76
- "@#{shortref_for_display(revision)}"
77
- rescue GitError
78
- nil
79
- end
83
+ specifiers = [rev, glob_for_display].compact
84
+ suffix =
85
+ if specifiers.any?
86
+ " (#{specifiers.join(", ")})"
87
+ else
88
+ ""
89
+ end
80
90
 
81
- "#{@safe_uri} (at #{at}#{rev})"
91
+ "#{@safe_uri}#{suffix}"
82
92
  end
83
93
 
84
94
  def name
@@ -146,7 +156,7 @@ module Bundler
146
156
 
147
157
  changed = cached_revision && cached_revision != git_proxy.revision
148
158
 
149
- if changed && !@unlocked && !git_proxy.contains?(cached_revision)
159
+ if !Bundler.settings[:disable_local_revision_check] && changed && !@unlocked && !git_proxy.contains?(cached_revision)
150
160
  raise GitError, "The Gemfile lock is pointing to revision #{shortref_for_display(cached_revision)} " \
151
161
  "but the current branch in your local override for #{name} does not contain such commit. " \
152
162
  "Please make sure your branch is up to date."
@@ -280,6 +290,14 @@ module Bundler
280
290
  ref[0..11]
281
291
  end
282
292
 
293
+ def glob_for_display
294
+ default_glob? ? nil : "glob: #{@glob}"
295
+ end
296
+
297
+ def default_glob?
298
+ @glob == DEFAULT_GLOB
299
+ end
300
+
283
301
  def uri_hash
284
302
  if uri =~ %r{^\w+://(\w+@)?}
285
303
  # Downcase the domain component of the URI
@@ -289,7 +307,9 @@ module Bundler
289
307
  # If there is no URI scheme, assume it is an ssh/git URI
290
308
  input = uri
291
309
  end
292
- SharedHelpers.digest(:SHA1).hexdigest(input)
310
+ # We use SHA1 here for historical reason and to preserve backward compatibility.
311
+ # But a transition to a simpler mangling algorithm would be welcome.
312
+ Bundler::Digest.sha1(input)
293
313
  end
294
314
 
295
315
  def cached_revision
@@ -25,7 +25,7 @@ module Bundler
25
25
  s.loaded_from = File.expand_path("..", __FILE__)
26
26
  end
27
27
 
28
- if local_spec = Bundler.rubygems.find_name("bundler").find {|s| s.version.to_s == VERSION }
28
+ if local_spec = Bundler.rubygems.find_bundler(VERSION)
29
29
  idx << local_spec
30
30
  end
31
31
 
@@ -33,10 +33,6 @@ module Bundler
33
33
  end
34
34
  end
35
35
 
36
- def cached!; end
37
-
38
- def remote!; end
39
-
40
36
  def options
41
37
  {}
42
38
  end
@@ -1,5 +1,7 @@
1
1
  # frozen_string_literal: true
2
2
 
3
+ require_relative "../../rubygems_gem_installer"
4
+
3
5
  module Bundler
4
6
  class Source
5
7
  class Path
@@ -33,7 +35,7 @@ module Bundler
33
35
  run_hooks(:post_build)
34
36
  end
35
37
 
36
- generate_bin unless spec.executables.nil? || spec.executables.empty?
38
+ generate_bin unless spec.executables.empty?
37
39
 
38
40
  run_hooks(:post_install)
39
41
  ensure
@@ -82,7 +82,9 @@ module Bundler
82
82
  end
83
83
 
84
84
  def install(spec, options = {})
85
- print_using_message "Using #{version_message(spec)} from #{self}"
85
+ using_message = "Using #{version_message(spec)} from #{self}"
86
+ using_message += " and installing its executables" unless spec.executables.empty?
87
+ print_using_message using_message
86
88
  generate_bin(spec, :disable_extensions => true)
87
89
  nil # no post-install message
88
90
  end
@@ -20,18 +20,38 @@ module Bundler
20
20
  @dependency_names = []
21
21
  @allow_remote = false
22
22
  @allow_cached = false
23
+ @allow_local = options["allow_local"] || false
23
24
  @caches = [cache_path, *Bundler.rubygems.gem_cache]
24
25
 
25
- Array(options["remotes"] || []).reverse_each {|r| add_remote(r) }
26
+ Array(options["remotes"]).reverse_each {|r| add_remote(r) }
27
+ end
28
+
29
+ def local_only!
30
+ @specs = nil
31
+ @allow_local = true
32
+ @allow_cached = false
33
+ @allow_remote = false
34
+ end
35
+
36
+ def local!
37
+ return if @allow_local
38
+
39
+ @specs = nil
40
+ @allow_local = true
26
41
  end
27
42
 
28
43
  def remote!
44
+ return if @allow_remote
45
+
29
46
  @specs = nil
30
47
  @allow_remote = true
31
48
  end
32
49
 
33
50
  def cached!
51
+ return if @allow_cached
52
+
34
53
  @specs = nil
54
+ @allow_local = true
35
55
  @allow_cached = true
36
56
  end
37
57
 
@@ -49,9 +69,17 @@ module Bundler
49
69
  o.is_a?(Rubygems) && (o.credless_remotes - credless_remotes).empty?
50
70
  end
51
71
 
72
+ def multiple_remotes?
73
+ @remotes.size > 1
74
+ end
75
+
76
+ def no_remotes?
77
+ @remotes.size == 0
78
+ end
79
+
52
80
  def can_lock?(spec)
53
- return super if Bundler.feature_flag.disable_multisource?
54
- spec.source.is_a?(Rubygems)
81
+ return super unless multiple_remotes?
82
+ include?(spec.source)
55
83
  end
56
84
 
57
85
  def options
@@ -73,12 +101,27 @@ module Bundler
73
101
  def to_s
74
102
  if remotes.empty?
75
103
  "locally installed gems"
76
- else
77
- remote_names = remotes.map(&:to_s).join(", ")
104
+ elsif @allow_remote && @allow_cached && @allow_local
105
+ "rubygems repository #{remote_names}, cached gems or installed locally"
106
+ elsif @allow_remote && @allow_local
78
107
  "rubygems repository #{remote_names} or installed locally"
108
+ elsif @allow_remote
109
+ "rubygems repository #{remote_names}"
110
+ elsif @allow_cached && @allow_local
111
+ "cached gems or installed locally"
112
+ else
113
+ "locally installed gems"
79
114
  end
80
115
  end
81
- alias_method :name, :to_s
116
+
117
+ def identifier
118
+ if remotes.empty?
119
+ "locally installed gems"
120
+ else
121
+ "rubygems repository #{remote_names}"
122
+ end
123
+ end
124
+ alias_method :name, :identifier
82
125
 
83
126
  def specs
84
127
  @specs ||= begin
@@ -87,7 +130,7 @@ module Bundler
87
130
  # small_idx.use large_idx.
88
131
  idx = @allow_remote ? remote_specs.dup : Index.new
89
132
  idx.use(cached_specs, :override_dupes) if @allow_cached || @allow_remote
90
- idx.use(installed_specs, :override_dupes)
133
+ idx.use(installed_specs, :override_dupes) if @allow_local
91
134
  idx
92
135
  end
93
136
  end
@@ -96,7 +139,7 @@ module Bundler
96
139
  force = opts[:force]
97
140
  ensure_builtin_gems_cached = opts[:ensure_builtin_gems_cached]
98
141
 
99
- if ensure_builtin_gems_cached && builtin_gem?(spec)
142
+ if ensure_builtin_gems_cached && spec.default_gem?
100
143
  if !cached_path(spec)
101
144
  cached_built_in_gem(spec) unless spec.remote
102
145
  force = true
@@ -105,7 +148,7 @@ module Bundler
105
148
  end
106
149
  end
107
150
 
108
- if (installed?(spec) || Plugin.installed?(spec.name)) && !force
151
+ if installed?(spec) && !force
109
152
  print_using_message "Using #{version_message(spec)}"
110
153
  return nil # no post-install message
111
154
  end
@@ -123,7 +166,7 @@ module Bundler
123
166
  begin
124
167
  s = Bundler.rubygems.spec_from_gem(path, Bundler.settings["trust-policy"])
125
168
  spec.__swap__(s)
126
- rescue StandardError
169
+ rescue Gem::Package::FormatError
127
170
  Bundler.rm_rf(path)
128
171
  raise
129
172
  end
@@ -135,6 +178,7 @@ module Bundler
135
178
  Bundler.ui.confirm message
136
179
 
137
180
  path = cached_gem(spec)
181
+ raise GemNotFound, "Could not find #{spec.file_name} for installation" unless path
138
182
  if requires_sudo?
139
183
  install_path = Bundler.tmp(spec.full_name)
140
184
  bin_path = install_path.join("bin")
@@ -145,6 +189,8 @@ module Bundler
145
189
 
146
190
  Bundler.mkdir_p bin_path, :no_sudo => true unless spec.executables.empty? || Bundler.rubygems.provides?(">= 2.7.5")
147
191
 
192
+ require_relative "../rubygems_gem_installer"
193
+
148
194
  installed_spec = Bundler::RubyGemsGemInstaller.at(
149
195
  path,
150
196
  :install_dir => install_path.to_s,
@@ -192,12 +238,8 @@ module Bundler
192
238
  end
193
239
 
194
240
  def cache(spec, custom_path = nil)
195
- if builtin_gem?(spec)
196
- cached_path = cached_built_in_gem(spec)
197
- else
198
- cached_path = cached_gem(spec)
199
- end
200
- raise GemNotFound, "Missing gem file '#{spec.full_name}.gem'." unless cached_path
241
+ cached_path = cached_gem(spec)
242
+ raise GemNotFound, "Missing gem file '#{spec.file_name}'." unless cached_path
201
243
  return if File.dirname(cached_path) == Bundler.app_cache.to_s
202
244
  Bundler.ui.info " * #{File.basename(cached_path)}"
203
245
  FileUtils.cp(cached_path, Bundler.app_cache(custom_path))
@@ -224,25 +266,16 @@ module Bundler
224
266
  @remotes.unshift(uri) unless @remotes.include?(uri)
225
267
  end
226
268
 
227
- def equivalent_remotes?(other_remotes)
228
- other_remotes.map(&method(:remove_auth)) == @remotes.map(&method(:remove_auth))
229
- end
230
-
231
- def replace_remotes(other_remotes, allow_equivalent = false)
232
- return false if other_remotes == @remotes
233
-
234
- equivalent = allow_equivalent && equivalent_remotes?(other_remotes)
235
-
236
- @remotes = []
237
- other_remotes.reverse_each do |r|
238
- add_remote r.to_s
269
+ def spec_names
270
+ if @allow_remote && dependency_api_available?
271
+ remote_specs.spec_names
272
+ else
273
+ []
239
274
  end
240
-
241
- !equivalent
242
275
  end
243
276
 
244
277
  def unmet_deps
245
- if @allow_remote && api_fetchers.any?
278
+ if @allow_remote && dependency_api_available?
246
279
  remote_specs.unmet_dependency_names
247
280
  else
248
281
  []
@@ -258,7 +291,7 @@ module Bundler
258
291
 
259
292
  def double_check_for(unmet_dependency_names)
260
293
  return unless @allow_remote
261
- return unless api_fetchers.any?
294
+ return unless dependency_api_available?
262
295
 
263
296
  unmet_dependency_names = unmet_dependency_names.call
264
297
  unless unmet_dependency_names.nil?
@@ -280,21 +313,32 @@ module Bundler
280
313
  remote_specs.each do |spec|
281
314
  case spec
282
315
  when EndpointSpecification, Gem::Specification, StubSpecification, LazySpecification
283
- names.concat(spec.runtime_dependencies)
316
+ names.concat(spec.runtime_dependencies.map(&:name))
284
317
  when RemoteSpecification # from the full index
285
318
  return nil
286
319
  else
287
320
  raise "unhandled spec type (#{spec.inspect})"
288
321
  end
289
322
  end
290
- names.map!(&:name) if names
291
323
  names
292
324
  end
293
325
 
326
+ def dependency_api_available?
327
+ api_fetchers.any?
328
+ end
329
+
294
330
  protected
295
331
 
332
+ def remote_names
333
+ remotes.map(&:to_s).join(", ")
334
+ end
335
+
296
336
  def credless_remotes
297
- remotes.map(&method(:suppress_configured_credentials))
337
+ if Bundler.settings[:allow_deployment_source_credential_changes]
338
+ remotes.map(&method(:remove_auth))
339
+ else
340
+ remotes.map(&method(:suppress_configured_credentials))
341
+ end
298
342
  end
299
343
 
300
344
  def remotes_for_spec(spec)
@@ -309,14 +353,17 @@ module Bundler
309
353
  end
310
354
 
311
355
  def cached_gem(spec)
312
- cached_gem = cached_path(spec)
313
- unless cached_gem
314
- raise Bundler::GemNotFound, "Could not find #{spec.file_name} for installation"
356
+ if spec.default_gem?
357
+ cached_built_in_gem(spec)
358
+ else
359
+ cached_path(spec)
315
360
  end
316
- cached_gem
317
361
  end
318
362
 
319
363
  def cached_path(spec)
364
+ global_cache_path = download_cache_path(spec)
365
+ @caches << global_cache_path if global_cache_path
366
+
320
367
  possibilities = @caches.map {|p| "#{p}/#{spec.file_name}" }
321
368
  possibilities.find {|p| File.exist?(p) }
322
369
  end
@@ -351,7 +398,6 @@ module Bundler
351
398
  def installed_specs
352
399
  @installed_specs ||= Index.build do |idx|
353
400
  Bundler.rubygems.all_specs.reverse_each do |spec|
354
- next if spec.name == "bundler"
355
401
  spec.source = self
356
402
  if Bundler.rubygems.spec_missing_extensions?(spec, false)
357
403
  Bundler.ui.debug "Source #{self} is ignoring #{spec} because it is missing extensions"
@@ -364,16 +410,12 @@ module Bundler
364
410
 
365
411
  def cached_specs
366
412
  @cached_specs ||= begin
367
- idx = installed_specs.dup
413
+ idx = @allow_local ? installed_specs.dup : Index.new
368
414
 
369
415
  Dir["#{cache_path}/*.gem"].each do |gemfile|
370
416
  next if gemfile =~ /^bundler\-[\d\.]+?\.gem/
371
417
  s ||= Bundler.rubygems.spec_from_gem(gemfile)
372
418
  s.source = self
373
- if Bundler.rubygems.spec_missing_extensions?(s, false)
374
- Bundler.ui.debug "Source #{self} is ignoring #{s} because it is missing extensions"
375
- next
376
- end
377
419
  idx << s
378
420
  end
379
421
 
@@ -406,11 +448,11 @@ module Bundler
406
448
  def fetch_names(fetchers, dependency_names, index, override_dupes)
407
449
  fetchers.each do |f|
408
450
  if dependency_names
409
- Bundler.ui.info "Fetching gem metadata from #{f.uri}", Bundler.ui.debug?
451
+ Bundler.ui.info "Fetching gem metadata from #{URICredentialsFilter.credential_filtered_uri(f.uri)}", Bundler.ui.debug?
410
452
  index.use f.specs_with_retry(dependency_names, self), override_dupes
411
453
  Bundler.ui.info "" unless Bundler.ui.debug? # new line now that the dots are over
412
454
  else
413
- Bundler.ui.info "Fetching source index from #{f.uri}"
455
+ Bundler.ui.info "Fetching source index from #{URICredentialsFilter.credential_filtered_uri(f.uri)}"
414
456
  index.use f.specs_with_retry(nil, self), override_dupes
415
457
  end
416
458
  end
@@ -421,19 +463,26 @@ module Bundler
421
463
 
422
464
  spec.fetch_platform
423
465
 
424
- download_path = requires_sudo? ? Bundler.tmp(spec.full_name) : rubygems_dir
425
- gem_path = "#{rubygems_dir}/cache/#{spec.full_name}.gem"
466
+ cache_path = download_cache_path(spec) || default_cache_path_for(rubygems_dir)
467
+ gem_path = "#{cache_path}/#{spec.file_name}"
468
+
469
+ if requires_sudo?
470
+ download_path = Bundler.tmp(spec.full_name)
471
+ download_cache_path = default_cache_path_for(download_path)
472
+ else
473
+ download_cache_path = cache_path
474
+ end
426
475
 
427
- SharedHelpers.filesystem_access("#{download_path}/cache") do |p|
476
+ SharedHelpers.filesystem_access(download_cache_path) do |p|
428
477
  FileUtils.mkdir_p(p)
429
478
  end
430
- download_gem(spec, download_path)
479
+ download_gem(spec, download_cache_path)
431
480
 
432
481
  if requires_sudo?
433
- SharedHelpers.filesystem_access("#{rubygems_dir}/cache") do |p|
482
+ SharedHelpers.filesystem_access(cache_path) do |p|
434
483
  Bundler.mkdir_p(p)
435
484
  end
436
- Bundler.sudo "mv #{download_path}/cache/#{spec.full_name}.gem #{gem_path}"
485
+ Bundler.sudo "mv #{download_cache_path}/#{spec.file_name} #{gem_path}"
437
486
  end
438
487
 
439
488
  gem_path
@@ -441,16 +490,8 @@ module Bundler
441
490
  Bundler.rm_rf(download_path) if requires_sudo?
442
491
  end
443
492
 
444
- def builtin_gem?(spec)
445
- # Ruby 2.1, where all included gems have this summary
446
- return true if spec.summary =~ /is bundled with Ruby/
447
-
448
- # Ruby 2.0, where gemspecs are stored in specifications/default/
449
- spec.loaded_from && spec.loaded_from.include?("specifications/default/")
450
- end
451
-
452
493
  def installed?(spec)
453
- installed_specs[spec].any?
494
+ installed_specs[spec].any? && !spec.deleted_gem?
454
495
  end
455
496
 
456
497
  def requires_sudo?
@@ -461,6 +502,10 @@ module Bundler
461
502
  Bundler.rubygems.gem_dir
462
503
  end
463
504
 
505
+ def default_cache_path_for(dir)
506
+ "#{dir}/cache"
507
+ end
508
+
464
509
  def cache_path
465
510
  Bundler.app_cache
466
511
  end
@@ -473,45 +518,13 @@ module Bundler
473
518
  # @param [Specification] spec
474
519
  # the spec we want to download or retrieve from the cache.
475
520
  #
476
- # @param [String] download_path
521
+ # @param [String] download_cache_path
477
522
  # the local directory the .gem will end up in.
478
523
  #
479
- def download_gem(spec, download_path)
480
- local_path = File.join(download_path, "cache/#{spec.full_name}.gem")
481
-
482
- if (cache_path = download_cache_path(spec)) && cache_path.file?
483
- SharedHelpers.filesystem_access(local_path) do
484
- FileUtils.cp(cache_path, local_path)
485
- end
486
- else
487
- uri = spec.remote.uri
488
- Bundler.ui.confirm("Fetching #{version_message(spec)}")
489
- rubygems_local_path = Bundler.rubygems.download_gem(spec, uri, download_path)
490
- if rubygems_local_path != local_path
491
- FileUtils.mv(rubygems_local_path, local_path)
492
- end
493
- cache_globally(spec, local_path)
494
- end
495
- end
496
-
497
- # Checks if the requested spec exists in the global cache. If it does
498
- # not, we create the relevant global cache subdirectory if it does not
499
- # exist and copy the spec from the local cache to the global cache.
500
- #
501
- # @param [Specification] spec
502
- # the spec we want to copy to the global cache.
503
- #
504
- # @param [String] local_cache_path
505
- # the local directory from which we want to copy the .gem.
506
- #
507
- def cache_globally(spec, local_cache_path)
508
- return unless cache_path = download_cache_path(spec)
509
- return if cache_path.exist?
510
-
511
- SharedHelpers.filesystem_access(cache_path.dirname, &:mkpath)
512
- SharedHelpers.filesystem_access(cache_path) do
513
- FileUtils.cp(local_cache_path, cache_path)
514
- end
524
+ def download_gem(spec, download_cache_path)
525
+ uri = spec.remote.uri
526
+ Bundler.ui.confirm("Fetching #{version_message(spec)}")
527
+ Bundler.rubygems.download_gem(spec, uri, download_cache_path)
515
528
  end
516
529
 
517
530
  # Returns the global cache path of the calling Rubygems::Source object.
@@ -530,7 +543,7 @@ module Bundler
530
543
  return unless remote = spec.remote
531
544
  return unless cache_slug = remote.cache_slug
532
545
 
533
- Bundler.user_cache.join("gems", cache_slug, spec.file_name)
546
+ Bundler.user_cache.join("gems", cache_slug)
534
547
  end
535
548
 
536
549
  def extension_cache_slug(spec)
@@ -0,0 +1,68 @@
1
+ # frozen_string_literal: true
2
+
3
+ module Bundler
4
+ class Source
5
+ class RubygemsAggregate
6
+ attr_reader :source_map, :sources
7
+
8
+ def initialize(sources, source_map)
9
+ @sources = sources
10
+ @source_map = source_map
11
+
12
+ @index = build_index
13
+ end
14
+
15
+ def specs
16
+ @index
17
+ end
18
+
19
+ def identifier
20
+ to_s
21
+ end
22
+
23
+ def to_s
24
+ "any of the sources"
25
+ end
26
+
27
+ private
28
+
29
+ def build_index
30
+ Index.build do |idx|
31
+ dependency_names = source_map.pinned_spec_names
32
+
33
+ sources.all_sources.each do |source|
34
+ source.dependency_names = dependency_names - source_map.pinned_spec_names(source)
35
+ idx.add_source source.specs
36
+ dependency_names.concat(source.unmet_deps).uniq!
37
+ end
38
+
39
+ double_check_for_index(idx, dependency_names)
40
+ end
41
+ end
42
+
43
+ # Suppose the gem Foo depends on the gem Bar. Foo exists in Source A. Bar has some versions that exist in both
44
+ # sources A and B. At this point, the API request will have found all the versions of Bar in source A,
45
+ # but will not have found any versions of Bar from source B, which is a problem if the requested version
46
+ # of Foo specifically depends on a version of Bar that is only found in source B. This ensures that for
47
+ # each spec we found, we add all possible versions from all sources to the index.
48
+ def double_check_for_index(idx, dependency_names)
49
+ pinned_names = source_map.pinned_spec_names
50
+
51
+ names = :names # do this so we only have to traverse to get dependency_names from the index once
52
+ unmet_dependency_names = lambda do
53
+ return names unless names == :names
54
+ new_names = sources.all_sources.map(&:dependency_names_to_double_check)
55
+ return names = nil if new_names.compact!
56
+ names = new_names.flatten(1).concat(dependency_names)
57
+ names.uniq!
58
+ names -= pinned_names
59
+ names
60
+ end
61
+
62
+ sources.all_sources.each do |source|
63
+ source.double_check_for(unmet_dependency_names)
64
+ end
65
+ end
66
+ end
67
+ end
68
+ end
@@ -7,6 +7,7 @@ module Bundler
7
7
  autoload :Metadata, File.expand_path("source/metadata", __dir__)
8
8
  autoload :Path, File.expand_path("source/path", __dir__)
9
9
  autoload :Rubygems, File.expand_path("source/rubygems", __dir__)
10
+ autoload :RubygemsAggregate, File.expand_path("source/rubygems_aggregate", __dir__)
10
11
 
11
12
  attr_accessor :dependency_names
12
13
 
@@ -33,6 +34,18 @@ module Bundler
33
34
  spec.source == self
34
35
  end
35
36
 
37
+ def local!; end
38
+
39
+ def local_only!; end
40
+
41
+ def cached!; end
42
+
43
+ def remote!; end
44
+
45
+ def add_dependency_names(names)
46
+ @dependency_names = Array(dependency_names) | Array(names)
47
+ end
48
+
36
49
  # it's possible that gems from one source depend on gems from some
37
50
  # other source, so now we download gemspecs and iterate over those
38
51
  # dependencies, looking for gems we don't have info on yet.
@@ -42,6 +55,10 @@ module Bundler
42
55
  specs.dependency_names
43
56
  end
44
57
 
58
+ def spec_names
59
+ specs.spec_names
60
+ end
61
+
45
62
  def include?(other)
46
63
  other == self
47
64
  end
@@ -50,6 +67,10 @@ module Bundler
50
67
  "#<#{self.class}:0x#{object_id} #{self}>"
51
68
  end
52
69
 
70
+ def identifier
71
+ to_s
72
+ end
73
+
53
74
  def path?
54
75
  instance_of?(Bundler::Source::Path)
55
76
  end