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
@@ -4,19 +4,18 @@ module Bundler
4
4
  class DepProxy
5
5
  attr_reader :__platform, :dep
6
6
 
7
+ @proxies = {}
8
+
9
+ def self.get_proxy(dep, platform)
10
+ @proxies[[dep, platform]] ||= new(dep, platform).freeze
11
+ end
12
+
7
13
  def initialize(dep, platform)
8
14
  @dep = dep
9
15
  @__platform = platform
10
16
  end
11
17
 
12
- def hash
13
- @hash ||= [dep, __platform].hash
14
- end
15
-
16
- def ==(other)
17
- return false if other.class != self.class
18
- dep == other.dep && __platform == other.__platform
19
- end
18
+ private_class_method :new
20
19
 
21
20
  alias_method :eql?, :==
22
21
 
@@ -39,6 +38,14 @@ module Bundler
39
38
  s
40
39
  end
41
40
 
41
+ def dup
42
+ raise NoMethodError.new("DepProxy cannot be duplicated")
43
+ end
44
+
45
+ def clone
46
+ raise NoMethodError.new("DepProxy cannot be cloned")
47
+ end
48
+
42
49
  private
43
50
 
44
51
  def method_missing(*args, &blk)
@@ -7,7 +7,7 @@ require_relative "rubygems_ext"
7
7
  module Bundler
8
8
  class Dependency < Gem::Dependency
9
9
  attr_reader :autorequire
10
- attr_reader :groups, :platforms, :gemfile, :git, :branch
10
+ attr_reader :groups, :platforms, :gemfile, :git, :github, :branch, :ref
11
11
 
12
12
  PLATFORM_MAP = {
13
13
  :ruby => Gem::Platform::RUBY,
@@ -82,7 +82,9 @@ module Bundler
82
82
  @groups = Array(options["group"] || :default).map(&:to_sym)
83
83
  @source = options["source"]
84
84
  @git = options["git"]
85
+ @github = options["github"]
85
86
  @branch = options["branch"]
87
+ @ref = options["ref"]
86
88
  @platforms = Array(options["platforms"])
87
89
  @env = options["env"]
88
90
  @should_include = options.fetch("should_include", true)
@@ -96,15 +98,11 @@ module Bundler
96
98
  def gem_platforms(valid_platforms)
97
99
  return valid_platforms if @platforms.empty?
98
100
 
99
- valid_generic_platforms = valid_platforms.map {|p| [p, GemHelpers.generic(p)] }.to_h
100
- @gem_platforms ||= expanded_platforms.compact.uniq
101
-
102
- filtered_generic_platforms = valid_generic_platforms.values & @gem_platforms
103
- valid_generic_platforms.select {|_, v| filtered_generic_platforms.include?(v) }.keys
101
+ valid_platforms.select {|p| expanded_platforms.include?(GemHelpers.generic(p)) }
104
102
  end
105
103
 
106
104
  def expanded_platforms
107
- @platforms.map {|pl| PLATFORM_MAP[pl] }
105
+ @expanded_platforms ||= @platforms.map {|pl| PLATFORM_MAP[pl] }.compact.uniq
108
106
  end
109
107
 
110
108
  def should_include?
@@ -0,0 +1,71 @@
1
+ # frozen_string_literal: true
2
+
3
+ # This code was extracted from https://github.com/Solistra/ruby-digest which is under public domain
4
+ module Bundler
5
+ module Digest
6
+ # The initial constant values for the 32-bit constant words A, B, C, D, and
7
+ # E, respectively.
8
+ SHA1_WORDS = [0x67452301, 0xEFCDAB89, 0x98BADCFE, 0x10325476, 0xC3D2E1F0].freeze
9
+
10
+ # The 8-bit field used for bitwise `AND` masking. Defaults to `0xFFFFFFFF`.
11
+ SHA1_MASK = 0xFFFFFFFF
12
+
13
+ class << self
14
+ def sha1(string)
15
+ unless string.is_a?(String)
16
+ raise TypeError, "can't convert #{string.class.inspect} into String"
17
+ end
18
+
19
+ buffer = string.b
20
+
21
+ words = SHA1_WORDS.dup
22
+ generate_split_buffer(buffer) do |chunk|
23
+ w = []
24
+ chunk.each_slice(4) do |a, b, c, d|
25
+ w << (((a << 8 | b) << 8 | c) << 8 | d)
26
+ end
27
+ a, b, c, d, e = *words
28
+ (16..79).each do |i|
29
+ w[i] = SHA1_MASK & rotate((w[i-3] ^ w[i-8] ^ w[i-14] ^ w[i-16]), 1)
30
+ end
31
+ 0.upto(79) do |i|
32
+ case i
33
+ when 0..19
34
+ f = ((b & c) | (~b & d))
35
+ k = 0x5A827999
36
+ when 20..39
37
+ f = (b ^ c ^ d)
38
+ k = 0x6ED9EBA1
39
+ when 40..59
40
+ f = ((b & c) | (b & d) | (c & d))
41
+ k = 0x8F1BBCDC
42
+ when 60..79
43
+ f = (b ^ c ^ d)
44
+ k = 0xCA62C1D6
45
+ end
46
+ t = SHA1_MASK & (SHA1_MASK & rotate(a, 5) + f + e + k + w[i])
47
+ a, b, c, d, e = t, a, SHA1_MASK & rotate(b, 30), c, d # rubocop:disable Style/ParallelAssignment
48
+ end
49
+ mutated = [a, b, c, d, e]
50
+ words.map!.with_index {|word, index| SHA1_MASK & (word + mutated[index]) }
51
+ end
52
+
53
+ words.pack("N*").unpack("H*").first
54
+ end
55
+
56
+ private
57
+
58
+ def generate_split_buffer(string, &block)
59
+ size = string.bytesize * 8
60
+ buffer = string.bytes << 128
61
+ buffer << 0 while buffer.size % 64 != 56
62
+ buffer.concat([size].pack("Q>").bytes)
63
+ buffer.each_slice(64, &block)
64
+ end
65
+
66
+ def rotate(value, spaces)
67
+ value << spaces | value >> (32 - spaces)
68
+ end
69
+ end
70
+ end
71
+ end
data/lib/bundler/dsl.rb CHANGED
@@ -18,6 +18,8 @@ module Bundler
18
18
  VALID_KEYS = %w[group groups git path glob name branch ref tag require submodules
19
19
  platform platforms type source install_if gemfile].freeze
20
20
 
21
+ GITHUB_PULL_REQUEST_URL = %r{\Ahttps://github\.com/([A-Za-z0-9_\-\.]+/[A-Za-z0-9_\-\.]+)/pull/(\d+)\z}.freeze
22
+
21
23
  attr_reader :gemspecs
22
24
  attr_accessor :dependencies
23
25
 
@@ -103,8 +105,8 @@ module Bundler
103
105
  if current = @dependencies.find {|d| d.name == dep.name }
104
106
  deleted_dep = @dependencies.delete(current) if current.type == :development
105
107
 
106
- if current.requirement != dep.requirement
107
- unless deleted_dep
108
+ unless deleted_dep
109
+ if current.requirement != dep.requirement
108
110
  return if dep.type == :development
109
111
 
110
112
  update_prompt = ""
@@ -122,17 +124,14 @@ module Bundler
122
124
  raise GemfileError, "You cannot specify the same gem twice with different version requirements.\n" \
123
125
  "You specified: #{current.name} (#{current.requirement}) and #{dep.name} (#{dep.requirement})" \
124
126
  "#{update_prompt}"
127
+ else
128
+ Bundler.ui.warn "Your Gemfile lists the gem #{current.name} (#{current.requirement}) more than once.\n" \
129
+ "You should probably keep only one of them.\n" \
130
+ "Remove any duplicate entries and specify the gem only once.\n" \
131
+ "While it's not a problem now, it could cause errors if you change the version of one of them later."
125
132
  end
126
133
 
127
- else
128
- Bundler.ui.warn "Your Gemfile lists the gem #{current.name} (#{current.requirement}) more than once.\n" \
129
- "You should probably keep only one of them.\n" \
130
- "Remove any duplicate entries and specify the gem only once.\n" \
131
- "While it's not a problem now, it could cause errors if you change the version of one of them later."
132
- end
133
-
134
- if current.source != dep.source
135
- unless deleted_dep
134
+ if current.source != dep.source
136
135
  return if dep.type == :development
137
136
  raise GemfileError, "You cannot specify the same gem twice coming from different sources.\n" \
138
137
  "You specified that #{dep.name} (#{dep.requirement}) should come from " \
@@ -164,8 +163,7 @@ module Bundler
164
163
  elsif block_given?
165
164
  with_source(@sources.add_rubygems_source("remotes" => source), &blk)
166
165
  else
167
- check_primary_source_safety(@sources)
168
- @sources.global_rubygems_source = source
166
+ @sources.add_global_rubygems_remote(source)
169
167
  end
170
168
  end
171
169
 
@@ -183,24 +181,14 @@ module Bundler
183
181
  end
184
182
 
185
183
  def path(path, options = {}, &blk)
186
- unless block_given?
187
- msg = "You can no longer specify a path source by itself. Instead, \n" \
188
- "either use the :path option on a gem, or specify the gems that \n" \
189
- "bundler should find in the path source by passing a block to \n" \
190
- "the path method, like: \n\n" \
191
- " path 'dir/containing/rails' do\n" \
192
- " gem 'rails'\n" \
193
- " end\n\n"
194
-
195
- raise DeprecatedError, msg if Bundler.feature_flag.disable_multisource?
196
- SharedHelpers.major_deprecation(2, msg.strip)
197
- end
198
-
199
184
  source_options = normalize_hash(options).merge(
200
185
  "path" => Pathname.new(path),
201
186
  "root_path" => gemfile_root,
202
187
  "gemspec" => gemspecs.find {|g| g.name == options["name"] }
203
188
  )
189
+
190
+ source_options["global"] = true unless block_given?
191
+
204
192
  source = @sources.add_path_source(source_options)
205
193
  with_source(source, &blk)
206
194
  end
@@ -229,6 +217,7 @@ module Bundler
229
217
  end
230
218
 
231
219
  def to_definition(lockfile, unlock)
220
+ check_primary_source_safety
232
221
  Definition.new(lockfile, @dependencies, @sources, unlock, @ruby_version, @optional_groups, @gemfiles)
233
222
  end
234
223
 
@@ -279,30 +268,33 @@ module Bundler
279
268
  raise GemfileError, "Undefined local variable or method `#{name}' for Gemfile"
280
269
  end
281
270
 
271
+ def check_primary_source_safety
272
+ check_path_source_safety
273
+ check_rubygems_source_safety
274
+ end
275
+
282
276
  private
283
277
 
284
278
  def add_git_sources
285
279
  git_source(:github) do |repo_name|
286
- warn_deprecated_git_source(:github, <<-'RUBY'.strip, 'Change any "reponame" :github sources to "username/reponame".')
287
- "https://github.com/#{repo_name}.git"
288
- RUBY
289
- repo_name = "#{repo_name}/#{repo_name}" unless repo_name.include?("/")
290
- "https://github.com/#{repo_name}.git"
280
+ if repo_name =~ GITHUB_PULL_REQUEST_URL
281
+ {
282
+ "git" => "https://github.com/#{$1}.git",
283
+ "branch" => "refs/pull/#{$2}/head",
284
+ "ref" => nil,
285
+ "tag" => nil,
286
+ }
287
+ else
288
+ repo_name = "#{repo_name}/#{repo_name}" unless repo_name.include?("/")
289
+ "https://github.com/#{repo_name}.git"
290
+ end
291
291
  end
292
292
 
293
293
  git_source(:gist) do |repo_name|
294
- warn_deprecated_git_source(:gist, '"https://gist.github.com/#{repo_name}.git"')
295
-
296
294
  "https://gist.github.com/#{repo_name}.git"
297
295
  end
298
296
 
299
297
  git_source(:bitbucket) do |repo_name|
300
- warn_deprecated_git_source(:bitbucket, <<-'RUBY'.strip)
301
- user_name, repo_name = repo_name.split("/")
302
- repo_name ||= user_name
303
- "https://#{user_name}@bitbucket.org/#{user_name}/#{repo_name}.git"
304
- RUBY
305
-
306
298
  user_name, repo_name = repo_name.split("/")
307
299
  repo_name ||= user_name
308
300
  "https://#{user_name}@bitbucket.org/#{user_name}/#{repo_name}.git"
@@ -373,7 +365,11 @@ repo_name ||= user_name
373
365
 
374
366
  git_name = (git_names & opts.keys).last
375
367
  if @git_sources[git_name]
376
- opts["git"] = @git_sources[git_name].call(opts[git_name])
368
+ git_opts = @git_sources[git_name].call(opts[git_name])
369
+ git_opts = { "git" => git_opts } if git_opts.is_a?(String)
370
+ opts.merge!(git_opts) do |key, _gemfile_value, _git_source_value|
371
+ raise GemfileError, %(The :#{key} option can't be used with `#{git_name}: #{opts[git_name].inspect}`)
372
+ end
377
373
  end
378
374
 
379
375
  %w[git path].each do |type|
@@ -440,44 +436,49 @@ repo_name ||= user_name
440
436
  end
441
437
  end
442
438
 
443
- def check_primary_source_safety(source_list)
444
- return if source_list.rubygems_primary_remotes.empty? && source_list.global_rubygems_source.nil?
439
+ def check_path_source_safety
440
+ return if @sources.global_path_source.nil?
445
441
 
446
- if Bundler.feature_flag.disable_multisource?
442
+ msg = "You can no longer specify a path source by itself. Instead, \n" \
443
+ "either use the :path option on a gem, or specify the gems that \n" \
444
+ "bundler should find in the path source by passing a block to \n" \
445
+ "the path method, like: \n\n" \
446
+ " path 'dir/containing/rails' do\n" \
447
+ " gem 'rails'\n" \
448
+ " end\n\n"
449
+
450
+ SharedHelpers.major_deprecation(2, msg.strip)
451
+ end
452
+
453
+ def check_rubygems_source_safety
454
+ if @sources.implicit_global_source?
455
+ implicit_global_source_warning
456
+ elsif @sources.aggregate_global_source?
457
+ multiple_global_source_warning
458
+ end
459
+ end
460
+
461
+ def implicit_global_source_warning
462
+ Bundler::SharedHelpers.major_deprecation 2, "This Gemfile does not include an explicit global source. " \
463
+ "Not using an explicit global source may result in a different lockfile being generated depending on " \
464
+ "the gems you have installed locally before bundler is run. " \
465
+ "Instead, define a global source in your Gemfile like this: source \"https://rubygems.org\"."
466
+ end
467
+
468
+ def multiple_global_source_warning
469
+ if Bundler.feature_flag.bundler_3_mode?
447
470
  msg = "This Gemfile contains multiple primary sources. " \
448
471
  "Each source after the first must include a block to indicate which gems " \
449
472
  "should come from that source"
450
- unless Bundler.feature_flag.bundler_2_mode?
451
- msg += ". To downgrade this error to a warning, run " \
452
- "`bundle config unset disable_multisource`"
453
- end
454
473
  raise GemfileEvalError, msg
455
474
  else
456
475
  Bundler::SharedHelpers.major_deprecation 2, "Your Gemfile contains multiple primary sources. " \
457
476
  "Using `source` more than once without a block is a security risk, and " \
458
477
  "may result in installing unexpected gems. To resolve this warning, use " \
459
- "a block to indicate which gems should come from the secondary source. " \
460
- "To upgrade this warning to an error, run `bundle config set --local " \
461
- "disable_multisource true`."
478
+ "a block to indicate which gems should come from the secondary source."
462
479
  end
463
480
  end
464
481
 
465
- def warn_deprecated_git_source(name, replacement, additional_message = nil)
466
- additional_message &&= " #{additional_message}"
467
- replacement = if replacement.count("\n").zero?
468
- "{|repo_name| #{replacement} }"
469
- else
470
- "do |repo_name|\n#{replacement.to_s.gsub(/^/, " ")}\n end"
471
- end
472
-
473
- Bundler::SharedHelpers.major_deprecation 3, <<-EOS
474
- The :#{name} git source is deprecated, and will be removed in the future.#{additional_message} Add this code to the top of your Gemfile to ensure it continues to work:
475
-
476
- git_source(:#{name}) #{replacement}
477
-
478
- EOS
479
- end
480
-
481
482
  class DSLError < GemfileError
482
483
  # @return [String] the description that should be presented to the user.
483
484
  #
@@ -3,17 +3,17 @@
3
3
  module Bundler
4
4
  # used for Creating Specifications from the Gemcutter Endpoint
5
5
  class EndpointSpecification < Gem::Specification
6
- ILLFORMED_MESSAGE = 'Ill-formed requirement ["#<YAML::Syck::DefaultKey'.freeze
7
6
  include MatchPlatform
8
7
 
9
- attr_reader :name, :version, :platform, :required_rubygems_version, :required_ruby_version, :checksum
8
+ attr_reader :name, :version, :platform, :checksum
10
9
  attr_accessor :source, :remote, :dependencies
11
10
 
12
- def initialize(name, version, platform, dependencies, metadata = nil)
11
+ def initialize(name, version, platform, spec_fetcher, dependencies, metadata = nil)
13
12
  super()
14
13
  @name = name
15
14
  @version = Gem::Version.create version
16
15
  @platform = platform
16
+ @spec_fetcher = spec_fetcher
17
17
  @dependencies = dependencies.map {|dep, reqs| build_dependency(dep, reqs) }
18
18
 
19
19
  @loaded_from = nil
@@ -22,6 +22,14 @@ module Bundler
22
22
  parse_metadata(metadata)
23
23
  end
24
24
 
25
+ def required_ruby_version
26
+ @required_ruby_version ||= _remote_specification.required_ruby_version
27
+ end
28
+
29
+ def required_rubygems_version
30
+ @required_rubygems_version ||= _remote_specification.required_rubygems_version
31
+ end
32
+
25
33
  def fetch_platform
26
34
  @platform
27
35
  end
@@ -106,12 +114,21 @@ module Bundler
106
114
 
107
115
  private
108
116
 
117
+ def _remote_specification
118
+ @_remote_specification ||= @spec_fetcher.fetch_spec([@name, @version, @platform])
119
+ end
120
+
109
121
  def local_specification_path
110
122
  "#{base_dir}/specifications/#{full_name}.gemspec"
111
123
  end
112
124
 
113
125
  def parse_metadata(data)
114
- return unless data
126
+ unless data
127
+ @required_ruby_version = nil
128
+ @required_rubygems_version = nil
129
+ return
130
+ end
131
+
115
132
  data.each do |k, v|
116
133
  next unless v
117
134
  case k.to_s
@@ -129,13 +146,6 @@ module Bundler
129
146
 
130
147
  def build_dependency(name, requirements)
131
148
  Gem::Dependency.new(name, requirements)
132
- rescue ArgumentError => e
133
- raise unless e.message.include?(ILLFORMED_MESSAGE)
134
- puts # we shouldn't print the error message on the "fetching info" status line
135
- raise GemspecError,
136
- "Unfortunately, the gem #{name} (#{version}) has an invalid " \
137
- "gemspec.\nPlease ask the gem author to yank the bad version to fix " \
138
- "this issue. For more information, see http://bit.ly/syck-defaultkey."
139
149
  end
140
150
  end
141
151
  end
@@ -38,7 +38,10 @@ module Bundler
38
38
 
39
39
  # Replaces `ENV` with the bundler environment variables backed up
40
40
  def replace_with_backup
41
- ENV.replace(backup) unless Gem.win_platform?
41
+ unless Gem.win_platform?
42
+ ENV.replace(backup)
43
+ return
44
+ end
42
45
 
43
46
  # Fallback logic for Windows below to workaround
44
47
  # https://bugs.ruby-lang.org/issues/16798. Can be dropped once all
@@ -75,10 +75,26 @@ module Bundler
75
75
  end
76
76
  end
77
77
 
78
+ def permission_type
79
+ case @permission_type
80
+ when :create
81
+ "executable permissions for all parent directories and write permissions for `#{parent_folder}`"
82
+ when :delete
83
+ permissions = "executable permissions for all parent directories and write permissions for `#{parent_folder}`"
84
+ permissions += ", and the same thing for all subdirectories inside #{@path}" if File.directory?(@path)
85
+ permissions
86
+ else
87
+ "#{@permission_type} permissions for that path"
88
+ end
89
+ end
90
+
91
+ def parent_folder
92
+ File.dirname(@path)
93
+ end
94
+
78
95
  def message
79
96
  "There was an error while trying to #{action} `#{@path}`. " \
80
- "It is likely that you need to grant #{@permission_type} permissions " \
81
- "for that path."
97
+ "It is likely that you need to grant #{permission_type}."
82
98
  end
83
99
 
84
100
  status_code(23)
@@ -122,7 +138,7 @@ module Bundler
122
138
 
123
139
  class VirtualProtocolError < BundlerError
124
140
  def message
125
- "There was an error relating to virtualization and file access." \
141
+ "There was an error relating to virtualization and file access. " \
126
142
  "It is likely that you need to grant access to or mount some file system correctly."
127
143
  end
128
144
 
@@ -27,22 +27,17 @@ module Bundler
27
27
 
28
28
  (1..10).each {|v| define_method("bundler_#{v}_mode?") { major_version >= v } }
29
29
 
30
- settings_flag(:allow_bundler_dependency_conflicts) { bundler_3_mode? }
31
30
  settings_flag(:allow_offline_install) { bundler_3_mode? }
32
31
  settings_flag(:auto_clean_without_path) { bundler_3_mode? }
33
32
  settings_flag(:cache_all) { bundler_3_mode? }
34
33
  settings_flag(:default_install_uses_path) { bundler_3_mode? }
35
- settings_flag(:deployment_means_frozen) { bundler_3_mode? }
36
- settings_flag(:disable_multisource) { bundler_3_mode? }
37
34
  settings_flag(:forget_cli_options) { bundler_3_mode? }
38
35
  settings_flag(:global_gem_cache) { bundler_3_mode? }
39
- settings_flag(:only_update_to_newer_versions) { bundler_3_mode? }
40
36
  settings_flag(:path_relative_to_cwd) { bundler_3_mode? }
41
37
  settings_flag(:plugins) { @bundler_version >= Gem::Version.new("1.14") }
42
38
  settings_flag(:print_only_version_number) { bundler_3_mode? }
43
39
  settings_flag(:setup_makes_kernel_gem_public) { !bundler_3_mode? }
44
40
  settings_flag(:suppress_install_using_messages) { bundler_3_mode? }
45
- settings_flag(:unlock_source_unlocks_spec) { !bundler_3_mode? }
46
41
  settings_flag(:update_requires_all_flag) { bundler_4_mode? }
47
42
  settings_flag(:use_gem_version_promoter_for_major_updates) { bundler_3_mode? }
48
43
 
@@ -57,22 +57,17 @@ module Bundler
57
57
  gem_info
58
58
  end
59
59
 
60
- def fetch_spec(spec)
61
- spec -= [nil, "ruby", ""]
62
- contents = compact_index_client.spec(*spec)
63
- return nil if contents.nil?
64
- contents.unshift(spec.first)
65
- contents[3].map! {|d| Gem::Dependency.new(*d) }
66
- EndpointSpecification.new(*contents)
67
- end
68
- compact_index_request :fetch_spec
69
-
70
60
  def available?
71
- return nil unless SharedHelpers.md5_available?
72
- user_home = Bundler.user_home
73
- return nil unless user_home.directory? && user_home.writable?
61
+ unless SharedHelpers.md5_available?
62
+ Bundler.ui.debug("FIPS mode is enabled, bundler can't use the CompactIndex API")
63
+ return nil
64
+ end
65
+ if fetch_uri.scheme == "file"
66
+ Bundler.ui.debug("Using a local server, bundler won't use the CompactIndex API")
67
+ return false
68
+ end
74
69
  # Read info file checksums out of /versions, so we can know if gems are up to date
75
- fetch_uri.scheme != "file" && compact_index_client.update_and_parse_checksums!
70
+ compact_index_client.update_and_parse_checksums!
76
71
  rescue CompactIndexClient::Updater::MisMatchedChecksumError => e
77
72
  Bundler.ui.debug(e.message)
78
73
  nil
@@ -111,7 +106,7 @@ module Bundler
111
106
  def bundle_worker(func = nil)
112
107
  @bundle_worker ||= begin
113
108
  worker_name = "Compact Index (#{display_uri.host})"
114
- Bundler::Worker.new(Bundler.current_ruby.rbx? ? 1 : 25, worker_name, func)
109
+ Bundler::Worker.new(Bundler.settings.processor_count, worker_name, func)
115
110
  end
116
111
  @bundle_worker.tap do |worker|
117
112
  worker.instance_variable_set(:@func, func) if func
@@ -14,8 +14,10 @@ module Bundler
14
14
  def fetch(uri, headers = {}, counter = 0)
15
15
  raise HTTPError, "Too many redirects" if counter >= redirect_limit
16
16
 
17
+ filtered_uri = URICredentialsFilter.credential_filtered_uri(uri)
18
+
17
19
  response = request(uri, headers)
18
- Bundler.ui.debug("HTTP #{response.code} #{response.message} #{uri}")
20
+ Bundler.ui.debug("HTTP #{response.code} #{response.message} #{filtered_uri}")
19
21
 
20
22
  case response
21
23
  when Net::HTTPSuccess, Net::HTTPNotModified
@@ -40,7 +42,7 @@ module Bundler
40
42
  raise BadAuthenticationError, uri.host if uri.userinfo
41
43
  raise AuthenticationRequiredError, uri.host
42
44
  when Net::HTTPNotFound
43
- raise FallbackError, "Net::HTTPNotFound: #{URICredentialsFilter.credential_filtered_uri(uri)}"
45
+ raise FallbackError, "Net::HTTPNotFound: #{filtered_uri}"
44
46
  else
45
47
  raise HTTPError, "#{response.class}#{": #{response.body}" unless response.body.empty?}"
46
48
  end
@@ -49,7 +51,9 @@ module Bundler
49
51
  def request(uri, headers)
50
52
  validate_uri_scheme!(uri)
51
53
 
52
- Bundler.ui.debug "HTTP GET #{uri}"
54
+ filtered_uri = URICredentialsFilter.credential_filtered_uri(uri)
55
+
56
+ Bundler.ui.debug "HTTP GET #{filtered_uri}"
53
57
  req = Net::HTTP::Get.new uri.request_uri, headers
54
58
  if uri.user
55
59
  user = CGI.unescape(uri.user)
@@ -64,12 +68,11 @@ module Bundler
64
68
  raise CertificateFailureError.new(uri)
65
69
  rescue *HTTP_ERRORS => e
66
70
  Bundler.ui.trace e
67
- case e.message
68
- when /host down:/, /getaddrinfo: nodename nor servname provided/
71
+ if e.is_a?(SocketError) || e.message =~ /host down:/
69
72
  raise NetworkDownError, "Could not reach host #{uri.host}. Check your network " \
70
73
  "connection and try again."
71
74
  else
72
- raise HTTPError, "Network error while fetching #{URICredentialsFilter.credential_filtered_uri(uri)}" \
75
+ raise HTTPError, "Network error while fetching #{filtered_uri}" \
73
76
  " (#{e})"
74
77
  end
75
78
  end
@@ -1,7 +1,6 @@
1
1
  # frozen_string_literal: true
2
2
 
3
3
  require_relative "base"
4
- require "rubygems/remote_fetcher"
5
4
 
6
5
  module Bundler
7
6
  class Fetcher
@@ -22,32 +21,6 @@ module Bundler
22
21
  raise HTTPError, "Could not fetch specs from #{display_uri} due to underlying error <#{e.message}>"
23
22
  end
24
23
  end
25
-
26
- def fetch_spec(spec)
27
- spec -= [nil, "ruby", ""]
28
- spec_file_name = "#{spec.join "-"}.gemspec"
29
-
30
- uri = Bundler::URI.parse("#{remote_uri}#{Gem::MARSHAL_SPEC_DIR}#{spec_file_name}.rz")
31
- if uri.scheme == "file"
32
- path = Bundler.rubygems.correct_for_windows_path(uri.path)
33
- Bundler.load_marshal Bundler.rubygems.inflate(Gem.read_binary(path))
34
- elsif cached_spec_path = gemspec_cached_path(spec_file_name)
35
- Bundler.load_gemspec(cached_spec_path)
36
- else
37
- Bundler.load_marshal Bundler.rubygems.inflate(downloader.fetch(uri).body)
38
- end
39
- rescue MarshalError
40
- raise HTTPError, "Gemspec #{spec} contained invalid data.\n" \
41
- "Your network or your gem server is probably having issues right now."
42
- end
43
-
44
- private
45
-
46
- # cached gem specification path, if one exists
47
- def gemspec_cached_path(spec_file_name)
48
- paths = Bundler.rubygems.spec_cache_dirs.map {|dir| File.join(dir, spec_file_name) }
49
- paths.find {|path| File.file? path }
50
- end
51
24
  end
52
25
  end
53
26
  end