bundler 2.2.11 → 2.3.6

This diff represents the content of publicly available package versions that have been released to one of the supported registries. The information contained in this diff is provided for informational purposes only and reflects changes between package versions as they appear in their respective public registries.
Files changed (174) hide show
  1. checksums.yaml +4 -4
  2. data/CHANGELOG.md +414 -5
  3. data/README.md +1 -1
  4. data/bundler.gemspec +2 -3
  5. data/exe/bundle +7 -8
  6. data/lib/bundler/.document +1 -0
  7. data/lib/bundler/build_metadata.rb +2 -2
  8. data/lib/bundler/cli/cache.rb +1 -1
  9. data/lib/bundler/cli/check.rb +4 -2
  10. data/lib/bundler/cli/common.rb +15 -2
  11. data/lib/bundler/cli/doctor.rb +24 -5
  12. data/lib/bundler/cli/exec.rb +1 -6
  13. data/lib/bundler/cli/gem.rb +130 -26
  14. data/lib/bundler/cli/info.rb +16 -4
  15. data/lib/bundler/cli/install.rb +12 -27
  16. data/lib/bundler/cli/issue.rb +4 -3
  17. data/lib/bundler/cli/list.rb +7 -1
  18. data/lib/bundler/cli/lock.rb +5 -1
  19. data/lib/bundler/cli/open.rb +1 -2
  20. data/lib/bundler/cli/outdated.rb +10 -11
  21. data/lib/bundler/cli/platform.rb +1 -1
  22. data/lib/bundler/cli/remove.rb +1 -2
  23. data/lib/bundler/cli/update.rb +17 -8
  24. data/lib/bundler/cli.rb +41 -55
  25. data/lib/bundler/compact_index_client/cache.rb +0 -9
  26. data/lib/bundler/compact_index_client/updater.rb +10 -11
  27. data/lib/bundler/compact_index_client.rb +2 -8
  28. data/lib/bundler/current_ruby.rb +5 -4
  29. data/lib/bundler/definition.rb +147 -290
  30. data/lib/bundler/dependency.rb +5 -7
  31. data/lib/bundler/digest.rb +71 -0
  32. data/lib/bundler/dsl.rb +67 -66
  33. data/lib/bundler/endpoint_specification.rb +21 -11
  34. data/lib/bundler/env.rb +1 -1
  35. data/lib/bundler/environment_preserver.rb +4 -1
  36. data/lib/bundler/errors.rb +19 -3
  37. data/lib/bundler/feature_flag.rb +0 -4
  38. data/lib/bundler/fetcher/compact_index.rb +10 -15
  39. data/lib/bundler/fetcher/downloader.rb +9 -6
  40. data/lib/bundler/fetcher/index.rb +0 -27
  41. data/lib/bundler/fetcher.rb +10 -16
  42. data/lib/bundler/friendly_errors.rb +5 -32
  43. data/lib/bundler/gem_helper.rb +21 -16
  44. data/lib/bundler/index.rb +2 -7
  45. data/lib/bundler/injector.rb +12 -3
  46. data/lib/bundler/inline.rb +2 -1
  47. data/lib/bundler/installer/gem_installer.rb +4 -22
  48. data/lib/bundler/installer/parallel_installer.rb +36 -15
  49. data/lib/bundler/installer/standalone.rb +14 -9
  50. data/lib/bundler/installer.rb +8 -17
  51. data/lib/bundler/lazy_specification.rb +23 -2
  52. data/lib/bundler/lockfile_generator.rb +1 -1
  53. data/lib/bundler/lockfile_parser.rb +16 -45
  54. data/lib/bundler/man/bundle-add.1 +10 -2
  55. data/lib/bundler/man/bundle-add.1.ronn +7 -1
  56. data/lib/bundler/man/bundle-binstubs.1 +1 -1
  57. data/lib/bundler/man/bundle-cache.1 +1 -1
  58. data/lib/bundler/man/bundle-check.1 +1 -1
  59. data/lib/bundler/man/bundle-clean.1 +1 -1
  60. data/lib/bundler/man/bundle-config.1 +23 -15
  61. data/lib/bundler/man/bundle-config.1.ronn +24 -17
  62. data/lib/bundler/man/bundle-doctor.1 +1 -1
  63. data/lib/bundler/man/bundle-exec.1 +1 -1
  64. data/lib/bundler/man/bundle-gem.1 +14 -1
  65. data/lib/bundler/man/bundle-gem.1.ronn +16 -0
  66. data/lib/bundler/man/bundle-info.1 +1 -1
  67. data/lib/bundler/man/bundle-init.1 +1 -1
  68. data/lib/bundler/man/bundle-inject.1 +1 -1
  69. data/lib/bundler/man/bundle-install.1 +2 -2
  70. data/lib/bundler/man/bundle-install.1.ronn +2 -2
  71. data/lib/bundler/man/bundle-list.1 +1 -1
  72. data/lib/bundler/man/bundle-lock.1 +1 -1
  73. data/lib/bundler/man/bundle-open.1 +1 -1
  74. data/lib/bundler/man/bundle-outdated.1 +1 -1
  75. data/lib/bundler/man/bundle-platform.1 +1 -1
  76. data/lib/bundler/man/bundle-pristine.1 +1 -1
  77. data/lib/bundler/man/bundle-remove.1 +1 -1
  78. data/lib/bundler/man/bundle-show.1 +1 -1
  79. data/lib/bundler/man/bundle-update.1 +5 -5
  80. data/lib/bundler/man/bundle-update.1.ronn +5 -4
  81. data/lib/bundler/man/bundle-viz.1 +1 -1
  82. data/lib/bundler/man/bundle.1 +1 -1
  83. data/lib/bundler/man/gemfile.5 +28 -2
  84. data/lib/bundler/man/gemfile.5.ronn +9 -1
  85. data/lib/bundler/plugin/api/source.rb +22 -0
  86. data/lib/bundler/plugin/index.rb +4 -1
  87. data/lib/bundler/plugin/installer.rb +10 -10
  88. data/lib/bundler/plugin/source_list.rb +4 -0
  89. data/lib/bundler/plugin.rb +28 -8
  90. data/lib/bundler/process_lock.rb +1 -1
  91. data/lib/bundler/psyched_yaml.rb +1 -13
  92. data/lib/bundler/remote_specification.rb +7 -0
  93. data/lib/bundler/resolver/spec_group.rb +1 -25
  94. data/lib/bundler/resolver.rb +55 -147
  95. data/lib/bundler/retry.rb +1 -1
  96. data/lib/bundler/ruby_version.rb +1 -1
  97. data/lib/bundler/rubygems_ext.rb +30 -8
  98. data/lib/bundler/rubygems_gem_installer.rb +68 -1
  99. data/lib/bundler/rubygems_integration.rb +43 -60
  100. data/lib/bundler/runtime.rb +18 -11
  101. data/lib/bundler/self_manager.rb +168 -0
  102. data/lib/bundler/settings.rb +96 -20
  103. data/lib/bundler/setup.rb +2 -2
  104. data/lib/bundler/shared_helpers.rb +4 -19
  105. data/lib/bundler/source/git/git_proxy.rb +8 -6
  106. data/lib/bundler/source/git.rb +22 -4
  107. data/lib/bundler/source/metadata.rb +1 -5
  108. data/lib/bundler/source/path/installer.rb +1 -1
  109. data/lib/bundler/source/path.rb +3 -1
  110. data/lib/bundler/source/rubygems.rb +111 -106
  111. data/lib/bundler/source/rubygems_aggregate.rb +68 -0
  112. data/lib/bundler/source.rb +21 -0
  113. data/lib/bundler/source_list.rb +100 -60
  114. data/lib/bundler/source_map.rb +58 -0
  115. data/lib/bundler/spec_set.rb +17 -31
  116. data/lib/bundler/stub_specification.rb +8 -0
  117. data/lib/bundler/templates/Executable.bundler +7 -7
  118. data/lib/bundler/templates/Gemfile +0 -2
  119. data/lib/bundler/templates/gems.rb +0 -3
  120. data/lib/bundler/templates/newgem/Gemfile.tt +5 -2
  121. data/lib/bundler/templates/newgem/README.md.tt +5 -3
  122. data/lib/bundler/templates/newgem/Rakefile.tt +15 -2
  123. data/lib/bundler/templates/newgem/github/workflows/main.yml.tt +15 -6
  124. data/lib/bundler/templates/newgem/newgem.gemspec.tt +18 -16
  125. data/lib/bundler/templates/newgem/sig/newgem.rbs.tt +8 -0
  126. data/lib/bundler/templates/newgem/standard.yml.tt +3 -0
  127. data/lib/bundler/templates/newgem/test/minitest/{newgem_test.rb.tt → test_newgem.rb.tt} +1 -1
  128. data/lib/bundler/ui/shell.rb +1 -1
  129. data/lib/bundler/vendor/.document +1 -0
  130. data/lib/bundler/vendor/connection_pool/LICENSE +20 -0
  131. data/lib/bundler/vendor/connection_pool/lib/connection_pool/timed_stack.rb +19 -21
  132. data/lib/bundler/vendor/connection_pool/lib/connection_pool/version.rb +1 -1
  133. data/lib/bundler/vendor/connection_pool/lib/connection_pool/wrapper.rb +57 -0
  134. data/lib/bundler/vendor/connection_pool/lib/connection_pool.rb +39 -74
  135. data/lib/bundler/vendor/fileutils/LICENSE.txt +22 -0
  136. data/lib/bundler/vendor/molinillo/LICENSE +9 -0
  137. data/lib/bundler/vendor/molinillo/lib/molinillo/dependency_graph.rb +2 -2
  138. data/lib/bundler/vendor/molinillo/lib/molinillo/modules/specification_provider.rb +1 -1
  139. data/lib/bundler/vendor/net-http-persistent/README.rdoc +82 -0
  140. data/lib/bundler/vendor/thor/LICENSE.md +20 -0
  141. data/lib/bundler/vendor/thor/lib/thor/actions/file_manipulation.rb +5 -5
  142. data/lib/bundler/vendor/thor/lib/thor/actions/inject_into_file.rb +1 -2
  143. data/lib/bundler/vendor/thor/lib/thor/actions.rb +6 -2
  144. data/lib/bundler/vendor/thor/lib/thor/core_ext/hash_with_indifferent_access.rb +6 -0
  145. data/lib/bundler/vendor/thor/lib/thor/error.rb +9 -4
  146. data/lib/bundler/vendor/thor/lib/thor/parser/options.rb +19 -1
  147. data/lib/bundler/vendor/thor/lib/thor/shell/basic.rb +22 -4
  148. data/lib/bundler/vendor/thor/lib/thor/shell.rb +1 -1
  149. data/lib/bundler/vendor/thor/lib/thor/util.rb +1 -1
  150. data/lib/bundler/vendor/thor/lib/thor/version.rb +1 -1
  151. data/lib/bundler/vendor/tmpdir/lib/tmpdir.rb +1 -1
  152. data/lib/bundler/vendor/tsort/LICENSE.txt +22 -0
  153. data/lib/bundler/vendor/tsort/lib/tsort.rb +453 -0
  154. data/lib/bundler/vendor/uri/LICENSE.txt +22 -0
  155. data/lib/bundler/vendor/uri/lib/uri/common.rb +17 -80
  156. data/lib/bundler/vendor/uri/lib/uri/ftp.rb +0 -1
  157. data/lib/bundler/vendor/uri/lib/uri/generic.rb +5 -6
  158. data/lib/bundler/vendor/uri/lib/uri/http.rb +0 -1
  159. data/lib/bundler/vendor/uri/lib/uri/https.rb +0 -1
  160. data/lib/bundler/vendor/uri/lib/uri/ldap.rb +1 -1
  161. data/lib/bundler/vendor/uri/lib/uri/mailto.rb +0 -1
  162. data/lib/bundler/vendor/uri/lib/uri/rfc2396_parser.rb +1 -14
  163. data/lib/bundler/vendor/uri/lib/uri/rfc3986_parser.rb +1 -12
  164. data/lib/bundler/vendor/uri/lib/uri/version.rb +1 -1
  165. data/lib/bundler/vendor/uri/lib/uri/ws.rb +84 -0
  166. data/lib/bundler/vendor/uri/lib/uri/wss.rb +22 -0
  167. data/lib/bundler/vendor/uri/lib/uri.rb +0 -1
  168. data/lib/bundler/vendored_tsort.rb +4 -0
  169. data/lib/bundler/version.rb +1 -1
  170. data/lib/bundler/worker.rb +19 -4
  171. data/lib/bundler.rb +28 -31
  172. metadata +27 -9
  173. data/lib/bundler/gemdeps.rb +0 -29
  174. data/lib/bundler/vendor/connection_pool/lib/connection_pool/monotonic_time.rb +0 -66
@@ -28,7 +28,8 @@ module Bundler
28
28
  " is a chance you are experiencing a man-in-the-middle attack, but" \
29
29
  " most likely your system doesn't have the CA certificates needed" \
30
30
  " for verification. For information about OpenSSL certificates, see" \
31
- " http://bit.ly/ruby-ssl. To connect without using SSL, edit your Gemfile" \
31
+ " https://railsapps.github.io/openssl-certificate-verify-failed.html." \
32
+ " To connect without using SSL, edit your Gemfile" \
32
33
  " sources and change 'https' to 'http'."
33
34
  end
34
35
  end
@@ -47,7 +48,8 @@ module Bundler
47
48
  remote_uri = filter_uri(remote_uri)
48
49
  super "Authentication is required for #{remote_uri}.\n" \
49
50
  "Please supply credentials for this source. You can do this by running:\n" \
50
- " bundle config set --global #{remote_uri} username:password"
51
+ "`bundle config set --global #{remote_uri} username:password`\n" \
52
+ "or by storing the credentials in the `#{Settings.key_for(remote_uri)}` environment variable"
51
53
  end
52
54
  end
53
55
  # This error is raised if HTTP authentication is provided, but incorrect.
@@ -69,8 +71,8 @@ module Bundler
69
71
  :HTTPUnsupportedMediaType, :HTTPVersionNotSupported].freeze
70
72
  FAIL_ERRORS = begin
71
73
  fail_errors = [AuthenticationRequiredError, BadAuthenticationError, FallbackError]
72
- fail_errors << Gem::Requirement::BadRequirementError if defined?(Gem::Requirement::BadRequirementError)
73
- fail_errors.concat(NET_ERRORS.map {|e| SharedHelpers.const_get_safely(e, Net) }.compact)
74
+ fail_errors << Gem::Requirement::BadRequirementError
75
+ fail_errors.concat(NET_ERRORS.map {|e| Net.const_get(e) })
74
76
  end.freeze
75
77
 
76
78
  class << self
@@ -120,7 +122,6 @@ module Bundler
120
122
 
121
123
  # return the specs in the bundler format as an index
122
124
  def specs(gem_names, source)
123
- old = Bundler.rubygems.sources
124
125
  index = Bundler::Index.new
125
126
 
126
127
  if Bundler::Fetcher.disable_endpoint
@@ -128,17 +129,15 @@ module Bundler
128
129
  specs = fetchers.last.specs(gem_names)
129
130
  else
130
131
  specs = []
131
- fetchers.shift until fetchers.first.available? || fetchers.empty?
132
- fetchers.dup.each do |f|
133
- break unless f.api_fetcher? && !gem_names || !specs = f.specs(gem_names)
134
- fetchers.delete(f)
132
+ @fetchers = fetchers.drop_while do |f|
133
+ !f.available? || (f.api_fetcher? && !gem_names) || !specs = f.specs(gem_names)
135
134
  end
136
135
  @use_api = false if fetchers.none?(&:api_fetcher?)
137
136
  end
138
137
 
139
138
  specs.each do |name, version, platform, dependencies, metadata|
140
139
  spec = if dependencies
141
- EndpointSpecification.new(name, version, platform, dependencies, metadata)
140
+ EndpointSpecification.new(name, version, platform, self, dependencies, metadata)
142
141
  else
143
142
  RemoteSpecification.new(name, version, platform, self)
144
143
  end
@@ -151,8 +150,6 @@ module Bundler
151
150
  rescue CertificateFailureError
152
151
  Bundler.ui.info "" if gem_names && use_api # newline after dots
153
152
  raise
154
- ensure
155
- Bundler.rubygems.sources = old
156
153
  end
157
154
 
158
155
  def use_api
@@ -273,8 +270,7 @@ module Bundler
273
270
  # cached gem specification path, if one exists
274
271
  def gemspec_cached_path(spec_file_name)
275
272
  paths = Bundler.rubygems.spec_cache_dirs.map {|dir| File.join(dir, spec_file_name) }
276
- paths = paths.select {|path| File.file? path }
277
- paths.first
273
+ paths.find {|path| File.file? path }
278
274
  end
279
275
 
280
276
  HTTP_ERRORS = [
@@ -302,8 +298,6 @@ module Bundler
302
298
  store
303
299
  end
304
300
 
305
- private
306
-
307
301
  def remote_uri
308
302
  @remote.uri
309
303
  end
@@ -49,8 +49,6 @@ module Bundler
49
49
  "Alternatively, you can increase the amount of memory the JVM is able to use by running Bundler with jruby -J-Xmx1024m -S bundle (JRuby defaults to 500MB)."
50
50
  else request_issue_report_for(error)
51
51
  end
52
- rescue StandardError
53
- raise error
54
52
  end
55
53
 
56
54
  def exit_status(error)
@@ -65,34 +63,6 @@ module Bundler
65
63
  def request_issue_report_for(e)
66
64
  Bundler.ui.error <<-EOS.gsub(/^ {8}/, ""), nil, nil
67
65
  --- ERROR REPORT TEMPLATE -------------------------------------------------------
68
- # Error Report
69
-
70
- ## Questions
71
-
72
- Please fill out answers to these questions, it'll help us figure out
73
- why things are going wrong.
74
-
75
- - **What did you do?**
76
-
77
- I ran the command `#{$PROGRAM_NAME} #{ARGV.join(" ")}`
78
-
79
- - **What did you expect to happen?**
80
-
81
- I expected Bundler to...
82
-
83
- - **What happened instead?**
84
-
85
- Instead, what happened was...
86
-
87
- - **Have you tried any solutions posted on similar issues in our issue tracker, stack overflow, or google?**
88
-
89
- I tried...
90
-
91
- - **Have you read our issues document, https://github.com/rubygems/rubygems/blob/master/bundler/doc/contributing/ISSUES.md?**
92
-
93
- ...
94
-
95
- ## Backtrace
96
66
 
97
67
  ```
98
68
  #{e.class}: #{e.message}
@@ -111,8 +81,7 @@ module Bundler
111
81
  First, try this link to see if there are any existing issue reports for this error:
112
82
  #{issues_url(e)}
113
83
 
114
- If there aren't any reports for this error yet, please create copy and paste the report template above into a new issue. Don't forget to anonymize any private data! The new issue form is located at:
115
- https://github.com/rubygems/rubygems/issues/new?labels=Bundler
84
+ If there aren't any reports for this error yet, please fill in the new issue form located at #{new_issue_url}, and copy and paste the report template above in there.
116
85
  EOS
117
86
  end
118
87
 
@@ -123,6 +92,10 @@ module Bundler
123
92
  "https://github.com/rubygems/rubygems/search?q=" \
124
93
  "#{CGI.escape(message)}&type=Issues"
125
94
  end
95
+
96
+ def new_issue_url
97
+ "https://github.com/rubygems/rubygems/issues/new?labels=Bundler&template=bundler-related-issue.md"
98
+ end
126
99
  end
127
100
 
128
101
  def self.with_friendly_errors
@@ -47,6 +47,11 @@ module Bundler
47
47
  built_gem_path = build_gem
48
48
  end
49
49
 
50
+ desc "Generate SHA512 checksum if #{name}-#{version}.gem into the checksums directory."
51
+ task "build:checksum" => "build" do
52
+ build_checksum(built_gem_path)
53
+ end
54
+
50
55
  desc "Build and install #{name}-#{version}.gem into system gems."
51
56
  task "install" => "build" do
52
57
  install_gem(built_gem_path)
@@ -71,7 +76,7 @@ module Bundler
71
76
  tag_version { git_push(args[:remote]) } unless already_tagged?
72
77
  end
73
78
 
74
- task "release:rubygem_push" do
79
+ task "release:rubygem_push" => "build" do
75
80
  rubygem_push(built_gem_path) if gem_push?
76
81
  end
77
82
 
@@ -93,13 +98,21 @@ module Bundler
93
98
  built_gem_path ||= build_gem
94
99
  cmd = [*gem_command, "install", built_gem_path.to_s]
95
100
  cmd << "--local" if local
96
- _, status = sh_with_status(cmd)
97
- unless status.success?
98
- raise "Couldn't install gem, run `gem install #{built_gem_path}' for more detailed output"
99
- end
101
+ sh(cmd)
100
102
  Bundler.ui.confirm "#{name} (#{version}) installed."
101
103
  end
102
104
 
105
+ def build_checksum(built_gem_path = nil)
106
+ built_gem_path ||= build_gem
107
+ SharedHelpers.filesystem_access(File.join(base, "checksums")) {|p| FileUtils.mkdir_p(p) }
108
+ file_name = "#{File.basename(built_gem_path)}.sha512"
109
+ require "digest/sha2"
110
+ checksum = ::Digest::SHA512.file(built_gem_path).hexdigest
111
+ target = File.join(base, "checksums", file_name)
112
+ File.write(target, checksum + "\n")
113
+ Bundler.ui.confirm "#{name} #{version} checksum written to checksums/#{file_name}."
114
+ end
115
+
103
116
  protected
104
117
 
105
118
  def rubygem_push(path)
@@ -116,8 +129,8 @@ module Bundler
116
129
 
117
130
  def git_push(remote = nil)
118
131
  remote ||= default_remote
119
- perform_git_push "#{remote} refs/heads/#{current_branch}"
120
- perform_git_push "#{remote} refs/tags/#{version_tag}"
132
+ sh("git push #{remote} refs/heads/#{current_branch}".shellsplit)
133
+ sh("git push #{remote} refs/tags/#{version_tag}".shellsplit)
121
134
  Bundler.ui.confirm "Pushed git commits and release tag."
122
135
  end
123
136
 
@@ -145,13 +158,6 @@ module Bundler
145
158
  allowed_push_host || env_rubygems_host || "rubygems.org"
146
159
  end
147
160
 
148
- def perform_git_push(options = "")
149
- cmd = "git push #{options}"
150
- out, status = sh_with_status(cmd.shellsplit)
151
- return if status.success?
152
- raise "Couldn't git push. `#{cmd}' failed with the following output:\n\n#{out}\n"
153
- end
154
-
155
161
  def already_tagged?
156
162
  return false unless sh(%w[git tag]).split(/\n/).include?(version_tag)
157
163
  Bundler.ui.confirm "Tag #{version_tag} has already been created."
@@ -202,8 +208,7 @@ module Bundler
202
208
  def sh(cmd, &block)
203
209
  out, status = sh_with_status(cmd, &block)
204
210
  unless status.success?
205
- cmd = cmd.shelljoin if cmd.respond_to?(:shelljoin)
206
- raise(out.empty? ? "Running `#{cmd}` failed. Run this command directly for more detailed output." : out)
211
+ raise("Running `#{cmd.shelljoin}` failed with the following output:\n\n#{out}\n")
207
212
  end
208
213
  out
209
214
  end
data/lib/bundler/index.rb CHANGED
@@ -122,10 +122,9 @@ module Bundler
122
122
  names
123
123
  end
124
124
 
125
- # returns a list of the dependencies
126
125
  def unmet_dependency_names
127
126
  dependency_names.select do |name|
128
- name != "bundler" && search(name).empty?
127
+ search(name).empty?
129
128
  end
130
129
  end
131
130
 
@@ -196,11 +195,7 @@ module Bundler
196
195
  if base # allow all platforms when searching from a lockfile
197
196
  dependency.matches_spec?(spec)
198
197
  else
199
- if Gem::Platform.respond_to? :match_spec?
200
- dependency.matches_spec?(spec) && Gem::Platform.match_spec?(spec)
201
- else
202
- dependency.matches_spec?(spec) && Gem::Platform.match(spec.platform)
203
- end
198
+ dependency.matches_spec?(spec) && Gem::Platform.match_spec?(spec)
204
199
  end
205
200
  end
206
201
 
@@ -112,9 +112,12 @@ module Bundler
112
112
 
113
113
  source = ", :source => \"#{d.source}\"" unless d.source.nil?
114
114
  git = ", :git => \"#{d.git}\"" unless d.git.nil?
115
+ github = ", :github => \"#{d.github}\"" unless d.github.nil?
115
116
  branch = ", :branch => \"#{d.branch}\"" unless d.branch.nil?
117
+ ref = ", :ref => \"#{d.ref}\"" unless d.ref.nil?
118
+ require_path = ", :require => #{convert_autorequire(d.autorequire)}" unless d.autorequire.nil?
116
119
 
117
- %(gem #{name}#{requirement}#{group}#{source}#{git}#{branch})
120
+ %(gem #{name}#{requirement}#{group}#{source}#{git}#{github}#{branch}#{ref}#{require_path})
118
121
  end.join("\n")
119
122
  end
120
123
 
@@ -128,7 +131,7 @@ module Bundler
128
131
  # evaluates a gemfile to remove the specified gem
129
132
  # from it.
130
133
  def remove_deps(gemfile_path)
131
- initial_gemfile = IO.readlines(gemfile_path)
134
+ initial_gemfile = File.readlines(gemfile_path)
132
135
 
133
136
  Bundler.ui.info "Removing gems from #{gemfile_path}"
134
137
 
@@ -181,7 +184,7 @@ module Bundler
181
184
  patterns = /gem\s+(['"])#{Regexp.union(gems)}\1|gem\s*\((['"])#{Regexp.union(gems)}\2\)/
182
185
  new_gemfile = []
183
186
  multiline_removal = false
184
- IO.readlines(gemfile_path).each do |line|
187
+ File.readlines(gemfile_path).each do |line|
185
188
  match_data = line.match(patterns)
186
189
  if match_data && is_not_within_comment?(line, match_data)
187
190
  multiline_removal = line.rstrip.end_with?(",")
@@ -269,5 +272,11 @@ module Bundler
269
272
  def show_warning(message)
270
273
  Bundler.ui.info Bundler.ui.add_color(message, :yellow)
271
274
  end
275
+
276
+ def convert_autorequire(autorequire)
277
+ autorequire = autorequire.first
278
+ return autorequire if autorequire == "false"
279
+ autorequire.inspect
280
+ end
272
281
  end
273
282
  end
@@ -50,8 +50,9 @@ def gemfile(install = false, options = {}, &gemfile)
50
50
  Bundler::Plugin.gemfile_install(&gemfile) if Bundler.feature_flag.plugins?
51
51
  builder = Bundler::Dsl.new
52
52
  builder.instance_eval(&gemfile)
53
+ builder.check_primary_source_safety
53
54
 
54
- Bundler.settings.temporary(:frozen => false) do
55
+ Bundler.settings.temporary(:deployment => false, :frozen => false) do
55
56
  definition = builder.to_definition(nil, true)
56
57
  def definition.lock(*); end
57
58
  definition.validate_runtime!
@@ -1,7 +1,5 @@
1
1
  # frozen_string_literal: true
2
2
 
3
- require "shellwords"
4
-
5
3
  module Bundler
6
4
  class GemInstaller
7
5
  attr_reader :spec, :standalone, :worker, :force, :installer
@@ -15,7 +13,7 @@ module Bundler
15
13
  end
16
14
 
17
15
  def install_from_spec
18
- post_install_message = spec_settings ? install_with_settings : install
16
+ post_install_message = install
19
17
  Bundler.ui.debug "#{worker}: #{spec.name} (#{spec.version}) from #{spec.loaded_from}"
20
18
  generate_executable_stubs
21
19
  return true, post_install_message
@@ -31,34 +29,23 @@ module Bundler
31
29
 
32
30
  def specific_failure_message(e)
33
31
  message = "#{e.class}: #{e.message}\n"
34
- message += " " + e.backtrace.join("\n ") + "\n\n" if Bundler.ui.debug?
32
+ message += " " + e.backtrace.join("\n ") + "\n\n"
35
33
  message = message.lines.first + Bundler.ui.add_color(message.lines.drop(1).join, :clear)
36
34
  message + Bundler.ui.add_color(failure_message, :red)
37
35
  end
38
36
 
39
37
  def failure_message
40
- return install_error_message if spec.source.options["git"]
41
- "#{install_error_message}\n#{gem_install_message}"
38
+ install_error_message
42
39
  end
43
40
 
44
41
  def install_error_message
45
42
  "An error occurred while installing #{spec.name} (#{spec.version}), and Bundler cannot continue."
46
43
  end
47
44
 
48
- def gem_install_message
49
- source = spec.source
50
- return unless source.respond_to?(:remotes)
51
-
52
- if source.remotes.size == 1
53
- "Make sure that `gem install #{spec.name} -v '#{spec.version}' --source '#{source.remotes.first}'` succeeds before bundling."
54
- else
55
- "Make sure that `gem install #{spec.name} -v '#{spec.version}'` succeeds before bundling."
56
- end
57
- end
58
-
59
45
  def spec_settings
60
46
  # Fetch the build settings, if there are any
61
47
  if settings = Bundler.settings["build.#{spec.name}"]
48
+ require "shellwords"
62
49
  Shellwords.shellsplit(settings)
63
50
  end
64
51
  end
@@ -67,11 +54,6 @@ module Bundler
67
54
  spec.source.install(spec, :force => force, :ensure_builtin_gems_cached => standalone, :build_args => Array(spec_settings))
68
55
  end
69
56
 
70
- def install_with_settings
71
- # Build arguments are global, so this is mutexed
72
- Bundler.rubygems.install_with_build_args([spec_settings]) { install }
73
- end
74
-
75
57
  def out_of_space_message
76
58
  "#{install_error_message}\nYour disk is out of space. Free some space to be able to install your bundle."
77
59
  end
@@ -6,10 +6,11 @@ require_relative "gem_installer"
6
6
  module Bundler
7
7
  class ParallelInstaller
8
8
  class SpecInstallation
9
- attr_accessor :spec, :name, :post_install_message, :state, :error
9
+ attr_accessor :spec, :name, :full_name, :post_install_message, :state, :error
10
10
  def initialize(spec)
11
11
  @spec = spec
12
12
  @name = spec.name
13
+ @full_name = spec.full_name
13
14
  @state = :none
14
15
  @post_install_message = ""
15
16
  @error = nil
@@ -27,13 +28,8 @@ module Bundler
27
28
  state == :failed
28
29
  end
29
30
 
30
- def installation_attempted?
31
- installed? || failed?
32
- end
33
-
34
- # Only true when spec in neither installed nor already enqueued
35
31
  def ready_to_enqueue?
36
- !enqueued? && !installation_attempted?
32
+ state == :none
37
33
  end
38
34
 
39
35
  def has_post_install_message?
@@ -54,14 +50,11 @@ module Bundler
54
50
  # Represents only the non-development dependencies, the ones that are
55
51
  # itself and are in the total list.
56
52
  def dependencies
57
- @dependencies ||= begin
58
- all_dependencies.reject {|dep| ignorable_dependency? dep }
59
- end
53
+ @dependencies ||= all_dependencies.reject {|dep| ignorable_dependency? dep }
60
54
  end
61
55
 
62
56
  def missing_lockfile_dependencies(all_spec_names)
63
- deps = all_dependencies.reject {|dep| ignorable_dependency? dep }
64
- deps.reject {|dep| all_spec_names.include? dep.name }
57
+ dependencies.reject {|dep| all_spec_names.include? dep.name }
65
58
  end
66
59
 
67
60
  # Represents all dependencies
@@ -70,7 +63,7 @@ module Bundler
70
63
  end
71
64
 
72
65
  def to_s
73
- "#<#{self.class} #{@spec.full_name} (#{state})>"
66
+ "#<#{self.class} #{full_name} (#{state})>"
74
67
  end
75
68
  end
76
69
 
@@ -93,18 +86,48 @@ module Bundler
93
86
  def call
94
87
  check_for_corrupt_lockfile
95
88
 
89
+ if @rake
90
+ do_install(@rake, 0)
91
+ Gem::Specification.reset
92
+ end
93
+
96
94
  if @size > 1
97
95
  install_with_worker
98
96
  else
99
97
  install_serially
100
98
  end
101
99
 
100
+ check_for_unmet_dependencies
101
+
102
102
  handle_error if failed_specs.any?
103
103
  @specs
104
104
  ensure
105
105
  worker_pool && worker_pool.stop
106
106
  end
107
107
 
108
+ def check_for_unmet_dependencies
109
+ unmet_dependencies = @specs.map do |s|
110
+ [
111
+ s,
112
+ s.dependencies.reject {|dep| @specs.any? {|spec| dep.matches_spec?(spec.spec) } },
113
+ ]
114
+ end.reject {|a| a.last.empty? }
115
+ return if unmet_dependencies.empty?
116
+
117
+ warning = []
118
+ warning << "Your lockfile doesn't include a valid resolution."
119
+ warning << "You can fix this by regenerating your lockfile or trying to manually editing the bad locked gems to a version that satisfies all dependencies."
120
+ warning << "The unmet dependencies are:"
121
+
122
+ unmet_dependencies.each do |spec, unmet_spec_dependencies|
123
+ unmet_spec_dependencies.each do |unmet_spec_dependency|
124
+ warning << "* #{unmet_spec_dependency}, depended upon #{spec.full_name}, unsatisfied by #{@specs.find {|s| s.name == unmet_spec_dependency.name && !unmet_spec_dependency.matches_spec?(s.spec) }.full_name}"
125
+ end
126
+ end
127
+
128
+ Bundler.ui.warn(warning.join("\n"))
129
+ end
130
+
108
131
  def check_for_corrupt_lockfile
109
132
  missing_dependencies = @specs.map do |s|
110
133
  [
@@ -217,8 +240,6 @@ module Bundler
217
240
  # are installed.
218
241
  def enqueue_specs
219
242
  @specs.select(&:ready_to_enqueue?).each do |spec|
220
- next if @rake && !@rake.installed? && spec.name != @rake.name
221
-
222
243
  if spec.dependencies_installed? @specs
223
244
  spec.state = :enqueued
224
245
  worker_pool.enq spec
@@ -3,7 +3,7 @@
3
3
  module Bundler
4
4
  class Standalone
5
5
  def initialize(groups, definition)
6
- @specs = groups.empty? ? definition.requested_specs : definition.specs_for(groups.map(&:to_sym))
6
+ @specs = definition.specs_for(groups)
7
7
  end
8
8
 
9
9
  def generate
@@ -12,12 +12,13 @@ module Bundler
12
12
  end
13
13
  File.open File.join(bundler_path, "setup.rb"), "w" do |file|
14
14
  file.puts "require 'rbconfig'"
15
- file.puts "ruby_engine = RUBY_ENGINE"
16
- file.puts "ruby_version = RbConfig::CONFIG[\"ruby_version\"]"
17
- file.puts "path = File.expand_path('..', __FILE__)"
18
15
  file.puts reverse_rubygems_kernel_mixin
19
16
  paths.each do |path|
20
- file.puts %($:.unshift File.expand_path("\#{path}/#{path}"))
17
+ if Pathname.new(path).absolute?
18
+ file.puts %($:.unshift "#{path}")
19
+ else
20
+ file.puts %($:.unshift File.expand_path("\#{__dir__}/#{path}"))
21
+ end
21
22
  end
22
23
  end
23
24
  end
@@ -28,14 +29,14 @@ module Bundler
28
29
  @specs.map do |spec|
29
30
  next if spec.name == "bundler"
30
31
  Array(spec.require_paths).map do |path|
31
- gem_path(path, spec).sub(version_dir, '#{ruby_engine}/#{ruby_version}')
32
+ gem_path(path, spec).sub(version_dir, '#{RUBY_ENGINE}/#{RbConfig::CONFIG["ruby_version"]}')
32
33
  # This is a static string intentionally. It's interpolated at a later time.
33
34
  end
34
- end.flatten
35
+ end.flatten.compact
35
36
  end
36
37
 
37
38
  def version_dir
38
- "#{Bundler::RubyVersion.system.engine}/#{RbConfig::CONFIG["ruby_version"]}"
39
+ "#{RUBY_ENGINE}/#{RbConfig::CONFIG["ruby_version"]}"
39
40
  end
40
41
 
41
42
  def bundler_path
@@ -44,7 +45,11 @@ module Bundler
44
45
 
45
46
  def gem_path(path, spec)
46
47
  full_path = Pathname.new(path).absolute? ? path : File.join(spec.full_gem_path, path)
47
- Pathname.new(full_path).relative_path_from(Bundler.root.join(bundler_path)).to_s
48
+ if spec.source.instance_of?(Source::Path)
49
+ full_path
50
+ else
51
+ Pathname.new(full_path).relative_path_from(Bundler.root.join(bundler_path)).to_s
52
+ end
48
53
  rescue TypeError
49
54
  error_message = "#{spec.name} #{spec.version} has an invalid gemspec"
50
55
  raise Gem::InvalidSpecificationException.new(error_message)
@@ -1,6 +1,5 @@
1
1
  # frozen_string_literal: true
2
2
 
3
- require "rubygems/dependency_installer"
4
3
  require_relative "worker"
5
4
  require_relative "installer/parallel_installer"
6
5
  require_relative "installer/standalone"
@@ -89,6 +88,8 @@ module Bundler
89
88
  end
90
89
  install(options)
91
90
 
91
+ Gem::Specification.reset # invalidate gem specification cache so that installed gems are immediately available
92
+
92
93
  lock unless Bundler.frozen_bundle?
93
94
  Standalone.new(options[:standalone], @definition).generate if options[:standalone]
94
95
  end
@@ -133,7 +134,7 @@ module Bundler
133
134
  next
134
135
  end
135
136
 
136
- mode = Bundler::WINDOWS ? "wb:UTF-8" : "w"
137
+ mode = Gem.win_platform? ? "wb:UTF-8" : "w"
137
138
  require "erb"
138
139
  content = if RUBY_VERSION >= "2.6"
139
140
  ERB.new(template, :trim_mode => "-").result(binding)
@@ -142,7 +143,7 @@ module Bundler
142
143
  end
143
144
 
144
145
  File.write(binstub_path, content, :mode => mode, :perm => 0o777 & ~File.umask)
145
- if Bundler::WINDOWS || options[:all_platforms]
146
+ if Gem.win_platform? || options[:all_platforms]
146
147
  prefix = "@ruby -x \"%~f0\" %*\n@exit /b %ERRORLEVEL%\n\n"
147
148
  File.write("#{binstub_path}.cmd", prefix + content, :mode => mode)
148
149
  end
@@ -180,7 +181,7 @@ module Bundler
180
181
  executable_path = Pathname(spec.full_gem_path).join(spec.bindir, executable).relative_path_from(bin_path)
181
182
  executable_path = executable_path
182
183
 
183
- mode = Bundler::WINDOWS ? "wb:UTF-8" : "w"
184
+ mode = Gem.win_platform? ? "wb:UTF-8" : "w"
184
185
  require "erb"
185
186
  content = if RUBY_VERSION >= "2.6"
186
187
  ERB.new(template, :trim_mode => "-").result(binding)
@@ -189,7 +190,7 @@ module Bundler
189
190
  end
190
191
 
191
192
  File.write("#{bin_path}/#{executable}", content, :mode => mode, :perm => 0o755)
192
- if Bundler::WINDOWS || options[:all_platforms]
193
+ if Gem.win_platform? || options[:all_platforms]
193
194
  prefix = "@ruby -x \"%~f0\" %*\n@exit /b %ERRORLEVEL%\n\n"
194
195
  File.write("#{bin_path}/#{executable}.cmd", prefix + content, :mode => mode)
195
196
  end
@@ -217,17 +218,7 @@ module Bundler
217
218
  return jobs
218
219
  end
219
220
 
220
- # Parallelization has some issues on Windows, so it's not yet the default
221
- return 1 if Gem.win_platform?
222
-
223
- processor_count
224
- end
225
-
226
- def processor_count
227
- require "etc"
228
- Etc.nprocessors
229
- rescue StandardError
230
- 1
221
+ Bundler.settings.processor_count
231
222
  end
232
223
 
233
224
  def load_plugins
@@ -248,7 +239,7 @@ module Bundler
248
239
 
249
240
  def ensure_specs_are_compatible!
250
241
  system_ruby = Bundler::RubyVersion.system
251
- rubygems_version = Gem::Version.create(Gem::VERSION)
242
+ rubygems_version = Bundler.rubygems.version
252
243
  @definition.specs.each do |spec|
253
244
  if required_ruby_version = spec.required_ruby_version
254
245
  unless required_ruby_version.satisfied_by?(system_ruby.gem_version)
@@ -38,8 +38,24 @@ module Bundler
38
38
  identifier.hash
39
39
  end
40
40
 
41
+ ##
42
+ # Does this locked specification satisfy +dependency+?
43
+ #
44
+ # NOTE: Rubygems default requirement is ">= 0", which doesn't match
45
+ # prereleases of 0 versions, like "0.0.0.dev" or "0.0.0.SNAPSHOT". However,
46
+ # bundler users expect those to work. We need to make sure that Gemfile
47
+ # dependencies without explicit requirements (which use ">= 0" under the
48
+ # hood by default) are still valid for locked specs using this kind of
49
+ # versions. The method implements an ad-hoc fix for that. A better solution
50
+ # might be to change default rubygems requirement of dependencies to be ">=
51
+ # 0.A" but that's a major refactoring likely to break things. Hopefully we
52
+ # can attempt it in the future.
53
+ #
54
+
41
55
  def satisfies?(dependency)
42
- @name == dependency.name && dependency.requirement.satisfied_by?(Gem::Version.new(@version))
56
+ effective_requirement = dependency.requirement == Gem::Requirement.default ? Gem::Requirement.new(">= 0.A") : dependency.requirement
57
+
58
+ @name == dependency.name && effective_requirement.satisfied_by?(Gem::Version.new(@version))
43
59
  end
44
60
 
45
61
  def to_lock
@@ -73,7 +89,12 @@ module Bundler
73
89
  same_platform_candidates = candidates.select do |spec|
74
90
  MatchPlatform.platforms_match?(spec.platform, platform_object)
75
91
  end
76
- search = same_platform_candidates.last || candidates.last
92
+ installable_candidates = same_platform_candidates.select do |spec|
93
+ spec.is_a?(StubSpecification) ||
94
+ (spec.required_ruby_version.satisfied_by?(Gem.ruby_version) &&
95
+ spec.required_rubygems_version.satisfied_by?(Gem.rubygems_version))
96
+ end
97
+ search = installable_candidates.last
77
98
  search.dependencies = dependencies if search && (search.is_a?(RemoteSpecification) || search.is_a?(EndpointSpecification))
78
99
  search
79
100
  end
@@ -71,7 +71,7 @@ module Bundler
71
71
  end
72
72
 
73
73
  def add_bundled_with
74
- add_section("BUNDLED WITH", definition.locked_bundler_version.to_s)
74
+ add_section("BUNDLED WITH", Bundler::VERSION)
75
75
  end
76
76
 
77
77
  def add_section(name, value)