activesupport 4.2.0 → 5.2.0
Sign up to get free protection for your applications and to get access to all the features.
Potentially problematic release.
This version of activesupport might be problematic. Click here for more details.
- checksums.yaml +5 -5
- data/CHANGELOG.md +366 -232
- data/MIT-LICENSE +2 -2
- data/README.rdoc +4 -5
- data/lib/active_support.rb +17 -7
- data/lib/active_support/all.rb +5 -3
- data/lib/active_support/array_inquirer.rb +48 -0
- data/lib/active_support/backtrace_cleaner.rb +7 -5
- data/lib/active_support/benchmarkable.rb +6 -4
- data/lib/active_support/builder.rb +3 -1
- data/lib/active_support/cache.rb +271 -177
- data/lib/active_support/cache/file_store.rb +41 -35
- data/lib/active_support/cache/mem_cache_store.rb +97 -88
- data/lib/active_support/cache/memory_store.rb +27 -30
- data/lib/active_support/cache/null_store.rb +7 -8
- data/lib/active_support/cache/redis_cache_store.rb +454 -0
- data/lib/active_support/cache/strategy/local_cache.rb +67 -34
- data/lib/active_support/cache/strategy/local_cache_middleware.rb +10 -9
- data/lib/active_support/callbacks.rb +654 -560
- data/lib/active_support/concern.rb +5 -3
- data/lib/active_support/concurrency/load_interlock_aware_monitor.rb +17 -0
- data/lib/active_support/concurrency/share_lock.rb +227 -0
- data/lib/active_support/configurable.rb +8 -5
- data/lib/active_support/core_ext.rb +3 -1
- data/lib/active_support/core_ext/array.rb +9 -6
- data/lib/active_support/core_ext/array/access.rb +29 -1
- data/lib/active_support/core_ext/array/conversions.rb +22 -18
- data/lib/active_support/core_ext/array/extract_options.rb +2 -0
- data/lib/active_support/core_ext/array/grouping.rb +11 -18
- data/lib/active_support/core_ext/array/inquiry.rb +19 -0
- data/lib/active_support/core_ext/array/prepend_and_append.rb +5 -3
- data/lib/active_support/core_ext/array/wrap.rb +7 -4
- data/lib/active_support/core_ext/benchmark.rb +3 -1
- data/lib/active_support/core_ext/big_decimal.rb +3 -1
- data/lib/active_support/core_ext/big_decimal/conversions.rb +10 -12
- data/lib/active_support/core_ext/class.rb +4 -3
- data/lib/active_support/core_ext/class/attribute.rb +41 -22
- data/lib/active_support/core_ext/class/attribute_accessors.rb +3 -1
- data/lib/active_support/core_ext/class/subclasses.rb +20 -8
- data/lib/active_support/core_ext/date.rb +6 -4
- data/lib/active_support/core_ext/date/acts_like.rb +3 -1
- data/lib/active_support/core_ext/date/blank.rb +14 -0
- data/lib/active_support/core_ext/date/calculations.rb +11 -9
- data/lib/active_support/core_ext/date/conversions.rb +31 -23
- data/lib/active_support/core_ext/date/zones.rb +4 -2
- data/lib/active_support/core_ext/date_and_time/calculations.rb +179 -56
- data/lib/active_support/core_ext/date_and_time/compatibility.rb +16 -0
- data/lib/active_support/core_ext/date_and_time/zones.rb +12 -12
- data/lib/active_support/core_ext/date_time.rb +7 -4
- data/lib/active_support/core_ext/date_time/acts_like.rb +4 -2
- data/lib/active_support/core_ext/date_time/blank.rb +14 -0
- data/lib/active_support/core_ext/date_time/calculations.rb +58 -20
- data/lib/active_support/core_ext/date_time/compatibility.rb +18 -0
- data/lib/active_support/core_ext/date_time/conversions.rb +16 -12
- data/lib/active_support/core_ext/digest/uuid.rb +7 -5
- data/lib/active_support/core_ext/enumerable.rb +107 -28
- data/lib/active_support/core_ext/file.rb +3 -1
- data/lib/active_support/core_ext/file/atomic.rb +38 -31
- data/lib/active_support/core_ext/hash.rb +11 -9
- data/lib/active_support/core_ext/hash/compact.rb +24 -15
- data/lib/active_support/core_ext/hash/conversions.rb +63 -43
- data/lib/active_support/core_ext/hash/deep_merge.rb +9 -13
- data/lib/active_support/core_ext/hash/except.rb +11 -8
- data/lib/active_support/core_ext/hash/indifferent_access.rb +4 -3
- data/lib/active_support/core_ext/hash/keys.rb +33 -27
- data/lib/active_support/core_ext/hash/reverse_merge.rb +5 -2
- data/lib/active_support/core_ext/hash/slice.rb +8 -8
- data/lib/active_support/core_ext/hash/transform_values.rb +16 -7
- data/lib/active_support/core_ext/integer.rb +5 -3
- data/lib/active_support/core_ext/integer/inflections.rb +3 -1
- data/lib/active_support/core_ext/integer/multiple.rb +2 -0
- data/lib/active_support/core_ext/integer/time.rb +11 -33
- data/lib/active_support/core_ext/kernel.rb +6 -5
- data/lib/active_support/core_ext/kernel/agnostics.rb +2 -0
- data/lib/active_support/core_ext/kernel/concern.rb +5 -1
- data/lib/active_support/core_ext/kernel/reporting.rb +4 -83
- data/lib/active_support/core_ext/kernel/singleton_class.rb +2 -0
- data/lib/active_support/core_ext/load_error.rb +3 -22
- data/lib/active_support/core_ext/marshal.rb +13 -10
- data/lib/active_support/core_ext/module.rb +14 -11
- data/lib/active_support/core_ext/module/aliasing.rb +6 -44
- data/lib/active_support/core_ext/module/anonymous.rb +12 -1
- data/lib/active_support/core_ext/module/attr_internal.rb +8 -9
- data/lib/active_support/core_ext/module/attribute_accessors.rb +43 -40
- data/lib/active_support/core_ext/module/attribute_accessors_per_thread.rb +150 -0
- data/lib/active_support/core_ext/module/concerning.rb +11 -12
- data/lib/active_support/core_ext/module/delegation.rb +121 -39
- data/lib/active_support/core_ext/module/deprecation.rb +4 -2
- data/lib/active_support/core_ext/module/introspection.rb +9 -9
- data/lib/active_support/core_ext/module/reachable.rb +5 -2
- data/lib/active_support/core_ext/module/redefine_method.rb +49 -0
- data/lib/active_support/core_ext/module/remove_method.rb +8 -3
- data/lib/active_support/core_ext/name_error.rb +22 -2
- data/lib/active_support/core_ext/numeric.rb +6 -3
- data/lib/active_support/core_ext/numeric/bytes.rb +22 -0
- data/lib/active_support/core_ext/numeric/conversions.rb +79 -74
- data/lib/active_support/core_ext/numeric/inquiry.rb +28 -0
- data/lib/active_support/core_ext/numeric/time.rb +35 -38
- data/lib/active_support/core_ext/object.rb +14 -13
- data/lib/active_support/core_ext/object/acts_like.rb +12 -1
- data/lib/active_support/core_ext/object/blank.rb +29 -4
- data/lib/active_support/core_ext/object/conversions.rb +6 -4
- data/lib/active_support/core_ext/object/deep_dup.rb +13 -4
- data/lib/active_support/core_ext/object/duplicable.rb +98 -45
- data/lib/active_support/core_ext/object/inclusion.rb +5 -3
- data/lib/active_support/core_ext/object/instance_variables.rb +3 -1
- data/lib/active_support/core_ext/object/json.rb +49 -19
- data/lib/active_support/core_ext/object/to_param.rb +3 -1
- data/lib/active_support/core_ext/object/to_query.rb +6 -4
- data/lib/active_support/core_ext/object/try.rb +70 -22
- data/lib/active_support/core_ext/object/with_options.rb +16 -3
- data/lib/active_support/core_ext/range.rb +7 -4
- data/lib/active_support/core_ext/range/conversions.rb +27 -7
- data/lib/active_support/core_ext/range/each.rb +19 -17
- data/lib/active_support/core_ext/range/include_range.rb +21 -19
- data/lib/active_support/core_ext/range/include_time_with_zone.rb +23 -0
- data/lib/active_support/core_ext/range/overlaps.rb +2 -0
- data/lib/active_support/core_ext/regexp.rb +6 -0
- data/lib/active_support/core_ext/securerandom.rb +25 -0
- data/lib/active_support/core_ext/string.rb +15 -13
- data/lib/active_support/core_ext/string/access.rb +9 -7
- data/lib/active_support/core_ext/string/behavior.rb +3 -1
- data/lib/active_support/core_ext/string/conversions.rb +8 -5
- data/lib/active_support/core_ext/string/exclude.rb +2 -0
- data/lib/active_support/core_ext/string/filters.rb +10 -8
- data/lib/active_support/core_ext/string/indent.rb +6 -4
- data/lib/active_support/core_ext/string/inflections.rb +61 -24
- data/lib/active_support/core_ext/string/inquiry.rb +3 -1
- data/lib/active_support/core_ext/string/multibyte.rb +15 -7
- data/lib/active_support/core_ext/string/output_safety.rb +35 -35
- data/lib/active_support/core_ext/string/starts_ends_with.rb +2 -0
- data/lib/active_support/core_ext/string/strip.rb +4 -5
- data/lib/active_support/core_ext/string/zones.rb +4 -2
- data/lib/active_support/core_ext/time.rb +7 -5
- data/lib/active_support/core_ext/time/acts_like.rb +3 -1
- data/lib/active_support/core_ext/time/calculations.rb +101 -51
- data/lib/active_support/core_ext/time/compatibility.rb +16 -0
- data/lib/active_support/core_ext/time/conversions.rb +20 -13
- data/lib/active_support/core_ext/time/zones.rb +41 -7
- data/lib/active_support/core_ext/uri.rb +5 -4
- data/lib/active_support/current_attributes.rb +195 -0
- data/lib/active_support/dependencies.rb +143 -160
- data/lib/active_support/dependencies/autoload.rb +2 -0
- data/lib/active_support/dependencies/interlock.rb +57 -0
- data/lib/active_support/deprecation.rb +12 -9
- data/lib/active_support/deprecation/behaviors.rb +41 -12
- data/lib/active_support/deprecation/constant_accessor.rb +52 -0
- data/lib/active_support/deprecation/instance_delegator.rb +17 -2
- data/lib/active_support/deprecation/method_wrappers.rb +54 -21
- data/lib/active_support/deprecation/proxy_wrappers.rb +56 -28
- data/lib/active_support/deprecation/reporting.rb +32 -12
- data/lib/active_support/descendants_tracker.rb +2 -0
- data/lib/active_support/digest.rb +20 -0
- data/lib/active_support/duration.rb +326 -30
- data/lib/active_support/duration/iso8601_parser.rb +125 -0
- data/lib/active_support/duration/iso8601_serializer.rb +55 -0
- data/lib/active_support/encrypted_configuration.rb +49 -0
- data/lib/active_support/encrypted_file.rb +99 -0
- data/lib/active_support/evented_file_update_checker.rb +205 -0
- data/lib/active_support/execution_wrapper.rb +128 -0
- data/lib/active_support/executor.rb +8 -0
- data/lib/active_support/file_update_checker.rb +63 -37
- data/lib/active_support/gem_version.rb +4 -2
- data/lib/active_support/gzip.rb +7 -5
- data/lib/active_support/hash_with_indifferent_access.rb +130 -30
- data/lib/active_support/i18n.rb +8 -6
- data/lib/active_support/i18n_railtie.rb +34 -14
- data/lib/active_support/inflections.rb +13 -11
- data/lib/active_support/inflector.rb +7 -5
- data/lib/active_support/inflector/inflections.rb +61 -12
- data/lib/active_support/inflector/methods.rb +161 -136
- data/lib/active_support/inflector/transliterate.rb +48 -27
- data/lib/active_support/json.rb +4 -2
- data/lib/active_support/json/decoding.rb +16 -13
- data/lib/active_support/json/encoding.rb +15 -57
- data/lib/active_support/key_generator.rb +25 -25
- data/lib/active_support/lazy_load_hooks.rb +50 -20
- data/lib/active_support/locale/en.yml +2 -0
- data/lib/active_support/log_subscriber.rb +13 -10
- data/lib/active_support/log_subscriber/test_helper.rb +14 -12
- data/lib/active_support/logger.rb +54 -3
- data/lib/active_support/logger_silence.rb +12 -7
- data/lib/active_support/logger_thread_safe_level.rb +33 -0
- data/lib/active_support/message_encryptor.rb +173 -51
- data/lib/active_support/message_verifier.rb +150 -17
- data/lib/active_support/messages/metadata.rb +71 -0
- data/lib/active_support/messages/rotation_configuration.rb +22 -0
- data/lib/active_support/messages/rotator.rb +56 -0
- data/lib/active_support/multibyte.rb +4 -2
- data/lib/active_support/multibyte/chars.rb +37 -24
- data/lib/active_support/multibyte/unicode.rb +100 -96
- data/lib/active_support/notifications.rb +11 -7
- data/lib/active_support/notifications/fanout.rb +10 -8
- data/lib/active_support/notifications/instrumenter.rb +27 -7
- data/lib/active_support/number_helper.rb +94 -68
- data/lib/active_support/number_helper/number_converter.rb +13 -11
- data/lib/active_support/number_helper/number_to_currency_converter.rb +9 -9
- data/lib/active_support/number_helper/number_to_delimited_converter.rb +9 -3
- data/lib/active_support/number_helper/number_to_human_converter.rb +11 -9
- data/lib/active_support/number_helper/number_to_human_size_converter.rb +9 -8
- data/lib/active_support/number_helper/number_to_percentage_converter.rb +3 -1
- data/lib/active_support/number_helper/number_to_phone_converter.rb +13 -4
- data/lib/active_support/number_helper/number_to_rounded_converter.rb +23 -56
- data/lib/active_support/number_helper/rounding_helper.rb +66 -0
- data/lib/active_support/option_merger.rb +3 -1
- data/lib/active_support/ordered_hash.rb +6 -4
- data/lib/active_support/ordered_options.rb +22 -4
- data/lib/active_support/per_thread_registry.rb +13 -6
- data/lib/active_support/proxy_object.rb +2 -0
- data/lib/active_support/rails.rb +16 -8
- data/lib/active_support/railtie.rb +43 -9
- data/lib/active_support/reloader.rb +131 -0
- data/lib/active_support/rescuable.rb +108 -53
- data/lib/active_support/security_utils.rb +17 -6
- data/lib/active_support/string_inquirer.rb +11 -3
- data/lib/active_support/subscriber.rb +15 -14
- data/lib/active_support/tagged_logging.rb +14 -11
- data/lib/active_support/test_case.rb +18 -46
- data/lib/active_support/testing/assertions.rb +137 -20
- data/lib/active_support/testing/autorun.rb +4 -2
- data/lib/active_support/testing/constant_lookup.rb +2 -1
- data/lib/active_support/testing/declarative.rb +3 -1
- data/lib/active_support/testing/deprecation.rb +14 -10
- data/lib/active_support/testing/file_fixtures.rb +36 -0
- data/lib/active_support/testing/isolation.rb +34 -25
- data/lib/active_support/testing/method_call_assertions.rb +43 -0
- data/lib/active_support/testing/setup_and_teardown.rb +12 -3
- data/lib/active_support/testing/stream.rb +44 -0
- data/lib/active_support/testing/tagged_logging.rb +3 -1
- data/lib/active_support/testing/time_helpers.rb +96 -27
- data/lib/active_support/time.rb +14 -12
- data/lib/active_support/time_with_zone.rb +195 -53
- data/lib/active_support/values/time_zone.rb +200 -61
- data/lib/active_support/values/unicode_tables.dat +0 -0
- data/lib/active_support/version.rb +3 -1
- data/lib/active_support/xml_mini.rb +69 -51
- data/lib/active_support/xml_mini/jdom.rb +116 -113
- data/lib/active_support/xml_mini/libxml.rb +17 -16
- data/lib/active_support/xml_mini/libxmlsax.rb +16 -18
- data/lib/active_support/xml_mini/nokogiri.rb +15 -15
- data/lib/active_support/xml_mini/nokogirisax.rb +15 -16
- data/lib/active_support/xml_mini/rexml.rb +17 -16
- metadata +55 -43
- data/lib/active_support/concurrency/latch.rb +0 -27
- data/lib/active_support/core_ext/big_decimal/yaml_conversions.rb +0 -14
- data/lib/active_support/core_ext/class/delegating_attributes.rb +0 -45
- data/lib/active_support/core_ext/date_time/zones.rb +0 -6
- data/lib/active_support/core_ext/kernel/debugger.rb +0 -10
- data/lib/active_support/core_ext/module/method_transplanting.rb +0 -11
- data/lib/active_support/core_ext/module/qualified_const.rb +0 -52
- data/lib/active_support/core_ext/object/itself.rb +0 -15
- data/lib/active_support/core_ext/struct.rb +0 -6
- data/lib/active_support/core_ext/thread.rb +0 -86
- data/lib/active_support/core_ext/time/marshal.rb +0 -30
@@ -0,0 +1,128 @@
|
|
1
|
+
# frozen_string_literal: true
|
2
|
+
|
3
|
+
require "active_support/callbacks"
|
4
|
+
|
5
|
+
module ActiveSupport
|
6
|
+
class ExecutionWrapper
|
7
|
+
include ActiveSupport::Callbacks
|
8
|
+
|
9
|
+
Null = Object.new # :nodoc:
|
10
|
+
def Null.complete! # :nodoc:
|
11
|
+
end
|
12
|
+
|
13
|
+
define_callbacks :run
|
14
|
+
define_callbacks :complete
|
15
|
+
|
16
|
+
def self.to_run(*args, &block)
|
17
|
+
set_callback(:run, *args, &block)
|
18
|
+
end
|
19
|
+
|
20
|
+
def self.to_complete(*args, &block)
|
21
|
+
set_callback(:complete, *args, &block)
|
22
|
+
end
|
23
|
+
|
24
|
+
RunHook = Struct.new(:hook) do # :nodoc:
|
25
|
+
def before(target)
|
26
|
+
hook_state = target.send(:hook_state)
|
27
|
+
hook_state[hook] = hook.run
|
28
|
+
end
|
29
|
+
end
|
30
|
+
|
31
|
+
CompleteHook = Struct.new(:hook) do # :nodoc:
|
32
|
+
def before(target)
|
33
|
+
hook_state = target.send(:hook_state)
|
34
|
+
if hook_state.key?(hook)
|
35
|
+
hook.complete hook_state[hook]
|
36
|
+
end
|
37
|
+
end
|
38
|
+
alias after before
|
39
|
+
end
|
40
|
+
|
41
|
+
# Register an object to be invoked during both the +run+ and
|
42
|
+
# +complete+ steps.
|
43
|
+
#
|
44
|
+
# +hook.complete+ will be passed the value returned from +hook.run+,
|
45
|
+
# and will only be invoked if +run+ has previously been called.
|
46
|
+
# (Mostly, this means it won't be invoked if an exception occurs in
|
47
|
+
# a preceding +to_run+ block; all ordinary +to_complete+ blocks are
|
48
|
+
# invoked in that situation.)
|
49
|
+
def self.register_hook(hook, outer: false)
|
50
|
+
if outer
|
51
|
+
to_run RunHook.new(hook), prepend: true
|
52
|
+
to_complete :after, CompleteHook.new(hook)
|
53
|
+
else
|
54
|
+
to_run RunHook.new(hook)
|
55
|
+
to_complete CompleteHook.new(hook)
|
56
|
+
end
|
57
|
+
end
|
58
|
+
|
59
|
+
# Run this execution.
|
60
|
+
#
|
61
|
+
# Returns an instance, whose +complete!+ method *must* be invoked
|
62
|
+
# after the work has been performed.
|
63
|
+
#
|
64
|
+
# Where possible, prefer +wrap+.
|
65
|
+
def self.run!
|
66
|
+
if active?
|
67
|
+
Null
|
68
|
+
else
|
69
|
+
new.tap do |instance|
|
70
|
+
success = nil
|
71
|
+
begin
|
72
|
+
instance.run!
|
73
|
+
success = true
|
74
|
+
ensure
|
75
|
+
instance.complete! unless success
|
76
|
+
end
|
77
|
+
end
|
78
|
+
end
|
79
|
+
end
|
80
|
+
|
81
|
+
# Perform the work in the supplied block as an execution.
|
82
|
+
def self.wrap
|
83
|
+
return yield if active?
|
84
|
+
|
85
|
+
instance = run!
|
86
|
+
begin
|
87
|
+
yield
|
88
|
+
ensure
|
89
|
+
instance.complete!
|
90
|
+
end
|
91
|
+
end
|
92
|
+
|
93
|
+
class << self # :nodoc:
|
94
|
+
attr_accessor :active
|
95
|
+
end
|
96
|
+
|
97
|
+
def self.inherited(other) # :nodoc:
|
98
|
+
super
|
99
|
+
other.active = Concurrent::Hash.new
|
100
|
+
end
|
101
|
+
|
102
|
+
self.active = Concurrent::Hash.new
|
103
|
+
|
104
|
+
def self.active? # :nodoc:
|
105
|
+
@active[Thread.current]
|
106
|
+
end
|
107
|
+
|
108
|
+
def run! # :nodoc:
|
109
|
+
self.class.active[Thread.current] = true
|
110
|
+
run_callbacks(:run)
|
111
|
+
end
|
112
|
+
|
113
|
+
# Complete this in-flight execution. This method *must* be called
|
114
|
+
# exactly once on the result of any call to +run!+.
|
115
|
+
#
|
116
|
+
# Where possible, prefer +wrap+.
|
117
|
+
def complete!
|
118
|
+
run_callbacks(:complete)
|
119
|
+
ensure
|
120
|
+
self.class.active.delete Thread.current
|
121
|
+
end
|
122
|
+
|
123
|
+
private
|
124
|
+
def hook_state
|
125
|
+
@_hook_state ||= {}
|
126
|
+
end
|
127
|
+
end
|
128
|
+
end
|
@@ -1,3 +1,7 @@
|
|
1
|
+
# frozen_string_literal: true
|
2
|
+
|
3
|
+
require "active_support/core_ext/time/calculations"
|
4
|
+
|
1
5
|
module ActiveSupport
|
2
6
|
# FileUpdateChecker specifies the API used by Rails to watch files
|
3
7
|
# and control reloading. The API depends on four methods:
|
@@ -23,7 +27,7 @@ module ActiveSupport
|
|
23
27
|
# I18n.reload!
|
24
28
|
# end
|
25
29
|
#
|
26
|
-
#
|
30
|
+
# ActiveSupport::Reloader.to_prepare do
|
27
31
|
# i18n_reloader.execute_if_updated
|
28
32
|
# end
|
29
33
|
class FileUpdateChecker
|
@@ -35,7 +39,11 @@ module ActiveSupport
|
|
35
39
|
# This method must also receive a block that will be called once a path
|
36
40
|
# changes. The array of files and list of directories cannot be changed
|
37
41
|
# after FileUpdateChecker has been initialized.
|
38
|
-
def initialize(files, dirs={}, &block)
|
42
|
+
def initialize(files, dirs = {}, &block)
|
43
|
+
unless block
|
44
|
+
raise ArgumentError, "A block is required to initialize a FileUpdateChecker"
|
45
|
+
end
|
46
|
+
|
39
47
|
@files = files.freeze
|
40
48
|
@glob = compile_glob(dirs)
|
41
49
|
@block = block
|
@@ -81,6 +89,7 @@ module ActiveSupport
|
|
81
89
|
# Execute the block given if updated.
|
82
90
|
def execute_if_updated
|
83
91
|
if updated?
|
92
|
+
yield if block_given?
|
84
93
|
execute
|
85
94
|
true
|
86
95
|
else
|
@@ -90,48 +99,65 @@ module ActiveSupport
|
|
90
99
|
|
91
100
|
private
|
92
101
|
|
93
|
-
|
94
|
-
|
95
|
-
|
96
|
-
|
97
|
-
|
102
|
+
def watched
|
103
|
+
@watched || begin
|
104
|
+
all = @files.select { |f| File.exist?(f) }
|
105
|
+
all.concat(Dir[@glob]) if @glob
|
106
|
+
all
|
107
|
+
end
|
98
108
|
end
|
99
|
-
end
|
100
109
|
|
101
|
-
|
102
|
-
|
103
|
-
|
110
|
+
def updated_at(paths)
|
111
|
+
@updated_at || max_mtime(paths) || Time.at(0)
|
112
|
+
end
|
104
113
|
|
105
|
-
|
106
|
-
|
107
|
-
|
108
|
-
|
109
|
-
|
110
|
-
|
111
|
-
|
112
|
-
|
113
|
-
|
114
|
-
|
115
|
-
|
114
|
+
# This method returns the maximum mtime of the files in +paths+, or +nil+
|
115
|
+
# if the array is empty.
|
116
|
+
#
|
117
|
+
# Files with a mtime in the future are ignored. Such abnormal situation
|
118
|
+
# can happen for example if the user changes the clock by hand. It is
|
119
|
+
# healthy to consider this edge case because with mtimes in the future
|
120
|
+
# reloading is not triggered.
|
121
|
+
def max_mtime(paths)
|
122
|
+
time_now = Time.now
|
123
|
+
max_mtime = nil
|
124
|
+
|
125
|
+
# Time comparisons are performed with #compare_without_coercion because
|
126
|
+
# AS redefines these operators in a way that is much slower and does not
|
127
|
+
# bring any benefit in this particular code.
|
128
|
+
#
|
129
|
+
# Read t1.compare_without_coercion(t2) < 0 as t1 < t2.
|
130
|
+
paths.each do |path|
|
131
|
+
mtime = File.mtime(path)
|
116
132
|
|
117
|
-
|
118
|
-
hash.freeze # Freeze so changes aren't accidentally pushed
|
119
|
-
return if hash.empty?
|
133
|
+
next if time_now.compare_without_coercion(mtime) < 0
|
120
134
|
|
121
|
-
|
122
|
-
|
135
|
+
if max_mtime.nil? || max_mtime.compare_without_coercion(mtime) < 0
|
136
|
+
max_mtime = mtime
|
137
|
+
end
|
138
|
+
end
|
139
|
+
|
140
|
+
max_mtime
|
123
141
|
end
|
124
|
-
"{#{globs.join(",")}}"
|
125
|
-
end
|
126
142
|
|
127
|
-
|
128
|
-
|
129
|
-
|
143
|
+
def compile_glob(hash)
|
144
|
+
hash.freeze # Freeze so changes aren't accidentally pushed
|
145
|
+
return if hash.empty?
|
130
146
|
|
131
|
-
|
132
|
-
|
133
|
-
|
134
|
-
|
135
|
-
|
147
|
+
globs = hash.map do |key, value|
|
148
|
+
"#{escape(key)}/**/*#{compile_ext(value)}"
|
149
|
+
end
|
150
|
+
"{#{globs.join(",")}}"
|
151
|
+
end
|
152
|
+
|
153
|
+
def escape(key)
|
154
|
+
key.gsub(",", '\,')
|
155
|
+
end
|
156
|
+
|
157
|
+
def compile_ext(array)
|
158
|
+
array = Array(array)
|
159
|
+
return if array.empty?
|
160
|
+
".{#{array.join(",")}}"
|
161
|
+
end
|
136
162
|
end
|
137
163
|
end
|
@@ -1,11 +1,13 @@
|
|
1
|
+
# frozen_string_literal: true
|
2
|
+
|
1
3
|
module ActiveSupport
|
2
|
-
# Returns the version of the currently loaded Active Support as a <tt>Gem::Version</tt
|
4
|
+
# Returns the version of the currently loaded Active Support as a <tt>Gem::Version</tt>.
|
3
5
|
def self.gem_version
|
4
6
|
Gem::Version.new VERSION::STRING
|
5
7
|
end
|
6
8
|
|
7
9
|
module VERSION
|
8
|
-
MAJOR =
|
10
|
+
MAJOR = 5
|
9
11
|
MINOR = 2
|
10
12
|
TINY = 0
|
11
13
|
PRE = nil
|
data/lib/active_support/gzip.rb
CHANGED
@@ -1,5 +1,7 @@
|
|
1
|
-
|
2
|
-
|
1
|
+
# frozen_string_literal: true
|
2
|
+
|
3
|
+
require "zlib"
|
4
|
+
require "stringio"
|
3
5
|
|
4
6
|
module ActiveSupport
|
5
7
|
# A convenient wrapper for the zlib standard library that allows
|
@@ -9,7 +11,7 @@ module ActiveSupport
|
|
9
11
|
# # => "\x1F\x8B\b\x00o\x8D\xCDO\x00\x03K\xCE\xCF-(J-.V\xC8MU\x04\x00R>n\x83\f\x00\x00\x00"
|
10
12
|
#
|
11
13
|
# ActiveSupport::Gzip.decompress(gzip)
|
12
|
-
# # => "compress me!"
|
14
|
+
# # => "compress me!"
|
13
15
|
module Gzip
|
14
16
|
class Stream < StringIO
|
15
17
|
def initialize(*)
|
@@ -21,11 +23,11 @@ module ActiveSupport
|
|
21
23
|
|
22
24
|
# Decompresses a gzipped string.
|
23
25
|
def self.decompress(source)
|
24
|
-
Zlib::GzipReader.
|
26
|
+
Zlib::GzipReader.wrap(StringIO.new(source), &:read)
|
25
27
|
end
|
26
28
|
|
27
29
|
# Compresses a string using gzip.
|
28
|
-
def self.compress(source, level=Zlib::DEFAULT_COMPRESSION, strategy=Zlib::DEFAULT_STRATEGY)
|
30
|
+
def self.compress(source, level = Zlib::DEFAULT_COMPRESSION, strategy = Zlib::DEFAULT_STRATEGY)
|
29
31
|
output = Stream.new
|
30
32
|
gz = Zlib::GzipWriter.new(output, level, strategy)
|
31
33
|
gz.write(source)
|
@@ -1,5 +1,7 @@
|
|
1
|
-
|
2
|
-
|
1
|
+
# frozen_string_literal: true
|
2
|
+
|
3
|
+
require "active_support/core_ext/hash/keys"
|
4
|
+
require "active_support/core_ext/hash/reverse_merge"
|
3
5
|
|
4
6
|
module ActiveSupport
|
5
7
|
# Implements a hash where keys <tt>:foo</tt> and <tt>"foo"</tt> are considered
|
@@ -40,6 +42,12 @@ module ActiveSupport
|
|
40
42
|
# rgb = { black: '#000000', white: '#FFFFFF' }.with_indifferent_access
|
41
43
|
#
|
42
44
|
# which may be handy.
|
45
|
+
#
|
46
|
+
# To access this class outside of Rails, require the core extension with:
|
47
|
+
#
|
48
|
+
# require "active_support/core_ext/hash/indifferent_access"
|
49
|
+
#
|
50
|
+
# which will, in turn, require this file.
|
43
51
|
class HashWithIndifferentAccess < Hash
|
44
52
|
# Returns +true+ so that <tt>Array#extract_options!</tt> finds members of
|
45
53
|
# this class.
|
@@ -59,24 +67,12 @@ module ActiveSupport
|
|
59
67
|
if constructor.respond_to?(:to_hash)
|
60
68
|
super()
|
61
69
|
update(constructor)
|
62
|
-
else
|
63
|
-
super(constructor)
|
64
|
-
end
|
65
|
-
end
|
66
70
|
|
67
|
-
|
68
|
-
|
69
|
-
self
|
71
|
+
hash = constructor.to_hash
|
72
|
+
self.default = hash.default if hash.default
|
73
|
+
self.default_proc = hash.default_proc if hash.default_proc
|
70
74
|
else
|
71
|
-
super
|
72
|
-
end
|
73
|
-
end
|
74
|
-
|
75
|
-
def self.new_from_hash_copying_default(hash)
|
76
|
-
hash = hash.to_hash
|
77
|
-
new(hash).tap do |new_hash|
|
78
|
-
new_hash.default = hash.default
|
79
|
-
new_hash.default_proc = hash.default_proc if hash.default_proc
|
75
|
+
super(constructor)
|
80
76
|
end
|
81
77
|
end
|
82
78
|
|
@@ -92,7 +88,7 @@ module ActiveSupport
|
|
92
88
|
# hash = ActiveSupport::HashWithIndifferentAccess.new
|
93
89
|
# hash[:key] = 'value'
|
94
90
|
#
|
95
|
-
# This value can be later fetched using either +:key+ or
|
91
|
+
# This value can be later fetched using either +:key+ or <tt>'key'</tt>.
|
96
92
|
def []=(key, value)
|
97
93
|
regular_writer(convert_key(key), convert_value(value, for: :assignment))
|
98
94
|
end
|
@@ -154,6 +150,19 @@ module ActiveSupport
|
|
154
150
|
alias_method :has_key?, :key?
|
155
151
|
alias_method :member?, :key?
|
156
152
|
|
153
|
+
# Same as <tt>Hash#[]</tt> where the key passed as argument can be
|
154
|
+
# either a string or a symbol:
|
155
|
+
#
|
156
|
+
# counters = ActiveSupport::HashWithIndifferentAccess.new
|
157
|
+
# counters[:foo] = 1
|
158
|
+
#
|
159
|
+
# counters['foo'] # => 1
|
160
|
+
# counters[:foo] # => 1
|
161
|
+
# counters[:zoo] # => nil
|
162
|
+
def [](key)
|
163
|
+
super(convert_key(key))
|
164
|
+
end
|
165
|
+
|
157
166
|
# Same as <tt>Hash#fetch</tt> where the key passed as argument can be
|
158
167
|
# either a string or a symbol:
|
159
168
|
#
|
@@ -168,6 +177,36 @@ module ActiveSupport
|
|
168
177
|
super(convert_key(key), *extras)
|
169
178
|
end
|
170
179
|
|
180
|
+
if Hash.new.respond_to?(:dig)
|
181
|
+
# Same as <tt>Hash#dig</tt> where the key passed as argument can be
|
182
|
+
# either a string or a symbol:
|
183
|
+
#
|
184
|
+
# counters = ActiveSupport::HashWithIndifferentAccess.new
|
185
|
+
# counters[:foo] = { bar: 1 }
|
186
|
+
#
|
187
|
+
# counters.dig('foo', 'bar') # => 1
|
188
|
+
# counters.dig(:foo, :bar) # => 1
|
189
|
+
# counters.dig(:zoo) # => nil
|
190
|
+
def dig(*args)
|
191
|
+
args[0] = convert_key(args[0]) if args.size > 0
|
192
|
+
super(*args)
|
193
|
+
end
|
194
|
+
end
|
195
|
+
|
196
|
+
# Same as <tt>Hash#default</tt> where the key passed as argument can be
|
197
|
+
# either a string or a symbol:
|
198
|
+
#
|
199
|
+
# hash = ActiveSupport::HashWithIndifferentAccess.new(1)
|
200
|
+
# hash.default # => 1
|
201
|
+
#
|
202
|
+
# hash = ActiveSupport::HashWithIndifferentAccess.new { |hash, key| key }
|
203
|
+
# hash.default # => nil
|
204
|
+
# hash.default('foo') # => 'foo'
|
205
|
+
# hash.default(:foo) # => 'foo'
|
206
|
+
def default(*args)
|
207
|
+
super(*args.map { |arg| convert_key(arg) })
|
208
|
+
end
|
209
|
+
|
171
210
|
# Returns an array of the values at the specified indices:
|
172
211
|
#
|
173
212
|
# hash = ActiveSupport::HashWithIndifferentAccess.new
|
@@ -178,17 +217,30 @@ module ActiveSupport
|
|
178
217
|
indices.collect { |key| self[convert_key(key)] }
|
179
218
|
end
|
180
219
|
|
220
|
+
# Returns an array of the values at the specified indices, but also
|
221
|
+
# raises an exception when one of the keys can't be found.
|
222
|
+
#
|
223
|
+
# hash = ActiveSupport::HashWithIndifferentAccess.new
|
224
|
+
# hash[:a] = 'x'
|
225
|
+
# hash[:b] = 'y'
|
226
|
+
# hash.fetch_values('a', 'b') # => ["x", "y"]
|
227
|
+
# hash.fetch_values('a', 'c') { |key| 'z' } # => ["x", "z"]
|
228
|
+
# hash.fetch_values('a', 'c') # => KeyError: key not found: "c"
|
229
|
+
def fetch_values(*indices, &block)
|
230
|
+
indices.collect { |key| fetch(key, &block) }
|
231
|
+
end if Hash.method_defined?(:fetch_values)
|
232
|
+
|
181
233
|
# Returns a shallow copy of the hash.
|
182
234
|
#
|
183
235
|
# hash = ActiveSupport::HashWithIndifferentAccess.new({ a: { b: 'b' } })
|
184
236
|
# dup = hash.dup
|
185
237
|
# dup[:a][:c] = 'c'
|
186
238
|
#
|
187
|
-
# hash[:a][:c] # =>
|
239
|
+
# hash[:a][:c] # => "c"
|
188
240
|
# dup[:a][:c] # => "c"
|
189
241
|
def dup
|
190
242
|
self.class.new(self).tap do |new_hash|
|
191
|
-
new_hash
|
243
|
+
set_defaults(new_hash)
|
192
244
|
end
|
193
245
|
end
|
194
246
|
|
@@ -196,7 +248,7 @@ module ActiveSupport
|
|
196
248
|
# modify the receiver but rather returns a new hash with indifferent
|
197
249
|
# access with the result of the merge.
|
198
250
|
def merge(hash, &block)
|
199
|
-
|
251
|
+
dup.update(hash, &block)
|
200
252
|
end
|
201
253
|
|
202
254
|
# Like +merge+ but the other way around: Merges the receiver into the
|
@@ -206,20 +258,22 @@ module ActiveSupport
|
|
206
258
|
# hash['a'] = nil
|
207
259
|
# hash.reverse_merge(a: 0, b: 1) # => {"a"=>nil, "b"=>1}
|
208
260
|
def reverse_merge(other_hash)
|
209
|
-
super(self.class.
|
261
|
+
super(self.class.new(other_hash))
|
210
262
|
end
|
263
|
+
alias_method :with_defaults, :reverse_merge
|
211
264
|
|
212
265
|
# Same semantics as +reverse_merge+ but modifies the receiver in-place.
|
213
266
|
def reverse_merge!(other_hash)
|
214
|
-
|
267
|
+
super(self.class.new(other_hash))
|
215
268
|
end
|
269
|
+
alias_method :with_defaults!, :reverse_merge!
|
216
270
|
|
217
271
|
# Replaces the contents of this hash with other_hash.
|
218
272
|
#
|
219
273
|
# h = { "a" => 100, "b" => 200 }
|
220
274
|
# h.replace({ "c" => 300, "d" => 400 }) # => {"c"=>300, "d"=>400}
|
221
275
|
def replace(other_hash)
|
222
|
-
super(self.class.
|
276
|
+
super(self.class.new(other_hash))
|
223
277
|
end
|
224
278
|
|
225
279
|
# Removes the specified key from the hash.
|
@@ -238,28 +292,64 @@ module ActiveSupport
|
|
238
292
|
def to_options!; self end
|
239
293
|
|
240
294
|
def select(*args, &block)
|
295
|
+
return to_enum(:select) unless block_given?
|
241
296
|
dup.tap { |hash| hash.select!(*args, &block) }
|
242
297
|
end
|
243
298
|
|
244
299
|
def reject(*args, &block)
|
300
|
+
return to_enum(:reject) unless block_given?
|
245
301
|
dup.tap { |hash| hash.reject!(*args, &block) }
|
246
302
|
end
|
247
303
|
|
304
|
+
def transform_values(*args, &block)
|
305
|
+
return to_enum(:transform_values) unless block_given?
|
306
|
+
dup.tap { |hash| hash.transform_values!(*args, &block) }
|
307
|
+
end
|
308
|
+
|
309
|
+
def transform_keys(*args, &block)
|
310
|
+
return to_enum(:transform_keys) unless block_given?
|
311
|
+
dup.tap { |hash| hash.transform_keys!(*args, &block) }
|
312
|
+
end
|
313
|
+
|
314
|
+
def transform_keys!
|
315
|
+
return enum_for(:transform_keys!) { size } unless block_given?
|
316
|
+
keys.each do |key|
|
317
|
+
self[yield(key)] = delete(key)
|
318
|
+
end
|
319
|
+
self
|
320
|
+
end
|
321
|
+
|
322
|
+
def slice(*keys)
|
323
|
+
keys.map! { |key| convert_key(key) }
|
324
|
+
self.class.new(super)
|
325
|
+
end
|
326
|
+
|
327
|
+
def slice!(*keys)
|
328
|
+
keys.map! { |key| convert_key(key) }
|
329
|
+
super
|
330
|
+
end
|
331
|
+
|
332
|
+
def compact
|
333
|
+
dup.tap(&:compact!)
|
334
|
+
end
|
335
|
+
|
248
336
|
# Convert to a regular hash with string keys.
|
249
337
|
def to_hash
|
250
|
-
_new_hash = Hash.new
|
338
|
+
_new_hash = Hash.new
|
339
|
+
set_defaults(_new_hash)
|
340
|
+
|
251
341
|
each do |key, value|
|
252
342
|
_new_hash[key] = convert_value(value, for: :to_hash)
|
253
343
|
end
|
254
344
|
_new_hash
|
255
345
|
end
|
256
346
|
|
257
|
-
|
258
|
-
def convert_key(key)
|
347
|
+
private
|
348
|
+
def convert_key(key) # :doc:
|
259
349
|
key.kind_of?(Symbol) ? key.to_s : key
|
260
350
|
end
|
261
351
|
|
262
|
-
def convert_value(value, options = {})
|
352
|
+
def convert_value(value, options = {}) # :doc:
|
263
353
|
if value.is_a? Hash
|
264
354
|
if options[:for] == :to_hash
|
265
355
|
value.to_hash
|
@@ -267,7 +357,7 @@ module ActiveSupport
|
|
267
357
|
value.nested_under_indifferent_access
|
268
358
|
end
|
269
359
|
elsif value.is_a?(Array)
|
270
|
-
|
360
|
+
if options[:for] != :assignment || value.frozen?
|
271
361
|
value = value.dup
|
272
362
|
end
|
273
363
|
value.map! { |e| convert_value(e, options) }
|
@@ -275,7 +365,17 @@ module ActiveSupport
|
|
275
365
|
value
|
276
366
|
end
|
277
367
|
end
|
368
|
+
|
369
|
+
def set_defaults(target) # :doc:
|
370
|
+
if default_proc
|
371
|
+
target.default_proc = default_proc.dup
|
372
|
+
else
|
373
|
+
target.default = default
|
374
|
+
end
|
375
|
+
end
|
278
376
|
end
|
279
377
|
end
|
280
378
|
|
379
|
+
# :stopdoc:
|
380
|
+
|
281
381
|
HashWithIndifferentAccess = ActiveSupport::HashWithIndifferentAccess
|