activesupport 5.1.7 → 6.1.7
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 +4 -4
- data/CHANGELOG.md +434 -490
- data/MIT-LICENSE +1 -1
- data/README.rdoc +6 -5
- data/lib/active_support/actionable_error.rb +48 -0
- data/lib/active_support/all.rb +2 -0
- data/lib/active_support/array_inquirer.rb +6 -2
- data/lib/active_support/backtrace_cleaner.rb +31 -3
- data/lib/active_support/benchmarkable.rb +3 -1
- data/lib/active_support/builder.rb +2 -0
- data/lib/active_support/cache/file_store.rb +37 -36
- data/lib/active_support/cache/mem_cache_store.rb +72 -56
- data/lib/active_support/cache/memory_store.rb +61 -33
- data/lib/active_support/cache/null_store.rb +10 -3
- data/lib/active_support/cache/redis_cache_store.rb +493 -0
- data/lib/active_support/cache/strategy/local_cache.rb +67 -21
- data/lib/active_support/cache/strategy/local_cache_middleware.rb +2 -0
- data/lib/active_support/cache.rb +310 -126
- data/lib/active_support/callbacks.rb +106 -100
- data/lib/active_support/concern.rb +79 -6
- data/lib/active_support/concurrency/load_interlock_aware_monitor.rb +18 -0
- data/lib/active_support/concurrency/share_lock.rb +2 -1
- data/lib/active_support/configurable.rb +12 -14
- data/lib/active_support/configuration_file.rb +51 -0
- data/lib/active_support/core_ext/array/access.rb +21 -7
- data/lib/active_support/core_ext/array/conversions.rb +7 -5
- data/lib/active_support/core_ext/array/extract.rb +21 -0
- data/lib/active_support/core_ext/array/extract_options.rb +2 -0
- data/lib/active_support/core_ext/array/grouping.rb +2 -0
- data/lib/active_support/core_ext/array/inquiry.rb +2 -0
- data/lib/active_support/core_ext/array/wrap.rb +2 -0
- data/lib/active_support/core_ext/array.rb +3 -1
- data/lib/active_support/core_ext/benchmark.rb +4 -2
- data/lib/active_support/core_ext/big_decimal/conversions.rb +2 -0
- data/lib/active_support/core_ext/big_decimal.rb +2 -0
- data/lib/active_support/core_ext/class/attribute.rb +50 -47
- data/lib/active_support/core_ext/class/attribute_accessors.rb +2 -0
- data/lib/active_support/core_ext/class/subclasses.rb +18 -40
- data/lib/active_support/core_ext/class.rb +2 -0
- data/lib/active_support/core_ext/date/acts_like.rb +2 -0
- data/lib/active_support/core_ext/date/blank.rb +2 -0
- data/lib/active_support/core_ext/date/calculations.rb +8 -5
- data/lib/active_support/core_ext/date/conversions.rb +12 -10
- data/lib/active_support/core_ext/date/zones.rb +2 -0
- data/lib/active_support/core_ext/date.rb +2 -0
- data/lib/active_support/core_ext/date_and_time/calculations.rb +61 -37
- data/lib/active_support/core_ext/date_and_time/compatibility.rb +18 -1
- data/lib/active_support/core_ext/date_and_time/zones.rb +2 -1
- data/lib/active_support/core_ext/date_time/acts_like.rb +2 -0
- data/lib/active_support/core_ext/date_time/blank.rb +2 -0
- data/lib/active_support/core_ext/date_time/calculations.rb +3 -1
- data/lib/active_support/core_ext/date_time/compatibility.rb +7 -5
- data/lib/active_support/core_ext/date_time/conversions.rb +2 -1
- data/lib/active_support/core_ext/date_time.rb +2 -0
- data/lib/active_support/core_ext/digest/uuid.rb +4 -1
- data/lib/active_support/core_ext/digest.rb +3 -0
- data/lib/active_support/core_ext/enumerable.rb +174 -71
- data/lib/active_support/core_ext/file/atomic.rb +3 -1
- data/lib/active_support/core_ext/file.rb +2 -0
- data/lib/active_support/core_ext/hash/conversions.rb +7 -5
- data/lib/active_support/core_ext/hash/deep_merge.rb +8 -12
- data/lib/active_support/core_ext/hash/deep_transform_values.rb +46 -0
- data/lib/active_support/core_ext/hash/except.rb +4 -2
- data/lib/active_support/core_ext/hash/indifferent_access.rb +2 -0
- data/lib/active_support/core_ext/hash/keys.rb +3 -30
- data/lib/active_support/core_ext/hash/reverse_merge.rb +5 -2
- data/lib/active_support/core_ext/hash/slice.rb +8 -29
- data/lib/active_support/core_ext/hash.rb +3 -2
- data/lib/active_support/core_ext/integer/inflections.rb +2 -0
- data/lib/active_support/core_ext/integer/multiple.rb +3 -1
- data/lib/active_support/core_ext/integer/time.rb +7 -14
- data/lib/active_support/core_ext/integer.rb +2 -0
- data/lib/active_support/core_ext/kernel/concern.rb +2 -0
- data/lib/active_support/core_ext/kernel/reporting.rb +2 -0
- data/lib/active_support/core_ext/kernel/singleton_class.rb +2 -0
- data/lib/active_support/core_ext/kernel.rb +2 -1
- data/lib/active_support/core_ext/load_error.rb +3 -8
- data/lib/active_support/core_ext/marshal.rb +4 -0
- data/lib/active_support/core_ext/module/aliasing.rb +2 -0
- data/lib/active_support/core_ext/module/anonymous.rb +2 -0
- data/lib/active_support/core_ext/module/attr_internal.rb +4 -2
- data/lib/active_support/core_ext/module/attribute_accessors.rb +44 -56
- data/lib/active_support/core_ext/module/attribute_accessors_per_thread.rb +18 -18
- data/lib/active_support/core_ext/module/concerning.rb +15 -10
- data/lib/active_support/core_ext/module/delegation.rb +103 -58
- data/lib/active_support/core_ext/module/deprecation.rb +2 -0
- data/lib/active_support/core_ext/module/introspection.rb +18 -15
- data/lib/active_support/core_ext/module/redefine_method.rb +40 -0
- data/lib/active_support/core_ext/module/remove_method.rb +5 -23
- data/lib/active_support/core_ext/module.rb +3 -1
- data/lib/active_support/core_ext/name_error.rb +36 -2
- data/lib/active_support/core_ext/numeric/bytes.rb +2 -0
- data/lib/active_support/core_ext/numeric/conversions.rb +131 -129
- data/lib/active_support/core_ext/numeric/time.rb +7 -15
- data/lib/active_support/core_ext/numeric.rb +2 -1
- data/lib/active_support/core_ext/object/acts_like.rb +12 -1
- data/lib/active_support/core_ext/object/blank.rb +13 -3
- data/lib/active_support/core_ext/object/conversions.rb +2 -0
- data/lib/active_support/core_ext/object/deep_dup.rb +3 -1
- data/lib/active_support/core_ext/object/duplicable.rb +9 -114
- data/lib/active_support/core_ext/object/inclusion.rb +2 -0
- data/lib/active_support/core_ext/object/instance_variables.rb +2 -0
- data/lib/active_support/core_ext/object/json.rb +22 -2
- data/lib/active_support/core_ext/object/to_param.rb +2 -0
- data/lib/active_support/core_ext/object/to_query.rb +2 -0
- data/lib/active_support/core_ext/object/try.rb +19 -7
- data/lib/active_support/core_ext/object/with_options.rb +4 -2
- data/lib/active_support/core_ext/object.rb +2 -0
- data/lib/active_support/core_ext/range/compare_range.rb +82 -0
- data/lib/active_support/core_ext/range/conversions.rb +35 -25
- data/lib/active_support/core_ext/range/each.rb +5 -2
- data/lib/active_support/core_ext/range/include_time_with_zone.rb +28 -0
- data/lib/active_support/core_ext/range/overlaps.rb +2 -0
- data/lib/active_support/core_ext/range.rb +4 -1
- data/lib/active_support/core_ext/regexp.rb +10 -5
- data/lib/active_support/core_ext/securerandom.rb +25 -3
- data/lib/active_support/core_ext/string/access.rb +7 -16
- data/lib/active_support/core_ext/string/behavior.rb +2 -0
- data/lib/active_support/core_ext/string/conversions.rb +3 -0
- data/lib/active_support/core_ext/string/exclude.rb +2 -0
- data/lib/active_support/core_ext/string/filters.rb +44 -1
- data/lib/active_support/core_ext/string/indent.rb +2 -0
- data/lib/active_support/core_ext/string/inflections.rb +69 -16
- data/lib/active_support/core_ext/string/inquiry.rb +3 -0
- data/lib/active_support/core_ext/string/multibyte.rb +9 -4
- data/lib/active_support/core_ext/string/output_safety.rb +104 -20
- data/lib/active_support/core_ext/string/starts_ends_with.rb +4 -2
- data/lib/active_support/core_ext/string/strip.rb +5 -1
- data/lib/active_support/core_ext/string/zones.rb +2 -0
- data/lib/active_support/core_ext/string.rb +2 -0
- data/lib/active_support/core_ext/symbol/starts_ends_with.rb +14 -0
- data/lib/active_support/core_ext/symbol.rb +3 -0
- data/lib/active_support/core_ext/time/acts_like.rb +2 -0
- data/lib/active_support/core_ext/time/calculations.rb +76 -18
- data/lib/active_support/core_ext/time/compatibility.rb +4 -2
- data/lib/active_support/core_ext/time/conversions.rb +4 -0
- data/lib/active_support/core_ext/time/zones.rb +6 -4
- data/lib/active_support/core_ext/time.rb +2 -0
- data/lib/active_support/core_ext/uri.rb +11 -6
- data/lib/active_support/core_ext.rb +3 -1
- data/lib/active_support/current_attributes/test_helper.rb +13 -0
- data/lib/active_support/current_attributes.rb +210 -0
- data/lib/active_support/dependencies/autoload.rb +2 -0
- data/lib/active_support/dependencies/interlock.rb +2 -0
- data/lib/active_support/dependencies/zeitwerk_integration.rb +120 -0
- data/lib/active_support/dependencies.rb +134 -60
- data/lib/active_support/deprecation/behaviors.rb +43 -11
- data/lib/active_support/deprecation/constant_accessor.rb +4 -2
- data/lib/active_support/deprecation/disallowed.rb +56 -0
- data/lib/active_support/deprecation/instance_delegator.rb +2 -1
- data/lib/active_support/deprecation/method_wrappers.rb +29 -21
- data/lib/active_support/deprecation/proxy_wrappers.rb +32 -6
- data/lib/active_support/deprecation/reporting.rb +54 -9
- data/lib/active_support/deprecation.rb +9 -2
- data/lib/active_support/descendants_tracker.rb +61 -9
- data/lib/active_support/digest.rb +22 -0
- data/lib/active_support/duration/iso8601_parser.rb +6 -6
- data/lib/active_support/duration/iso8601_serializer.rb +20 -14
- data/lib/active_support/duration.rb +102 -45
- data/lib/active_support/encrypted_configuration.rb +45 -0
- data/lib/active_support/encrypted_file.rb +117 -0
- data/lib/active_support/environment_inquirer.rb +20 -0
- data/lib/active_support/evented_file_update_checker.rb +84 -117
- data/lib/active_support/execution_wrapper.rb +19 -13
- data/lib/active_support/executor.rb +2 -0
- data/lib/active_support/file_update_checker.rb +2 -1
- data/lib/active_support/fork_tracker.rb +64 -0
- data/lib/active_support/gem_version.rb +3 -1
- data/lib/active_support/gzip.rb +2 -0
- data/lib/active_support/hash_with_indifferent_access.rb +123 -41
- data/lib/active_support/i18n.rb +4 -1
- data/lib/active_support/i18n_railtie.rb +19 -14
- data/lib/active_support/inflections.rb +2 -0
- data/lib/active_support/inflector/inflections.rb +19 -8
- data/lib/active_support/inflector/methods.rb +87 -77
- data/lib/active_support/inflector/transliterate.rb +56 -18
- data/lib/active_support/inflector.rb +2 -0
- data/lib/active_support/json/decoding.rb +27 -26
- data/lib/active_support/json/encoding.rb +13 -3
- data/lib/active_support/json.rb +2 -0
- data/lib/active_support/key_generator.rb +3 -33
- data/lib/active_support/lazy_load_hooks.rb +7 -2
- data/lib/active_support/locale/en.rb +33 -0
- data/lib/active_support/locale/en.yml +7 -3
- data/lib/active_support/log_subscriber/test_helper.rb +2 -0
- data/lib/active_support/log_subscriber.rb +42 -11
- data/lib/active_support/logger.rb +4 -17
- data/lib/active_support/logger_silence.rb +13 -20
- data/lib/active_support/logger_thread_safe_level.rb +54 -7
- data/lib/active_support/message_encryptor.rb +100 -32
- data/lib/active_support/message_verifier.rb +85 -14
- data/lib/active_support/messages/metadata.rb +80 -0
- data/lib/active_support/messages/rotation_configuration.rb +23 -0
- data/lib/active_support/messages/rotator.rb +57 -0
- data/lib/active_support/multibyte/chars.rb +12 -68
- data/lib/active_support/multibyte/unicode.rb +17 -327
- data/lib/active_support/multibyte.rb +2 -0
- data/lib/active_support/notifications/fanout.rb +118 -16
- data/lib/active_support/notifications/instrumenter.rb +73 -9
- data/lib/active_support/notifications.rb +74 -8
- data/lib/active_support/number_helper/number_converter.rb +7 -6
- data/lib/active_support/number_helper/number_to_currency_converter.rb +6 -9
- data/lib/active_support/number_helper/number_to_delimited_converter.rb +5 -2
- data/lib/active_support/number_helper/number_to_human_converter.rb +6 -3
- data/lib/active_support/number_helper/number_to_human_size_converter.rb +6 -3
- data/lib/active_support/number_helper/number_to_percentage_converter.rb +5 -1
- data/lib/active_support/number_helper/number_to_phone_converter.rb +5 -2
- data/lib/active_support/number_helper/number_to_rounded_converter.rb +14 -27
- data/lib/active_support/number_helper/rounding_helper.rb +16 -30
- data/lib/active_support/number_helper.rb +40 -12
- data/lib/active_support/option_merger.rb +24 -3
- data/lib/active_support/ordered_hash.rb +3 -1
- data/lib/active_support/ordered_options.rb +17 -5
- data/lib/active_support/parameter_filter.rb +133 -0
- data/lib/active_support/per_thread_registry.rb +4 -1
- data/lib/active_support/proxy_object.rb +2 -0
- data/lib/active_support/rails.rb +3 -10
- data/lib/active_support/railtie.rb +60 -9
- data/lib/active_support/reloader.rb +12 -11
- data/lib/active_support/rescuable.rb +7 -6
- data/lib/active_support/secure_compare_rotator.rb +51 -0
- data/lib/active_support/security_utils.rb +26 -15
- data/lib/active_support/string_inquirer.rb +6 -3
- data/lib/active_support/subscriber.rb +74 -24
- data/lib/active_support/tagged_logging.rb +44 -8
- data/lib/active_support/test_case.rb +94 -2
- data/lib/active_support/testing/assertions.rb +58 -20
- data/lib/active_support/testing/autorun.rb +2 -0
- data/lib/active_support/testing/constant_lookup.rb +2 -0
- data/lib/active_support/testing/declarative.rb +2 -0
- data/lib/active_support/testing/deprecation.rb +2 -1
- data/lib/active_support/testing/file_fixtures.rb +4 -0
- data/lib/active_support/testing/isolation.rb +4 -2
- data/lib/active_support/testing/method_call_assertions.rb +30 -1
- data/lib/active_support/testing/parallelization/server.rb +78 -0
- data/lib/active_support/testing/parallelization/worker.rb +100 -0
- data/lib/active_support/testing/parallelization.rb +51 -0
- data/lib/active_support/testing/setup_and_teardown.rb +12 -7
- data/lib/active_support/testing/stream.rb +3 -2
- data/lib/active_support/testing/tagged_logging.rb +2 -0
- data/lib/active_support/testing/time_helpers.rb +78 -13
- data/lib/active_support/time.rb +2 -0
- data/lib/active_support/time_with_zone.rb +113 -41
- data/lib/active_support/values/time_zone.rb +54 -25
- data/lib/active_support/version.rb +2 -0
- data/lib/active_support/xml_mini/jdom.rb +5 -4
- data/lib/active_support/xml_mini/libxml.rb +4 -2
- data/lib/active_support/xml_mini/libxmlsax.rb +6 -4
- data/lib/active_support/xml_mini/nokogiri.rb +4 -2
- data/lib/active_support/xml_mini/nokogirisax.rb +5 -3
- data/lib/active_support/xml_mini/rexml.rb +12 -3
- data/lib/active_support/xml_mini.rb +5 -11
- data/lib/active_support.rb +18 -13
- metadata +71 -32
- data/lib/active_support/core_ext/array/prepend_and_append.rb +0 -7
- data/lib/active_support/core_ext/hash/compact.rb +0 -27
- data/lib/active_support/core_ext/hash/transform_values.rb +0 -30
- data/lib/active_support/core_ext/kernel/agnostics.rb +0 -11
- data/lib/active_support/core_ext/module/reachable.rb +0 -8
- data/lib/active_support/core_ext/numeric/inquiry.rb +0 -26
- data/lib/active_support/core_ext/range/include_range.rb +0 -23
- data/lib/active_support/values/unicode_tables.dat +0 -0
@@ -1,9 +1,12 @@
|
|
1
|
+
# frozen_string_literal: true
|
2
|
+
|
1
3
|
require "active_support/duration"
|
2
4
|
require "active_support/core_ext/time/conversions"
|
3
5
|
require "active_support/time_with_zone"
|
4
6
|
require "active_support/core_ext/time/zones"
|
5
7
|
require "active_support/core_ext/date_and_time/calculations"
|
6
8
|
require "active_support/core_ext/date/calculations"
|
9
|
+
require "active_support/core_ext/module/remove_method"
|
7
10
|
|
8
11
|
class Time
|
9
12
|
include DateAndTime::Calculations
|
@@ -45,12 +48,15 @@ class Time
|
|
45
48
|
# Time.at can be called with a time or numerical value
|
46
49
|
time_or_number = args.first
|
47
50
|
|
48
|
-
if time_or_number.is_a?(ActiveSupport::TimeWithZone)
|
51
|
+
if time_or_number.is_a?(ActiveSupport::TimeWithZone)
|
52
|
+
at_without_coercion(time_or_number.to_r).getlocal
|
53
|
+
elsif time_or_number.is_a?(DateTime)
|
49
54
|
at_without_coercion(time_or_number.to_f).getlocal
|
50
55
|
else
|
51
56
|
at_without_coercion(time_or_number)
|
52
57
|
end
|
53
58
|
end
|
59
|
+
ruby2_keywords(:at_with_coercion) if respond_to?(:ruby2_keywords, true)
|
54
60
|
alias_method :at_without_coercion, :at
|
55
61
|
alias_method :at, :at_with_coercion
|
56
62
|
|
@@ -103,25 +109,41 @@ class Time
|
|
103
109
|
subsec
|
104
110
|
end
|
105
111
|
|
112
|
+
unless Time.method_defined?(:floor)
|
113
|
+
def floor(precision = 0)
|
114
|
+
change(nsec: 0) + subsec.floor(precision)
|
115
|
+
end
|
116
|
+
end
|
117
|
+
|
118
|
+
# Restricted Ruby version due to a bug in `Time#ceil`
|
119
|
+
# See https://bugs.ruby-lang.org/issues/17025 for more details
|
120
|
+
if RUBY_VERSION <= "2.8"
|
121
|
+
remove_possible_method :ceil
|
122
|
+
def ceil(precision = 0)
|
123
|
+
change(nsec: 0) + subsec.ceil(precision)
|
124
|
+
end
|
125
|
+
end
|
126
|
+
|
106
127
|
# Returns a new Time where one or more of the elements have been changed according
|
107
128
|
# to the +options+ parameter. The time options (<tt>:hour</tt>, <tt>:min</tt>,
|
108
129
|
# <tt>:sec</tt>, <tt>:usec</tt>, <tt>:nsec</tt>) reset cascadingly, so if only
|
109
130
|
# the hour is passed, then minute, sec, usec and nsec is set to 0. If the hour
|
110
|
-
# and minute is passed, then sec, usec and nsec is set to 0. The +options+
|
111
|
-
#
|
112
|
-
# <tt>:
|
113
|
-
# <tt>:
|
131
|
+
# and minute is passed, then sec, usec and nsec is set to 0. The +options+ parameter
|
132
|
+
# takes a hash with any of these keys: <tt>:year</tt>, <tt>:month</tt>, <tt>:day</tt>,
|
133
|
+
# <tt>:hour</tt>, <tt>:min</tt>, <tt>:sec</tt>, <tt>:usec</tt>, <tt>:nsec</tt>,
|
134
|
+
# <tt>:offset</tt>. Pass either <tt>:usec</tt> or <tt>:nsec</tt>, not both.
|
114
135
|
#
|
115
136
|
# Time.new(2012, 8, 29, 22, 35, 0).change(day: 1) # => Time.new(2012, 8, 1, 22, 35, 0)
|
116
137
|
# Time.new(2012, 8, 29, 22, 35, 0).change(year: 1981, day: 1) # => Time.new(1981, 8, 1, 22, 35, 0)
|
117
138
|
# Time.new(2012, 8, 29, 22, 35, 0).change(year: 1981, hour: 0) # => Time.new(1981, 8, 29, 0, 0, 0)
|
118
139
|
def change(options)
|
119
|
-
new_year
|
120
|
-
new_month
|
121
|
-
new_day
|
122
|
-
new_hour
|
123
|
-
new_min
|
124
|
-
new_sec
|
140
|
+
new_year = options.fetch(:year, year)
|
141
|
+
new_month = options.fetch(:month, month)
|
142
|
+
new_day = options.fetch(:day, day)
|
143
|
+
new_hour = options.fetch(:hour, hour)
|
144
|
+
new_min = options.fetch(:min, options[:hour] ? 0 : min)
|
145
|
+
new_sec = options.fetch(:sec, (options[:hour] || options[:min]) ? 0 : sec)
|
146
|
+
new_offset = options.fetch(:offset, nil)
|
125
147
|
|
126
148
|
if new_nsec = options[:nsec]
|
127
149
|
raise ArgumentError, "Can't change both :nsec and :usec at the same time: #{options.inspect}" if options[:usec]
|
@@ -130,13 +152,20 @@ class Time
|
|
130
152
|
new_usec = options.fetch(:usec, (options[:hour] || options[:min] || options[:sec]) ? 0 : Rational(nsec, 1000))
|
131
153
|
end
|
132
154
|
|
133
|
-
if
|
134
|
-
|
155
|
+
raise ArgumentError, "argument out of range" if new_usec >= 1000000
|
156
|
+
|
157
|
+
new_sec += Rational(new_usec, 1000000)
|
158
|
+
|
159
|
+
if new_offset
|
160
|
+
::Time.new(new_year, new_month, new_day, new_hour, new_min, new_sec, new_offset)
|
161
|
+
elsif utc?
|
162
|
+
::Time.utc(new_year, new_month, new_day, new_hour, new_min, new_sec)
|
163
|
+
elsif zone&.respond_to?(:utc_to_local)
|
164
|
+
::Time.new(new_year, new_month, new_day, new_hour, new_min, new_sec, zone)
|
135
165
|
elsif zone
|
136
|
-
::Time.local(new_year, new_month, new_day, new_hour, new_min, new_sec
|
166
|
+
::Time.local(new_year, new_month, new_day, new_hour, new_min, new_sec)
|
137
167
|
else
|
138
|
-
|
139
|
-
::Time.new(new_year, new_month, new_day, new_hour, new_min, new_sec + (new_usec.to_r / 1000000), utc_offset)
|
168
|
+
::Time.new(new_year, new_month, new_day, new_hour, new_min, new_sec, utc_offset)
|
140
169
|
end
|
141
170
|
end
|
142
171
|
|
@@ -162,8 +191,7 @@ class Time
|
|
162
191
|
options[:hours] = options.fetch(:hours, 0) + 24 * partial_days
|
163
192
|
end
|
164
193
|
|
165
|
-
d = to_date.advance(options)
|
166
|
-
d = d.gregorian if d.julian?
|
194
|
+
d = to_date.gregorian.advance(options)
|
167
195
|
time_advanced_by_date = change(year: d.year, month: d.month, day: d.day)
|
168
196
|
seconds_to_advance = \
|
169
197
|
options.fetch(:seconds, 0) +
|
@@ -304,4 +332,34 @@ class Time
|
|
304
332
|
end
|
305
333
|
alias_method :eql_without_coercion, :eql?
|
306
334
|
alias_method :eql?, :eql_with_coercion
|
335
|
+
|
336
|
+
# Returns a new time the specified number of days ago.
|
337
|
+
def prev_day(days = 1)
|
338
|
+
advance(days: -days)
|
339
|
+
end
|
340
|
+
|
341
|
+
# Returns a new time the specified number of days in the future.
|
342
|
+
def next_day(days = 1)
|
343
|
+
advance(days: days)
|
344
|
+
end
|
345
|
+
|
346
|
+
# Returns a new time the specified number of months ago.
|
347
|
+
def prev_month(months = 1)
|
348
|
+
advance(months: -months)
|
349
|
+
end
|
350
|
+
|
351
|
+
# Returns a new time the specified number of months in the future.
|
352
|
+
def next_month(months = 1)
|
353
|
+
advance(months: months)
|
354
|
+
end
|
355
|
+
|
356
|
+
# Returns a new time the specified number of years ago.
|
357
|
+
def prev_year(years = 1)
|
358
|
+
advance(years: -years)
|
359
|
+
end
|
360
|
+
|
361
|
+
# Returns a new time the specified number of years in the future.
|
362
|
+
def next_year(years = 1)
|
363
|
+
advance(years: years)
|
364
|
+
end
|
307
365
|
end
|
@@ -1,10 +1,12 @@
|
|
1
|
+
# frozen_string_literal: true
|
2
|
+
|
1
3
|
require "active_support/core_ext/date_and_time/compatibility"
|
2
|
-
require "active_support/core_ext/module/
|
4
|
+
require "active_support/core_ext/module/redefine_method"
|
3
5
|
|
4
6
|
class Time
|
5
7
|
include DateAndTime::Compatibility
|
6
8
|
|
7
|
-
|
9
|
+
silence_redefinition_of_method :to_time
|
8
10
|
|
9
11
|
# Either return +self+ or the time in the local system timezone depending
|
10
12
|
# on the setting of +ActiveSupport.to_time_preserves_timezone+.
|
@@ -1,9 +1,13 @@
|
|
1
|
+
# frozen_string_literal: true
|
2
|
+
|
3
|
+
require "time"
|
1
4
|
require "active_support/inflector/methods"
|
2
5
|
require "active_support/values/time_zone"
|
3
6
|
|
4
7
|
class Time
|
5
8
|
DATE_FORMATS = {
|
6
9
|
db: "%Y-%m-%d %H:%M:%S",
|
10
|
+
inspect: "%Y-%m-%d %H:%M:%S.%9N %z",
|
7
11
|
number: "%Y%m%d%H%M%S",
|
8
12
|
nsec: "%Y%m%d%H%M%S%9N",
|
9
13
|
usec: "%Y%m%d%H%M%S%6N",
|
@@ -1,3 +1,5 @@
|
|
1
|
+
# frozen_string_literal: true
|
2
|
+
|
1
3
|
require "active_support/time_with_zone"
|
2
4
|
require "active_support/core_ext/time/acts_like"
|
3
5
|
require "active_support/core_ext/date_and_time/zones"
|
@@ -53,10 +55,10 @@ class Time
|
|
53
55
|
# end
|
54
56
|
# end
|
55
57
|
#
|
56
|
-
#
|
57
|
-
#
|
58
|
-
#
|
59
|
-
#
|
58
|
+
# NOTE: This won't affect any <tt>ActiveSupport::TimeWithZone</tt>
|
59
|
+
# objects that have already been created, e.g. any model timestamp
|
60
|
+
# attributes that have been read before the block will remain in
|
61
|
+
# the application's default timezone.
|
60
62
|
def use_zone(time_zone)
|
61
63
|
new_zone = find_zone!(time_zone)
|
62
64
|
begin
|
@@ -1,16 +1,17 @@
|
|
1
|
+
# frozen_string_literal: true
|
2
|
+
|
1
3
|
require "uri"
|
2
|
-
str = "\xE6\x97\xA5\xE6\x9C\xAC\xE8\xAA\x9E" # Ni-ho-nn-go in UTF-8, means Japanese.
|
3
|
-
parser = URI::Parser.new
|
4
4
|
|
5
|
-
|
5
|
+
if RUBY_VERSION < "2.6.0"
|
6
|
+
require "active_support/core_ext/module/redefine_method"
|
6
7
|
URI::Parser.class_eval do
|
7
|
-
|
8
|
+
silence_redefinition_of_method :unescape
|
8
9
|
def unescape(str, escaped = /%[a-fA-F\d]{2}/)
|
9
10
|
# TODO: Are we actually sure that ASCII == UTF-8?
|
10
11
|
# YK: My initial experiments say yes, but let's be sure please
|
11
12
|
enc = str.encoding
|
12
13
|
enc = Encoding::UTF_8 if enc == Encoding::US_ASCII
|
13
|
-
str.gsub(escaped) { |match| [match[1, 2].hex].pack("C") }.force_encoding(enc)
|
14
|
+
str.dup.force_encoding(Encoding::ASCII_8BIT).gsub(escaped) { |match| [match[1, 2].hex].pack("C") }.force_encoding(enc)
|
14
15
|
end
|
15
16
|
end
|
16
17
|
end
|
@@ -18,7 +19,11 @@ end
|
|
18
19
|
module URI
|
19
20
|
class << self
|
20
21
|
def parser
|
21
|
-
|
22
|
+
ActiveSupport::Deprecation.warn(<<-MSG.squish)
|
23
|
+
URI.parser is deprecated and will be removed in Rails 7.0.
|
24
|
+
Use `URI::DEFAULT_PARSER` instead.
|
25
|
+
MSG
|
26
|
+
URI::DEFAULT_PARSER
|
22
27
|
end
|
23
28
|
end
|
24
29
|
end
|
@@ -0,0 +1,13 @@
|
|
1
|
+
# frozen_string_literal: true
|
2
|
+
|
3
|
+
module ActiveSupport::CurrentAttributes::TestHelper # :nodoc:
|
4
|
+
def before_setup
|
5
|
+
ActiveSupport::CurrentAttributes.reset_all
|
6
|
+
super
|
7
|
+
end
|
8
|
+
|
9
|
+
def after_teardown
|
10
|
+
super
|
11
|
+
ActiveSupport::CurrentAttributes.reset_all
|
12
|
+
end
|
13
|
+
end
|
@@ -0,0 +1,210 @@
|
|
1
|
+
# frozen_string_literal: true
|
2
|
+
|
3
|
+
require "active_support/callbacks"
|
4
|
+
require "active_support/core_ext/enumerable"
|
5
|
+
require "active_support/core_ext/module/delegation"
|
6
|
+
|
7
|
+
module ActiveSupport
|
8
|
+
# Abstract super class that provides a thread-isolated attributes singleton, which resets automatically
|
9
|
+
# before and after each request. This allows you to keep all the per-request attributes easily
|
10
|
+
# available to the whole system.
|
11
|
+
#
|
12
|
+
# The following full app-like example demonstrates how to use a Current class to
|
13
|
+
# facilitate easy access to the global, per-request attributes without passing them deeply
|
14
|
+
# around everywhere:
|
15
|
+
#
|
16
|
+
# # app/models/current.rb
|
17
|
+
# class Current < ActiveSupport::CurrentAttributes
|
18
|
+
# attribute :account, :user
|
19
|
+
# attribute :request_id, :user_agent, :ip_address
|
20
|
+
#
|
21
|
+
# resets { Time.zone = nil }
|
22
|
+
#
|
23
|
+
# def user=(user)
|
24
|
+
# super
|
25
|
+
# self.account = user.account
|
26
|
+
# Time.zone = user.time_zone
|
27
|
+
# end
|
28
|
+
# end
|
29
|
+
#
|
30
|
+
# # app/controllers/concerns/authentication.rb
|
31
|
+
# module Authentication
|
32
|
+
# extend ActiveSupport::Concern
|
33
|
+
#
|
34
|
+
# included do
|
35
|
+
# before_action :authenticate
|
36
|
+
# end
|
37
|
+
#
|
38
|
+
# private
|
39
|
+
# def authenticate
|
40
|
+
# if authenticated_user = User.find_by(id: cookies.encrypted[:user_id])
|
41
|
+
# Current.user = authenticated_user
|
42
|
+
# else
|
43
|
+
# redirect_to new_session_url
|
44
|
+
# end
|
45
|
+
# end
|
46
|
+
# end
|
47
|
+
#
|
48
|
+
# # app/controllers/concerns/set_current_request_details.rb
|
49
|
+
# module SetCurrentRequestDetails
|
50
|
+
# extend ActiveSupport::Concern
|
51
|
+
#
|
52
|
+
# included do
|
53
|
+
# before_action do
|
54
|
+
# Current.request_id = request.uuid
|
55
|
+
# Current.user_agent = request.user_agent
|
56
|
+
# Current.ip_address = request.ip
|
57
|
+
# end
|
58
|
+
# end
|
59
|
+
# end
|
60
|
+
#
|
61
|
+
# class ApplicationController < ActionController::Base
|
62
|
+
# include Authentication
|
63
|
+
# include SetCurrentRequestDetails
|
64
|
+
# end
|
65
|
+
#
|
66
|
+
# class MessagesController < ApplicationController
|
67
|
+
# def create
|
68
|
+
# Current.account.messages.create(message_params)
|
69
|
+
# end
|
70
|
+
# end
|
71
|
+
#
|
72
|
+
# class Message < ApplicationRecord
|
73
|
+
# belongs_to :creator, default: -> { Current.user }
|
74
|
+
# after_create { |message| Event.create(record: message) }
|
75
|
+
# end
|
76
|
+
#
|
77
|
+
# class Event < ApplicationRecord
|
78
|
+
# before_create do
|
79
|
+
# self.request_id = Current.request_id
|
80
|
+
# self.user_agent = Current.user_agent
|
81
|
+
# self.ip_address = Current.ip_address
|
82
|
+
# end
|
83
|
+
# end
|
84
|
+
#
|
85
|
+
# A word of caution: It's easy to overdo a global singleton like Current and tangle your model as a result.
|
86
|
+
# Current should only be used for a few, top-level globals, like account, user, and request details.
|
87
|
+
# The attributes stuck in Current should be used by more or less all actions on all requests. If you start
|
88
|
+
# sticking controller-specific attributes in there, you're going to create a mess.
|
89
|
+
class CurrentAttributes
|
90
|
+
include ActiveSupport::Callbacks
|
91
|
+
define_callbacks :reset
|
92
|
+
|
93
|
+
class << self
|
94
|
+
# Returns singleton instance for this class in this thread. If none exists, one is created.
|
95
|
+
def instance
|
96
|
+
current_instances[current_instances_key] ||= new
|
97
|
+
end
|
98
|
+
|
99
|
+
# Declares one or more attributes that will be given both class and instance accessor methods.
|
100
|
+
def attribute(*names)
|
101
|
+
generated_attribute_methods.module_eval do
|
102
|
+
names.each do |name|
|
103
|
+
define_method(name) do
|
104
|
+
attributes[name.to_sym]
|
105
|
+
end
|
106
|
+
|
107
|
+
define_method("#{name}=") do |attribute|
|
108
|
+
attributes[name.to_sym] = attribute
|
109
|
+
end
|
110
|
+
end
|
111
|
+
end
|
112
|
+
|
113
|
+
names.each do |name|
|
114
|
+
define_singleton_method(name) do
|
115
|
+
instance.public_send(name)
|
116
|
+
end
|
117
|
+
|
118
|
+
define_singleton_method("#{name}=") do |attribute|
|
119
|
+
instance.public_send("#{name}=", attribute)
|
120
|
+
end
|
121
|
+
end
|
122
|
+
end
|
123
|
+
|
124
|
+
# Calls this block before #reset is called on the instance. Used for resetting external collaborators that depend on current values.
|
125
|
+
def before_reset(&block)
|
126
|
+
set_callback :reset, :before, &block
|
127
|
+
end
|
128
|
+
|
129
|
+
# Calls this block after #reset is called on the instance. Used for resetting external collaborators, like Time.zone.
|
130
|
+
def resets(&block)
|
131
|
+
set_callback :reset, :after, &block
|
132
|
+
end
|
133
|
+
alias_method :after_reset, :resets
|
134
|
+
|
135
|
+
delegate :set, :reset, to: :instance
|
136
|
+
|
137
|
+
def reset_all # :nodoc:
|
138
|
+
current_instances.each_value(&:reset)
|
139
|
+
end
|
140
|
+
|
141
|
+
def clear_all # :nodoc:
|
142
|
+
reset_all
|
143
|
+
current_instances.clear
|
144
|
+
end
|
145
|
+
|
146
|
+
private
|
147
|
+
def generated_attribute_methods
|
148
|
+
@generated_attribute_methods ||= Module.new.tap { |mod| include mod }
|
149
|
+
end
|
150
|
+
|
151
|
+
def current_instances
|
152
|
+
Thread.current[:current_attributes_instances] ||= {}
|
153
|
+
end
|
154
|
+
|
155
|
+
def current_instances_key
|
156
|
+
@current_instances_key ||= name.to_sym
|
157
|
+
end
|
158
|
+
|
159
|
+
def method_missing(name, *args, &block)
|
160
|
+
# Caches the method definition as a singleton method of the receiver.
|
161
|
+
#
|
162
|
+
# By letting #delegate handle it, we avoid an enclosure that'll capture args.
|
163
|
+
singleton_class.delegate name, to: :instance
|
164
|
+
|
165
|
+
send(name, *args, &block)
|
166
|
+
end
|
167
|
+
ruby2_keywords(:method_missing) if respond_to?(:ruby2_keywords, true)
|
168
|
+
end
|
169
|
+
|
170
|
+
attr_accessor :attributes
|
171
|
+
|
172
|
+
def initialize
|
173
|
+
@attributes = {}
|
174
|
+
end
|
175
|
+
|
176
|
+
# Expose one or more attributes within a block. Old values are returned after the block concludes.
|
177
|
+
# Example demonstrating the common use of needing to set Current attributes outside the request-cycle:
|
178
|
+
#
|
179
|
+
# class Chat::PublicationJob < ApplicationJob
|
180
|
+
# def perform(attributes, room_number, creator)
|
181
|
+
# Current.set(person: creator) do
|
182
|
+
# Chat::Publisher.publish(attributes: attributes, room_number: room_number)
|
183
|
+
# end
|
184
|
+
# end
|
185
|
+
# end
|
186
|
+
def set(set_attributes)
|
187
|
+
old_attributes = compute_attributes(set_attributes.keys)
|
188
|
+
assign_attributes(set_attributes)
|
189
|
+
yield
|
190
|
+
ensure
|
191
|
+
assign_attributes(old_attributes)
|
192
|
+
end
|
193
|
+
|
194
|
+
# Reset all attributes. Should be called before and after actions, when used as a per-request singleton.
|
195
|
+
def reset
|
196
|
+
run_callbacks :reset do
|
197
|
+
self.attributes = {}
|
198
|
+
end
|
199
|
+
end
|
200
|
+
|
201
|
+
private
|
202
|
+
def assign_attributes(new_attributes)
|
203
|
+
new_attributes.each { |key, value| public_send("#{key}=", value) }
|
204
|
+
end
|
205
|
+
|
206
|
+
def compute_attributes(keys)
|
207
|
+
keys.index_with { |key| public_send(key) }
|
208
|
+
end
|
209
|
+
end
|
210
|
+
end
|
@@ -0,0 +1,120 @@
|
|
1
|
+
# frozen_string_literal: true
|
2
|
+
|
3
|
+
require "set"
|
4
|
+
require "active_support/core_ext/string/inflections"
|
5
|
+
|
6
|
+
module ActiveSupport
|
7
|
+
module Dependencies
|
8
|
+
module ZeitwerkIntegration # :nodoc: all
|
9
|
+
module Decorations
|
10
|
+
def clear
|
11
|
+
Dependencies.unload_interlock do
|
12
|
+
Rails.autoloaders.main.reload
|
13
|
+
rescue Zeitwerk::ReloadingDisabledError
|
14
|
+
raise "reloading is disabled because config.cache_classes is true"
|
15
|
+
end
|
16
|
+
end
|
17
|
+
|
18
|
+
def constantize(cpath)
|
19
|
+
ActiveSupport::Inflector.constantize(cpath)
|
20
|
+
end
|
21
|
+
|
22
|
+
def safe_constantize(cpath)
|
23
|
+
ActiveSupport::Inflector.safe_constantize(cpath)
|
24
|
+
end
|
25
|
+
|
26
|
+
def autoloaded_constants
|
27
|
+
Rails.autoloaders.main.unloadable_cpaths
|
28
|
+
end
|
29
|
+
|
30
|
+
def autoloaded?(object)
|
31
|
+
cpath = object.is_a?(Module) ? real_mod_name(object) : object.to_s
|
32
|
+
Rails.autoloaders.main.unloadable_cpath?(cpath)
|
33
|
+
end
|
34
|
+
|
35
|
+
def verbose=(verbose)
|
36
|
+
l = verbose ? logger || Rails.logger : nil
|
37
|
+
Rails.autoloaders.each { |autoloader| autoloader.logger = l }
|
38
|
+
end
|
39
|
+
|
40
|
+
def unhook!
|
41
|
+
:no_op
|
42
|
+
end
|
43
|
+
end
|
44
|
+
|
45
|
+
module RequireDependency
|
46
|
+
def require_dependency(filename)
|
47
|
+
filename = filename.to_path if filename.respond_to?(:to_path)
|
48
|
+
if abspath = ActiveSupport::Dependencies.search_for_file(filename)
|
49
|
+
require abspath
|
50
|
+
else
|
51
|
+
require filename
|
52
|
+
end
|
53
|
+
end
|
54
|
+
end
|
55
|
+
|
56
|
+
module Inflector
|
57
|
+
# Concurrent::Map is not needed. This is a private class, and overrides
|
58
|
+
# must be defined while the application boots.
|
59
|
+
@overrides = {}
|
60
|
+
|
61
|
+
def self.camelize(basename, _abspath)
|
62
|
+
@overrides[basename] || basename.camelize
|
63
|
+
end
|
64
|
+
|
65
|
+
def self.inflect(overrides)
|
66
|
+
@overrides.merge!(overrides)
|
67
|
+
end
|
68
|
+
end
|
69
|
+
|
70
|
+
class << self
|
71
|
+
def take_over(enable_reloading:)
|
72
|
+
setup_autoloaders(enable_reloading)
|
73
|
+
freeze_paths
|
74
|
+
decorate_dependencies
|
75
|
+
end
|
76
|
+
|
77
|
+
private
|
78
|
+
def setup_autoloaders(enable_reloading)
|
79
|
+
Dependencies.autoload_paths.each do |autoload_path|
|
80
|
+
# Zeitwerk only accepts existing directories in `push_dir` to
|
81
|
+
# prevent misconfigurations.
|
82
|
+
next unless File.directory?(autoload_path)
|
83
|
+
|
84
|
+
autoloader = \
|
85
|
+
autoload_once?(autoload_path) ? Rails.autoloaders.once : Rails.autoloaders.main
|
86
|
+
|
87
|
+
autoloader.push_dir(autoload_path)
|
88
|
+
autoloader.do_not_eager_load(autoload_path) unless eager_load?(autoload_path)
|
89
|
+
end
|
90
|
+
|
91
|
+
Rails.autoloaders.main.enable_reloading if enable_reloading
|
92
|
+
|
93
|
+
# Order matters.
|
94
|
+
Rails.autoloaders.once.setup
|
95
|
+
Rails.autoloaders.main.setup
|
96
|
+
end
|
97
|
+
|
98
|
+
def autoload_once?(autoload_path)
|
99
|
+
Dependencies.autoload_once_paths.include?(autoload_path)
|
100
|
+
end
|
101
|
+
|
102
|
+
def eager_load?(autoload_path)
|
103
|
+
Dependencies._eager_load_paths.member?(autoload_path)
|
104
|
+
end
|
105
|
+
|
106
|
+
def freeze_paths
|
107
|
+
Dependencies.autoload_paths.freeze
|
108
|
+
Dependencies.autoload_once_paths.freeze
|
109
|
+
Dependencies._eager_load_paths.freeze
|
110
|
+
end
|
111
|
+
|
112
|
+
def decorate_dependencies
|
113
|
+
Dependencies.unhook!
|
114
|
+
Dependencies.singleton_class.prepend(Decorations)
|
115
|
+
Object.prepend(RequireDependency)
|
116
|
+
end
|
117
|
+
end
|
118
|
+
end
|
119
|
+
end
|
120
|
+
end
|