rubygems-update 4.0.21 → 4.0.23
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.
- checksums.yaml +4 -4
- data/CHANGELOG.md +22 -0
- data/Manifest.txt +1 -1
- data/bundler/CHANGELOG.md +28 -0
- data/bundler/lib/bundler/build_metadata.rb +2 -2
- data/bundler/lib/bundler/cli/lock.rb +14 -3
- data/bundler/lib/bundler/cli/platform.rb +15 -1
- data/bundler/lib/bundler/cli.rb +17 -5
- data/bundler/lib/bundler/fetcher/downloader.rb +10 -4
- data/bundler/lib/bundler/installer.rb +4 -0
- data/bundler/lib/bundler/man/bundle-lock.1 +1 -1
- data/bundler/lib/bundler/man/bundle-lock.1.ronn +1 -1
- data/bundler/lib/bundler/man/bundle-outdated.1 +1 -1
- data/bundler/lib/bundler/man/bundle-outdated.1.ronn +1 -1
- data/bundler/lib/bundler/man/bundle-update.1 +2 -2
- data/bundler/lib/bundler/man/bundle-update.1.ronn +2 -2
- data/bundler/lib/bundler/templates/newgem/ext/newgem/Cargo.toml.tt +1 -1
- data/bundler/lib/bundler/vendor/connection_pool/lib/connection_pool/timed_stack.rb +14 -4
- data/bundler/lib/bundler/vendor/connection_pool/lib/connection_pool/version.rb +1 -1
- data/bundler/lib/bundler/vendor/connection_pool/lib/connection_pool.rb +3 -0
- data/bundler/lib/bundler/vendor/fileutils/lib/fileutils.rb +54 -29
- data/bundler/lib/bundler/vendor/net-http-persistent/lib/net/http/persistent/pool.rb +1 -1
- data/bundler/lib/bundler/vendor/net-http-persistent/lib/net/http/persistent/timed_stack_multi.rb +10 -1
- data/bundler/lib/bundler/vendor/net-http-persistent/lib/net/http/persistent.rb +12 -6
- data/bundler/lib/bundler/vendor/thor/lib/thor/actions/inject_into_file.rb +35 -2
- data/bundler/lib/bundler/vendor/thor/lib/thor/base.rb +2 -1
- data/bundler/lib/bundler/vendor/thor/lib/thor/shell/basic.rb +14 -6
- data/bundler/lib/bundler/vendor/thor/lib/thor/shell/color.rb +2 -0
- data/bundler/lib/bundler/vendor/thor/lib/thor/version.rb +1 -1
- data/bundler/lib/bundler/vendor/thor/lib/thor.rb +34 -1
- data/bundler/lib/bundler/vendor/uri/lib/uri/common.rb +1 -1
- data/bundler/lib/bundler/vendor/uri/lib/uri/generic.rb +15 -3
- data/bundler/lib/bundler/vendor/uri/lib/uri/version.rb +1 -1
- data/bundler/lib/bundler/version.rb +1 -1
- data/bundler/lib/bundler.rb +1 -3
- data/lib/rubygems/commands/exec_command.rb +3 -0
- data/lib/rubygems/ext/builder.rb +7 -2
- data/lib/rubygems/gemcutter_utilities/webauthn_listener.rb +9 -0
- data/lib/rubygems/installer.rb +4 -0
- data/lib/rubygems/package.rb +36 -5
- data/lib/rubygems/uninstaller.rb +1 -0
- data/lib/rubygems/vendor/net-http/lib/net/http/exceptions.rb +2 -1
- data/lib/rubygems/vendor/net-http/lib/net/http/generic_request.rb +15 -7
- data/lib/rubygems/vendor/net-http/lib/net/http/header.rb +64 -19
- data/lib/rubygems/vendor/net-http/lib/net/http/request.rb +1 -0
- data/lib/rubygems/vendor/net-http/lib/net/http/requests.rb +74 -25
- data/lib/rubygems/vendor/net-http/lib/net/http/response.rb +42 -16
- data/lib/rubygems/vendor/net-http/lib/net/http/responses.rb +68 -0
- data/lib/rubygems/vendor/net-http/lib/net/http.rb +129 -37
- data/lib/rubygems/vendor/net-protocol/COPYING +56 -0
- data/lib/rubygems/vendor/net-protocol/lib/net/protocol.rb +95 -26
- data/lib/rubygems/vendor/optparse/lib/optparse.rb +23 -30
- data/lib/rubygems/vendor/timeout/lib/timeout.rb +190 -77
- data/lib/rubygems/vendor/uri/lib/uri/common.rb +1 -1
- data/lib/rubygems/vendor/uri/lib/uri/generic.rb +15 -3
- data/lib/rubygems/vendor/uri/lib/uri/version.rb +1 -1
- data/lib/rubygems.rb +1 -1
- metadata +2 -2
- data/lib/rubygems/vendor/net-protocol/LICENSE.txt +0 -22
|
@@ -426,8 +426,9 @@ require 'set' unless defined?(Set)
|
|
|
426
426
|
#
|
|
427
427
|
class Gem::OptionParser
|
|
428
428
|
# The version string
|
|
429
|
-
VERSION = "0.8.
|
|
430
|
-
|
|
429
|
+
VERSION = "0.8.1"
|
|
430
|
+
# An alias for compatibility
|
|
431
|
+
Version = VERSION
|
|
431
432
|
|
|
432
433
|
# :stopdoc:
|
|
433
434
|
NoArgument = [NO_ARGUMENT = :NONE, nil].freeze
|
|
@@ -471,7 +472,6 @@ class Gem::OptionParser
|
|
|
471
472
|
Completion.candidate(key, icase, pat, &method(:each))
|
|
472
473
|
end
|
|
473
474
|
|
|
474
|
-
public
|
|
475
475
|
def complete(key, icase = false, pat = nil)
|
|
476
476
|
candidates = candidate(key, icase, pat, &method(:each)).sort_by {|k, v, kn| kn.size}
|
|
477
477
|
if candidates.size == 1
|
|
@@ -561,7 +561,7 @@ class Gem::OptionParser
|
|
|
561
561
|
# Parses +arg+ and returns rest of +arg+ and matched portion to the
|
|
562
562
|
# argument pattern. Yields when the pattern doesn't match substring.
|
|
563
563
|
#
|
|
564
|
-
def parse_arg(arg) # :nodoc:
|
|
564
|
+
private def parse_arg(arg) # :nodoc:
|
|
565
565
|
pattern or return nil, [arg]
|
|
566
566
|
unless m = pattern.match(arg)
|
|
567
567
|
yield(InvalidArgument, arg)
|
|
@@ -579,14 +579,13 @@ class Gem::OptionParser
|
|
|
579
579
|
yield(InvalidArgument, arg) # didn't match whole arg
|
|
580
580
|
return arg[s.length..-1], m
|
|
581
581
|
end
|
|
582
|
-
private :parse_arg
|
|
583
582
|
|
|
584
583
|
#
|
|
585
584
|
# Parses argument, converts and returns +arg+, +block+ and result of
|
|
586
585
|
# conversion. Yields at semi-error condition instead of raising an
|
|
587
586
|
# exception.
|
|
588
587
|
#
|
|
589
|
-
def conv_arg(arg, val = []) # :nodoc:
|
|
588
|
+
private def conv_arg(arg, val = []) # :nodoc:
|
|
590
589
|
v, = *val
|
|
591
590
|
if conv
|
|
592
591
|
val = conv.call(*val)
|
|
@@ -598,7 +597,6 @@ class Gem::OptionParser
|
|
|
598
597
|
end
|
|
599
598
|
return arg, block, val
|
|
600
599
|
end
|
|
601
|
-
private :conv_arg
|
|
602
600
|
|
|
603
601
|
#
|
|
604
602
|
# Produces the summary text. Each line of the summary is yielded to the
|
|
@@ -882,14 +880,13 @@ class Gem::OptionParser
|
|
|
882
880
|
# +lopts+:: Long style option list.
|
|
883
881
|
# +nlopts+:: Negated long style options list.
|
|
884
882
|
#
|
|
885
|
-
def update(sw, sopts, lopts, nsw = nil, nlopts = nil) # :nodoc:
|
|
883
|
+
private def update(sw, sopts, lopts, nsw = nil, nlopts = nil) # :nodoc:
|
|
886
884
|
sopts.each {|o| @short[o] = sw} if sopts
|
|
887
885
|
lopts.each {|o| @long[o] = sw} if lopts
|
|
888
886
|
nlopts.each {|o| @long[o] = nsw} if nsw and nlopts
|
|
889
887
|
used = @short.invert.update(@long.invert)
|
|
890
888
|
@list.delete_if {|o| Switch === o and !used[o]}
|
|
891
889
|
end
|
|
892
|
-
private :update
|
|
893
890
|
|
|
894
891
|
#
|
|
895
892
|
# Inserts +switch+ at the head of the list, and associates short, long
|
|
@@ -1458,14 +1455,13 @@ XXX
|
|
|
1458
1455
|
# +prv+:: Previously specified argument.
|
|
1459
1456
|
# +msg+:: Exception message.
|
|
1460
1457
|
#
|
|
1461
|
-
def notwice(obj, prv, msg) # :nodoc:
|
|
1458
|
+
private def notwice(obj, prv, msg) # :nodoc:
|
|
1462
1459
|
unless !prv or prv == obj
|
|
1463
1460
|
raise(ArgumentError, "argument #{msg} given twice: #{obj}",
|
|
1464
1461
|
ParseError.filter_backtrace(caller(2)))
|
|
1465
1462
|
end
|
|
1466
1463
|
obj
|
|
1467
1464
|
end
|
|
1468
|
-
private :notwice
|
|
1469
1465
|
|
|
1470
1466
|
SPLAT_PROC = proc {|*a| a.length <= 1 ? a.first : a} # :nodoc:
|
|
1471
1467
|
|
|
@@ -1732,7 +1728,7 @@ XXX
|
|
|
1732
1728
|
parse_in_order(argv, setter, **keywords, &nonopt)
|
|
1733
1729
|
end
|
|
1734
1730
|
|
|
1735
|
-
def parse_in_order(argv = default_argv, setter = nil, exact: require_exact, **, &nonopt) # :nodoc:
|
|
1731
|
+
private def parse_in_order(argv = default_argv, setter = nil, exact: require_exact, **, &nonopt) # :nodoc:
|
|
1736
1732
|
opt, arg, val, rest = nil
|
|
1737
1733
|
nonopt ||= proc {|a| throw :terminate, a}
|
|
1738
1734
|
argv.unshift(arg) if arg = catch(:terminate) {
|
|
@@ -1823,10 +1819,9 @@ XXX
|
|
|
1823
1819
|
|
|
1824
1820
|
argv
|
|
1825
1821
|
end
|
|
1826
|
-
private :parse_in_order
|
|
1827
1822
|
|
|
1828
1823
|
# Calls callback with _val_.
|
|
1829
|
-
def callback!(cb, max_arity, *args) # :nodoc:
|
|
1824
|
+
private def callback!(cb, max_arity, *args) # :nodoc:
|
|
1830
1825
|
args.compact!
|
|
1831
1826
|
|
|
1832
1827
|
if (size = args.size) < max_arity and cb.to_proc.lambda?
|
|
@@ -1836,7 +1831,6 @@ XXX
|
|
|
1836
1831
|
end
|
|
1837
1832
|
cb.call(*args)
|
|
1838
1833
|
end
|
|
1839
|
-
private :callback!
|
|
1840
1834
|
|
|
1841
1835
|
#
|
|
1842
1836
|
# Parses command line arguments +argv+ in permutation mode and returns
|
|
@@ -1950,24 +1944,22 @@ XXX
|
|
|
1950
1944
|
# Traverses @stack, sending each element method +id+ with +args+ and
|
|
1951
1945
|
# +block+.
|
|
1952
1946
|
#
|
|
1953
|
-
def visit(id, *args, &block) # :nodoc:
|
|
1947
|
+
private def visit(id, *args, &block) # :nodoc:
|
|
1954
1948
|
@stack.reverse_each do |el|
|
|
1955
1949
|
el.__send__(id, *args, &block)
|
|
1956
1950
|
end
|
|
1957
1951
|
nil
|
|
1958
1952
|
end
|
|
1959
|
-
private :visit
|
|
1960
1953
|
|
|
1961
1954
|
#
|
|
1962
1955
|
# Searches +key+ in @stack for +id+ hash and returns or yields the result.
|
|
1963
1956
|
#
|
|
1964
|
-
def search(id, key) # :nodoc:
|
|
1957
|
+
private def search(id, key) # :nodoc:
|
|
1965
1958
|
block_given = block_given?
|
|
1966
1959
|
visit(:search, id, key) do |k|
|
|
1967
1960
|
return block_given ? yield(k) : k
|
|
1968
1961
|
end
|
|
1969
1962
|
end
|
|
1970
|
-
private :search
|
|
1971
1963
|
|
|
1972
1964
|
#
|
|
1973
1965
|
# Completes shortened long style option switch and returns pair of
|
|
@@ -1978,7 +1970,7 @@ XXX
|
|
|
1978
1970
|
# +icase+:: Search case insensitive if true.
|
|
1979
1971
|
# +pat+:: Optional pattern for completion.
|
|
1980
1972
|
#
|
|
1981
|
-
def complete(typ, opt, icase = false, *pat) # :nodoc:
|
|
1973
|
+
private def complete(typ, opt, icase = false, *pat) # :nodoc:
|
|
1982
1974
|
if pat.empty?
|
|
1983
1975
|
search(typ, opt) {|sw| return [sw, opt]} # exact match or...
|
|
1984
1976
|
end
|
|
@@ -1988,7 +1980,6 @@ XXX
|
|
|
1988
1980
|
exc = ambiguous ? AmbiguousOption : InvalidOption
|
|
1989
1981
|
raise exc.new(opt, additional: proc {|o| additional_message(typ, o)})
|
|
1990
1982
|
end
|
|
1991
|
-
private :complete
|
|
1992
1983
|
|
|
1993
1984
|
#
|
|
1994
1985
|
# Returns additional info.
|
|
@@ -2323,42 +2314,42 @@ XXX
|
|
|
2323
2314
|
# Raises when ambiguously completable string is encountered.
|
|
2324
2315
|
#
|
|
2325
2316
|
class AmbiguousOption < ParseError
|
|
2326
|
-
|
|
2317
|
+
Reason = 'ambiguous option' # :nodoc:
|
|
2327
2318
|
end
|
|
2328
2319
|
|
|
2329
2320
|
#
|
|
2330
2321
|
# Raises when there is an argument for a switch which takes no argument.
|
|
2331
2322
|
#
|
|
2332
2323
|
class NeedlessArgument < ParseError
|
|
2333
|
-
|
|
2324
|
+
Reason = 'needless argument' # :nodoc:
|
|
2334
2325
|
end
|
|
2335
2326
|
|
|
2336
2327
|
#
|
|
2337
2328
|
# Raises when a switch with mandatory argument has no argument.
|
|
2338
2329
|
#
|
|
2339
2330
|
class MissingArgument < ParseError
|
|
2340
|
-
|
|
2331
|
+
Reason = 'missing argument' # :nodoc:
|
|
2341
2332
|
end
|
|
2342
2333
|
|
|
2343
2334
|
#
|
|
2344
2335
|
# Raises when switch is undefined.
|
|
2345
2336
|
#
|
|
2346
2337
|
class InvalidOption < ParseError
|
|
2347
|
-
|
|
2338
|
+
Reason = 'invalid option' # :nodoc:
|
|
2348
2339
|
end
|
|
2349
2340
|
|
|
2350
2341
|
#
|
|
2351
2342
|
# Raises when the given argument does not match required format.
|
|
2352
2343
|
#
|
|
2353
2344
|
class InvalidArgument < ParseError
|
|
2354
|
-
|
|
2345
|
+
Reason = 'invalid argument' # :nodoc:
|
|
2355
2346
|
end
|
|
2356
2347
|
|
|
2357
2348
|
#
|
|
2358
2349
|
# Raises when the given argument word can't be completed uniquely.
|
|
2359
2350
|
#
|
|
2360
2351
|
class AmbiguousArgument < InvalidArgument
|
|
2361
|
-
|
|
2352
|
+
Reason = 'ambiguous argument' # :nodoc:
|
|
2362
2353
|
end
|
|
2363
2354
|
|
|
2364
2355
|
#
|
|
@@ -2457,9 +2448,11 @@ XXX
|
|
|
2457
2448
|
# and DecimalNumeric. See Acceptable argument classes (in source code).
|
|
2458
2449
|
#
|
|
2459
2450
|
module Acceptables
|
|
2460
|
-
|
|
2461
|
-
|
|
2462
|
-
|
|
2451
|
+
# :stopdoc:
|
|
2452
|
+
DecimalInteger = Gem::OptionParser::DecimalInteger
|
|
2453
|
+
OctalInteger = Gem::OptionParser::OctalInteger
|
|
2454
|
+
DecimalNumeric = Gem::OptionParser::DecimalNumeric
|
|
2455
|
+
# :startdoc:
|
|
2463
2456
|
end
|
|
2464
2457
|
end
|
|
2465
2458
|
|
|
@@ -20,9 +20,9 @@
|
|
|
20
20
|
|
|
21
21
|
module Gem::Timeout
|
|
22
22
|
# The version
|
|
23
|
-
VERSION = "0.
|
|
23
|
+
VERSION = "0.6.1"
|
|
24
24
|
|
|
25
|
-
# Internal
|
|
25
|
+
# Internal exception raised to when a timeout is triggered.
|
|
26
26
|
class ExitException < Exception
|
|
27
27
|
def exception(*) # :nodoc:
|
|
28
28
|
self
|
|
@@ -44,12 +44,101 @@ module Gem::Timeout
|
|
|
44
44
|
end
|
|
45
45
|
|
|
46
46
|
# :stopdoc:
|
|
47
|
-
|
|
48
|
-
|
|
49
|
-
|
|
50
|
-
|
|
51
|
-
|
|
52
|
-
|
|
47
|
+
|
|
48
|
+
# We keep a private reference so that time mocking libraries won't break Gem::Timeout.
|
|
49
|
+
GET_TIME = Process.method(:clock_gettime)
|
|
50
|
+
if defined?(Ractor.make_shareable)
|
|
51
|
+
# Ractor.make_shareable(Method) only works on Ruby 4+
|
|
52
|
+
Ractor.make_shareable(GET_TIME) rescue nil
|
|
53
|
+
end
|
|
54
|
+
private_constant :GET_TIME
|
|
55
|
+
|
|
56
|
+
class State
|
|
57
|
+
def initialize
|
|
58
|
+
@condvar = ConditionVariable.new
|
|
59
|
+
@queue = Queue.new
|
|
60
|
+
@queue_mutex = Mutex.new
|
|
61
|
+
|
|
62
|
+
@timeout_thread = nil
|
|
63
|
+
@timeout_thread_mutex = Mutex.new
|
|
64
|
+
end
|
|
65
|
+
|
|
66
|
+
if defined?(Ractor.store_if_absent) && defined?(Ractor.shareable?) && Ractor.shareable?(GET_TIME)
|
|
67
|
+
# Ractor support if
|
|
68
|
+
# 1. Ractor.store_if_absent is available
|
|
69
|
+
# 2. Method object can be shareable (4.0~)
|
|
70
|
+
def self.instance
|
|
71
|
+
Ractor.store_if_absent :timeout_gem_state do
|
|
72
|
+
State.new
|
|
73
|
+
end
|
|
74
|
+
end
|
|
75
|
+
else
|
|
76
|
+
GLOBAL_STATE = State.new
|
|
77
|
+
|
|
78
|
+
def self.instance
|
|
79
|
+
GLOBAL_STATE
|
|
80
|
+
end
|
|
81
|
+
end
|
|
82
|
+
|
|
83
|
+
def create_timeout_thread
|
|
84
|
+
# Threads unexpectedly inherit the interrupt mask: https://github.com/ruby/timeout/issues/41
|
|
85
|
+
# So reset the interrupt mask to the default one for the timeout thread
|
|
86
|
+
Thread.handle_interrupt(Object => :immediate) do
|
|
87
|
+
watcher = Thread.new do
|
|
88
|
+
requests = []
|
|
89
|
+
while true
|
|
90
|
+
until @queue.empty? and !requests.empty? # wait to have at least one request
|
|
91
|
+
req = @queue.pop
|
|
92
|
+
requests << req unless req.done?
|
|
93
|
+
end
|
|
94
|
+
closest_deadline = requests.min_by(&:deadline).deadline
|
|
95
|
+
|
|
96
|
+
now = 0.0
|
|
97
|
+
@queue_mutex.synchronize do
|
|
98
|
+
while (now = GET_TIME.call(Process::CLOCK_MONOTONIC)) < closest_deadline and @queue.empty?
|
|
99
|
+
@condvar.wait(@queue_mutex, closest_deadline - now)
|
|
100
|
+
end
|
|
101
|
+
end
|
|
102
|
+
|
|
103
|
+
requests.each do |req|
|
|
104
|
+
req.interrupt if req.expired?(now)
|
|
105
|
+
end
|
|
106
|
+
requests.reject!(&:done?)
|
|
107
|
+
end
|
|
108
|
+
end
|
|
109
|
+
|
|
110
|
+
if !watcher.group.enclosed? && (!defined?(Ractor.main?) || Ractor.main?)
|
|
111
|
+
ThreadGroup::Default.add(watcher)
|
|
112
|
+
end
|
|
113
|
+
|
|
114
|
+
watcher.name = "Gem::Timeout stdlib thread"
|
|
115
|
+
watcher.thread_variable_set(:"\0__detached_thread__", true)
|
|
116
|
+
watcher
|
|
117
|
+
end
|
|
118
|
+
end
|
|
119
|
+
|
|
120
|
+
def ensure_timeout_thread_created
|
|
121
|
+
unless @timeout_thread&.alive?
|
|
122
|
+
# If the Mutex is already owned we are in a signal handler.
|
|
123
|
+
# In that case, just return and let the main thread create the Gem::Timeout thread.
|
|
124
|
+
return if @timeout_thread_mutex.owned?
|
|
125
|
+
|
|
126
|
+
Sync.synchronize @timeout_thread_mutex do
|
|
127
|
+
unless @timeout_thread&.alive?
|
|
128
|
+
@timeout_thread = create_timeout_thread
|
|
129
|
+
end
|
|
130
|
+
end
|
|
131
|
+
end
|
|
132
|
+
end
|
|
133
|
+
|
|
134
|
+
def add_request(request)
|
|
135
|
+
Sync.synchronize @queue_mutex do
|
|
136
|
+
@queue << request
|
|
137
|
+
@condvar.signal
|
|
138
|
+
end
|
|
139
|
+
end
|
|
140
|
+
end
|
|
141
|
+
private_constant :State
|
|
53
142
|
|
|
54
143
|
class Request
|
|
55
144
|
attr_reader :deadline
|
|
@@ -64,6 +153,7 @@ module Gem::Timeout
|
|
|
64
153
|
@done = false # protected by @mutex
|
|
65
154
|
end
|
|
66
155
|
|
|
156
|
+
# Only called by the timeout thread, so does not need Sync.synchronize
|
|
67
157
|
def done?
|
|
68
158
|
@mutex.synchronize do
|
|
69
159
|
@done
|
|
@@ -74,6 +164,7 @@ module Gem::Timeout
|
|
|
74
164
|
now >= @deadline
|
|
75
165
|
end
|
|
76
166
|
|
|
167
|
+
# Only called by the timeout thread, so does not need Sync.synchronize
|
|
77
168
|
def interrupt
|
|
78
169
|
@mutex.synchronize do
|
|
79
170
|
unless @done
|
|
@@ -84,64 +175,36 @@ module Gem::Timeout
|
|
|
84
175
|
end
|
|
85
176
|
|
|
86
177
|
def finished
|
|
87
|
-
|
|
178
|
+
Sync.synchronize @mutex do
|
|
88
179
|
@done = true
|
|
89
180
|
end
|
|
90
181
|
end
|
|
91
182
|
end
|
|
92
183
|
private_constant :Request
|
|
93
184
|
|
|
94
|
-
|
|
95
|
-
|
|
96
|
-
|
|
97
|
-
|
|
98
|
-
|
|
99
|
-
|
|
100
|
-
|
|
101
|
-
|
|
102
|
-
|
|
103
|
-
|
|
104
|
-
|
|
105
|
-
|
|
106
|
-
|
|
107
|
-
|
|
108
|
-
|
|
109
|
-
end
|
|
110
|
-
|
|
111
|
-
requests.each do |req|
|
|
112
|
-
req.interrupt if req.expired?(now)
|
|
113
|
-
end
|
|
114
|
-
requests.reject!(&:done?)
|
|
115
|
-
end
|
|
116
|
-
end
|
|
117
|
-
ThreadGroup::Default.add(watcher) unless watcher.group.enclosed?
|
|
118
|
-
watcher.name = "Gem::Timeout stdlib thread"
|
|
119
|
-
watcher.thread_variable_set(:"\0__detached_thread__", true)
|
|
120
|
-
watcher
|
|
121
|
-
end
|
|
122
|
-
private_class_method :create_timeout_thread
|
|
123
|
-
|
|
124
|
-
def self.ensure_timeout_thread_created
|
|
125
|
-
unless @timeout_thread and @timeout_thread.alive?
|
|
126
|
-
# If the Mutex is already owned we are in a signal handler.
|
|
127
|
-
# In that case, just return and let the main thread create the @timeout_thread.
|
|
128
|
-
return if TIMEOUT_THREAD_MUTEX.owned?
|
|
129
|
-
TIMEOUT_THREAD_MUTEX.synchronize do
|
|
130
|
-
unless @timeout_thread and @timeout_thread.alive?
|
|
131
|
-
@timeout_thread = create_timeout_thread
|
|
132
|
-
end
|
|
185
|
+
module Sync
|
|
186
|
+
# Calls mutex.synchronize(&block) but if that fails on CRuby due to being in a trap handler,
|
|
187
|
+
# run mutex.synchronize(&block) in a separate Thread instead.
|
|
188
|
+
def self.synchronize(mutex, &block)
|
|
189
|
+
begin
|
|
190
|
+
mutex.synchronize(&block)
|
|
191
|
+
rescue ThreadError => e
|
|
192
|
+
raise e unless e.message == "can't be called from trap context"
|
|
193
|
+
# Workaround CRuby issue https://bugs.ruby-lang.org/issues/19473
|
|
194
|
+
# which raises on Mutex#synchronize in trap handler.
|
|
195
|
+
# It's expensive to create a Thread just for this,
|
|
196
|
+
# but better than failing.
|
|
197
|
+
Thread.new {
|
|
198
|
+
mutex.synchronize(&block)
|
|
199
|
+
}.join
|
|
133
200
|
end
|
|
134
201
|
end
|
|
135
202
|
end
|
|
136
|
-
|
|
137
|
-
# We keep a private reference so that time mocking libraries won't break
|
|
138
|
-
# Gem::Timeout.
|
|
139
|
-
GET_TIME = Process.method(:clock_gettime)
|
|
140
|
-
private_constant :GET_TIME
|
|
203
|
+
private_constant :Sync
|
|
141
204
|
|
|
142
205
|
# :startdoc:
|
|
143
206
|
|
|
144
|
-
# Perform an operation in a block, raising an
|
|
207
|
+
# Perform an operation in a block, raising an exception if it takes longer than
|
|
145
208
|
# +sec+ seconds to complete.
|
|
146
209
|
#
|
|
147
210
|
# +sec+:: Number of seconds to wait for the block to terminate. Any non-negative number
|
|
@@ -149,45 +212,91 @@ module Gem::Timeout
|
|
|
149
212
|
# value of 0 or +nil+ will execute the block without any timeout.
|
|
150
213
|
# Any negative number will raise an ArgumentError.
|
|
151
214
|
# +klass+:: Exception Class to raise if the block fails to terminate
|
|
152
|
-
# in +sec+ seconds. Omitting will use the default, Gem::Timeout::Error
|
|
215
|
+
# in +sec+ seconds. Omitting will use the default, Gem::Timeout::Error.
|
|
153
216
|
# +message+:: Error message to raise with Exception Class.
|
|
154
|
-
# Omitting will use the default, "execution expired"
|
|
217
|
+
# Omitting will use the default, <tt>"execution expired"</tt>.
|
|
155
218
|
#
|
|
156
219
|
# Returns the result of the block *if* the block completed before
|
|
157
|
-
# +sec+ seconds, otherwise
|
|
220
|
+
# +sec+ seconds, otherwise raises an exception, based on the value of +klass+.
|
|
221
|
+
#
|
|
222
|
+
# The exception raised to terminate the given block is the given +klass+, or
|
|
223
|
+
# Gem::Timeout::ExitException if +klass+ is not given. The reason for that behavior
|
|
224
|
+
# is that Gem::Timeout::Error inherits from RuntimeError and might be caught unexpectedly by +rescue+.
|
|
225
|
+
# Gem::Timeout::ExitException inherits from Exception so it will only be rescued by <tt>rescue Exception</tt>.
|
|
226
|
+
# Note that the Gem::Timeout::ExitException is translated to a Gem::Timeout::Error once it reaches the Gem::Timeout.timeout call,
|
|
227
|
+
# so outside that call it will be a Gem::Timeout::Error.
|
|
158
228
|
#
|
|
159
|
-
#
|
|
160
|
-
# the block
|
|
161
|
-
#
|
|
162
|
-
# method cannot be relied on to enforce timeouts for untrusted blocks.
|
|
229
|
+
# In general, be aware that the code block may rescue the exception, and in such a case not respect the timeout.
|
|
230
|
+
# Also, the block can use +ensure+ to prevent the handling of the exception.
|
|
231
|
+
# For those reasons, this method cannot be relied on to enforce timeouts for untrusted blocks.
|
|
163
232
|
#
|
|
164
233
|
# If a scheduler is defined, it will be used to handle the timeout by invoking
|
|
165
|
-
# Scheduler#timeout_after.
|
|
234
|
+
# Fiber::Scheduler#timeout_after.
|
|
166
235
|
#
|
|
167
236
|
# Note that this is both a method of module Gem::Timeout, so you can <tt>include
|
|
168
237
|
# Gem::Timeout</tt> into your classes so they have a #timeout method, as well as
|
|
169
238
|
# a module method, so you can call it directly as Gem::Timeout.timeout().
|
|
170
|
-
|
|
239
|
+
#
|
|
240
|
+
# ==== Ensuring the exception does not fire inside ensure blocks
|
|
241
|
+
#
|
|
242
|
+
# When using Gem::Timeout.timeout, it can be desirable to ensure the timeout exception does not fire inside an +ensure+ block.
|
|
243
|
+
# The simplest and best way to do so is to put the Gem::Timeout.timeout call inside the body of the +begin+/+ensure+/+end+:
|
|
244
|
+
#
|
|
245
|
+
# begin
|
|
246
|
+
# Gem::Timeout.timeout(sec) { some_long_operation }
|
|
247
|
+
# ensure
|
|
248
|
+
# cleanup # safe, cannot be interrupted by timeout
|
|
249
|
+
# end
|
|
250
|
+
#
|
|
251
|
+
# If that is not feasible, e.g. if there are +ensure+ blocks inside +some_long_operation+,
|
|
252
|
+
# they need to not be interrupted by timeout, and it's not possible to move these ensure blocks outside,
|
|
253
|
+
# one can use Thread.handle_interrupt to delay the timeout exception like so:
|
|
254
|
+
#
|
|
255
|
+
# Thread.handle_interrupt(Gem::Timeout::Error => :never) {
|
|
256
|
+
# Gem::Timeout.timeout(sec, Gem::Timeout::Error) do
|
|
257
|
+
# setup # timeout cannot happen here, no matter how long it takes
|
|
258
|
+
# Thread.handle_interrupt(Gem::Timeout::Error => :immediate) {
|
|
259
|
+
# some_long_operation # timeout can happen here
|
|
260
|
+
# }
|
|
261
|
+
# ensure
|
|
262
|
+
# cleanup # timeout cannot happen here, no matter how long it takes
|
|
263
|
+
# end
|
|
264
|
+
# }
|
|
265
|
+
#
|
|
266
|
+
# An important thing to note is the need to pass an exception +klass+ to Gem::Timeout.timeout,
|
|
267
|
+
# otherwise it does not work. Specifically, using <tt>Thread.handle_interrupt(Gem::Timeout::ExitException => ...)</tt>
|
|
268
|
+
# is unsupported and causes subtle errors like raising the wrong exception outside the block, do not use that.
|
|
269
|
+
#
|
|
270
|
+
# Note that Thread.handle_interrupt is somewhat dangerous because if setup or cleanup hangs
|
|
271
|
+
# then the current thread will hang too and the timeout will never fire.
|
|
272
|
+
# Also note the block might run for longer than +sec+ seconds:
|
|
273
|
+
# e.g. +some_long_operation+ executes for +sec+ seconds + whatever time cleanup takes.
|
|
274
|
+
#
|
|
275
|
+
# If you want the timeout to only happen on blocking operations, one can use +:on_blocking+
|
|
276
|
+
# instead of +:immediate+. However, that means if the block uses no blocking operations after +sec+ seconds,
|
|
277
|
+
# the block will not be interrupted.
|
|
278
|
+
def self.timeout(sec, klass = nil, message = nil, &block) #:yield: +sec+
|
|
171
279
|
return yield(sec) if sec == nil or sec.zero?
|
|
172
280
|
raise ArgumentError, "Timeout sec must be a non-negative number" if 0 > sec
|
|
173
281
|
|
|
174
282
|
message ||= "execution expired"
|
|
175
283
|
|
|
176
284
|
if Fiber.respond_to?(:current_scheduler) && (scheduler = Fiber.current_scheduler)&.respond_to?(:timeout_after)
|
|
177
|
-
|
|
178
|
-
|
|
179
|
-
|
|
180
|
-
Gem::Timeout.ensure_timeout_thread_created
|
|
181
|
-
perform = Proc.new do |exc|
|
|
182
|
-
request = Request.new(Thread.current, sec, exc, message)
|
|
183
|
-
QUEUE_MUTEX.synchronize do
|
|
184
|
-
QUEUE << request
|
|
185
|
-
CONDVAR.signal
|
|
285
|
+
perform = Proc.new do |exc|
|
|
286
|
+
scheduler.timeout_after(sec, exc, message, &block)
|
|
186
287
|
end
|
|
187
|
-
|
|
188
|
-
|
|
189
|
-
|
|
190
|
-
|
|
288
|
+
else
|
|
289
|
+
state = State.instance
|
|
290
|
+
state.ensure_timeout_thread_created
|
|
291
|
+
|
|
292
|
+
perform = Proc.new do |exc|
|
|
293
|
+
request = Request.new(Thread.current, sec, exc, message)
|
|
294
|
+
state.add_request(request)
|
|
295
|
+
begin
|
|
296
|
+
return yield(sec)
|
|
297
|
+
ensure
|
|
298
|
+
request.finished
|
|
299
|
+
end
|
|
191
300
|
end
|
|
192
301
|
end
|
|
193
302
|
|
|
@@ -197,5 +306,9 @@ module Gem::Timeout
|
|
|
197
306
|
Error.handle_timeout(message, &perform)
|
|
198
307
|
end
|
|
199
308
|
end
|
|
200
|
-
|
|
309
|
+
|
|
310
|
+
# See Gem::Timeout.timeout
|
|
311
|
+
private def timeout(*args, &block)
|
|
312
|
+
Gem::Timeout.timeout(*args, &block)
|
|
313
|
+
end
|
|
201
314
|
end
|
|
@@ -466,7 +466,7 @@ module Gem::URI
|
|
|
466
466
|
#
|
|
467
467
|
# uri = Gem::URI.parse("http://john:S3nsit1ve@my.example.com")
|
|
468
468
|
# uri.user = "sam"
|
|
469
|
-
# uri.to_s #=> "http://sam
|
|
469
|
+
# uri.to_s #=> "http://sam@my.example.com"
|
|
470
470
|
#
|
|
471
471
|
def user=(user)
|
|
472
472
|
check_user(user)
|
|
@@ -1021,9 +1021,21 @@ module Gem::URI
|
|
|
1021
1021
|
|
|
1022
1022
|
# RFC2396, Section 5.2, 6), a)
|
|
1023
1023
|
base_path << '' if base_path.last == '..'
|
|
1024
|
-
|
|
1025
|
-
|
|
1024
|
+
# Remove "<segment>/.." pairs in a single left-to-right pass (O(n)).
|
|
1025
|
+
# This deliberately differs from the relative-path stack handling
|
|
1026
|
+
# below: a leading ".." (one with no preceding segment left to
|
|
1027
|
+
# cancel) discards the whole base path, reproducing the previous
|
|
1028
|
+
# index/slice! implementation exactly.
|
|
1029
|
+
reduced = []
|
|
1030
|
+
base_path.each do |seg|
|
|
1031
|
+
if seg == '..'
|
|
1032
|
+
break if reduced.empty?
|
|
1033
|
+
reduced.pop
|
|
1034
|
+
else
|
|
1035
|
+
reduced << seg
|
|
1036
|
+
end
|
|
1026
1037
|
end
|
|
1038
|
+
base_path = reduced
|
|
1027
1039
|
|
|
1028
1040
|
if (first = rel_path.first) and first.empty?
|
|
1029
1041
|
base_path.clear
|
data/lib/rubygems.rb
CHANGED
metadata
CHANGED
|
@@ -1,7 +1,7 @@
|
|
|
1
1
|
--- !ruby/object:Gem::Specification
|
|
2
2
|
name: rubygems-update
|
|
3
3
|
version: !ruby/object:Gem::Version
|
|
4
|
-
version: 4.0.
|
|
4
|
+
version: 4.0.23
|
|
5
5
|
platform: ruby
|
|
6
6
|
authors:
|
|
7
7
|
- Jim Weirich
|
|
@@ -649,7 +649,7 @@ files:
|
|
|
649
649
|
- lib/rubygems/vendor/net-http/lib/net/http/responses.rb
|
|
650
650
|
- lib/rubygems/vendor/net-http/lib/net/http/status.rb
|
|
651
651
|
- lib/rubygems/vendor/net-http/lib/net/https.rb
|
|
652
|
-
- lib/rubygems/vendor/net-protocol/
|
|
652
|
+
- lib/rubygems/vendor/net-protocol/COPYING
|
|
653
653
|
- lib/rubygems/vendor/net-protocol/lib/net/protocol.rb
|
|
654
654
|
- lib/rubygems/vendor/optparse/COPYING
|
|
655
655
|
- lib/rubygems/vendor/optparse/lib/optionparser.rb
|
|
@@ -1,22 +0,0 @@
|
|
|
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.
|