bundler 2.3.27 → 2.4.0

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 (186) hide show
  1. checksums.yaml +4 -4
  2. data/CHANGELOG.md +44 -3
  3. data/README.md +2 -2
  4. data/bundler.gemspec +2 -2
  5. data/exe/bundle +1 -4
  6. data/lib/bundler/build_metadata.rb +2 -2
  7. data/lib/bundler/cli/add.rb +1 -1
  8. data/lib/bundler/cli/check.rb +1 -1
  9. data/lib/bundler/cli/common.rb +1 -0
  10. data/lib/bundler/cli/console.rb +2 -2
  11. data/lib/bundler/cli/doctor.rb +4 -6
  12. data/lib/bundler/cli/gem.rb +62 -40
  13. data/lib/bundler/cli/install.rb +2 -3
  14. data/lib/bundler/cli/lock.rb +8 -5
  15. data/lib/bundler/cli/outdated.rb +1 -3
  16. data/lib/bundler/cli/viz.rb +1 -1
  17. data/lib/bundler/cli.rb +43 -2
  18. data/lib/bundler/compact_index_client/cache.rb +1 -1
  19. data/lib/bundler/compact_index_client/updater.rb +40 -39
  20. data/lib/bundler/constants.rb +1 -1
  21. data/lib/bundler/definition.rb +61 -31
  22. data/lib/bundler/dependency.rb +12 -11
  23. data/lib/bundler/digest.rb +1 -1
  24. data/lib/bundler/dsl.rb +1 -1
  25. data/lib/bundler/env.rb +1 -1
  26. data/lib/bundler/environment_preserver.rb +1 -0
  27. data/lib/bundler/errors.rb +1 -11
  28. data/lib/bundler/fetcher/compact_index.rb +9 -11
  29. data/lib/bundler/fetcher/dependency.rb +1 -1
  30. data/lib/bundler/fetcher/downloader.rb +2 -5
  31. data/lib/bundler/fetcher.rb +2 -6
  32. data/lib/bundler/force_platform.rb +18 -0
  33. data/lib/bundler/friendly_errors.rb +0 -3
  34. data/lib/bundler/gem_version_promoter.rb +52 -86
  35. data/lib/bundler/graph.rb +3 -3
  36. data/lib/bundler/index.rb +5 -18
  37. data/lib/bundler/injector.rb +1 -1
  38. data/lib/bundler/inline.rb +2 -2
  39. data/lib/bundler/installer/parallel_installer.rb +0 -31
  40. data/lib/bundler/installer.rb +6 -16
  41. data/lib/bundler/lazy_specification.rb +37 -33
  42. data/lib/bundler/lockfile_parser.rb +5 -5
  43. data/lib/bundler/man/bundle-add.1 +1 -1
  44. data/lib/bundler/man/bundle-binstubs.1 +1 -1
  45. data/lib/bundler/man/bundle-cache.1 +1 -1
  46. data/lib/bundler/man/bundle-check.1 +1 -1
  47. data/lib/bundler/man/bundle-clean.1 +1 -1
  48. data/lib/bundler/man/bundle-config.1 +1 -1
  49. data/lib/bundler/man/bundle-console.1 +1 -1
  50. data/lib/bundler/man/bundle-doctor.1 +1 -1
  51. data/lib/bundler/man/bundle-exec.1 +1 -1
  52. data/lib/bundler/man/bundle-gem.1 +27 -37
  53. data/lib/bundler/man/bundle-gem.1.ronn +5 -5
  54. data/lib/bundler/man/bundle-help.1 +1 -1
  55. data/lib/bundler/man/bundle-info.1 +1 -1
  56. data/lib/bundler/man/bundle-init.1 +1 -1
  57. data/lib/bundler/man/bundle-inject.1 +1 -1
  58. data/lib/bundler/man/bundle-install.1 +1 -30
  59. data/lib/bundler/man/bundle-install.1.ronn +0 -29
  60. data/lib/bundler/man/bundle-list.1 +1 -1
  61. data/lib/bundler/man/bundle-lock.1 +1 -1
  62. data/lib/bundler/man/bundle-open.1 +1 -1
  63. data/lib/bundler/man/bundle-outdated.1 +1 -1
  64. data/lib/bundler/man/bundle-platform.1 +2 -2
  65. data/lib/bundler/man/bundle-platform.1.ronn +1 -1
  66. data/lib/bundler/man/bundle-plugin.1 +1 -1
  67. data/lib/bundler/man/bundle-pristine.1 +1 -1
  68. data/lib/bundler/man/bundle-remove.1 +1 -1
  69. data/lib/bundler/man/bundle-show.1 +1 -1
  70. data/lib/bundler/man/bundle-update.1 +1 -1
  71. data/lib/bundler/man/bundle-version.1 +1 -1
  72. data/lib/bundler/man/bundle-viz.1 +1 -1
  73. data/lib/bundler/man/bundle.1 +1 -1
  74. data/lib/bundler/man/gemfile.5 +1 -1
  75. data/lib/bundler/mirror.rb +5 -7
  76. data/lib/bundler/plugin/index.rb +4 -4
  77. data/lib/bundler/plugin/installer/rubygems.rb +0 -4
  78. data/lib/bundler/resolver/base.rb +7 -11
  79. data/lib/bundler/resolver/candidate.rb +92 -0
  80. data/lib/bundler/resolver/incompatibility.rb +15 -0
  81. data/lib/bundler/resolver/package.rb +63 -0
  82. data/lib/bundler/resolver/root.rb +25 -0
  83. data/lib/bundler/resolver/spec_group.rb +26 -36
  84. data/lib/bundler/resolver.rb +285 -277
  85. data/lib/bundler/rubygems_ext.rb +11 -6
  86. data/lib/bundler/rubygems_gem_installer.rb +4 -2
  87. data/lib/bundler/rubygems_integration.rb +1 -9
  88. data/lib/bundler/runtime.rb +1 -5
  89. data/lib/bundler/settings.rb +0 -6
  90. data/lib/bundler/shared_helpers.rb +1 -0
  91. data/lib/bundler/source/git/git_proxy.rb +190 -67
  92. data/lib/bundler/source/git.rb +15 -17
  93. data/lib/bundler/source/metadata.rb +0 -1
  94. data/lib/bundler/source/path/installer.rb +1 -22
  95. data/lib/bundler/source/path.rb +5 -5
  96. data/lib/bundler/source/rubygems.rb +13 -67
  97. data/lib/bundler/source_list.rb +8 -2
  98. data/lib/bundler/spec_set.rb +7 -9
  99. data/lib/bundler/templates/Executable +1 -1
  100. data/lib/bundler/templates/Executable.bundler +4 -9
  101. data/lib/bundler/templates/Executable.standalone +2 -0
  102. data/lib/bundler/templates/newgem/Cargo.toml.tt +7 -0
  103. data/lib/bundler/templates/newgem/Gemfile.tt +3 -0
  104. data/lib/bundler/templates/newgem/README.md.tt +6 -4
  105. data/lib/bundler/templates/newgem/Rakefile.tt +2 -1
  106. data/lib/bundler/templates/newgem/circleci/config.yml.tt +12 -0
  107. data/lib/bundler/templates/newgem/ext/newgem/Cargo.toml.tt +15 -0
  108. data/lib/bundler/templates/newgem/ext/newgem/extconf-rust.rb.tt +6 -0
  109. data/lib/bundler/templates/newgem/ext/newgem/src/lib.rs.tt +12 -0
  110. data/lib/bundler/templates/newgem/github/workflows/main.yml.tt +10 -0
  111. data/lib/bundler/templates/newgem/gitignore.tt +3 -0
  112. data/lib/bundler/templates/newgem/gitlab-ci.yml.tt +8 -0
  113. data/lib/bundler/templates/newgem/newgem.gemspec.tt +8 -2
  114. data/lib/bundler/ui/shell.rb +35 -12
  115. data/lib/bundler/ui/silent.rb +21 -5
  116. data/lib/bundler/vendor/connection_pool/lib/connection_pool/timed_stack.rb +3 -3
  117. data/lib/bundler/vendor/connection_pool/lib/connection_pool/wrapper.rb +0 -1
  118. data/lib/bundler/vendor/connection_pool/lib/connection_pool.rb +3 -1
  119. data/lib/bundler/vendor/fileutils/lib/fileutils.rb +1350 -408
  120. data/lib/bundler/vendor/net-http-persistent/README.rdoc +1 -1
  121. data/lib/bundler/vendor/net-http-persistent/lib/net/http/persistent.rb +1 -1
  122. data/lib/bundler/vendor/pub_grub/LICENSE.txt +21 -0
  123. data/lib/bundler/vendor/pub_grub/lib/pub_grub/assignment.rb +20 -0
  124. data/lib/bundler/vendor/pub_grub/lib/pub_grub/basic_package_source.rb +189 -0
  125. data/lib/bundler/vendor/pub_grub/lib/pub_grub/failure_writer.rb +182 -0
  126. data/lib/bundler/vendor/pub_grub/lib/pub_grub/incompatibility.rb +151 -0
  127. data/lib/bundler/vendor/pub_grub/lib/pub_grub/package.rb +43 -0
  128. data/lib/bundler/vendor/pub_grub/lib/pub_grub/partial_solution.rb +121 -0
  129. data/lib/bundler/vendor/pub_grub/lib/pub_grub/rubygems.rb +45 -0
  130. data/lib/bundler/vendor/pub_grub/lib/pub_grub/solve_failure.rb +19 -0
  131. data/lib/bundler/vendor/pub_grub/lib/pub_grub/static_package_source.rb +53 -0
  132. data/lib/bundler/vendor/pub_grub/lib/pub_grub/term.rb +105 -0
  133. data/lib/bundler/vendor/pub_grub/lib/pub_grub/version.rb +3 -0
  134. data/lib/bundler/vendor/pub_grub/lib/pub_grub/version_constraint.rb +124 -0
  135. data/lib/bundler/vendor/pub_grub/lib/pub_grub/version_range.rb +409 -0
  136. data/lib/bundler/vendor/pub_grub/lib/pub_grub/version_solver.rb +240 -0
  137. data/lib/bundler/vendor/pub_grub/lib/pub_grub/version_union.rb +178 -0
  138. data/lib/bundler/vendor/pub_grub/lib/pub_grub.rb +31 -0
  139. data/lib/bundler/vendor/thor/lib/thor/shell/basic.rb +1 -1
  140. data/lib/bundler/vendor/uri/lib/uri/common.rb +64 -16
  141. data/lib/bundler/vendor/uri/lib/uri/file.rb +7 -1
  142. data/lib/bundler/vendor/uri/lib/uri/ftp.rb +2 -1
  143. data/lib/bundler/vendor/uri/lib/uri/generic.rb +27 -7
  144. data/lib/bundler/vendor/uri/lib/uri/http.rb +40 -2
  145. data/lib/bundler/vendor/uri/lib/uri/https.rb +2 -1
  146. data/lib/bundler/vendor/uri/lib/uri/ldap.rb +1 -1
  147. data/lib/bundler/vendor/uri/lib/uri/ldaps.rb +2 -1
  148. data/lib/bundler/vendor/uri/lib/uri/mailto.rb +2 -2
  149. data/lib/bundler/vendor/uri/lib/uri/rfc2396_parser.rb +13 -7
  150. data/lib/bundler/vendor/uri/lib/uri/rfc3986_parser.rb +10 -5
  151. data/lib/bundler/vendor/uri/lib/uri/version.rb +1 -1
  152. data/lib/bundler/vendor/uri/lib/uri/ws.rb +1 -2
  153. data/lib/bundler/vendor/uri/lib/uri/wss.rb +2 -1
  154. data/lib/bundler/vendor/uri/lib/uri.rb +3 -2
  155. data/lib/bundler/vendored_persistent.rb +1 -33
  156. data/lib/bundler/{vendored_tmpdir.rb → vendored_pub_grub.rb} +1 -1
  157. data/lib/bundler/version.rb +5 -1
  158. data/lib/bundler/worker.rb +5 -7
  159. data/lib/bundler.rb +20 -64
  160. metadata +33 -32
  161. data/lib/bundler/templates/newgem/travis.yml.tt +0 -6
  162. data/lib/bundler/vendor/molinillo/LICENSE +0 -9
  163. data/lib/bundler/vendor/molinillo/lib/molinillo/delegates/resolution_state.rb +0 -57
  164. data/lib/bundler/vendor/molinillo/lib/molinillo/delegates/specification_provider.rb +0 -88
  165. data/lib/bundler/vendor/molinillo/lib/molinillo/dependency_graph/action.rb +0 -36
  166. data/lib/bundler/vendor/molinillo/lib/molinillo/dependency_graph/add_edge_no_circular.rb +0 -66
  167. data/lib/bundler/vendor/molinillo/lib/molinillo/dependency_graph/add_vertex.rb +0 -62
  168. data/lib/bundler/vendor/molinillo/lib/molinillo/dependency_graph/delete_edge.rb +0 -63
  169. data/lib/bundler/vendor/molinillo/lib/molinillo/dependency_graph/detach_vertex_named.rb +0 -61
  170. data/lib/bundler/vendor/molinillo/lib/molinillo/dependency_graph/log.rb +0 -126
  171. data/lib/bundler/vendor/molinillo/lib/molinillo/dependency_graph/set_payload.rb +0 -46
  172. data/lib/bundler/vendor/molinillo/lib/molinillo/dependency_graph/tag.rb +0 -36
  173. data/lib/bundler/vendor/molinillo/lib/molinillo/dependency_graph/vertex.rb +0 -164
  174. data/lib/bundler/vendor/molinillo/lib/molinillo/dependency_graph.rb +0 -255
  175. data/lib/bundler/vendor/molinillo/lib/molinillo/errors.rb +0 -149
  176. data/lib/bundler/vendor/molinillo/lib/molinillo/gem_metadata.rb +0 -6
  177. data/lib/bundler/vendor/molinillo/lib/molinillo/modules/specification_provider.rb +0 -112
  178. data/lib/bundler/vendor/molinillo/lib/molinillo/modules/ui.rb +0 -67
  179. data/lib/bundler/vendor/molinillo/lib/molinillo/resolution.rb +0 -839
  180. data/lib/bundler/vendor/molinillo/lib/molinillo/resolver.rb +0 -46
  181. data/lib/bundler/vendor/molinillo/lib/molinillo/state.rb +0 -58
  182. data/lib/bundler/vendor/molinillo/lib/molinillo.rb +0 -11
  183. data/lib/bundler/vendor/tmpdir/lib/tmpdir.rb +0 -154
  184. data/lib/bundler/vendored_molinillo.rb +0 -4
  185. data/lib/bundler/version_ranges.rb +0 -122
  186. /data/lib/bundler/templates/newgem/ext/newgem/{extconf.rb.tt → extconf-c.rb.tt} +0 -0
@@ -16,6 +16,7 @@ require "rubygems/specification"
16
16
  require "rubygems/source"
17
17
 
18
18
  require_relative "match_metadata"
19
+ require_relative "force_platform"
19
20
  require_relative "match_platform"
20
21
 
21
22
  # Cherry-pick fixes to `Gem.ruby_version` to be useful for modern Bundler
@@ -153,12 +154,16 @@ module Gem
153
154
  end
154
155
 
155
156
  class Dependency
157
+ include ::Bundler::ForcePlatform
158
+
156
159
  attr_accessor :source, :groups
157
160
 
158
161
  alias_method :eql?, :==
159
162
 
160
163
  def force_ruby_platform
161
- false
164
+ return @force_ruby_platform if defined?(@force_ruby_platform) && !@force_ruby_platform.nil?
165
+
166
+ @force_ruby_platform = default_force_ruby_platform
162
167
  end
163
168
 
164
169
  def encode_with(coder)
@@ -277,6 +282,10 @@ module Gem
277
282
  without_gnu_nor_abi_modifiers
278
283
  end
279
284
  end
285
+
286
+ if RUBY_ENGINE == "truffleruby" && !defined?(REUSE_AS_BINARY_ON_TRUFFLERUBY)
287
+ REUSE_AS_BINARY_ON_TRUFFLERUBY = %w[libv8 libv8-node sorbet-static].freeze
288
+ end
280
289
  end
281
290
 
282
291
  Platform.singleton_class.module_eval do
@@ -338,11 +347,7 @@ module Gem
338
347
  end
339
348
 
340
349
  def glob_files_in_dir(glob, base_path)
341
- if RUBY_VERSION >= "2.5"
342
- Dir.glob(glob, :base => base_path).map! {|f| File.expand_path(f, base_path) }
343
- else
344
- Dir.glob(File.join(base_path.to_s.gsub(/[\[\]]/, '\\\\\\&'), glob)).map! {|f| File.expand_path(f) }
345
- end
350
+ Dir.glob(glob, :base => base_path).map! {|f| File.expand_path(f, base_path) }
346
351
  end
347
352
  end
348
353
  end
@@ -109,8 +109,10 @@ module Bundler
109
109
 
110
110
  def strict_rm_rf(dir)
111
111
  Bundler.rm_rf dir
112
- rescue Errno::ENOTEMPTY => e
113
- raise DirectoryRemovalError.new(e.cause, "Could not delete previous installation of `#{dir}`")
112
+ rescue StandardError => e
113
+ raise unless File.exist?(dir)
114
+
115
+ raise DirectoryRemovalError.new(e, "Could not delete previous installation of `#{dir}`")
114
116
  end
115
117
 
116
118
  def validate_bundler_checksum(checksum)
@@ -272,11 +272,7 @@ module Bundler
272
272
 
273
273
  e = Gem::LoadError.new(message)
274
274
  e.name = dep.name
275
- if e.respond_to?(:requirement=)
276
- e.requirement = dep.requirement
277
- elsif e.respond_to?(:version_requirement=)
278
- e.version_requirement = dep.requirement
279
- end
275
+ e.requirement = dep.requirement
280
276
  raise e
281
277
  end
282
278
 
@@ -508,10 +504,6 @@ module Bundler
508
504
  Gem::Package.build(spec, skip_validation)
509
505
  end
510
506
 
511
- def repository_subdirectories
512
- Gem::REPOSITORY_SUBDIRECTORIES
513
- end
514
-
515
507
  def path_separator
516
508
  Gem.path_separator
517
509
  end
@@ -300,11 +300,7 @@ module Bundler
300
300
  e = Gem::LoadError.new "You have already activated #{activated_spec.name} #{activated_spec.version}, " \
301
301
  "but your Gemfile requires #{spec.name} #{spec.version}. #{suggestion}"
302
302
  e.name = spec.name
303
- if e.respond_to?(:requirement=)
304
- e.requirement = Gem::Requirement.new(spec.version.to_s)
305
- else
306
- e.version_requirement = Gem::Requirement.new(spec.version.to_s)
307
- end
303
+ e.requirement = Gem::Requirement.new(spec.version.to_s)
308
304
  raise e
309
305
  end
310
306
  end
@@ -277,12 +277,6 @@ module Bundler
277
277
  end
278
278
  end
279
279
 
280
- def allow_sudo?
281
- key = key_for(:path)
282
- path_configured = @temporary.key?(key) || @local_config.key?(key)
283
- !path_configured
284
- end
285
-
286
280
  def ignore_config?
287
281
  ENV["BUNDLE_IGNORE_CONFIG"]
288
282
  end
@@ -284,6 +284,7 @@ module Bundler
284
284
  Bundler::SharedHelpers.set_env "BUNDLE_BIN_PATH", exe_file
285
285
  Bundler::SharedHelpers.set_env "BUNDLE_GEMFILE", find_gemfile.to_s
286
286
  Bundler::SharedHelpers.set_env "BUNDLER_VERSION", Bundler::VERSION
287
+ Bundler::SharedHelpers.set_env "BUNDLER_SETUP", File.expand_path("setup", __dir__)
287
288
  end
288
289
 
289
290
  def set_path
@@ -31,7 +31,6 @@ module Bundler
31
31
  msg = String.new
32
32
  msg << "Git error: command `#{command}` in directory #{path} has failed."
33
33
  msg << "\n#{extra_info}" if extra_info
34
- msg << "\nIf this error persists you could try removing the cache directory '#{path}'" if path.exist?
35
34
  super msg
36
35
  end
37
36
  end
@@ -47,23 +46,26 @@ module Bundler
47
46
  # All actions required by the Git source is encapsulated in this
48
47
  # object.
49
48
  class GitProxy
50
- attr_accessor :path, :uri, :ref
49
+ attr_accessor :path, :uri, :branch, :tag, :ref, :explicit_ref
51
50
  attr_writer :revision
52
51
 
53
- def initialize(path, uri, ref, revision = nil, git = nil)
52
+ def initialize(path, uri, options = {}, revision = nil, git = nil)
54
53
  @path = path
55
54
  @uri = uri
56
- @ref = ref
55
+ @branch = options["branch"]
56
+ @tag = options["tag"]
57
+ @ref = options["ref"]
58
+ @explicit_ref = branch || tag || ref
57
59
  @revision = revision
58
60
  @git = git
59
61
  end
60
62
 
61
63
  def revision
62
- @revision ||= find_local_revision
64
+ @revision ||= allowed_with_path { find_local_revision }
63
65
  end
64
66
 
65
- def branch
66
- @branch ||= allowed_with_path do
67
+ def current_branch
68
+ @current_branch ||= allowed_with_path do
67
69
  git("rev-parse", "--abbrev-ref", "HEAD", :dir => path).strip
68
70
  end
69
71
  end
@@ -76,36 +78,26 @@ module Bundler
76
78
  end
77
79
 
78
80
  def version
79
- git("--version").match(/(git version\s*)?((\.?\d+)+).*/)[2]
81
+ @version ||= full_version.match(/((\.?\d+)+).*/)[1]
80
82
  end
81
83
 
82
84
  def full_version
83
- git("--version").sub("git version", "").strip
85
+ @full_version ||= git("--version").sub(/git version\s*/, "").strip
84
86
  end
85
87
 
86
88
  def checkout
87
- return if path.exist? && has_revision_cached?
88
- extra_ref = "#{ref}:#{ref}" if ref && ref.start_with?("refs/")
89
+ return if has_revision_cached?
89
90
 
90
- Bundler.ui.info "Fetching #{URICredentialsFilter.credential_filtered_uri(uri)}"
91
+ Bundler.ui.info "Fetching #{credential_filtered_uri}"
91
92
 
92
- configured_uri = configured_uri_for(uri).to_s
93
+ extra_fetch_needed = clone_needs_extra_fetch?
94
+ unshallow_needed = clone_needs_unshallow?
95
+ return unless extra_fetch_needed || unshallow_needed
93
96
 
94
- unless path.exist?
95
- SharedHelpers.filesystem_access(path.dirname) do |p|
96
- FileUtils.mkdir_p(p)
97
- end
98
- git_retry "clone", "--bare", "--no-hardlinks", "--quiet", "--", configured_uri, path.to_s
99
- return unless extra_ref
100
- end
101
-
102
- with_path do
103
- git_retry(*["fetch", "--force", "--quiet", "--tags", "--", configured_uri, "refs/heads/*:refs/heads/*", extra_ref].compact, :dir => path)
104
- end
97
+ git_remote_fetch(unshallow_needed ? ["--unshallow"] : depth_args)
105
98
  end
106
99
 
107
100
  def copy_to(destination, submodules = false)
108
- # method 1
109
101
  unless File.exist?(destination.join(".git"))
110
102
  begin
111
103
  SharedHelpers.filesystem_access(destination.dirname) do |p|
@@ -114,7 +106,7 @@ module Bundler
114
106
  SharedHelpers.filesystem_access(destination) do |p|
115
107
  FileUtils.rm_rf(p)
116
108
  end
117
- git_retry "clone", "--no-checkout", "--quiet", path.to_s, destination.to_s
109
+ git "clone", "--no-checkout", "--quiet", path.to_s, destination.to_s
118
110
  File.chmod(((File.stat(destination).mode | 0o777) & ~File.umask), destination)
119
111
  rescue Errno::EEXIST => e
120
112
  file_path = e.message[%r{.*?((?:[a-zA-Z]:)?/.*)}, 1]
@@ -123,14 +115,10 @@ module Bundler
123
115
  "this file and try again."
124
116
  end
125
117
  end
126
- # method 2
127
- git_retry "fetch", "--force", "--quiet", "--tags", path.to_s, :dir => destination
128
118
 
129
- begin
130
- git "reset", "--hard", @revision, :dir => destination
131
- rescue GitCommandError => e
132
- raise MissingGitRevisionError.new(e.command, destination, @revision, URICredentialsFilter.credential_filtered_uri(uri))
133
- end
119
+ git "fetch", "--force", "--quiet", *extra_fetch_args, :dir => destination
120
+
121
+ git "reset", "--hard", @revision, :dir => destination
134
122
 
135
123
  if submodules
136
124
  git_retry "submodule", "update", "--init", "--recursive", :dir => destination
@@ -142,14 +130,102 @@ module Bundler
142
130
 
143
131
  private
144
132
 
145
- def git_null(*command, dir: nil)
146
- check_allowed(command)
133
+ def git_remote_fetch(args)
134
+ command = ["fetch", "--force", "--quiet", "--no-tags", *args, "--", configured_uri, refspec].compact
135
+ command_with_no_credentials = check_allowed(command)
136
+
137
+ Bundler::Retry.new("`#{command_with_no_credentials}` at #{path}", [MissingGitRevisionError]).attempts do
138
+ out, err, status = capture(command, path)
139
+ return out if status.success?
140
+
141
+ if err.include?("couldn't find remote ref")
142
+ raise MissingGitRevisionError.new(command_with_no_credentials, path, explicit_ref, credential_filtered_uri)
143
+ else
144
+ raise GitCommandError.new(command_with_no_credentials, path, err)
145
+ end
146
+ end
147
+ end
148
+
149
+ def clone_needs_extra_fetch?
150
+ return true if path.exist?
151
+
152
+ SharedHelpers.filesystem_access(path.dirname) do |p|
153
+ FileUtils.mkdir_p(p)
154
+ end
155
+ git_retry "clone", "--bare", "--no-hardlinks", "--quiet", *extra_clone_args, "--", configured_uri, path.to_s
156
+
157
+ extra_ref
158
+ end
147
159
 
148
- out, status = SharedHelpers.with_clean_git_env do
149
- capture_and_ignore_stderr(*capture3_args_for(command, dir))
160
+ def clone_needs_unshallow?
161
+ return false unless path.join("shallow").exist?
162
+ return true if full_clone?
163
+
164
+ @revision && @revision != head_revision
165
+ end
166
+
167
+ def extra_ref
168
+ return false if not_pinned?
169
+ return true unless full_clone?
170
+
171
+ ref.start_with?("refs/")
172
+ end
173
+
174
+ def depth
175
+ return @depth if defined?(@depth)
176
+
177
+ @depth = if !supports_fetching_unreachable_refs?
178
+ nil
179
+ elsif not_pinned? || pinned_to_full_sha?
180
+ 1
181
+ elsif ref.include?("~")
182
+ parsed_depth = ref.split("~").last
183
+ parsed_depth.to_i + 1
150
184
  end
185
+ end
186
+
187
+ def refspec
188
+ return ref if pinned_to_full_sha?
189
+
190
+ ref_to_fetch = @revision || fully_qualified_ref
191
+
192
+ ref_to_fetch ||= if ref.include?("~")
193
+ ref.split("~").first
194
+ elsif ref.start_with?("refs/")
195
+ ref
196
+ else
197
+ "refs/*"
198
+ end
199
+
200
+ "#{ref_to_fetch}:#{ref_to_fetch}"
201
+ end
202
+
203
+ def fully_qualified_ref
204
+ if branch
205
+ "refs/heads/#{branch}"
206
+ elsif tag
207
+ "refs/tags/#{tag}"
208
+ elsif ref.nil?
209
+ "refs/heads/#{current_branch}"
210
+ end
211
+ end
212
+
213
+ def not_pinned?
214
+ branch || tag || ref.nil?
215
+ end
216
+
217
+ def pinned_to_full_sha?
218
+ ref =~ /\A\h{40}\z/
219
+ end
220
+
221
+ def legacy_locked_revision?
222
+ !@revision.nil? && @revision =~ /\A\h{7}\z/
223
+ end
151
224
 
152
- [URICredentialsFilter.credential_filtered_string(out, uri), status]
225
+ def git_null(*command, dir: nil)
226
+ check_allowed(command)
227
+
228
+ capture(command, dir, :ignore_err => true)
153
229
  end
154
230
 
155
231
  def git_retry(*command, dir: nil)
@@ -163,49 +239,62 @@ module Bundler
163
239
  def git(*command, dir: nil)
164
240
  command_with_no_credentials = check_allowed(command)
165
241
 
166
- out, status = SharedHelpers.with_clean_git_env do
167
- capture_and_filter_stderr(*capture3_args_for(command, dir))
168
- end
242
+ out, err, status = capture(command, dir)
169
243
 
170
- filtered_out = URICredentialsFilter.credential_filtered_string(out, uri)
244
+ Bundler.ui.warn err unless err.empty?
171
245
 
172
- raise GitCommandError.new(command_with_no_credentials, dir || SharedHelpers.pwd, filtered_out) unless status.success?
246
+ raise GitCommandError.new(command_with_no_credentials, dir || SharedHelpers.pwd, out) unless status.success?
173
247
 
174
- filtered_out
248
+ out
175
249
  end
176
250
 
177
251
  def has_revision_cached?
178
- return unless @revision
179
- with_path { git("cat-file", "-e", @revision, :dir => path) }
252
+ return unless @revision && path.exist?
253
+ git("cat-file", "-e", @revision, :dir => path)
180
254
  true
181
255
  rescue GitError
182
256
  false
183
257
  end
184
258
 
185
- def remove_cache
186
- FileUtils.rm_rf(path)
259
+ def find_local_revision
260
+ return head_revision if explicit_ref.nil?
261
+
262
+ find_revision_for(explicit_ref)
187
263
  end
188
264
 
189
- def find_local_revision
190
- allowed_with_path do
191
- git("rev-parse", "--verify", ref || "HEAD", :dir => path).strip
192
- end
265
+ def head_revision
266
+ verify("HEAD")
267
+ end
268
+
269
+ def find_revision_for(reference)
270
+ verify(reference)
193
271
  rescue GitCommandError => e
194
- raise MissingGitRevisionError.new(e.command, path, ref, URICredentialsFilter.credential_filtered_uri(uri))
272
+ raise MissingGitRevisionError.new(e.command, path, reference, credential_filtered_uri)
273
+ end
274
+
275
+ def verify(reference)
276
+ git("rev-parse", "--verify", reference, :dir => path).strip
195
277
  end
196
278
 
197
- # Adds credentials to the URI as Fetcher#configured_uri_for does
198
- def configured_uri_for(uri)
199
- if /https?:/ =~ uri
279
+ # Adds credentials to the URI
280
+ def configured_uri
281
+ if /https?:/.match?(uri)
200
282
  remote = Bundler::URI(uri)
201
283
  config_auth = Bundler.settings[remote.to_s] || Bundler.settings[remote.host]
202
284
  remote.userinfo ||= config_auth
203
285
  remote.to_s
286
+ elsif File.exist?(uri)
287
+ "file://#{uri}"
204
288
  else
205
- uri
289
+ uri.to_s
206
290
  end
207
291
  end
208
292
 
293
+ # Removes credentials from the URI
294
+ def credential_filtered_uri
295
+ URICredentialsFilter.credential_filtered_uri(uri)
296
+ end
297
+
209
298
  def allow?
210
299
  allowed = @git ? @git.allow_git_ops? : true
211
300
 
@@ -231,17 +320,17 @@ module Bundler
231
320
  command_with_no_credentials
232
321
  end
233
322
 
234
- def capture_and_filter_stderr(*cmd)
235
- require "open3"
236
- return_value, captured_err, status = Open3.capture3(*cmd)
237
- Bundler.ui.warn URICredentialsFilter.credential_filtered_string(captured_err, uri) unless captured_err.empty?
238
- [return_value, status]
239
- end
323
+ def capture(cmd, dir, ignore_err: false)
324
+ SharedHelpers.with_clean_git_env do
325
+ require "open3"
326
+ out, err, status = Open3.capture3(*capture3_args_for(cmd, dir))
327
+
328
+ filtered_out = URICredentialsFilter.credential_filtered_string(out, uri)
329
+ return [filtered_out, status] if ignore_err
240
330
 
241
- def capture_and_ignore_stderr(*cmd)
242
- require "open3"
243
- return_value, _, status = Open3.capture3(*cmd)
244
- [return_value, status]
331
+ filtered_err = URICredentialsFilter.credential_filtered_string(err, uri)
332
+ [filtered_out, filtered_err, status]
333
+ end
245
334
  end
246
335
 
247
336
  def capture3_args_for(cmd, dir)
@@ -254,9 +343,43 @@ module Bundler
254
343
  end
255
344
  end
256
345
 
346
+ def extra_clone_args
347
+ return [] if full_clone?
348
+
349
+ args = ["--depth", depth.to_s, "--single-branch"]
350
+ args.unshift("--no-tags") if supports_cloning_with_no_tags?
351
+
352
+ args += ["--branch", branch || tag] if branch || tag
353
+ args
354
+ end
355
+
356
+ def depth_args
357
+ return [] if full_clone?
358
+
359
+ ["--depth", depth.to_s]
360
+ end
361
+
362
+ def extra_fetch_args
363
+ extra_args = [path.to_s, *depth_args]
364
+ extra_args.push(revision) unless legacy_locked_revision?
365
+ extra_args
366
+ end
367
+
368
+ def full_clone?
369
+ depth.nil?
370
+ end
371
+
257
372
  def supports_minus_c?
258
373
  @supports_minus_c ||= Gem::Version.new(version) >= Gem::Version.new("1.8.5")
259
374
  end
375
+
376
+ def supports_fetching_unreachable_refs?
377
+ @supports_fetching_unreachable_refs ||= Gem::Version.new(version) >= Gem::Version.new("2.5.0")
378
+ end
379
+
380
+ def supports_cloning_with_no_tags?
381
+ @supports_cloning_with_no_tags ||= Gem::Version.new(version) >= Gem::Version.new("2.14.0-rc0")
382
+ end
260
383
  end
261
384
  end
262
385
  end
@@ -64,7 +64,7 @@ module Bundler
64
64
  at = if local?
65
65
  path
66
66
  elsif user_ref = options["ref"]
67
- if ref =~ /\A[a-z0-9]{4,}\z/i
67
+ if /\A[a-z0-9]{4,}\z/i.match?(ref)
68
68
  shortref_for_display(user_ref)
69
69
  else
70
70
  user_ref
@@ -72,7 +72,7 @@ module Bundler
72
72
  elsif ref
73
73
  ref
74
74
  else
75
- git_proxy.branch
75
+ current_branch
76
76
  end
77
77
 
78
78
  rev = "at #{at}@#{shortref_for_display(revision)}"
@@ -102,13 +102,7 @@ module Bundler
102
102
  @install_path ||= begin
103
103
  git_scope = "#{base_name}-#{shortref_for_path(revision)}"
104
104
 
105
- path = Bundler.install_path.join(git_scope)
106
-
107
- if !path.exist? && Bundler.requires_sudo?
108
- Bundler.user_bundle_path.join(Bundler.ruby_scope).join(git_scope)
109
- else
110
- path
111
- end
105
+ Bundler.install_path.join(git_scope)
112
106
  end
113
107
  end
114
108
 
@@ -132,7 +126,7 @@ module Bundler
132
126
  path = Pathname.new(path)
133
127
  path = path.expand_path(Bundler.root) unless path.relative?
134
128
 
135
- unless options["branch"] || Bundler.settings[:disable_local_branch_check]
129
+ unless branch || Bundler.settings[:disable_local_branch_check]
136
130
  raise GitError, "Cannot use local override for #{name} at #{path} because " \
137
131
  ":branch is not specified in Gemfile. Specify a branch or run " \
138
132
  "`bundle config unset local.#{override_for(original_path)}` to remove the local override"
@@ -147,14 +141,14 @@ module Bundler
147
141
 
148
142
  # Create a new git proxy without the cached revision
149
143
  # so the Gemfile.lock always picks up the new revision.
150
- @git_proxy = GitProxy.new(path, uri, ref)
144
+ @git_proxy = GitProxy.new(path, uri, options)
151
145
 
152
- if git_proxy.branch != options["branch"] && !Bundler.settings[:disable_local_branch_check]
146
+ if current_branch != branch && !Bundler.settings[:disable_local_branch_check]
153
147
  raise GitError, "Local override for #{name} at #{path} is using branch " \
154
- "#{git_proxy.branch} but Gemfile specifies #{options["branch"]}"
148
+ "#{current_branch} but Gemfile specifies #{branch}"
155
149
  end
156
150
 
157
- changed = cached_revision && cached_revision != git_proxy.revision
151
+ changed = cached_revision && cached_revision != revision
158
152
 
159
153
  if !Bundler.settings[:disable_local_revision_check] && changed && !@unlocked && !git_proxy.contains?(cached_revision)
160
154
  raise GitError, "The Gemfile lock is pointing to revision #{shortref_for_display(cached_revision)} " \
@@ -219,7 +213,7 @@ module Bundler
219
213
  # across different projects, this cache will be shared.
220
214
  # When using local git repos, this is set to the local repo.
221
215
  def cache_path
222
- @cache_path ||= if Bundler.requires_sudo? || Bundler.feature_flag.global_gem_cache?
216
+ @cache_path ||= if Bundler.feature_flag.global_gem_cache?
223
217
  Bundler.user_cache
224
218
  else
225
219
  Bundler.bundle_path.join("cache", "bundler")
@@ -234,6 +228,10 @@ module Bundler
234
228
  git_proxy.revision
235
229
  end
236
230
 
231
+ def current_branch
232
+ git_proxy.current_branch
233
+ end
234
+
237
235
  def allow_git_ops?
238
236
  @allow_remote || @allow_cached
239
237
  end
@@ -297,7 +295,7 @@ module Bundler
297
295
  end
298
296
 
299
297
  def uri_hash
300
- if uri =~ %r{^\w+://(\w+@)?}
298
+ if %r{^\w+://(\w+@)?}.match?(uri)
301
299
  # Downcase the domain component of the URI
302
300
  # and strip off a trailing slash, if one is present
303
301
  input = Bundler::URI.parse(uri).normalize.to_s.sub(%r{/$}, "")
@@ -319,7 +317,7 @@ module Bundler
319
317
  end
320
318
 
321
319
  def git_proxy
322
- @git_proxy ||= GitProxy.new(cache_path, uri, ref, cached_revision, self)
320
+ @git_proxy ||= GitProxy.new(cache_path, uri, options, cached_revision, self)
323
321
  end
324
322
 
325
323
  def fetch
@@ -15,7 +15,6 @@ module Bundler
15
15
  s.version = VERSION
16
16
  s.license = "MIT"
17
17
  s.platform = Gem::Platform::RUBY
18
- s.source = self
19
18
  s.authors = ["bundler team"]
20
19
  s.bindir = "exe"
21
20
  s.homepage = "https://bundler.io"
@@ -18,13 +18,7 @@ module Bundler
18
18
  @build_args = options[:build_args] || Bundler.rubygems.build_args
19
19
  @gem_bin_dir = "#{Bundler.rubygems.gem_dir}/bin"
20
20
  @disable_extensions = options[:disable_extensions]
21
-
22
- if Bundler.requires_sudo?
23
- @tmp_dir = Bundler.tmp(spec.full_name).to_s
24
- @bin_dir = "#{@tmp_dir}/bin"
25
- else
26
- @bin_dir = @gem_bin_dir
27
- end
21
+ @bin_dir = @gem_bin_dir
28
22
  end
29
23
 
30
24
  def post_install
@@ -38,25 +32,10 @@ module Bundler
38
32
  generate_bin unless spec.executables.empty?
39
33
 
40
34
  run_hooks(:post_install)
41
- ensure
42
- Bundler.rm_rf(@tmp_dir) if Bundler.requires_sudo?
43
35
  end
44
36
 
45
37
  private
46
38
 
47
- def generate_bin
48
- super
49
-
50
- if Bundler.requires_sudo?
51
- SharedHelpers.filesystem_access(@gem_bin_dir) do |p|
52
- Bundler.mkdir_p(p)
53
- end
54
- spec.executables.each do |exe|
55
- Bundler.sudo "cp -R #{@bin_dir}/#{exe} #{@gem_bin_dir}"
56
- end
57
- end
58
- end
59
-
60
39
  def run_hooks(type)
61
40
  hooks_meth = "#{type}_hooks"
62
41
  return unless Gem.respond_to?(hooks_meth)
@@ -224,13 +224,13 @@ module Bundler
224
224
 
225
225
  # Some gem authors put absolute paths in their gemspec
226
226
  # and we have to save them from themselves
227
- spec.files = spec.files.map do |p|
228
- next p unless p =~ /\A#{Pathname::SEPARATOR_PAT}/
229
- next if File.directory?(p)
227
+ spec.files = spec.files.map do |path|
228
+ next path unless /\A#{Pathname::SEPARATOR_PAT}/.match?(path)
229
+ next if File.directory?(path)
230
230
  begin
231
- Pathname.new(p).relative_path_from(gem_dir).to_s
231
+ Pathname.new(path).relative_path_from(gem_dir).to_s
232
232
  rescue ArgumentError
233
- p
233
+ path
234
234
  end
235
235
  end.compact
236
236