bundler 2.1.4 → 2.2.18

Sign up to get free protection for your applications and to get access to all the features.

Potentially problematic release.


This version of bundler might be problematic. Click here for more details.

Files changed (227) hide show
  1. checksums.yaml +4 -4
  2. data/CHANGELOG.md +1790 -1430
  3. data/README.md +6 -8
  4. data/bundler.gemspec +5 -6
  5. data/exe/bundle +3 -0
  6. data/lib/bundler/build_metadata.rb +3 -11
  7. data/lib/bundler/cli/add.rb +1 -1
  8. data/lib/bundler/cli/binstubs.rb +6 -2
  9. data/lib/bundler/cli/cache.rb +2 -7
  10. data/lib/bundler/cli/clean.rb +1 -1
  11. data/lib/bundler/cli/common.rb +29 -2
  12. data/lib/bundler/cli/console.rb +1 -1
  13. data/lib/bundler/cli/doctor.rb +1 -1
  14. data/lib/bundler/cli/exec.rb +4 -4
  15. data/lib/bundler/cli/fund.rb +36 -0
  16. data/lib/bundler/cli/gem.rb +129 -28
  17. data/lib/bundler/cli/info.rb +15 -4
  18. data/lib/bundler/cli/init.rb +2 -2
  19. data/lib/bundler/cli/inject.rb +1 -1
  20. data/lib/bundler/cli/install.rb +13 -11
  21. data/lib/bundler/cli/issue.rb +2 -2
  22. data/lib/bundler/cli/list.rb +12 -10
  23. data/lib/bundler/cli/outdated.rb +94 -76
  24. data/lib/bundler/cli/plugin.rb +10 -0
  25. data/lib/bundler/cli/pristine.rb +5 -0
  26. data/lib/bundler/cli/show.rb +1 -1
  27. data/lib/bundler/cli/update.rb +3 -1
  28. data/lib/bundler/cli.rb +72 -56
  29. data/lib/bundler/compact_index_client/cache.rb +6 -14
  30. data/lib/bundler/compact_index_client/gem_parser.rb +28 -0
  31. data/lib/bundler/compact_index_client/updater.rb +13 -17
  32. data/lib/bundler/compact_index_client.rb +1 -1
  33. data/lib/bundler/current_ruby.rb +1 -0
  34. data/lib/bundler/definition.rb +117 -188
  35. data/lib/bundler/dep_proxy.rb +16 -9
  36. data/lib/bundler/dependency.rb +3 -10
  37. data/lib/bundler/dsl.rb +40 -33
  38. data/lib/bundler/endpoint_specification.rb +1 -1
  39. data/lib/bundler/env.rb +1 -1
  40. data/lib/bundler/environment_preserver.rb +26 -2
  41. data/lib/bundler/errors.rb +1 -0
  42. data/lib/bundler/feature_flag.rb +0 -6
  43. data/lib/bundler/fetcher/base.rb +1 -1
  44. data/lib/bundler/fetcher/compact_index.rb +1 -1
  45. data/lib/bundler/fetcher/downloader.rb +9 -5
  46. data/lib/bundler/fetcher/index.rb +3 -4
  47. data/lib/bundler/fetcher.rb +5 -4
  48. data/lib/bundler/friendly_errors.rb +22 -13
  49. data/lib/bundler/gem_helper.rb +51 -18
  50. data/lib/bundler/gem_helpers.rb +36 -25
  51. data/lib/bundler/gem_version_promoter.rb +4 -4
  52. data/lib/bundler/graph.rb +1 -1
  53. data/lib/bundler/index.rb +13 -9
  54. data/lib/bundler/injector.rb +23 -5
  55. data/lib/bundler/inline.rb +3 -2
  56. data/lib/bundler/installer/gem_installer.rb +3 -3
  57. data/lib/bundler/installer/parallel_installer.rb +46 -25
  58. data/lib/bundler/installer/standalone.rb +17 -2
  59. data/lib/bundler/installer.rb +37 -49
  60. data/lib/bundler/lazy_specification.rb +45 -25
  61. data/lib/bundler/lockfile_generator.rb +1 -1
  62. data/lib/bundler/lockfile_parser.rb +4 -14
  63. data/lib/bundler/man/.document +1 -0
  64. data/{man → lib/bundler/man}/bundle-add.1 +1 -1
  65. data/{man/bundle-add.ronn → lib/bundler/man/bundle-add.1.ronn} +0 -0
  66. data/{man → lib/bundler/man}/bundle-binstubs.1 +5 -3
  67. data/{man/bundle-binstubs.ronn → lib/bundler/man/bundle-binstubs.1.ronn} +2 -4
  68. data/{man → lib/bundler/man}/bundle-cache.1 +1 -1
  69. data/{man/bundle-cache.ronn → lib/bundler/man/bundle-cache.1.ronn} +0 -0
  70. data/{man → lib/bundler/man}/bundle-check.1 +1 -1
  71. data/{man/bundle-check.ronn → lib/bundler/man/bundle-check.1.ronn} +0 -0
  72. data/{man → lib/bundler/man}/bundle-clean.1 +1 -1
  73. data/{man/bundle-clean.ronn → lib/bundler/man/bundle-clean.1.ronn} +0 -0
  74. data/{man → lib/bundler/man}/bundle-config.1 +40 -38
  75. data/{man/bundle-config.ronn → lib/bundler/man/bundle-config.1.ronn} +50 -50
  76. data/{man → lib/bundler/man}/bundle-doctor.1 +1 -1
  77. data/{man/bundle-doctor.ronn → lib/bundler/man/bundle-doctor.1.ronn} +0 -0
  78. data/{man → lib/bundler/man}/bundle-exec.1 +1 -1
  79. data/{man/bundle-exec.ronn → lib/bundler/man/bundle-exec.1.ronn} +0 -0
  80. data/{man → lib/bundler/man}/bundle-gem.1 +25 -3
  81. data/{man/bundle-gem.ronn → lib/bundler/man/bundle-gem.1.ronn} +30 -7
  82. data/{man → lib/bundler/man}/bundle-info.1 +1 -1
  83. data/{man/bundle-info.ronn → lib/bundler/man/bundle-info.1.ronn} +0 -0
  84. data/{man → lib/bundler/man}/bundle-init.1 +1 -1
  85. data/{man/bundle-init.ronn → lib/bundler/man/bundle-init.1.ronn} +0 -0
  86. data/{man → lib/bundler/man}/bundle-inject.1 +1 -1
  87. data/{man/bundle-inject.ronn → lib/bundler/man/bundle-inject.1.ronn} +0 -0
  88. data/{man → lib/bundler/man}/bundle-install.1 +30 -3
  89. data/{man/bundle-install.ronn → lib/bundler/man/bundle-install.1.ronn} +25 -3
  90. data/{man → lib/bundler/man}/bundle-list.1 +7 -7
  91. data/{man/bundle-list.ronn → lib/bundler/man/bundle-list.1.ronn} +6 -6
  92. data/{man → lib/bundler/man}/bundle-lock.1 +1 -1
  93. data/{man/bundle-lock.ronn → lib/bundler/man/bundle-lock.1.ronn} +0 -0
  94. data/{man → lib/bundler/man}/bundle-open.1 +1 -1
  95. data/{man/bundle-open.ronn → lib/bundler/man/bundle-open.1.ronn} +0 -0
  96. data/{man → lib/bundler/man}/bundle-outdated.1 +1 -1
  97. data/{man/bundle-outdated.ronn → lib/bundler/man/bundle-outdated.1.ronn} +0 -0
  98. data/{man → lib/bundler/man}/bundle-platform.1 +1 -1
  99. data/{man/bundle-platform.ronn → lib/bundler/man/bundle-platform.1.ronn} +0 -0
  100. data/{man → lib/bundler/man}/bundle-pristine.1 +1 -1
  101. data/{man/bundle-pristine.ronn → lib/bundler/man/bundle-pristine.1.ronn} +0 -0
  102. data/{man → lib/bundler/man}/bundle-remove.1 +1 -1
  103. data/{man/bundle-remove.ronn → lib/bundler/man/bundle-remove.1.ronn} +0 -0
  104. data/{man → lib/bundler/man}/bundle-show.1 +1 -1
  105. data/{man/bundle-show.ronn → lib/bundler/man/bundle-show.1.ronn} +0 -0
  106. data/{man → lib/bundler/man}/bundle-update.1 +1 -1
  107. data/{man/bundle-update.ronn → lib/bundler/man/bundle-update.1.ronn} +0 -0
  108. data/{man → lib/bundler/man}/bundle-viz.1 +1 -1
  109. data/{man/bundle-viz.ronn → lib/bundler/man/bundle-viz.1.ronn} +0 -0
  110. data/{man → lib/bundler/man}/bundle.1 +1 -1
  111. data/{man/bundle.ronn → lib/bundler/man/bundle.1.ronn} +0 -0
  112. data/{man → lib/bundler/man}/gemfile.5 +4 -4
  113. data/{man → lib/bundler/man}/gemfile.5.ronn +4 -4
  114. data/{man → lib/bundler/man}/index.txt +0 -0
  115. data/lib/bundler/mirror.rb +2 -2
  116. data/lib/bundler/plugin/api/source.rb +22 -1
  117. data/lib/bundler/plugin/dsl.rb +1 -1
  118. data/lib/bundler/plugin/index.rb +10 -1
  119. data/lib/bundler/plugin/installer/rubygems.rb +1 -1
  120. data/lib/bundler/plugin/installer.rb +9 -11
  121. data/lib/bundler/plugin/source_list.rb +5 -1
  122. data/lib/bundler/plugin.rb +33 -7
  123. data/lib/bundler/psyched_yaml.rb +0 -15
  124. data/lib/bundler/remote_specification.rb +5 -2
  125. data/lib/bundler/resolver/spec_group.rb +56 -53
  126. data/lib/bundler/resolver.rb +88 -115
  127. data/lib/bundler/retry.rb +2 -2
  128. data/lib/bundler/ruby_version.rb +1 -1
  129. data/lib/bundler/rubygems_ext.rb +71 -11
  130. data/lib/bundler/rubygems_gem_installer.rb +50 -9
  131. data/lib/bundler/rubygems_integration.rb +25 -60
  132. data/lib/bundler/runtime.rb +4 -14
  133. data/lib/bundler/settings.rb +107 -55
  134. data/lib/bundler/shared_helpers.rb +3 -3
  135. data/lib/bundler/similarity_detector.rb +1 -1
  136. data/lib/bundler/source/git/git_proxy.rb +82 -80
  137. data/lib/bundler/source/git.rb +24 -22
  138. data/lib/bundler/source/metadata.rb +0 -4
  139. data/lib/bundler/source/path/installer.rb +10 -10
  140. data/lib/bundler/source/path.rb +10 -4
  141. data/lib/bundler/source/rubygems/remote.rb +1 -1
  142. data/lib/bundler/source/rubygems.rb +60 -28
  143. data/lib/bundler/source/rubygems_aggregate.rb +64 -0
  144. data/lib/bundler/source.rb +16 -1
  145. data/lib/bundler/source_list.rb +52 -28
  146. data/lib/bundler/source_map.rb +58 -0
  147. data/lib/bundler/spec_set.rb +29 -17
  148. data/lib/bundler/stub_specification.rb +25 -7
  149. data/lib/bundler/templates/Gemfile +1 -1
  150. data/lib/bundler/templates/gems.rb +1 -1
  151. data/lib/bundler/templates/newgem/CHANGELOG.md.tt +5 -0
  152. data/lib/bundler/templates/newgem/CODE_OF_CONDUCT.md.tt +57 -47
  153. data/lib/bundler/templates/newgem/Gemfile.tt +9 -1
  154. data/lib/bundler/templates/newgem/README.md.tt +6 -5
  155. data/lib/bundler/templates/newgem/Rakefile.tt +19 -5
  156. data/lib/bundler/templates/newgem/bin/console.tt +1 -0
  157. data/lib/bundler/templates/newgem/circleci/config.yml.tt +13 -0
  158. data/lib/bundler/templates/newgem/ext/newgem/extconf.rb.tt +2 -0
  159. data/lib/bundler/templates/newgem/github/workflows/main.yml.tt +16 -0
  160. data/lib/bundler/templates/newgem/gitlab-ci.yml.tt +9 -0
  161. data/lib/bundler/templates/newgem/lib/newgem/version.rb.tt +2 -0
  162. data/lib/bundler/templates/newgem/lib/newgem.rb.tt +4 -2
  163. data/lib/bundler/templates/newgem/newgem.gemspec.tt +15 -7
  164. data/lib/bundler/templates/newgem/rubocop.yml.tt +13 -0
  165. data/lib/bundler/templates/newgem/spec/newgem_spec.rb.tt +2 -0
  166. data/lib/bundler/templates/newgem/spec/spec_helper.rb.tt +2 -1
  167. data/lib/bundler/templates/newgem/test/{newgem_test.rb.tt → minitest/newgem_test.rb.tt} +2 -0
  168. data/lib/bundler/templates/newgem/test/{test_helper.rb.tt → minitest/test_helper.rb.tt} +2 -0
  169. data/lib/bundler/templates/newgem/test/test-unit/newgem_test.rb.tt +15 -0
  170. data/lib/bundler/templates/newgem/test/test-unit/test_helper.rb.tt +6 -0
  171. data/lib/bundler/ui/shell.rb +5 -5
  172. data/lib/bundler/uri_credentials_filter.rb +3 -1
  173. data/lib/bundler/vendor/molinillo/lib/molinillo/delegates/specification_provider.rb +7 -0
  174. data/lib/bundler/vendor/molinillo/lib/molinillo/dependency_graph/tag.rb +2 -2
  175. data/lib/bundler/vendor/molinillo/lib/molinillo/dependency_graph/vertex.rb +11 -5
  176. data/lib/bundler/vendor/molinillo/lib/molinillo/dependency_graph.rb +34 -2
  177. data/lib/bundler/vendor/molinillo/lib/molinillo/errors.rb +3 -3
  178. data/lib/bundler/vendor/molinillo/lib/molinillo/gem_metadata.rb +1 -1
  179. data/lib/bundler/vendor/molinillo/lib/molinillo/modules/specification_provider.rb +12 -1
  180. data/lib/bundler/vendor/molinillo/lib/molinillo/resolution.rb +49 -47
  181. data/lib/bundler/vendor/molinillo/lib/molinillo.rb +0 -1
  182. data/lib/bundler/vendor/net-http-persistent/lib/net/http/persistent.rb +82 -189
  183. data/lib/bundler/vendor/thor/lib/thor/actions/create_link.rb +2 -1
  184. data/lib/bundler/vendor/thor/lib/thor/actions/file_manipulation.rb +4 -2
  185. data/lib/bundler/vendor/thor/lib/thor/actions.rb +1 -1
  186. data/lib/bundler/vendor/thor/lib/thor/base.rb +9 -0
  187. data/lib/bundler/vendor/thor/lib/thor/error.rb +1 -1
  188. data/lib/bundler/vendor/thor/lib/thor/parser/arguments.rb +5 -1
  189. data/lib/bundler/vendor/thor/lib/thor/parser/options.rb +9 -8
  190. data/lib/bundler/vendor/thor/lib/thor/shell/basic.rb +5 -2
  191. data/lib/bundler/vendor/thor/lib/thor/shell/color.rb +5 -1
  192. data/lib/bundler/vendor/thor/lib/thor/version.rb +1 -1
  193. data/lib/bundler/vendor/thor/lib/thor.rb +5 -13
  194. data/lib/bundler/vendor/tmpdir/lib/tmpdir.rb +154 -0
  195. data/lib/bundler/vendored_persistent.rb +0 -7
  196. data/lib/bundler/vendored_tmpdir.rb +4 -0
  197. data/lib/bundler/version.rb +1 -1
  198. data/lib/bundler/worker.rb +1 -1
  199. data/lib/bundler/yaml_serializer.rb +1 -1
  200. data/lib/bundler.rb +34 -9
  201. metadata +77 -86
  202. data/lib/bundler/vendor/molinillo/lib/molinillo/compatibility.rb +0 -26
  203. data/man/bundle-add.1.txt +0 -58
  204. data/man/bundle-binstubs.1.txt +0 -48
  205. data/man/bundle-cache.1.txt +0 -78
  206. data/man/bundle-check.1.txt +0 -33
  207. data/man/bundle-clean.1.txt +0 -26
  208. data/man/bundle-config.1.txt +0 -528
  209. data/man/bundle-doctor.1.txt +0 -44
  210. data/man/bundle-exec.1.txt +0 -178
  211. data/man/bundle-gem.1.txt +0 -91
  212. data/man/bundle-info.1.txt +0 -21
  213. data/man/bundle-init.1.txt +0 -34
  214. data/man/bundle-inject.1.txt +0 -32
  215. data/man/bundle-install.1.txt +0 -401
  216. data/man/bundle-list.1.txt +0 -43
  217. data/man/bundle-lock.1.txt +0 -93
  218. data/man/bundle-open.1.txt +0 -29
  219. data/man/bundle-outdated.1.txt +0 -131
  220. data/man/bundle-platform.1.txt +0 -57
  221. data/man/bundle-pristine.1.txt +0 -44
  222. data/man/bundle-remove.1.txt +0 -34
  223. data/man/bundle-show.1.txt +0 -27
  224. data/man/bundle-update.1.txt +0 -390
  225. data/man/bundle-viz.1.txt +0 -39
  226. data/man/bundle.1.txt +0 -116
  227. data/man/gemfile.5.txt +0 -649
@@ -17,8 +17,8 @@ module Bundler
17
17
  class GitNotAllowedError < GitError
18
18
  def initialize(command)
19
19
  msg = String.new
20
- msg << "Bundler is trying to run a `git #{command}` at runtime. You probably need to run `bundle install`. However, "
21
- msg << "this error message could probably be more useful. Please submit a ticket at https://github.com/bundler/bundler/issues "
20
+ msg << "Bundler is trying to run `#{command}` at runtime. You probably need to run `bundle install`. However, "
21
+ msg << "this error message could probably be more useful. Please submit a ticket at https://github.com/rubygems/rubygems/issues/new?labels=Bundler&template=bundler-related-issue.md "
22
22
  msg << "with steps to reproduce as well as the following\n\nCALLER: #{caller.join("\n")}"
23
23
  super msg
24
24
  end
@@ -27,21 +27,21 @@ module Bundler
27
27
  class GitCommandError < GitError
28
28
  attr_reader :command
29
29
 
30
- def initialize(command, path = nil, extra_info = nil)
30
+ def initialize(command, path, extra_info = nil)
31
31
  @command = command
32
32
 
33
33
  msg = String.new
34
- msg << "Git error: command `git #{command}` in directory #{SharedHelpers.pwd} has failed."
34
+ msg << "Git error: command `#{command}` in directory #{path} has failed."
35
35
  msg << "\n#{extra_info}" if extra_info
36
- msg << "\nIf this error persists you could try removing the cache directory '#{path}'" if path && path.exist?
36
+ msg << "\nIf this error persists you could try removing the cache directory '#{path}'" if path.exist?
37
37
  super msg
38
38
  end
39
39
  end
40
40
 
41
41
  class MissingGitRevisionError < GitCommandError
42
- def initialize(command, path, ref, repo)
42
+ def initialize(command, destination_path, ref, repo)
43
43
  msg = "Revision #{ref} does not exist in the repository #{repo}. Maybe you misspelled it?"
44
- super command, path, msg
44
+ super command, destination_path, msg
45
45
  end
46
46
  end
47
47
 
@@ -62,26 +62,18 @@ module Bundler
62
62
  end
63
63
 
64
64
  def revision
65
- return @revision if @revision
66
-
67
- begin
68
- @revision ||= find_local_revision
69
- rescue GitCommandError => e
70
- raise MissingGitRevisionError.new(e.command, path, ref, URICredentialsFilter.credential_filtered_uri(uri))
71
- end
72
-
73
- @revision
65
+ @revision ||= find_local_revision
74
66
  end
75
67
 
76
68
  def branch
77
- @branch ||= allowed_in_path do
78
- git("rev-parse --abbrev-ref HEAD").strip
69
+ @branch ||= allowed_with_path do
70
+ git("rev-parse", "--abbrev-ref", "HEAD", :dir => path).strip
79
71
  end
80
72
  end
81
73
 
82
74
  def contains?(commit)
83
- allowed_in_path do
84
- result, status = git_null("branch --contains #{commit}")
75
+ allowed_with_path do
76
+ result, status = git_null("branch", "--contains", commit, :dir => path)
85
77
  status.success? && result =~ /^\* (.*)$/
86
78
  end
87
79
  end
@@ -96,20 +88,22 @@ module Bundler
96
88
 
97
89
  def checkout
98
90
  return if path.exist? && has_revision_cached?
99
- extra_ref = "#{Shellwords.shellescape(ref)}:#{Shellwords.shellescape(ref)}" if ref && ref.start_with?("refs/")
91
+ extra_ref = "#{ref}:#{ref}" if ref && ref.start_with?("refs/")
100
92
 
101
93
  Bundler.ui.info "Fetching #{URICredentialsFilter.credential_filtered_uri(uri)}"
102
94
 
95
+ configured_uri = configured_uri_for(uri).to_s
96
+
103
97
  unless path.exist?
104
98
  SharedHelpers.filesystem_access(path.dirname) do |p|
105
99
  FileUtils.mkdir_p(p)
106
100
  end
107
- git_retry %(clone #{uri_escaped_with_configured_credentials} "#{path}" --bare --no-hardlinks --quiet)
101
+ git_retry "clone", configured_uri, path.to_s, "--bare", "--no-hardlinks", "--quiet"
108
102
  return unless extra_ref
109
103
  end
110
104
 
111
- in_path do
112
- git_retry %(fetch --force --quiet --tags #{uri_escaped_with_configured_credentials} "refs/heads/*:refs/heads/*" #{extra_ref})
105
+ with_path do
106
+ git_retry(*["fetch", "--force", "--quiet", "--tags", configured_uri, "refs/heads/*:refs/heads/*", extra_ref].compact, :dir => path)
113
107
  end
114
108
  end
115
109
 
@@ -123,68 +117,69 @@ module Bundler
123
117
  SharedHelpers.filesystem_access(destination) do |p|
124
118
  FileUtils.rm_rf(p)
125
119
  end
126
- git_retry %(clone --no-checkout --quiet "#{path}" "#{destination}")
120
+ git_retry "clone", "--no-checkout", "--quiet", path.to_s, destination.to_s
127
121
  File.chmod(((File.stat(destination).mode | 0o777) & ~File.umask), destination)
128
122
  rescue Errno::EEXIST => e
129
- file_path = e.message[%r{.*?(/.*)}, 1]
123
+ file_path = e.message[%r{.*?((?:[a-zA-Z]:)?/.*)}, 1]
130
124
  raise GitError, "Bundler could not install a gem because it needs to " \
131
125
  "create a directory, but a file exists - #{file_path}. Please delete " \
132
126
  "this file and try again."
133
127
  end
134
128
  end
135
129
  # method 2
136
- SharedHelpers.chdir(destination) do
137
- git_retry %(fetch --force --quiet --tags "#{path}")
130
+ git_retry "fetch", "--force", "--quiet", "--tags", path.to_s, :dir => destination
138
131
 
139
- begin
140
- git "reset --hard #{@revision}"
141
- rescue GitCommandError => e
142
- raise MissingGitRevisionError.new(e.command, path, @revision, URICredentialsFilter.credential_filtered_uri(uri))
143
- end
132
+ begin
133
+ git "reset", "--hard", @revision, :dir => destination
134
+ rescue GitCommandError => e
135
+ raise MissingGitRevisionError.new(e.command, destination, @revision, URICredentialsFilter.credential_filtered_uri(uri))
136
+ end
144
137
 
145
- if submodules
146
- git_retry "submodule update --init --recursive"
147
- elsif Gem::Version.create(version) >= Gem::Version.create("2.9.0")
148
- git_retry "submodule deinit --all --force"
149
- end
138
+ if submodules
139
+ git_retry "submodule", "update", "--init", "--recursive", :dir => destination
140
+ elsif Gem::Version.create(version) >= Gem::Version.create("2.9.0")
141
+ inner_command = "git -C $toplevel submodule deinit --force $sm_path"
142
+ git_retry "submodule", "foreach", "--quiet", inner_command, :dir => destination
150
143
  end
151
144
  end
152
145
 
153
- private
146
+ private
154
147
 
155
- def git_null(command)
156
- command_with_no_credentials = URICredentialsFilter.credential_filtered_string(command, uri)
157
- raise GitNotAllowedError.new(command_with_no_credentials) unless allow?
148
+ def git_null(*command, dir: nil)
149
+ check_allowed(command)
158
150
 
159
151
  out, status = SharedHelpers.with_clean_git_env do
160
- capture_and_ignore_stderr("git #{command}")
152
+ capture_and_ignore_stderr(*capture3_args_for(command, dir))
161
153
  end
162
154
 
163
155
  [URICredentialsFilter.credential_filtered_string(out, uri), status]
164
156
  end
165
157
 
166
- def git_retry(command)
167
- Bundler::Retry.new("`git #{URICredentialsFilter.credential_filtered_string(command, uri)}`", GitNotAllowedError).attempts do
168
- git(command)
158
+ def git_retry(*command, dir: nil)
159
+ command_with_no_credentials = check_allowed(command)
160
+
161
+ Bundler::Retry.new("`#{command_with_no_credentials}` at #{dir || SharedHelpers.pwd}").attempts do
162
+ git(*command, :dir => dir)
169
163
  end
170
164
  end
171
165
 
172
- def git(command, check_errors = true, error_msg = nil)
173
- command_with_no_credentials = URICredentialsFilter.credential_filtered_string(command, uri)
174
- raise GitNotAllowedError.new(command_with_no_credentials) unless allow?
166
+ def git(*command, dir: nil)
167
+ command_with_no_credentials = check_allowed(command)
175
168
 
176
169
  out, status = SharedHelpers.with_clean_git_env do
177
- capture_and_filter_stderr(uri, "git #{command}")
170
+ capture_and_filter_stderr(*capture3_args_for(command, dir))
178
171
  end
179
172
 
180
- stdout_with_no_credentials = URICredentialsFilter.credential_filtered_string(out, uri)
181
- raise GitCommandError.new(command_with_no_credentials, path, error_msg) if check_errors && !status.success?
182
- stdout_with_no_credentials
173
+ filtered_out = URICredentialsFilter.credential_filtered_string(out, uri)
174
+
175
+ raise GitCommandError.new(command_with_no_credentials, dir || SharedHelpers.pwd, filtered_out) unless status.success?
176
+
177
+ filtered_out
183
178
  end
184
179
 
185
180
  def has_revision_cached?
186
181
  return unless @revision
187
- in_path { git("cat-file -e #{@revision}") }
182
+ with_path { git("cat-file", "-e", @revision, :dir => path) }
188
183
  true
189
184
  rescue GitError
190
185
  false
@@ -195,23 +190,11 @@ module Bundler
195
190
  end
196
191
 
197
192
  def find_local_revision
198
- allowed_in_path do
199
- git("rev-parse --verify #{Shellwords.shellescape(ref)}", true).strip
200
- end
201
- end
202
-
203
- # Escape the URI for git commands
204
- def uri_escaped_with_configured_credentials
205
- remote = configured_uri_for(uri)
206
- if Bundler::WINDOWS
207
- # Windows quoting requires double quotes only, with double quotes
208
- # inside the string escaped by being doubled.
209
- '"' + remote.gsub('"') { '""' } + '"'
210
- else
211
- # Bash requires single quoted strings, with the single quotes escaped
212
- # by ending the string, escaping the quote, and restarting the string.
213
- "'" + remote.gsub("'") { "'\\''" } + "'"
193
+ allowed_with_path do
194
+ git("rev-parse", "--verify", ref || "HEAD", :dir => path).strip
214
195
  end
196
+ rescue GitCommandError => e
197
+ raise MissingGitRevisionError.new(e.command, path, ref, URICredentialsFilter.credential_filtered_uri(uri))
215
198
  end
216
199
 
217
200
  # Adds credentials to the URI as Fetcher#configured_uri_for does
@@ -230,29 +213,48 @@ module Bundler
230
213
  @git ? @git.allow_git_ops? : true
231
214
  end
232
215
 
233
- def in_path(&blk)
216
+ def with_path(&blk)
234
217
  checkout unless path.exist?
235
- _ = URICredentialsFilter # load it before we chdir
236
- SharedHelpers.chdir(path, &blk)
218
+ blk.call
237
219
  end
238
220
 
239
- def allowed_in_path
240
- return in_path { yield } if allow?
221
+ def allowed_with_path
222
+ return with_path { yield } if allow?
241
223
  raise GitError, "The git source #{uri} is not yet checked out. Please run `bundle install` before trying to start your application"
242
224
  end
243
225
 
244
- def capture_and_filter_stderr(uri, cmd)
226
+ def check_allowed(command)
227
+ command_with_no_credentials = URICredentialsFilter.credential_filtered_string("git #{command.shelljoin}", uri)
228
+ raise GitNotAllowedError.new(command_with_no_credentials) unless allow?
229
+ command_with_no_credentials
230
+ end
231
+
232
+ def capture_and_filter_stderr(*cmd)
245
233
  require "open3"
246
- return_value, captured_err, status = Open3.capture3(cmd)
247
- Bundler.ui.warn URICredentialsFilter.credential_filtered_string(captured_err, uri) if uri && !captured_err.empty?
234
+ return_value, captured_err, status = Open3.capture3(*cmd)
235
+ Bundler.ui.warn URICredentialsFilter.credential_filtered_string(captured_err, uri) unless captured_err.empty?
248
236
  [return_value, status]
249
237
  end
250
238
 
251
- def capture_and_ignore_stderr(cmd)
239
+ def capture_and_ignore_stderr(*cmd)
252
240
  require "open3"
253
- return_value, _, status = Open3.capture3(cmd)
241
+ return_value, _, status = Open3.capture3(*cmd)
254
242
  [return_value, status]
255
243
  end
244
+
245
+ def capture3_args_for(cmd, dir)
246
+ return ["git", *cmd] unless dir
247
+
248
+ if Bundler.feature_flag.bundler_3_mode? || supports_minus_c?
249
+ ["git", "-C", dir.to_s, *cmd]
250
+ else
251
+ ["git", *cmd, { :chdir => dir.to_s }]
252
+ end
253
+ end
254
+
255
+ def supports_minus_c?
256
+ @supports_minus_c ||= Gem::Version.new(version) >= Gem::Version.new("1.8.5")
257
+ end
256
258
  end
257
259
  end
258
260
  end
@@ -22,7 +22,7 @@ module Bundler
22
22
  @uri = options["uri"] || ""
23
23
  @safe_uri = URICredentialsFilter.credential_filtered_uri(@uri)
24
24
  @branch = options["branch"]
25
- @ref = options["ref"] || options["branch"] || options["tag"] || "master"
25
+ @ref = options["ref"] || options["branch"] || options["tag"]
26
26
  @submodules = options["submodules"]
27
27
  @name = options["name"]
28
28
  @version = options["version"].to_s.strip.gsub("-", ".pre.")
@@ -60,25 +60,27 @@ module Bundler
60
60
  alias_method :==, :eql?
61
61
 
62
62
  def to_s
63
- at = if local?
64
- path
65
- elsif user_ref = options["ref"]
66
- if ref =~ /\A[a-z0-9]{4,}\z/i
67
- shortref_for_display(user_ref)
63
+ begin
64
+ at = if local?
65
+ path
66
+ elsif user_ref = options["ref"]
67
+ if ref =~ /\A[a-z0-9]{4,}\z/i
68
+ shortref_for_display(user_ref)
69
+ else
70
+ user_ref
71
+ end
72
+ elsif ref
73
+ ref
68
74
  else
69
- user_ref
75
+ git_proxy.branch
70
76
  end
71
- else
72
- ref
73
- end
74
77
 
75
- rev = begin
76
- "@#{shortref_for_display(revision)}"
77
- rescue GitError
78
- nil
79
- end
78
+ rev = " (at #{at}@#{shortref_for_display(revision)})"
79
+ rescue GitError
80
+ ""
81
+ end
80
82
 
81
- "#{@safe_uri} (at #{at}#{rev})"
83
+ "#{@safe_uri}#{rev}"
82
84
  end
83
85
 
84
86
  def name
@@ -146,7 +148,7 @@ module Bundler
146
148
 
147
149
  changed = cached_revision && cached_revision != git_proxy.revision
148
150
 
149
- if changed && !@unlocked && !git_proxy.contains?(cached_revision)
151
+ if !Bundler.settings[:disable_local_revision_check] && changed && !@unlocked && !git_proxy.contains?(cached_revision)
150
152
  raise GitError, "The Gemfile lock is pointing to revision #{shortref_for_display(cached_revision)} " \
151
153
  "but the current branch in your local override for #{name} does not contain such commit. " \
152
154
  "Please make sure your branch is up to date."
@@ -230,7 +232,11 @@ module Bundler
230
232
  @allow_remote || @allow_cached
231
233
  end
232
234
 
233
- private
235
+ def local?
236
+ @local
237
+ end
238
+
239
+ private
234
240
 
235
241
  def serialize_gemspecs_in(destination)
236
242
  destination = destination.expand_path(Bundler.root) if destination.relative?
@@ -256,10 +262,6 @@ module Bundler
256
262
  cached_revision && super
257
263
  end
258
264
 
259
- def local?
260
- @local
261
- end
262
-
263
265
  def requires_checkout?
264
266
  allow_git_ops? && !local? && !cached_revision_checked_out?
265
267
  end
@@ -33,10 +33,6 @@ module Bundler
33
33
  end
34
34
  end
35
35
 
36
- def cached!; end
37
-
38
- def remote!; end
39
-
40
36
  def options
41
37
  {}
42
38
  end
@@ -1,5 +1,7 @@
1
1
  # frozen_string_literal: true
2
2
 
3
+ require_relative "../../rubygems_gem_installer"
4
+
3
5
  module Bundler
4
6
  class Source
5
7
  class Path
@@ -26,23 +28,21 @@ module Bundler
26
28
  end
27
29
 
28
30
  def post_install
29
- SharedHelpers.chdir(@gem_dir) do
30
- run_hooks(:pre_install)
31
+ run_hooks(:pre_install)
31
32
 
32
- unless @disable_extensions
33
- build_extensions
34
- run_hooks(:post_build)
35
- end
33
+ unless @disable_extensions
34
+ build_extensions
35
+ run_hooks(:post_build)
36
+ end
36
37
 
37
- generate_bin unless spec.executables.nil? || spec.executables.empty?
38
+ generate_bin unless spec.executables.empty?
38
39
 
39
- run_hooks(:post_install)
40
- end
40
+ run_hooks(:post_install)
41
41
  ensure
42
42
  Bundler.rm_rf(@tmp_dir) if Bundler.requires_sudo?
43
43
  end
44
44
 
45
- private
45
+ private
46
46
 
47
47
  def generate_bin
48
48
  super
@@ -82,7 +82,9 @@ module Bundler
82
82
  end
83
83
 
84
84
  def install(spec, options = {})
85
- print_using_message "Using #{version_message(spec)} from #{self}"
85
+ using_message = "Using #{version_message(spec)} from #{self}"
86
+ using_message += " and installing its executables" unless spec.executables.empty?
87
+ print_using_message using_message
86
88
  generate_bin(spec, :disable_extensions => true)
87
89
  nil # no post-install message
88
90
  end
@@ -125,14 +127,18 @@ module Bundler
125
127
  @expanded_original_path ||= expand(original_path)
126
128
  end
127
129
 
128
- private
130
+ private
129
131
 
130
132
  def expanded_path
131
133
  @expanded_path ||= expand(path)
132
134
  end
133
135
 
134
136
  def expand(somepath)
135
- somepath.expand_path(root_path)
137
+ if Bundler.current_ruby.jruby? # TODO: Unify when https://github.com/rubygems/bundler/issues/7598 fixed upstream and all supported jrubies include the fix
138
+ somepath.expand_path(root_path).expand_path
139
+ else
140
+ somepath.expand_path(root_path)
141
+ end
136
142
  rescue ArgumentError => e
137
143
  Bundler.ui.debug(e)
138
144
  raise PathError, "There was an error while trying to use the path " \
@@ -167,7 +173,7 @@ module Bundler
167
173
 
168
174
  if File.directory?(expanded_path)
169
175
  # We sort depth-first since `<<` will override the earlier-found specs
170
- Dir["#{expanded_path}/#{@glob}"].sort_by {|p| -p.split(File::SEPARATOR).size }.each do |file|
176
+ Gem::Util.glob_files_in_dir(@glob, expanded_path).sort_by {|p| -p.split(File::SEPARATOR).size }.each do |file|
171
177
  next unless spec = load_gemspec(file)
172
178
  spec.source = self
173
179
 
@@ -39,7 +39,7 @@ module Bundler
39
39
  "rubygems remote at #{anonymized_uri}"
40
40
  end
41
41
 
42
- private
42
+ private
43
43
 
44
44
  def apply_auth(uri, auth)
45
45
  if auth && uri.userinfo.nil?
@@ -20,17 +20,29 @@ module Bundler
20
20
  @dependency_names = []
21
21
  @allow_remote = false
22
22
  @allow_cached = false
23
+ @allow_local = options["allow_local"] || false
23
24
  @caches = [cache_path, *Bundler.rubygems.gem_cache]
24
25
 
25
- Array(options["remotes"] || []).reverse_each {|r| add_remote(r) }
26
+ Array(options["remotes"]).reverse_each {|r| add_remote(r) }
27
+ end
28
+
29
+ def local!
30
+ return if @allow_local
31
+
32
+ @specs = nil
33
+ @allow_local = true
26
34
  end
27
35
 
28
36
  def remote!
37
+ return if @allow_remote
38
+
29
39
  @specs = nil
30
40
  @allow_remote = true
31
41
  end
32
42
 
33
43
  def cached!
44
+ return if @allow_cached
45
+
34
46
  @specs = nil
35
47
  @allow_cached = true
36
48
  end
@@ -49,8 +61,12 @@ module Bundler
49
61
  o.is_a?(Rubygems) && (o.credless_remotes - credless_remotes).empty?
50
62
  end
51
63
 
64
+ def disable_multisource?
65
+ @remotes.size <= 1
66
+ end
67
+
52
68
  def can_lock?(spec)
53
- return super if Bundler.feature_flag.disable_multisource?
69
+ return super if disable_multisource?
54
70
  spec.source.is_a?(Rubygems)
55
71
  end
56
72
 
@@ -87,7 +103,7 @@ module Bundler
87
103
  # small_idx.use large_idx.
88
104
  idx = @allow_remote ? remote_specs.dup : Index.new
89
105
  idx.use(cached_specs, :override_dupes) if @allow_cached || @allow_remote
90
- idx.use(installed_specs, :override_dupes)
106
+ idx.use(installed_specs, :override_dupes) if @allow_local
91
107
  idx
92
108
  end
93
109
  end
@@ -145,20 +161,19 @@ module Bundler
145
161
 
146
162
  Bundler.mkdir_p bin_path, :no_sudo => true unless spec.executables.empty? || Bundler.rubygems.provides?(">= 2.7.5")
147
163
 
148
- installed_spec = nil
149
- Bundler.rubygems.preserve_paths do
150
- installed_spec = Bundler::RubyGemsGemInstaller.at(
151
- path,
152
- :install_dir => install_path.to_s,
153
- :bin_dir => bin_path.to_s,
154
- :ignore_dependencies => true,
155
- :wrappers => true,
156
- :env_shebang => true,
157
- :build_args => opts[:build_args],
158
- :bundler_expected_checksum => spec.respond_to?(:checksum) && spec.checksum,
159
- :bundler_extension_cache_path => extension_cache_path(spec)
160
- ).install
161
- end
164
+ require_relative "../rubygems_gem_installer"
165
+
166
+ installed_spec = Bundler::RubyGemsGemInstaller.at(
167
+ path,
168
+ :install_dir => install_path.to_s,
169
+ :bin_dir => bin_path.to_s,
170
+ :ignore_dependencies => true,
171
+ :wrappers => true,
172
+ :env_shebang => true,
173
+ :build_args => opts[:build_args],
174
+ :bundler_expected_checksum => spec.respond_to?(:checksum) && spec.checksum,
175
+ :bundler_extension_cache_path => extension_cache_path(spec)
176
+ ).install
162
177
  spec.full_gem_path = installed_spec.full_gem_path
163
178
 
164
179
  # SUDO HAX
@@ -244,8 +259,16 @@ module Bundler
244
259
  !equivalent
245
260
  end
246
261
 
262
+ def spec_names
263
+ if @allow_remote && dependency_api_available?
264
+ remote_specs.spec_names
265
+ else
266
+ []
267
+ end
268
+ end
269
+
247
270
  def unmet_deps
248
- if @allow_remote && api_fetchers.any?
271
+ if @allow_remote && dependency_api_available?
249
272
  remote_specs.unmet_dependency_names
250
273
  else
251
274
  []
@@ -261,7 +284,7 @@ module Bundler
261
284
 
262
285
  def double_check_for(unmet_dependency_names)
263
286
  return unless @allow_remote
264
- return unless api_fetchers.any?
287
+ return unless dependency_api_available?
265
288
 
266
289
  unmet_dependency_names = unmet_dependency_names.call
267
290
  unless unmet_dependency_names.nil?
@@ -283,18 +306,21 @@ module Bundler
283
306
  remote_specs.each do |spec|
284
307
  case spec
285
308
  when EndpointSpecification, Gem::Specification, StubSpecification, LazySpecification
286
- names.concat(spec.runtime_dependencies)
309
+ names.concat(spec.runtime_dependencies.map(&:name))
287
310
  when RemoteSpecification # from the full index
288
311
  return nil
289
312
  else
290
313
  raise "unhandled spec type (#{spec.inspect})"
291
314
  end
292
315
  end
293
- names.map!(&:name) if names
294
316
  names
295
317
  end
296
318
 
297
- protected
319
+ def dependency_api_available?
320
+ api_fetchers.any?
321
+ end
322
+
323
+ protected
298
324
 
299
325
  def credless_remotes
300
326
  remotes.map(&method(:suppress_configured_credentials))
@@ -354,7 +380,6 @@ module Bundler
354
380
  def installed_specs
355
381
  @installed_specs ||= Index.build do |idx|
356
382
  Bundler.rubygems.all_specs.reverse_each do |spec|
357
- next if spec.name == "bundler"
358
383
  spec.source = self
359
384
  if Bundler.rubygems.spec_missing_extensions?(spec, false)
360
385
  Bundler.ui.debug "Source #{self} is ignoring #{spec} because it is missing extensions"
@@ -367,7 +392,7 @@ module Bundler
367
392
 
368
393
  def cached_specs
369
394
  @cached_specs ||= begin
370
- idx = installed_specs.dup
395
+ idx = @allow_local ? installed_specs.dup : Index.new
371
396
 
372
397
  Dir["#{cache_path}/*.gem"].each do |gemfile|
373
398
  next if gemfile =~ /^bundler\-[\d\.]+?\.gem/
@@ -409,11 +434,11 @@ module Bundler
409
434
  def fetch_names(fetchers, dependency_names, index, override_dupes)
410
435
  fetchers.each do |f|
411
436
  if dependency_names
412
- Bundler.ui.info "Fetching gem metadata from #{f.uri}", Bundler.ui.debug?
437
+ Bundler.ui.info "Fetching gem metadata from #{URICredentialsFilter.credential_filtered_uri(f.uri)}", Bundler.ui.debug?
413
438
  index.use f.specs_with_retry(dependency_names, self), override_dupes
414
439
  Bundler.ui.info "" unless Bundler.ui.debug? # new line now that the dots are over
415
440
  else
416
- Bundler.ui.info "Fetching source index from #{f.uri}"
441
+ Bundler.ui.info "Fetching source index from #{URICredentialsFilter.credential_filtered_uri(f.uri)}"
417
442
  index.use f.specs_with_retry(nil, self), override_dupes
418
443
  end
419
444
  end
@@ -468,7 +493,7 @@ module Bundler
468
493
  Bundler.app_cache
469
494
  end
470
495
 
471
- private
496
+ private
472
497
 
473
498
  # Checks if the requested spec exists in the global cache. If it does,
474
499
  # we copy it to the download path, and if it does not, we download it.
@@ -490,8 +515,15 @@ module Bundler
490
515
  uri = spec.remote.uri
491
516
  Bundler.ui.confirm("Fetching #{version_message(spec)}")
492
517
  rubygems_local_path = Bundler.rubygems.download_gem(spec, uri, download_path)
518
+
519
+ # older rubygems return varying file:// variants depending on version
520
+ rubygems_local_path = rubygems_local_path.gsub(/\Afile:/, "") unless Bundler.rubygems.provides?(">= 3.2.0.rc.2")
521
+ rubygems_local_path = rubygems_local_path.gsub(%r{\A//}, "") if Bundler.rubygems.provides?("< 3.1.0")
522
+
493
523
  if rubygems_local_path != local_path
494
- FileUtils.mv(rubygems_local_path, local_path)
524
+ SharedHelpers.filesystem_access(local_path) do
525
+ FileUtils.mv(rubygems_local_path, local_path)
526
+ end
495
527
  end
496
528
  cache_globally(spec, local_path)
497
529
  end