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
@@ -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,18 +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
- next if name == "bundler"
141
139
  spec = if dependencies
142
- EndpointSpecification.new(name, version, platform, dependencies, metadata)
140
+ EndpointSpecification.new(name, version, platform, self, dependencies, metadata)
143
141
  else
144
142
  RemoteSpecification.new(name, version, platform, self)
145
143
  end
@@ -152,8 +150,6 @@ module Bundler
152
150
  rescue CertificateFailureError
153
151
  Bundler.ui.info "" if gem_names && use_api # newline after dots
154
152
  raise
155
- ensure
156
- Bundler.rubygems.sources = old
157
153
  end
158
154
 
159
155
  def use_api
@@ -274,8 +270,7 @@ module Bundler
274
270
  # cached gem specification path, if one exists
275
271
  def gemspec_cached_path(spec_file_name)
276
272
  paths = Bundler.rubygems.spec_cache_dirs.map {|dir| File.join(dir, spec_file_name) }
277
- paths = paths.select {|path| File.file? path }
278
- paths.first
273
+ paths.find {|path| File.file? path }
279
274
  end
280
275
 
281
276
  HTTP_ERRORS = [
@@ -303,8 +298,6 @@ module Bundler
303
298
  store
304
299
  end
305
300
 
306
- private
307
-
308
301
  def remote_uri
309
302
  @remote.uri
310
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,19 +129,21 @@ module Bundler
116
129
 
117
130
  def git_push(remote = nil)
118
131
  remote ||= default_remote
119
- perform_git_push remote
120
- perform_git_push "#{remote} #{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
 
124
137
  def default_remote
125
- current_branch = sh(%w[git rev-parse --abbrev-ref HEAD]).strip
126
- return "origin" if current_branch.empty?
138
+ remote_for_branch, status = sh_with_status(%W[git config --get branch.#{current_branch}.remote])
139
+ return "origin" unless status.success?
127
140
 
128
- remote_for_branch = sh(%W[git config --get branch.#{current_branch}.remote]).strip
129
- return "origin" if remote_for_branch.empty?
141
+ remote_for_branch.strip
142
+ end
130
143
 
131
- remote_for_branch
144
+ def current_branch
145
+ # We can replace this with `git branch --show-current` once we drop support for git < 2.22.0
146
+ sh(%w[git rev-parse --abbrev-ref HEAD]).gsub(%r{\Aheads/}, "").strip
132
147
  end
133
148
 
134
149
  def allowed_push_host
@@ -143,13 +158,6 @@ module Bundler
143
158
  allowed_push_host || env_rubygems_host || "rubygems.org"
144
159
  end
145
160
 
146
- def perform_git_push(options = "")
147
- cmd = "git push #{options}"
148
- out, status = sh_with_status(cmd.shellsplit)
149
- return if status.success?
150
- raise "Couldn't git push. `#{cmd}' failed with the following output:\n\n#{out}\n"
151
- end
152
-
153
161
  def already_tagged?
154
162
  return false unless sh(%w[git tag]).split(/\n/).include?(version_tag)
155
163
  Bundler.ui.confirm "Tag #{version_tag} has already been created."
@@ -200,8 +208,7 @@ module Bundler
200
208
  def sh(cmd, &block)
201
209
  out, status = sh_with_status(cmd, &block)
202
210
  unless status.success?
203
- cmd = cmd.shelljoin if cmd.respond_to?(:shelljoin)
204
- 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")
205
212
  end
206
213
  out
207
214
  end
@@ -81,8 +81,8 @@ module Bundler
81
81
  sort_dep_specs(spec_groups, locked_spec)
82
82
  end.tap do |specs|
83
83
  if DEBUG
84
- warn before_result
85
- warn " after sort_versions: #{debug_format_result(dep, specs).inspect}"
84
+ puts before_result
85
+ puts " after sort_versions: #{debug_format_result(dep, specs).inspect}"
86
86
  end
87
87
  end
88
88
  end
data/lib/bundler/index.rb CHANGED
@@ -1,7 +1,5 @@
1
1
  # frozen_string_literal: true
2
2
 
3
- require "set"
4
-
5
3
  module Bundler
6
4
  class Index
7
5
  include Enumerable
@@ -65,11 +63,14 @@ module Bundler
65
63
  def unsorted_search(query, base)
66
64
  results = local_search(query, base)
67
65
 
68
- seen = results.map(&:full_name).to_set unless @sources.empty?
66
+ seen = results.map(&:full_name).uniq unless @sources.empty?
69
67
 
70
68
  @sources.each do |source|
71
69
  source.unsorted_search(query, base).each do |spec|
72
- results << spec if seen.add?(spec.full_name)
70
+ next if seen.include?(spec.full_name)
71
+
72
+ seen << spec.full_name
73
+ results << spec
73
74
  end
74
75
  end
75
76
 
@@ -121,10 +122,9 @@ module Bundler
121
122
  names
122
123
  end
123
124
 
124
- # returns a list of the dependencies
125
125
  def unmet_dependency_names
126
126
  dependency_names.select do |name|
127
- name != "bundler" && search(name).empty?
127
+ search(name).empty?
128
128
  end
129
129
  end
130
130
 
@@ -170,7 +170,7 @@ module Bundler
170
170
  def dependencies_eql?(spec, other_spec)
171
171
  deps = spec.dependencies.select {|d| d.type != :development }
172
172
  other_deps = other_spec.dependencies.select {|d| d.type != :development }
173
- Set.new(deps) == Set.new(other_deps)
173
+ deps.sort == other_deps.sort
174
174
  end
175
175
 
176
176
  def add_source(index)
@@ -195,11 +195,7 @@ module Bundler
195
195
  if base # allow all platforms when searching from a lockfile
196
196
  dependency.matches_spec?(spec)
197
197
  else
198
- if Gem::Platform.respond_to? :match_spec?
199
- dependency.matches_spec?(spec) && Gem::Platform.match_spec?(spec)
200
- else
201
- dependency.matches_spec?(spec) && Gem::Platform.match(spec.platform)
202
- end
198
+ dependency.matches_spec?(spec) && Gem::Platform.match_spec?(spec)
203
199
  end
204
200
  end
205
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,11 +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__)"
15
+ file.puts reverse_rubygems_kernel_mixin
18
16
  paths.each do |path|
19
- 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
20
22
  end
21
23
  end
22
24
  end
@@ -27,14 +29,14 @@ module Bundler
27
29
  @specs.map do |spec|
28
30
  next if spec.name == "bundler"
29
31
  Array(spec.require_paths).map do |path|
30
- 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"]}')
31
33
  # This is a static string intentionally. It's interpolated at a later time.
32
34
  end
33
- end.flatten
35
+ end.flatten.compact
34
36
  end
35
37
 
36
38
  def version_dir
37
- "#{Bundler::RubyVersion.system.engine}/#{RbConfig::CONFIG["ruby_version"]}"
39
+ "#{RUBY_ENGINE}/#{RbConfig::CONFIG["ruby_version"]}"
38
40
  end
39
41
 
40
42
  def bundler_path
@@ -43,10 +45,28 @@ module Bundler
43
45
 
44
46
  def gem_path(path, spec)
45
47
  full_path = Pathname.new(path).absolute? ? path : File.join(spec.full_gem_path, path)
46
- 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
47
53
  rescue TypeError
48
54
  error_message = "#{spec.name} #{spec.version} has an invalid gemspec"
49
55
  raise Gem::InvalidSpecificationException.new(error_message)
50
56
  end
57
+
58
+ def reverse_rubygems_kernel_mixin
59
+ <<~END
60
+ kernel = (class << ::Kernel; self; end)
61
+ [kernel, ::Kernel].each do |k|
62
+ if k.private_method_defined?(:gem_original_require)
63
+ private_require = k.private_method_defined?(:require)
64
+ k.send(:remove_method, :require)
65
+ k.send(:define_method, :require, k.instance_method(:gem_original_require))
66
+ k.send(:private, :require) if private_require
67
+ end
68
+ end
69
+ END
70
+ end
51
71
  end
52
72
  end