bundler 2.5.17 → 2.5.21

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 (72) hide show
  1. checksums.yaml +4 -4
  2. data/CHANGELOG.md +68 -0
  3. data/lib/bundler/build_metadata.rb +2 -2
  4. data/lib/bundler/cli/add.rb +1 -1
  5. data/lib/bundler/cli/gem.rb +4 -1
  6. data/lib/bundler/cli/install.rb +9 -4
  7. data/lib/bundler/cli/lock.rb +5 -5
  8. data/lib/bundler/cli/outdated.rb +16 -18
  9. data/lib/bundler/definition.rb +15 -26
  10. data/lib/bundler/dsl.rb +27 -17
  11. data/lib/bundler/errors.rb +7 -5
  12. data/lib/bundler/fetcher.rb +2 -2
  13. data/lib/bundler/inline.rb +30 -9
  14. data/lib/bundler/installer/gem_installer.rb +4 -2
  15. data/lib/bundler/installer/parallel_installer.rb +3 -2
  16. data/lib/bundler/installer.rb +9 -11
  17. data/lib/bundler/lockfile_parser.rb +1 -1
  18. data/lib/bundler/man/bundle-add.1 +27 -16
  19. data/lib/bundler/man/bundle-add.1.ronn +37 -14
  20. data/lib/bundler/man/bundle-binstubs.1 +1 -1
  21. data/lib/bundler/man/bundle-cache.1 +1 -1
  22. data/lib/bundler/man/bundle-check.1 +1 -1
  23. data/lib/bundler/man/bundle-clean.1 +1 -1
  24. data/lib/bundler/man/bundle-config.1 +1 -1
  25. data/lib/bundler/man/bundle-console.1 +1 -1
  26. data/lib/bundler/man/bundle-doctor.1 +1 -1
  27. data/lib/bundler/man/bundle-exec.1 +1 -1
  28. data/lib/bundler/man/bundle-gem.1 +1 -1
  29. data/lib/bundler/man/bundle-help.1 +1 -1
  30. data/lib/bundler/man/bundle-info.1 +1 -1
  31. data/lib/bundler/man/bundle-init.1 +1 -1
  32. data/lib/bundler/man/bundle-inject.1 +1 -1
  33. data/lib/bundler/man/bundle-install.1 +1 -1
  34. data/lib/bundler/man/bundle-list.1 +1 -1
  35. data/lib/bundler/man/bundle-lock.1 +1 -1
  36. data/lib/bundler/man/bundle-open.1 +1 -1
  37. data/lib/bundler/man/bundle-outdated.1 +1 -1
  38. data/lib/bundler/man/bundle-platform.1 +1 -1
  39. data/lib/bundler/man/bundle-plugin.1 +1 -1
  40. data/lib/bundler/man/bundle-pristine.1 +1 -1
  41. data/lib/bundler/man/bundle-remove.1 +1 -1
  42. data/lib/bundler/man/bundle-show.1 +1 -1
  43. data/lib/bundler/man/bundle-update.1 +1 -1
  44. data/lib/bundler/man/bundle-version.1 +1 -1
  45. data/lib/bundler/man/bundle-viz.1 +1 -1
  46. data/lib/bundler/man/bundle.1 +1 -1
  47. data/lib/bundler/man/gemfile.5 +3 -1
  48. data/lib/bundler/man/gemfile.5.ronn +6 -0
  49. data/lib/bundler/resolver/base.rb +6 -0
  50. data/lib/bundler/resolver/package.rb +10 -1
  51. data/lib/bundler/resolver.rb +31 -9
  52. data/lib/bundler/retry.rb +1 -1
  53. data/lib/bundler/ruby_version.rb +7 -1
  54. data/lib/bundler/rubygems_ext.rb +43 -16
  55. data/lib/bundler/rubygems_gem_installer.rb +4 -3
  56. data/lib/bundler/self_manager.rb +4 -4
  57. data/lib/bundler/source/git/git_proxy.rb +6 -2
  58. data/lib/bundler/source/git.rb +21 -6
  59. data/lib/bundler/source/path.rb +2 -0
  60. data/lib/bundler/source/rubygems.rb +5 -12
  61. data/lib/bundler/stub_specification.rb +2 -2
  62. data/lib/bundler/templates/newgem/README.md.tt +6 -2
  63. data/lib/bundler/ui/shell.rb +24 -2
  64. data/lib/bundler/ui/silent.rb +12 -1
  65. data/lib/bundler/vendor/securerandom/.document +1 -0
  66. data/lib/bundler/vendor/securerandom/LICENSE.txt +22 -0
  67. data/lib/bundler/vendor/securerandom/lib/random/formatter.rb +373 -0
  68. data/lib/bundler/vendor/securerandom/lib/securerandom.rb +96 -0
  69. data/lib/bundler/vendored_securerandom.rb +14 -0
  70. data/lib/bundler/version.rb +1 -1
  71. data/lib/bundler.rb +30 -22
  72. metadata +8 -3
@@ -30,24 +30,32 @@ module Gem
30
30
  end
31
31
  end
32
32
 
33
- # Can be removed once RubyGems 3.5.14 support is dropped
34
- unless Gem.respond_to?(:open_file_with_flock)
35
- def self.open_file_with_flock(path, &block)
36
- flags = File.exist?(path) ? "r+" : "a+"
37
-
38
- File.open(path, flags) do |io|
39
- begin
40
- io.flock(File::LOCK_EX)
41
- rescue Errno::ENOSYS, Errno::ENOTSUP
42
- end
43
- yield io
44
- rescue Errno::ENOLCK # NFS
45
- if Thread.main != Thread.current
46
- raise
47
- else
48
- File.open(path, flags, &block)
33
+ # Can be removed once RubyGems 3.5.18 support is dropped
34
+ unless Gem.respond_to?(:open_file_with_lock)
35
+ class << self
36
+ remove_method :open_file_with_flock if Gem.respond_to?(:open_file_with_flock)
37
+
38
+ def open_file_with_flock(path, &block)
39
+ mode = IO::RDONLY | IO::APPEND | IO::CREAT | IO::BINARY
40
+ mode |= IO::SHARE_DELETE if IO.const_defined?(:SHARE_DELETE)
41
+
42
+ File.open(path, mode) do |io|
43
+ begin
44
+ io.flock(File::LOCK_EX)
45
+ rescue Errno::ENOSYS, Errno::ENOTSUP
46
+ rescue Errno::ENOLCK # NFS
47
+ raise unless Thread.main == Thread.current
48
+ end
49
+ yield io
49
50
  end
50
51
  end
52
+
53
+ def open_file_with_lock(path, &block)
54
+ file_lock = "#{path}.lock"
55
+ open_file_with_flock(file_lock, &block)
56
+ ensure
57
+ FileUtils.rm_f file_lock
58
+ end
51
59
  end
52
60
  end
53
61
 
@@ -407,4 +415,23 @@ module Gem
407
415
  end
408
416
  end
409
417
  end
418
+
419
+ unless Gem.rubygems_version >= Gem::Version.new("3.5.19")
420
+ class Resolver::ActivationRequest
421
+ remove_method :installed?
422
+
423
+ def installed?
424
+ case @spec
425
+ when Gem::Resolver::VendorSpecification then
426
+ true
427
+ else
428
+ this_spec = full_spec
429
+
430
+ Gem::Specification.any? do |s|
431
+ s == this_spec && s.base_dir == this_spec.base_dir
432
+ end
433
+ end
434
+ end
435
+ end
436
+ end
410
437
  end
@@ -81,11 +81,11 @@ module Bundler
81
81
  end
82
82
  end
83
83
 
84
- if Bundler.rubygems.provides?("< 3.5.15")
84
+ if Bundler.rubygems.provides?("< 3.5.19")
85
85
  def generate_bin_script(filename, bindir)
86
86
  bin_script_path = File.join bindir, formatted_program_filename(filename)
87
87
 
88
- Gem.open_file_with_flock("#{bin_script_path}.lock") do
88
+ Gem.open_file_with_lock(bin_script_path) do
89
89
  require "fileutils"
90
90
  FileUtils.rm_f bin_script_path # prior install may have been --no-wrappers
91
91
 
@@ -150,12 +150,13 @@ module Bundler
150
150
 
151
151
  def strict_rm_rf(dir)
152
152
  return unless File.exist?(dir)
153
+ return if Dir.empty?(dir)
153
154
 
154
155
  parent = File.dirname(dir)
155
156
  parent_st = File.stat(parent)
156
157
 
157
158
  if parent_st.world_writable? && !parent_st.sticky?
158
- raise InsecureInstallPathError.new(parent)
159
+ raise InsecureInstallPathError.new(spec.full_name, dir)
159
160
  end
160
161
 
161
162
  begin
@@ -98,10 +98,10 @@ module Bundler
98
98
 
99
99
  def needs_switching?
100
100
  autoswitching_applies? &&
101
- released?(lockfile_version) &&
102
- !running?(lockfile_version) &&
103
- !updating? &&
104
- Bundler.settings[:version] != "system"
101
+ Bundler.settings[:version] != "system" &&
102
+ released?(restart_version) &&
103
+ !running?(restart_version) &&
104
+ !updating?
105
105
  end
106
106
 
107
107
  def autoswitching_applies?
@@ -84,6 +84,12 @@ module Bundler
84
84
  end
85
85
  end
86
86
 
87
+ def not_a_repository?
88
+ _, status = git_null("rev-parse", "--resolve-git-dir", path.to_s, dir: path)
89
+
90
+ !status.success?
91
+ end
92
+
87
93
  def contains?(commit)
88
94
  allowed_with_path do
89
95
  result, status = git_null("branch", "--contains", commit, dir: path)
@@ -332,8 +338,6 @@ module Bundler
332
338
  config_auth = Bundler.settings[remote.to_s] || Bundler.settings[remote.host]
333
339
  remote.userinfo ||= config_auth
334
340
  remote.to_s
335
- elsif File.exist?(uri)
336
- "file://#{uri}"
337
341
  else
338
342
  uri.to_s
339
343
  end
@@ -70,13 +70,13 @@ module Bundler
70
70
  end
71
71
 
72
72
  def hash
73
- [self.class, uri, ref, branch, name, version, glob, submodules].hash
73
+ [self.class, uri, ref, branch, name, glob, submodules].hash
74
74
  end
75
75
 
76
76
  def eql?(other)
77
77
  other.is_a?(Git) && uri == other.uri && ref == other.ref &&
78
78
  branch == other.branch && name == other.name &&
79
- version == other.version && glob == other.glob &&
79
+ glob == other.glob &&
80
80
  submodules == other.submodules
81
81
  end
82
82
 
@@ -188,9 +188,11 @@ module Bundler
188
188
  end
189
189
 
190
190
  def specs(*)
191
- set_cache_path!(app_cache_path) if has_app_cache? && !local?
191
+ set_up_app_cache!(app_cache_path) if use_app_cache?
192
192
 
193
193
  if requires_checkout? && !@copied
194
+ FileUtils.rm_rf(app_cache_path) if use_app_cache? && git_proxy.not_a_repository?
195
+
194
196
  fetch
195
197
  checkout
196
198
  end
@@ -224,6 +226,7 @@ module Bundler
224
226
  git_proxy.checkout if requires_checkout?
225
227
  FileUtils.cp_r("#{cache_path}/.", app_cache_path)
226
228
  FileUtils.touch(app_cache_path.join(".bundlecache"))
229
+ FileUtils.rm_rf(Dir.glob(app_cache_path.join("hooks/*.sample")))
227
230
  end
228
231
 
229
232
  def load_spec_files
@@ -317,10 +320,19 @@ module Bundler
317
320
  @install_path = path
318
321
  end
319
322
 
323
+ def set_up_app_cache!(path)
324
+ FileUtils.mkdir_p(path.join("refs"))
325
+ set_cache_path!(path)
326
+ end
327
+
320
328
  def has_app_cache?
321
329
  cached_revision && super
322
330
  end
323
331
 
332
+ def use_app_cache?
333
+ has_app_cache? && !local?
334
+ end
335
+
324
336
  def requires_checkout?
325
337
  allow_git_ops? && !local? && !cached_revision_checked_out?
326
338
  end
@@ -386,9 +398,12 @@ module Bundler
386
398
  def validate_spec(_spec); end
387
399
 
388
400
  def load_gemspec(file)
389
- stub = Gem::StubSpecification.gemspec_stub(file, install_path.parent, install_path.parent)
390
- stub.full_gem_path = Pathname.new(file).dirname.expand_path(root).to_s
391
- StubSpecification.from_stub(stub)
401
+ dirname = Pathname.new(file).dirname
402
+ SharedHelpers.chdir(dirname.to_s) do
403
+ stub = Gem::StubSpecification.gemspec_stub(file, install_path.parent, install_path.parent)
404
+ stub.full_gem_path = dirname.expand_path(root).to_s
405
+ StubSpecification.from_stub(stub)
406
+ end
392
407
  end
393
408
 
394
409
  def git_scope
@@ -53,6 +53,8 @@ module Bundler
53
53
  "source at `#{@path}`"
54
54
  end
55
55
 
56
+ alias_method :to_gemfile, :path
57
+
56
58
  def hash
57
59
  [self.class, expanded_path, version].hash
58
60
  end
@@ -148,7 +148,7 @@ module Bundler
148
148
  end
149
149
 
150
150
  def install(spec, options = {})
151
- if (spec.default_gem? && !cached_built_in_gem(spec)) || (installed?(spec) && !options[:force])
151
+ if (spec.default_gem? && !cached_built_in_gem(spec, local: options[:local])) || (installed?(spec) && !options[:force])
152
152
  print_using_message "Using #{version_message(spec, options[:previous_spec])}"
153
153
  return nil # no post-install message
154
154
  end
@@ -222,12 +222,13 @@ module Bundler
222
222
  raise InstallError, e.message
223
223
  end
224
224
 
225
- def cached_built_in_gem(spec)
226
- cached_path = cached_path(spec)
227
- if cached_path.nil?
225
+ def cached_built_in_gem(spec, local: false)
226
+ cached_path = cached_gem(spec)
227
+ if cached_path.nil? && !local
228
228
  remote_spec = remote_specs.search(spec).first
229
229
  if remote_spec
230
230
  cached_path = fetch_gem(remote_spec)
231
+ spec.remote = remote_spec.remote
231
232
  else
232
233
  Bundler.ui.warn "#{spec.full_name} is built in to Ruby, and can't be cached because your Gemfile doesn't have any sources that contain it."
233
234
  end
@@ -324,14 +325,6 @@ module Bundler
324
325
  end
325
326
 
326
327
  def cached_gem(spec)
327
- if spec.default_gem?
328
- cached_built_in_gem(spec)
329
- else
330
- cached_path(spec)
331
- end
332
- end
333
-
334
- def cached_path(spec)
335
328
  global_cache_path = download_cache_path(spec)
336
329
  caches << global_cache_path if global_cache_path
337
330
 
@@ -45,8 +45,8 @@ module Bundler
45
45
  true
46
46
  end
47
47
 
48
- def activated
49
- stub.activated
48
+ def activated?
49
+ stub.activated?
50
50
  end
51
51
 
52
52
  def activated=(activated)
@@ -10,11 +10,15 @@ TODO: Replace `UPDATE_WITH_YOUR_GEM_NAME_IMMEDIATELY_AFTER_RELEASE_TO_RUBYGEMS_O
10
10
 
11
11
  Install the gem and add to the application's Gemfile by executing:
12
12
 
13
- $ bundle add UPDATE_WITH_YOUR_GEM_NAME_IMMEDIATELY_AFTER_RELEASE_TO_RUBYGEMS_ORG
13
+ ```bash
14
+ bundle add UPDATE_WITH_YOUR_GEM_NAME_IMMEDIATELY_AFTER_RELEASE_TO_RUBYGEMS_ORG
15
+ ```
14
16
 
15
17
  If bundler is not being used to manage dependencies, install the gem by executing:
16
18
 
17
- $ gem install UPDATE_WITH_YOUR_GEM_NAME_IMMEDIATELY_AFTER_RELEASE_TO_RUBYGEMS_ORG
19
+ ```bash
20
+ gem install UPDATE_WITH_YOUR_GEM_NAME_IMMEDIATELY_AFTER_RELEASE_TO_RUBYGEMS_ORG
21
+ ```
18
22
 
19
23
  ## Usage
20
24
 
@@ -6,14 +6,17 @@ module Bundler
6
6
  module UI
7
7
  class Shell
8
8
  LEVELS = %w[silent error warn confirm info debug].freeze
9
+ OUTPUT_STREAMS = [:stdout, :stderr].freeze
9
10
 
10
11
  attr_writer :shell
12
+ attr_reader :output_stream
11
13
 
12
14
  def initialize(options = {})
13
15
  Thor::Base.shell = options["no-color"] ? Thor::Shell::Basic : nil
14
16
  @shell = Thor::Base.shell.new
15
17
  @level = ENV["DEBUG"] ? "debug" : "info"
16
18
  @warning_history = []
19
+ @output_stream = :stdout
17
20
  end
18
21
 
19
22
  def add_color(string, *color)
@@ -84,7 +87,7 @@ module Bundler
84
87
  @shell.yes?(msg)
85
88
  end
86
89
 
87
- def no?
90
+ def no?(msg)
88
91
  @shell.no?(msg)
89
92
  end
90
93
 
@@ -101,6 +104,11 @@ module Bundler
101
104
  index <= LEVELS.index(@level)
102
105
  end
103
106
 
107
+ def output_stream=(symbol)
108
+ raise ArgumentError unless OUTPUT_STREAMS.include?(symbol)
109
+ @output_stream = symbol
110
+ end
111
+
104
112
  def trace(e, newline = nil, force = false)
105
113
  return unless debug? || force
106
114
  msg = "#{e.class}: #{e.message}\n#{e.backtrace.join("\n ")}"
@@ -111,6 +119,10 @@ module Bundler
111
119
  with_level("silent", &blk)
112
120
  end
113
121
 
122
+ def progress(&blk)
123
+ with_output_stream(:stderr, &blk)
124
+ end
125
+
114
126
  def unprinted_warnings
115
127
  []
116
128
  end
@@ -119,6 +131,8 @@ module Bundler
119
131
 
120
132
  # valimism
121
133
  def tell_me(msg, color = nil, newline = nil)
134
+ return tell_err(msg, color, newline) if output_stream == :stderr
135
+
122
136
  msg = word_wrap(msg) if newline.is_a?(Hash) && newline[:wrap]
123
137
  if newline.nil?
124
138
  @shell.say(msg, color)
@@ -130,7 +144,7 @@ module Bundler
130
144
  def tell_err(message, color = nil, newline = nil)
131
145
  return if @shell.send(:stderr).closed?
132
146
 
133
- newline ||= !message.to_s.match?(/( |\t)\Z/)
147
+ newline = !message.to_s.match?(/( |\t)\Z/) if newline.nil?
134
148
  message = word_wrap(message) if newline.is_a?(Hash) && newline[:wrap]
135
149
 
136
150
  color = nil if color && !$stderr.tty?
@@ -160,6 +174,14 @@ module Bundler
160
174
  ensure
161
175
  @level = original
162
176
  end
177
+
178
+ def with_output_stream(symbol)
179
+ original = output_stream
180
+ self.output_stream = symbol
181
+ yield
182
+ ensure
183
+ @output_stream = original
184
+ end
163
185
  end
164
186
  end
165
187
  end
@@ -53,6 +53,13 @@ module Bundler
53
53
  false
54
54
  end
55
55
 
56
+ def output_stream=(_symbol)
57
+ end
58
+
59
+ def output_stream
60
+ nil
61
+ end
62
+
56
63
  def ask(message)
57
64
  end
58
65
 
@@ -60,7 +67,7 @@ module Bundler
60
67
  raise "Cannot ask yes? with a silent shell"
61
68
  end
62
69
 
63
- def no?
70
+ def no?(msg)
64
71
  raise "Cannot ask no? with a silent shell"
65
72
  end
66
73
 
@@ -77,6 +84,10 @@ module Bundler
77
84
  yield
78
85
  end
79
86
 
87
+ def progress
88
+ yield
89
+ end
90
+
80
91
  def unprinted_warnings
81
92
  @warnings
82
93
  end
@@ -0,0 +1 @@
1
+ # Vendored files do not need to be documented
@@ -0,0 +1,22 @@
1
+ Copyright (C) 1993-2013 Yukihiro Matsumoto. All rights reserved.
2
+
3
+ Redistribution and use in source and binary forms, with or without
4
+ modification, are permitted provided that the following conditions
5
+ are met:
6
+ 1. Redistributions of source code must retain the above copyright
7
+ notice, this list of conditions and the following disclaimer.
8
+ 2. Redistributions in binary form must reproduce the above copyright
9
+ notice, this list of conditions and the following disclaimer in the
10
+ documentation and/or other materials provided with the distribution.
11
+
12
+ THIS SOFTWARE IS PROVIDED BY THE AUTHOR AND CONTRIBUTORS ``AS IS'' AND
13
+ ANY EXPRESS OR IMPLIED WARRANTIES, INCLUDING, BUT NOT LIMITED TO, THE
14
+ IMPLIED WARRANTIES OF MERCHANTABILITY AND FITNESS FOR A PARTICULAR PURPOSE
15
+ ARE DISCLAIMED. IN NO EVENT SHALL THE AUTHOR OR CONTRIBUTORS BE LIABLE
16
+ FOR ANY DIRECT, INDIRECT, INCIDENTAL, SPECIAL, EXEMPLARY, OR CONSEQUENTIAL
17
+ DAMAGES (INCLUDING, BUT NOT LIMITED TO, PROCUREMENT OF SUBSTITUTE GOODS
18
+ OR SERVICES; LOSS OF USE, DATA, OR PROFITS; OR BUSINESS INTERRUPTION)
19
+ HOWEVER CAUSED AND ON ANY THEORY OF LIABILITY, WHETHER IN CONTRACT, STRICT
20
+ LIABILITY, OR TORT (INCLUDING NEGLIGENCE OR OTHERWISE) ARISING IN ANY WAY
21
+ OUT OF THE USE OF THIS SOFTWARE, EVEN IF ADVISED OF THE POSSIBILITY OF
22
+ SUCH DAMAGE.