bundler 2.2.29 → 2.2.33

Sign up to get free protection for your applications and to get access to all the features.
Files changed (90) hide show
  1. checksums.yaml +4 -4
  2. data/CHANGELOG.md +79 -1
  3. data/README.md +1 -1
  4. data/lib/bundler/build_metadata.rb +2 -2
  5. data/lib/bundler/cli/doctor.rb +3 -2
  6. data/lib/bundler/cli/gem.rb +69 -7
  7. data/lib/bundler/cli/info.rb +16 -4
  8. data/lib/bundler/cli/issue.rb +4 -3
  9. data/lib/bundler/cli/update.rb +2 -2
  10. data/lib/bundler/cli.rb +4 -1
  11. data/lib/bundler/compact_index_client/updater.rb +0 -5
  12. data/lib/bundler/compact_index_client.rb +2 -2
  13. data/lib/bundler/definition.rb +62 -124
  14. data/lib/bundler/digest.rb +71 -0
  15. data/lib/bundler/dsl.rb +18 -3
  16. data/lib/bundler/environment_preserver.rb +4 -1
  17. data/lib/bundler/errors.rb +18 -2
  18. data/lib/bundler/fetcher.rb +2 -1
  19. data/lib/bundler/friendly_errors.rb +5 -30
  20. data/lib/bundler/gem_helper.rb +5 -16
  21. data/lib/bundler/lazy_specification.rb +17 -1
  22. data/lib/bundler/lockfile_parser.rb +1 -0
  23. data/lib/bundler/man/bundle-add.1 +1 -1
  24. data/lib/bundler/man/bundle-binstubs.1 +1 -1
  25. data/lib/bundler/man/bundle-cache.1 +1 -1
  26. data/lib/bundler/man/bundle-check.1 +1 -1
  27. data/lib/bundler/man/bundle-clean.1 +1 -1
  28. data/lib/bundler/man/bundle-config.1 +3 -3
  29. data/lib/bundler/man/bundle-config.1.ronn +2 -2
  30. data/lib/bundler/man/bundle-doctor.1 +1 -1
  31. data/lib/bundler/man/bundle-exec.1 +1 -1
  32. data/lib/bundler/man/bundle-gem.1 +14 -1
  33. data/lib/bundler/man/bundle-gem.1.ronn +16 -0
  34. data/lib/bundler/man/bundle-info.1 +1 -1
  35. data/lib/bundler/man/bundle-init.1 +1 -1
  36. data/lib/bundler/man/bundle-inject.1 +1 -1
  37. data/lib/bundler/man/bundle-install.1 +1 -1
  38. data/lib/bundler/man/bundle-list.1 +1 -1
  39. data/lib/bundler/man/bundle-lock.1 +1 -1
  40. data/lib/bundler/man/bundle-open.1 +1 -1
  41. data/lib/bundler/man/bundle-outdated.1 +1 -1
  42. data/lib/bundler/man/bundle-platform.1 +1 -1
  43. data/lib/bundler/man/bundle-pristine.1 +1 -1
  44. data/lib/bundler/man/bundle-remove.1 +1 -1
  45. data/lib/bundler/man/bundle-show.1 +1 -1
  46. data/lib/bundler/man/bundle-update.1 +1 -1
  47. data/lib/bundler/man/bundle-viz.1 +1 -1
  48. data/lib/bundler/man/bundle.1 +1 -1
  49. data/lib/bundler/man/gemfile.5 +27 -1
  50. data/lib/bundler/man/gemfile.5.ronn +8 -0
  51. data/lib/bundler/plugin/api/source.rb +1 -0
  52. data/lib/bundler/resolver.rb +2 -4
  53. data/lib/bundler/rubygems_ext.rb +4 -0
  54. data/lib/bundler/rubygems_gem_installer.rb +20 -4
  55. data/lib/bundler/rubygems_integration.rb +26 -9
  56. data/lib/bundler/runtime.rb +2 -2
  57. data/lib/bundler/shared_helpers.rb +2 -3
  58. data/lib/bundler/source/git/git_proxy.rb +7 -4
  59. data/lib/bundler/source/git.rb +3 -1
  60. data/lib/bundler/source/rubygems.rb +52 -84
  61. data/lib/bundler/source/rubygems_aggregate.rb +1 -1
  62. data/lib/bundler/source.rb +1 -1
  63. data/lib/bundler/source_list.rb +7 -29
  64. data/lib/bundler/spec_set.rb +1 -1
  65. data/lib/bundler/templates/newgem/Gemfile.tt +5 -2
  66. data/lib/bundler/templates/newgem/Rakefile.tt +5 -1
  67. data/lib/bundler/templates/newgem/github/workflows/main.yml.tt +2 -2
  68. data/lib/bundler/templates/newgem/newgem.gemspec.tt +12 -12
  69. data/lib/bundler/templates/newgem/sig/newgem.rbs.tt +8 -0
  70. data/lib/bundler/templates/newgem/standard.yml.tt +2 -0
  71. data/lib/bundler/vendor/.document +1 -0
  72. data/lib/bundler/vendor/connection_pool/LICENSE +20 -0
  73. data/lib/bundler/vendor/connection_pool/lib/connection_pool/timed_stack.rb +19 -21
  74. data/lib/bundler/vendor/connection_pool/lib/connection_pool/version.rb +1 -1
  75. data/lib/bundler/vendor/connection_pool/lib/connection_pool/wrapper.rb +57 -0
  76. data/lib/bundler/vendor/connection_pool/lib/connection_pool.rb +39 -74
  77. data/lib/bundler/vendor/fileutils/LICENSE.txt +22 -0
  78. data/lib/bundler/vendor/molinillo/LICENSE +9 -0
  79. data/lib/bundler/vendor/molinillo/lib/molinillo/dependency_graph.rb +2 -2
  80. data/lib/bundler/vendor/net-http-persistent/README.rdoc +82 -0
  81. data/lib/bundler/vendor/thor/LICENSE.md +20 -0
  82. data/lib/bundler/vendor/tsort/LICENSE.txt +22 -0
  83. data/lib/bundler/vendor/tsort/lib/tsort.rb +453 -0
  84. data/lib/bundler/vendor/uri/LICENSE.txt +22 -0
  85. data/lib/bundler/vendored_tsort.rb +4 -0
  86. data/lib/bundler/version.rb +1 -1
  87. data/lib/bundler/worker.rb +2 -2
  88. data/lib/bundler.rb +2 -1
  89. metadata +20 -7
  90. data/lib/bundler/vendor/connection_pool/lib/connection_pool/monotonic_time.rb +0 -66
@@ -98,26 +98,30 @@ module Bundler
98
98
  out << " specs:\n"
99
99
  end
100
100
 
101
- def to_err
101
+ def to_s
102
102
  if remotes.empty?
103
103
  "locally installed gems"
104
- elsif @allow_remote
104
+ elsif @allow_remote && @allow_cached && @allow_local
105
+ "rubygems repository #{remote_names}, cached gems or installed locally"
106
+ elsif @allow_remote && @allow_local
105
107
  "rubygems repository #{remote_names} or installed locally"
106
- elsif @allow_cached
107
- "cached gems from rubygems repository #{remote_names} or installed locally"
108
+ elsif @allow_remote
109
+ "rubygems repository #{remote_names}"
110
+ elsif @allow_cached && @allow_local
111
+ "cached gems or installed locally"
108
112
  else
109
113
  "locally installed gems"
110
114
  end
111
115
  end
112
116
 
113
- def to_s
117
+ def identifier
114
118
  if remotes.empty?
115
119
  "locally installed gems"
116
120
  else
117
- "rubygems repository #{remote_names} or installed locally"
121
+ "rubygems repository #{remote_names}"
118
122
  end
119
123
  end
120
- alias_method :name, :to_s
124
+ alias_method :name, :identifier
121
125
 
122
126
  def specs
123
127
  @specs ||= begin
@@ -135,7 +139,7 @@ module Bundler
135
139
  force = opts[:force]
136
140
  ensure_builtin_gems_cached = opts[:ensure_builtin_gems_cached]
137
141
 
138
- if ensure_builtin_gems_cached && builtin_gem?(spec)
142
+ if ensure_builtin_gems_cached && spec.default_gem?
139
143
  if !cached_path(spec)
140
144
  cached_built_in_gem(spec) unless spec.remote
141
145
  force = true
@@ -162,7 +166,7 @@ module Bundler
162
166
  begin
163
167
  s = Bundler.rubygems.spec_from_gem(path, Bundler.settings["trust-policy"])
164
168
  spec.__swap__(s)
165
- rescue StandardError
169
+ rescue Gem::Package::FormatError
166
170
  Bundler.rm_rf(path)
167
171
  raise
168
172
  end
@@ -174,6 +178,7 @@ module Bundler
174
178
  Bundler.ui.confirm message
175
179
 
176
180
  path = cached_gem(spec)
181
+ raise GemNotFound, "Could not find #{spec.file_name} for installation" unless path
177
182
  if requires_sudo?
178
183
  install_path = Bundler.tmp(spec.full_name)
179
184
  bin_path = install_path.join("bin")
@@ -233,12 +238,8 @@ module Bundler
233
238
  end
234
239
 
235
240
  def cache(spec, custom_path = nil)
236
- if builtin_gem?(spec)
237
- cached_path = cached_built_in_gem(spec)
238
- else
239
- cached_path = cached_gem(spec)
240
- end
241
- raise GemNotFound, "Missing gem file '#{spec.full_name}.gem'." unless cached_path
241
+ cached_path = cached_gem(spec)
242
+ raise GemNotFound, "Missing gem file '#{spec.file_name}'." unless cached_path
242
243
  return if File.dirname(cached_path) == Bundler.app_cache.to_s
243
244
  Bundler.ui.info " * #{File.basename(cached_path)}"
244
245
  FileUtils.cp(cached_path, Bundler.app_cache(custom_path))
@@ -265,10 +266,6 @@ module Bundler
265
266
  @remotes.unshift(uri) unless @remotes.include?(uri)
266
267
  end
267
268
 
268
- def equivalent_remotes?(other_remotes)
269
- other_remotes.map(&method(:remove_auth)) == @remotes.map(&method(:remove_auth))
270
- end
271
-
272
269
  def spec_names
273
270
  if @allow_remote && dependency_api_available?
274
271
  remote_specs.spec_names
@@ -337,7 +334,11 @@ module Bundler
337
334
  end
338
335
 
339
336
  def credless_remotes
340
- remotes.map(&method(:suppress_configured_credentials))
337
+ if Bundler.settings[:allow_deployment_source_credential_changes]
338
+ remotes.map(&method(:remove_auth))
339
+ else
340
+ remotes.map(&method(:suppress_configured_credentials))
341
+ end
341
342
  end
342
343
 
343
344
  def remotes_for_spec(spec)
@@ -352,14 +353,17 @@ module Bundler
352
353
  end
353
354
 
354
355
  def cached_gem(spec)
355
- cached_gem = cached_path(spec)
356
- unless cached_gem
357
- raise Bundler::GemNotFound, "Could not find #{spec.file_name} for installation"
356
+ if spec.default_gem?
357
+ cached_built_in_gem(spec)
358
+ else
359
+ cached_path(spec)
358
360
  end
359
- cached_gem
360
361
  end
361
362
 
362
363
  def cached_path(spec)
364
+ global_cache_path = download_cache_path(spec)
365
+ @caches << global_cache_path if global_cache_path
366
+
363
367
  possibilities = @caches.map {|p| "#{p}/#{spec.file_name}" }
364
368
  possibilities.find {|p| File.exist?(p) }
365
369
  end
@@ -459,19 +463,26 @@ module Bundler
459
463
 
460
464
  spec.fetch_platform
461
465
 
462
- download_path = requires_sudo? ? Bundler.tmp(spec.full_name) : rubygems_dir
463
- gem_path = "#{rubygems_dir}/cache/#{spec.full_name}.gem"
466
+ cache_path = download_cache_path(spec) || default_cache_path_for(rubygems_dir)
467
+ gem_path = "#{cache_path}/#{spec.file_name}"
464
468
 
465
- SharedHelpers.filesystem_access("#{download_path}/cache") do |p|
469
+ if requires_sudo?
470
+ download_path = Bundler.tmp(spec.full_name)
471
+ download_cache_path = default_cache_path_for(download_path)
472
+ else
473
+ download_cache_path = cache_path
474
+ end
475
+
476
+ SharedHelpers.filesystem_access(download_cache_path) do |p|
466
477
  FileUtils.mkdir_p(p)
467
478
  end
468
- download_gem(spec, download_path)
479
+ download_gem(spec, download_cache_path)
469
480
 
470
481
  if requires_sudo?
471
- SharedHelpers.filesystem_access("#{rubygems_dir}/cache") do |p|
482
+ SharedHelpers.filesystem_access(cache_path) do |p|
472
483
  Bundler.mkdir_p(p)
473
484
  end
474
- Bundler.sudo "mv #{download_path}/cache/#{spec.full_name}.gem #{gem_path}"
485
+ Bundler.sudo "mv #{download_cache_path}/#{spec.file_name} #{gem_path}"
475
486
  end
476
487
 
477
488
  gem_path
@@ -479,16 +490,8 @@ module Bundler
479
490
  Bundler.rm_rf(download_path) if requires_sudo?
480
491
  end
481
492
 
482
- def builtin_gem?(spec)
483
- # Ruby 2.1, where all included gems have this summary
484
- return true if spec.summary =~ /is bundled with Ruby/
485
-
486
- # Ruby 2.0, where gemspecs are stored in specifications/default/
487
- spec.loaded_from && spec.loaded_from.include?("specifications/default/")
488
- end
489
-
490
493
  def installed?(spec)
491
- installed_specs[spec].any?
494
+ installed_specs[spec].any? && !spec.deleted_gem?
492
495
  end
493
496
 
494
497
  def requires_sudo?
@@ -499,6 +502,10 @@ module Bundler
499
502
  Bundler.rubygems.gem_dir
500
503
  end
501
504
 
505
+ def default_cache_path_for(dir)
506
+ "#{dir}/cache"
507
+ end
508
+
502
509
  def cache_path
503
510
  Bundler.app_cache
504
511
  end
@@ -511,52 +518,13 @@ module Bundler
511
518
  # @param [Specification] spec
512
519
  # the spec we want to download or retrieve from the cache.
513
520
  #
514
- # @param [String] download_path
521
+ # @param [String] download_cache_path
515
522
  # the local directory the .gem will end up in.
516
523
  #
517
- def download_gem(spec, download_path)
518
- local_path = File.join(download_path, "cache/#{spec.full_name}.gem")
519
-
520
- if (cache_path = download_cache_path(spec)) && cache_path.file?
521
- SharedHelpers.filesystem_access(local_path) do
522
- FileUtils.cp(cache_path, local_path)
523
- end
524
- else
525
- uri = spec.remote.uri
526
- Bundler.ui.confirm("Fetching #{version_message(spec)}")
527
- rubygems_local_path = Bundler.rubygems.download_gem(spec, uri, download_path)
528
-
529
- # older rubygems return varying file:// variants depending on version
530
- rubygems_local_path = rubygems_local_path.gsub(/\Afile:/, "") unless Bundler.rubygems.provides?(">= 3.2.0.rc.2")
531
- rubygems_local_path = rubygems_local_path.gsub(%r{\A//}, "") if Bundler.rubygems.provides?("< 3.1.0")
532
-
533
- if rubygems_local_path != local_path
534
- SharedHelpers.filesystem_access(local_path) do
535
- FileUtils.mv(rubygems_local_path, local_path)
536
- end
537
- end
538
- cache_globally(spec, local_path)
539
- end
540
- end
541
-
542
- # Checks if the requested spec exists in the global cache. If it does
543
- # not, we create the relevant global cache subdirectory if it does not
544
- # exist and copy the spec from the local cache to the global cache.
545
- #
546
- # @param [Specification] spec
547
- # the spec we want to copy to the global cache.
548
- #
549
- # @param [String] local_cache_path
550
- # the local directory from which we want to copy the .gem.
551
- #
552
- def cache_globally(spec, local_cache_path)
553
- return unless cache_path = download_cache_path(spec)
554
- return if cache_path.exist?
555
-
556
- SharedHelpers.filesystem_access(cache_path.dirname, &:mkpath)
557
- SharedHelpers.filesystem_access(cache_path) do
558
- FileUtils.cp(local_cache_path, cache_path)
559
- end
524
+ def download_gem(spec, download_cache_path)
525
+ uri = spec.remote.uri
526
+ Bundler.ui.confirm("Fetching #{version_message(spec)}")
527
+ Bundler.rubygems.download_gem(spec, uri, download_cache_path)
560
528
  end
561
529
 
562
530
  # Returns the global cache path of the calling Rubygems::Source object.
@@ -575,7 +543,7 @@ module Bundler
575
543
  return unless remote = spec.remote
576
544
  return unless cache_slug = remote.cache_slug
577
545
 
578
- Bundler.user_cache.join("gems", cache_slug, spec.file_name)
546
+ Bundler.user_cache.join("gems", cache_slug)
579
547
  end
580
548
 
581
549
  def extension_cache_slug(spec)
@@ -16,7 +16,7 @@ module Bundler
16
16
  @index
17
17
  end
18
18
 
19
- def to_err
19
+ def identifier
20
20
  to_s
21
21
  end
22
22
 
@@ -67,7 +67,7 @@ module Bundler
67
67
  "#<#{self.class}:0x#{object_id} #{self}>"
68
68
  end
69
69
 
70
- def to_err
70
+ def identifier
71
71
  to_s
72
72
  end
73
73
 
@@ -98,7 +98,7 @@ module Bundler
98
98
  end
99
99
 
100
100
  def get(source)
101
- source_list_for(source).find {|s| equal_source?(source, s) || equivalent_source?(source, s) }
101
+ source_list_for(source).find {|s| equivalent_source?(source, s) }
102
102
  end
103
103
 
104
104
  def lock_sources
@@ -106,14 +106,14 @@ module Bundler
106
106
  end
107
107
 
108
108
  def lock_other_sources
109
- (path_sources + git_sources + plugin_sources).sort_by(&:to_s)
109
+ (path_sources + git_sources + plugin_sources).sort_by(&:identifier)
110
110
  end
111
111
 
112
112
  def lock_rubygems_sources
113
113
  if merged_gem_lockfile_sections?
114
114
  [combine_rubygems_sources]
115
115
  else
116
- rubygems_sources.sort_by(&:to_s)
116
+ rubygems_sources.sort_by(&:identifier)
117
117
  end
118
118
  end
119
119
 
@@ -173,7 +173,7 @@ module Bundler
173
173
  end
174
174
 
175
175
  def different_sources?(lock_sources, replacement_sources)
176
- !equal_sources?(lock_sources, replacement_sources) && !equivalent_sources?(lock_sources, replacement_sources)
176
+ !equivalent_sources?(lock_sources, replacement_sources)
177
177
  end
178
178
 
179
179
  def rubygems_aggregate_class
@@ -210,34 +210,12 @@ module Bundler
210
210
  end
211
211
  end
212
212
 
213
- def equal_sources?(lock_sources, replacement_sources)
214
- lock_sources.sort_by(&:to_s) == replacement_sources.sort_by(&:to_s)
215
- end
216
-
217
- def equal_source?(source, other_source)
218
- return source.include?(other_source) if source.is_a?(Source::Rubygems) && other_source.is_a?(Source::Rubygems)
219
-
220
- source == other_source
221
- end
222
-
223
- def equivalent_source?(source, other_source)
224
- return false unless Bundler.settings[:allow_deployment_source_credential_changes] && source.is_a?(Source::Rubygems)
225
-
226
- equivalent_rubygems_sources?([source], [other_source])
227
- end
228
-
229
213
  def equivalent_sources?(lock_sources, replacement_sources)
230
- return false unless Bundler.settings[:allow_deployment_source_credential_changes]
231
-
232
- lock_rubygems_sources, lock_other_sources = lock_sources.partition {|s| s.is_a?(Source::Rubygems) }
233
- replacement_rubygems_sources, replacement_other_sources = replacement_sources.partition {|s| s.is_a?(Source::Rubygems) }
234
-
235
- equivalent_rubygems_sources?(lock_rubygems_sources, replacement_rubygems_sources) && equal_sources?(lock_other_sources, replacement_other_sources)
214
+ lock_sources.sort_by(&:identifier) == replacement_sources.sort_by(&:identifier)
236
215
  end
237
216
 
238
- def equivalent_rubygems_sources?(lock_sources, replacement_sources)
239
- actual_remotes = replacement_sources.map(&:remotes).flatten.uniq
240
- lock_sources.all? {|s| s.equivalent_remotes?(actual_remotes) }
217
+ def equivalent_source?(source, other_source)
218
+ source == other_source
241
219
  end
242
220
  end
243
221
  end
@@ -1,6 +1,6 @@
1
1
  # frozen_string_literal: true
2
2
 
3
- require "tsort"
3
+ require_relative "vendored_tsort"
4
4
 
5
5
  module Bundler
6
6
  class SpecSet
@@ -14,7 +14,10 @@ gem "rake-compiler"
14
14
 
15
15
  gem "<%= config[:test] %>", "~> <%= config[:test_framework_version] %>"
16
16
  <%- end -%>
17
- <%- if config[:rubocop] -%>
17
+ <%- if config[:linter] == "rubocop" -%>
18
18
 
19
- gem "rubocop", "~> <%= config[:rubocop_version] %>"
19
+ gem "rubocop", "~> <%= config[:linter_version] %>"
20
+ <%- elsif config[:linter] == "standard" -%>
21
+
22
+ gem "standard", "~> <%= config[:linter_version] %>"
20
23
  <%- end -%>
@@ -18,12 +18,16 @@ require "rspec/core/rake_task"
18
18
  RSpec::Core::RakeTask.new(:spec)
19
19
 
20
20
  <% end -%>
21
- <% if config[:rubocop] -%>
21
+ <% if config[:linter] == "rubocop" -%>
22
22
  <% default_task_names << :rubocop -%>
23
23
  require "rubocop/rake_task"
24
24
 
25
25
  RuboCop::RakeTask.new
26
26
 
27
+ <% elsif config[:linter] == "standard" -%>
28
+ <% default_task_names << :standard -%>
29
+ require "standard/rake"
30
+
27
31
  <% end -%>
28
32
  <% if config[:ext] -%>
29
33
  <% default_task_names.unshift(:clobber, :compile) -%>
@@ -10,11 +10,11 @@ on:
10
10
  jobs:
11
11
  build:
12
12
  runs-on: ubuntu-latest
13
-
13
+ name: Ruby ${{ matrix.ruby }}
14
14
  strategy:
15
15
  matrix:
16
16
  ruby:
17
- - <%= RUBY_VERSION %>
17
+ - '<%= RUBY_VERSION %>'
18
18
 
19
19
  steps:
20
20
  - uses: actions/checkout@v2
@@ -3,16 +3,16 @@
3
3
  require_relative "lib/<%=config[:namespaced_path]%>/version"
4
4
 
5
5
  Gem::Specification.new do |spec|
6
- spec.name = <%= config[:name].inspect %>
7
- spec.version = <%= config[:constant_name] %>::VERSION
8
- spec.authors = [<%= config[:author].inspect %>]
9
- spec.email = [<%= config[:email].inspect %>]
10
-
11
- spec.summary = "TODO: Write a short summary, because RubyGems requires one."
12
- spec.description = "TODO: Write a longer description or delete this line."
13
- spec.homepage = "TODO: Put your gem's website or public repo URL here."
6
+ spec.name = <%= config[:name].inspect %>
7
+ spec.version = <%= config[:constant_name] %>::VERSION
8
+ spec.authors = [<%= config[:author].inspect %>]
9
+ spec.email = [<%= config[:email].inspect %>]
10
+
11
+ spec.summary = "TODO: Write a short summary, because RubyGems requires one."
12
+ spec.description = "TODO: Write a longer description or delete this line."
13
+ spec.homepage = "TODO: Put your gem's website or public repo URL here."
14
14
  <%- if config[:mit] -%>
15
- spec.license = "MIT"
15
+ spec.license = "MIT"
16
16
  <%- end -%>
17
17
  spec.required_ruby_version = ">= <%= config[:required_ruby_version] %>"
18
18
 
@@ -29,11 +29,11 @@ Gem::Specification.new do |spec|
29
29
  (f == __FILE__) || f.match(%r{\A(?:(?:test|spec|features)/|\.(?:git|travis|circleci)|appveyor)})
30
30
  end
31
31
  end
32
- spec.bindir = "exe"
33
- spec.executables = spec.files.grep(%r{\Aexe/}) { |f| File.basename(f) }
32
+ spec.bindir = "exe"
33
+ spec.executables = spec.files.grep(%r{\Aexe/}) { |f| File.basename(f) }
34
34
  spec.require_paths = ["lib"]
35
35
  <%- if config[:ext] -%>
36
- spec.extensions = ["ext/<%= config[:underscored_name] %>/extconf.rb"]
36
+ spec.extensions = ["ext/<%= config[:underscored_name] %>/extconf.rb"]
37
37
  <%- end -%>
38
38
 
39
39
  # Uncomment to register a new dependency of your gem
@@ -0,0 +1,8 @@
1
+ <%- config[:constant_array].each_with_index do |c, i| -%>
2
+ <%= " " * i %>module <%= c %>
3
+ <%- end -%>
4
+ <%= " " * config[:constant_array].size %>VERSION: String
5
+ <%= " " * config[:constant_array].size %># See the writing guide of rbs: https://github.com/ruby/rbs#guides
6
+ <%- (config[:constant_array].size-1).downto(0) do |i| -%>
7
+ <%= " " * i %>end
8
+ <%- end -%>
@@ -0,0 +1,2 @@
1
+ # For available configuration options, see:
2
+ # https://github.com/testdouble/standard
@@ -0,0 +1 @@
1
+ # Vendored files do not need to be documented
@@ -0,0 +1,20 @@
1
+ Copyright (c) 2011 Mike Perham
2
+
3
+ Permission is hereby granted, free of charge, to any person obtaining
4
+ a copy of this software and associated documentation files (the
5
+ "Software"), to deal in the Software without restriction, including
6
+ without limitation the rights to use, copy, modify, merge, publish,
7
+ distribute, sublicense, and/or sell copies of the Software, and to
8
+ permit persons to whom the Software is furnished to do so, subject to
9
+ the following conditions:
10
+
11
+ The above copyright notice and this permission notice shall be
12
+ included in all copies or substantial portions of the Software.
13
+
14
+ THE SOFTWARE IS PROVIDED "AS IS", WITHOUT WARRANTY OF ANY KIND,
15
+ EXPRESS OR IMPLIED, INCLUDING BUT NOT LIMITED TO THE WARRANTIES OF
16
+ MERCHANTABILITY, FITNESS FOR A PARTICULAR PURPOSE AND
17
+ NONINFRINGEMENT. IN NO EVENT SHALL THE AUTHORS OR COPYRIGHT HOLDERS BE
18
+ LIABLE FOR ANY CLAIM, DAMAGES OR OTHER LIABILITY, WHETHER IN AN ACTION
19
+ OF CONTRACT, TORT OR OTHERWISE, ARISING FROM, OUT OF OR IN CONNECTION
20
+ WITH THE SOFTWARE OR THE USE OR OTHER DEALINGS IN THE SOFTWARE.
@@ -1,13 +1,3 @@
1
- require 'thread'
2
- require 'timeout'
3
- require_relative 'monotonic_time'
4
-
5
- ##
6
- # Raised when you attempt to retrieve a connection from a pool that has been
7
- # shut down.
8
-
9
- class Bundler::ConnectionPool::PoolShuttingDownError < RuntimeError; end
10
-
11
1
  ##
12
2
  # The TimedStack manages a pool of homogeneous connections (or any resource
13
3
  # you wish to manage). Connections are created lazily up to a given maximum
@@ -25,7 +15,7 @@ class Bundler::ConnectionPool::PoolShuttingDownError < RuntimeError; end
25
15
  #
26
16
  # conn = ts.pop
27
17
  # ts.pop timeout: 5
28
- # #=> raises Timeout::Error after 5 seconds
18
+ # #=> raises Bundler::ConnectionPool::TimeoutError after 5 seconds
29
19
 
30
20
  class Bundler::ConnectionPool::TimedStack
31
21
  attr_reader :max
@@ -39,8 +29,8 @@ class Bundler::ConnectionPool::TimedStack
39
29
  @created = 0
40
30
  @que = []
41
31
  @max = size
42
- @mutex = Mutex.new
43
- @resource = ConditionVariable.new
32
+ @mutex = Thread::Mutex.new
33
+ @resource = Thread::ConditionVariable.new
44
34
  @shutdown_block = nil
45
35
  end
46
36
 
@@ -59,12 +49,12 @@ class Bundler::ConnectionPool::TimedStack
59
49
  @resource.broadcast
60
50
  end
61
51
  end
62
- alias_method :<<, :push
52
+ alias << push
63
53
 
64
54
  ##
65
55
  # Retrieves a connection from the stack. If a connection is available it is
66
56
  # immediately returned. If no connection is available within the given
67
- # timeout a Timeout::Error is raised.
57
+ # timeout a Bundler::ConnectionPool::TimeoutError is raised.
68
58
  #
69
59
  # +:timeout+ is the only checked entry in +options+ and is preferred over
70
60
  # the +timeout+ argument (which will be removed in a future release). Other
@@ -74,7 +64,7 @@ class Bundler::ConnectionPool::TimedStack
74
64
  options, timeout = timeout, 0.5 if Hash === timeout
75
65
  timeout = options.fetch :timeout, timeout
76
66
 
77
- deadline = Bundler::ConnectionPool.monotonic_time + timeout
67
+ deadline = current_time + timeout
78
68
  @mutex.synchronize do
79
69
  loop do
80
70
  raise Bundler::ConnectionPool::PoolShuttingDownError if @shutdown_block
@@ -83,18 +73,20 @@ class Bundler::ConnectionPool::TimedStack
83
73
  connection = try_create(options)
84
74
  return connection if connection
85
75
 
86
- to_wait = deadline - Bundler::ConnectionPool.monotonic_time
87
- raise Timeout::Error, "Waited #{timeout} sec" if to_wait <= 0
76
+ to_wait = deadline - current_time
77
+ raise Bundler::ConnectionPool::TimeoutError, "Waited #{timeout} sec" if to_wait <= 0
88
78
  @resource.wait(@mutex, to_wait)
89
79
  end
90
80
  end
91
81
  end
92
82
 
93
83
  ##
94
- # Shuts down the TimedStack which prevents connections from being checked
95
- # out. The +block+ is called once for each connection on the stack.
84
+ # Shuts down the TimedStack by passing each connection to +block+ and then
85
+ # removing it from the pool. Attempting to checkout a connection after
86
+ # shutdown will raise +Bundler::ConnectionPool::PoolShuttingDownError+ unless
87
+ # +:reload+ is +true+.
96
88
 
97
- def shutdown(&block)
89
+ def shutdown(reload: false, &block)
98
90
  raise ArgumentError, "shutdown must receive a block" unless block_given?
99
91
 
100
92
  @mutex.synchronize do
@@ -102,6 +94,7 @@ class Bundler::ConnectionPool::TimedStack
102
94
  @resource.broadcast
103
95
 
104
96
  shutdown_connections
97
+ @shutdown_block = nil if reload
105
98
  end
106
99
  end
107
100
 
@@ -121,6 +114,10 @@ class Bundler::ConnectionPool::TimedStack
121
114
 
122
115
  private
123
116
 
117
+ def current_time
118
+ Process.clock_gettime(Process::CLOCK_MONOTONIC)
119
+ end
120
+
124
121
  ##
125
122
  # This is an extension point for TimedStack and is called with a mutex.
126
123
  #
@@ -149,6 +146,7 @@ class Bundler::ConnectionPool::TimedStack
149
146
  conn = fetch_connection(options)
150
147
  @shutdown_block.call(conn)
151
148
  end
149
+ @created = 0
152
150
  end
153
151
 
154
152
  ##
@@ -1,3 +1,3 @@
1
1
  class Bundler::ConnectionPool
2
- VERSION = "2.2.2"
2
+ VERSION = "2.3.0"
3
3
  end
@@ -0,0 +1,57 @@
1
+ class Bundler::ConnectionPool
2
+ class Wrapper < ::BasicObject
3
+ METHODS = [:with, :pool_shutdown, :wrapped_pool]
4
+
5
+ def initialize(options = {}, &block)
6
+ @pool = options.fetch(:pool) { ::Bundler::ConnectionPool.new(options, &block) }
7
+ end
8
+
9
+ def wrapped_pool
10
+ @pool
11
+ end
12
+
13
+ def with(&block)
14
+ @pool.with(&block)
15
+ end
16
+
17
+ def pool_shutdown(&block)
18
+ @pool.shutdown(&block)
19
+ end
20
+
21
+ def pool_size
22
+ @pool.size
23
+ end
24
+
25
+ def pool_available
26
+ @pool.available
27
+ end
28
+
29
+ def respond_to?(id, *args)
30
+ METHODS.include?(id) || with { |c| c.respond_to?(id, *args) }
31
+ end
32
+
33
+ # rubocop:disable Style/MethodMissingSuper
34
+ # rubocop:disable Style/MissingRespondToMissing
35
+ if ::RUBY_VERSION >= "3.0.0"
36
+ def method_missing(name, *args, **kwargs, &block)
37
+ with do |connection|
38
+ connection.send(name, *args, **kwargs, &block)
39
+ end
40
+ end
41
+ elsif ::RUBY_VERSION >= "2.7.0"
42
+ ruby2_keywords def method_missing(name, *args, &block)
43
+ with do |connection|
44
+ connection.send(name, *args, &block)
45
+ end
46
+ end
47
+ else
48
+ def method_missing(name, *args, &block)
49
+ with do |connection|
50
+ connection.send(name, *args, &block)
51
+ end
52
+ end
53
+ end
54
+ # rubocop:enable Style/MethodMissingSuper
55
+ # rubocop:enable Style/MissingRespondToMissing
56
+ end
57
+ end