bundler 2.5.17 → 2.5.21

Sign up to get free protection for your applications and to get access to all the features.
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.