activesupport 5.1.6 → 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 +325 -576
- data/MIT-LICENSE +1 -1
- data/README.rdoc +3 -3
- data/lib/active_support/all.rb +2 -0
- data/lib/active_support/array_inquirer.rb +2 -0
- data/lib/active_support/backtrace_cleaner.rb +2 -0
- data/lib/active_support/benchmarkable.rb +2 -0
- data/lib/active_support/builder.rb +2 -0
- data/lib/active_support/cache/file_store.rb +5 -4
- data/lib/active_support/cache/mem_cache_store.rb +37 -27
- data/lib/active_support/cache/memory_store.rb +2 -0
- data/lib/active_support/cache/null_store.rb +2 -0
- data/lib/active_support/cache/redis_cache_store.rb +454 -0
- data/lib/active_support/cache/strategy/local_cache.rb +33 -2
- data/lib/active_support/cache/strategy/local_cache_middleware.rb +2 -0
- data/lib/active_support/cache.rb +181 -64
- data/lib/active_support/callbacks.rb +28 -39
- data/lib/active_support/concern.rb +3 -1
- data/lib/active_support/concurrency/share_lock.rb +2 -0
- data/lib/active_support/configurable.rb +2 -0
- data/lib/active_support/core_ext/array/access.rb +4 -2
- data/lib/active_support/core_ext/array/conversions.rb +2 -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/prepend_and_append.rb +4 -2
- data/lib/active_support/core_ext/array/wrap.rb +2 -0
- data/lib/active_support/core_ext/array.rb +2 -0
- data/lib/active_support/core_ext/benchmark.rb +2 -0
- 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 +34 -16
- data/lib/active_support/core_ext/class/attribute_accessors.rb +2 -0
- data/lib/active_support/core_ext/class/subclasses.rb +1 -2
- 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 +2 -0
- data/lib/active_support/core_ext/date/conversions.rb +10 -9
- 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 +50 -16
- data/lib/active_support/core_ext/date_and_time/compatibility.rb +3 -1
- data/lib/active_support/core_ext/date_and_time/zones.rb +2 -0
- 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 +2 -0
- data/lib/active_support/core_ext/date_time/compatibility.rb +7 -5
- data/lib/active_support/core_ext/date_time/conversions.rb +2 -0
- data/lib/active_support/core_ext/date_time.rb +2 -0
- data/lib/active_support/core_ext/digest/uuid.rb +3 -1
- data/lib/active_support/core_ext/enumerable.rb +3 -1
- data/lib/active_support/core_ext/file/atomic.rb +2 -0
- data/lib/active_support/core_ext/file.rb +2 -0
- data/lib/active_support/core_ext/hash/compact.rb +2 -0
- data/lib/active_support/core_ext/hash/conversions.rb +4 -2
- data/lib/active_support/core_ext/hash/deep_merge.rb +8 -12
- data/lib/active_support/core_ext/hash/except.rb +2 -0
- data/lib/active_support/core_ext/hash/indifferent_access.rb +2 -0
- data/lib/active_support/core_ext/hash/keys.rb +2 -0
- data/lib/active_support/core_ext/hash/reverse_merge.rb +5 -2
- data/lib/active_support/core_ext/hash/slice.rb +4 -4
- data/lib/active_support/core_ext/hash/transform_values.rb +2 -0
- data/lib/active_support/core_ext/hash.rb +2 -0
- data/lib/active_support/core_ext/integer/inflections.rb +2 -0
- data/lib/active_support/core_ext/integer/multiple.rb +2 -0
- 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/agnostics.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 -0
- data/lib/active_support/core_ext/load_error.rb +2 -7
- data/lib/active_support/core_ext/marshal.rb +2 -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 +2 -0
- data/lib/active_support/core_ext/module/attribute_accessors.rb +21 -24
- data/lib/active_support/core_ext/module/attribute_accessors_per_thread.rb +2 -0
- data/lib/active_support/core_ext/module/concerning.rb +7 -8
- data/lib/active_support/core_ext/module/delegation.rb +31 -29
- data/lib/active_support/core_ext/module/deprecation.rb +2 -0
- data/lib/active_support/core_ext/module/introspection.rb +2 -0
- data/lib/active_support/core_ext/module/reachable.rb +3 -0
- data/lib/active_support/core_ext/module/redefine_method.rb +49 -0
- data/lib/active_support/core_ext/module/remove_method.rb +5 -23
- data/lib/active_support/core_ext/module.rb +3 -0
- data/lib/active_support/core_ext/name_error.rb +7 -0
- data/lib/active_support/core_ext/numeric/bytes.rb +2 -0
- data/lib/active_support/core_ext/numeric/conversions.rb +9 -7
- data/lib/active_support/core_ext/numeric/inquiry.rb +2 -0
- data/lib/active_support/core_ext/numeric/time.rb +7 -15
- data/lib/active_support/core_ext/numeric.rb +2 -0
- data/lib/active_support/core_ext/object/acts_like.rb +12 -1
- data/lib/active_support/core_ext/object/blank.rb +12 -1
- data/lib/active_support/core_ext/object/conversions.rb +2 -0
- data/lib/active_support/core_ext/object/deep_dup.rb +2 -0
- data/lib/active_support/core_ext/object/duplicable.rb +10 -8
- 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 +8 -0
- 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 +2 -0
- data/lib/active_support/core_ext/object/with_options.rb +3 -1
- data/lib/active_support/core_ext/object.rb +2 -0
- data/lib/active_support/core_ext/range/conversions.rb +9 -1
- data/lib/active_support/core_ext/range/each.rb +5 -1
- data/lib/active_support/core_ext/range/include_range.rb +2 -0
- 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/range.rb +3 -0
- data/lib/active_support/core_ext/regexp.rb +2 -0
- data/lib/active_support/core_ext/securerandom.rb +2 -0
- data/lib/active_support/core_ext/string/access.rb +2 -0
- data/lib/active_support/core_ext/string/behavior.rb +2 -0
- data/lib/active_support/core_ext/string/conversions.rb +2 -0
- data/lib/active_support/core_ext/string/exclude.rb +2 -0
- data/lib/active_support/core_ext/string/filters.rb +2 -0
- data/lib/active_support/core_ext/string/indent.rb +2 -0
- data/lib/active_support/core_ext/string/inflections.rb +26 -12
- data/lib/active_support/core_ext/string/inquiry.rb +2 -0
- data/lib/active_support/core_ext/string/multibyte.rb +4 -0
- data/lib/active_support/core_ext/string/output_safety.rb +6 -7
- data/lib/active_support/core_ext/string/starts_ends_with.rb +2 -0
- data/lib/active_support/core_ext/string/strip.rb +2 -0
- 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/time/acts_like.rb +2 -0
- data/lib/active_support/core_ext/time/calculations.rb +23 -15
- data/lib/active_support/core_ext/time/compatibility.rb +4 -2
- data/lib/active_support/core_ext/time/conversions.rb +2 -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 +4 -1
- data/lib/active_support/core_ext.rb +3 -1
- data/lib/active_support/current_attributes.rb +195 -0
- data/lib/active_support/dependencies/autoload.rb +2 -0
- data/lib/active_support/dependencies/interlock.rb +2 -0
- data/lib/active_support/dependencies.rb +16 -25
- data/lib/active_support/deprecation/behaviors.rb +24 -9
- data/lib/active_support/deprecation/constant_accessor.rb +4 -2
- data/lib/active_support/deprecation/instance_delegator.rb +2 -0
- data/lib/active_support/deprecation/method_wrappers.rb +8 -8
- data/lib/active_support/deprecation/proxy_wrappers.rb +5 -2
- data/lib/active_support/deprecation/reporting.rb +5 -3
- data/lib/active_support/deprecation.rb +4 -2
- data/lib/active_support/descendants_tracker.rb +2 -0
- data/lib/active_support/digest.rb +20 -0
- data/lib/active_support/duration/iso8601_parser.rb +4 -2
- data/lib/active_support/duration/iso8601_serializer.rb +4 -2
- data/lib/active_support/duration.rb +11 -7
- 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 +2 -0
- data/lib/active_support/execution_wrapper.rb +2 -0
- data/lib/active_support/executor.rb +2 -0
- data/lib/active_support/file_update_checker.rb +2 -0
- data/lib/active_support/gem_version.rb +4 -2
- data/lib/active_support/gzip.rb +2 -0
- data/lib/active_support/hash_with_indifferent_access.rb +41 -1
- data/lib/active_support/i18n.rb +3 -1
- data/lib/active_support/i18n_railtie.rb +4 -6
- data/lib/active_support/inflections.rb +2 -0
- data/lib/active_support/inflector/inflections.rb +20 -4
- data/lib/active_support/inflector/methods.rb +41 -24
- data/lib/active_support/inflector/transliterate.rb +17 -8
- data/lib/active_support/inflector.rb +2 -0
- data/lib/active_support/json/decoding.rb +2 -0
- data/lib/active_support/json/encoding.rb +2 -0
- data/lib/active_support/json.rb +2 -0
- data/lib/active_support/key_generator.rb +3 -1
- data/lib/active_support/lazy_load_hooks.rb +2 -0
- data/lib/active_support/log_subscriber/test_helper.rb +2 -0
- data/lib/active_support/log_subscriber.rb +3 -2
- data/lib/active_support/logger.rb +2 -0
- data/lib/active_support/logger_silence.rb +3 -2
- data/lib/active_support/logger_thread_safe_level.rb +2 -0
- data/lib/active_support/message_encryptor.rb +95 -22
- data/lib/active_support/message_verifier.rb +78 -7
- 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/chars.rb +2 -0
- data/lib/active_support/multibyte/unicode.rb +4 -2
- data/lib/active_support/multibyte.rb +2 -0
- data/lib/active_support/notifications/fanout.rb +2 -0
- data/lib/active_support/notifications/instrumenter.rb +2 -0
- data/lib/active_support/notifications.rb +2 -0
- data/lib/active_support/number_helper/number_converter.rb +2 -0
- data/lib/active_support/number_helper/number_to_currency_converter.rb +2 -0
- data/lib/active_support/number_helper/number_to_delimited_converter.rb +2 -0
- data/lib/active_support/number_helper/number_to_human_converter.rb +2 -0
- data/lib/active_support/number_helper/number_to_human_size_converter.rb +2 -0
- data/lib/active_support/number_helper/number_to_percentage_converter.rb +2 -0
- data/lib/active_support/number_helper/number_to_phone_converter.rb +3 -1
- data/lib/active_support/number_helper/number_to_rounded_converter.rb +2 -20
- data/lib/active_support/number_helper/rounding_helper.rb +6 -4
- data/lib/active_support/number_helper.rb +2 -0
- data/lib/active_support/option_merger.rb +2 -0
- data/lib/active_support/ordered_hash.rb +2 -0
- data/lib/active_support/ordered_options.rb +4 -2
- data/lib/active_support/per_thread_registry.rb +2 -0
- data/lib/active_support/proxy_object.rb +2 -0
- data/lib/active_support/rails.rb +2 -0
- data/lib/active_support/railtie.rb +37 -8
- data/lib/active_support/reloader.rb +7 -5
- data/lib/active_support/rescuable.rb +3 -2
- data/lib/active_support/security_utils.rb +15 -11
- data/lib/active_support/string_inquirer.rb +2 -0
- data/lib/active_support/subscriber.rb +2 -0
- data/lib/active_support/tagged_logging.rb +2 -0
- data/lib/active_support/test_case.rb +2 -1
- data/lib/active_support/testing/assertions.rb +31 -14
- 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 -0
- data/lib/active_support/testing/file_fixtures.rb +2 -0
- data/lib/active_support/testing/isolation.rb +3 -1
- data/lib/active_support/testing/method_call_assertions.rb +2 -0
- data/lib/active_support/testing/setup_and_teardown.rb +10 -1
- data/lib/active_support/testing/stream.rb +2 -0
- data/lib/active_support/testing/tagged_logging.rb +2 -0
- data/lib/active_support/testing/time_helpers.rb +33 -3
- data/lib/active_support/time.rb +2 -0
- data/lib/active_support/time_with_zone.rb +38 -0
- data/lib/active_support/values/time_zone.rb +19 -8
- data/lib/active_support/version.rb +2 -0
- data/lib/active_support/xml_mini/jdom.rb +4 -2
- data/lib/active_support/xml_mini/libxml.rb +3 -1
- data/lib/active_support/xml_mini/libxmlsax.rb +4 -2
- data/lib/active_support/xml_mini/nokogiri.rb +3 -1
- data/lib/active_support/xml_mini/nokogirisax.rb +3 -1
- data/lib/active_support/xml_mini/rexml.rb +3 -1
- data/lib/active_support/xml_mini.rb +3 -1
- data/lib/active_support.rb +5 -13
- metadata +15 -5
@@ -1,3 +1,5 @@
|
|
1
|
+
# frozen_string_literal: true
|
2
|
+
|
1
3
|
require "active_support/core_ext/array/conversions"
|
2
4
|
require "active_support/core_ext/module/delegation"
|
3
5
|
require "active_support/core_ext/object/acts_like"
|
@@ -131,7 +133,7 @@ module ActiveSupport
|
|
131
133
|
class << self
|
132
134
|
# Creates a new Duration from string formatted according to ISO 8601 Duration.
|
133
135
|
#
|
134
|
-
# See {ISO 8601}[
|
136
|
+
# See {ISO 8601}[https://en.wikipedia.org/wiki/ISO_8601#Durations] for more information.
|
135
137
|
# This method allows negative parts to be present in pattern.
|
136
138
|
# If invalid string is provided, it will raise +ActiveSupport::Duration::ISO8601Parser::ParsingError+.
|
137
139
|
def parse(iso8601duration)
|
@@ -192,7 +194,6 @@ module ActiveSupport
|
|
192
194
|
end
|
193
195
|
|
194
196
|
parts[:seconds] = remainder
|
195
|
-
parts.reject! { |k, v| v.zero? }
|
196
197
|
|
197
198
|
new(value, parts)
|
198
199
|
end
|
@@ -209,6 +210,7 @@ module ActiveSupport
|
|
209
210
|
def initialize(value, parts) #:nodoc:
|
210
211
|
@value, @parts = value, parts.to_h
|
211
212
|
@parts.default = 0
|
213
|
+
@parts.reject! { |k, v| v.zero? }
|
212
214
|
end
|
213
215
|
|
214
216
|
def coerce(other) #:nodoc:
|
@@ -368,6 +370,8 @@ module ActiveSupport
|
|
368
370
|
alias :before :ago
|
369
371
|
|
370
372
|
def inspect #:nodoc:
|
373
|
+
return "0 seconds" if parts.empty?
|
374
|
+
|
371
375
|
parts.
|
372
376
|
reduce(::Hash.new(0)) { |h, (l, r)| h[l] += r; h }.
|
373
377
|
sort_by { |unit, _ | PARTS.index(unit) }.
|
@@ -379,10 +383,6 @@ module ActiveSupport
|
|
379
383
|
to_i
|
380
384
|
end
|
381
385
|
|
382
|
-
def respond_to_missing?(method, include_private = false) #:nodoc:
|
383
|
-
@value.respond_to?(method, include_private)
|
384
|
-
end
|
385
|
-
|
386
386
|
def init_with(coder) #:nodoc:
|
387
387
|
initialize(coder["value"], coder["parts"])
|
388
388
|
end
|
@@ -417,8 +417,12 @@ module ActiveSupport
|
|
417
417
|
end
|
418
418
|
end
|
419
419
|
|
420
|
+
def respond_to_missing?(method, _)
|
421
|
+
value.respond_to?(method)
|
422
|
+
end
|
423
|
+
|
420
424
|
def method_missing(method, *args, &block)
|
421
|
-
value.
|
425
|
+
value.public_send(method, *args, &block)
|
422
426
|
end
|
423
427
|
|
424
428
|
def raise_type_error(other)
|
@@ -0,0 +1,49 @@
|
|
1
|
+
# frozen_string_literal: true
|
2
|
+
|
3
|
+
require "yaml"
|
4
|
+
require "active_support/encrypted_file"
|
5
|
+
require "active_support/ordered_options"
|
6
|
+
require "active_support/core_ext/object/inclusion"
|
7
|
+
require "active_support/core_ext/module/delegation"
|
8
|
+
|
9
|
+
module ActiveSupport
|
10
|
+
class EncryptedConfiguration < EncryptedFile
|
11
|
+
delegate :[], :fetch, to: :config
|
12
|
+
delegate_missing_to :options
|
13
|
+
|
14
|
+
def initialize(config_path:, key_path:, env_key:, raise_if_missing_key:)
|
15
|
+
super content_path: config_path, key_path: key_path,
|
16
|
+
env_key: env_key, raise_if_missing_key: raise_if_missing_key
|
17
|
+
end
|
18
|
+
|
19
|
+
# Allow a config to be started without a file present
|
20
|
+
def read
|
21
|
+
super
|
22
|
+
rescue ActiveSupport::EncryptedFile::MissingContentError
|
23
|
+
""
|
24
|
+
end
|
25
|
+
|
26
|
+
def write(contents)
|
27
|
+
deserialize(contents)
|
28
|
+
|
29
|
+
super
|
30
|
+
end
|
31
|
+
|
32
|
+
def config
|
33
|
+
@config ||= deserialize(read).deep_symbolize_keys
|
34
|
+
end
|
35
|
+
|
36
|
+
private
|
37
|
+
def options
|
38
|
+
@options ||= ActiveSupport::InheritableOptions.new(config)
|
39
|
+
end
|
40
|
+
|
41
|
+
def serialize(config)
|
42
|
+
config.present? ? YAML.dump(config) : ""
|
43
|
+
end
|
44
|
+
|
45
|
+
def deserialize(config)
|
46
|
+
config.present? ? YAML.load(config, content_path) : {}
|
47
|
+
end
|
48
|
+
end
|
49
|
+
end
|
@@ -0,0 +1,99 @@
|
|
1
|
+
# frozen_string_literal: true
|
2
|
+
|
3
|
+
require "pathname"
|
4
|
+
require "active_support/message_encryptor"
|
5
|
+
|
6
|
+
module ActiveSupport
|
7
|
+
class EncryptedFile
|
8
|
+
class MissingContentError < RuntimeError
|
9
|
+
def initialize(content_path)
|
10
|
+
super "Missing encrypted content file in #{content_path}."
|
11
|
+
end
|
12
|
+
end
|
13
|
+
|
14
|
+
class MissingKeyError < RuntimeError
|
15
|
+
def initialize(key_path:, env_key:)
|
16
|
+
super \
|
17
|
+
"Missing encryption key to decrypt file with. " +
|
18
|
+
"Ask your team for your master key and write it to #{key_path} or put it in the ENV['#{env_key}']."
|
19
|
+
end
|
20
|
+
end
|
21
|
+
|
22
|
+
CIPHER = "aes-128-gcm"
|
23
|
+
|
24
|
+
def self.generate_key
|
25
|
+
SecureRandom.hex(ActiveSupport::MessageEncryptor.key_len(CIPHER))
|
26
|
+
end
|
27
|
+
|
28
|
+
|
29
|
+
attr_reader :content_path, :key_path, :env_key, :raise_if_missing_key
|
30
|
+
|
31
|
+
def initialize(content_path:, key_path:, env_key:, raise_if_missing_key:)
|
32
|
+
@content_path, @key_path = Pathname.new(content_path), Pathname.new(key_path)
|
33
|
+
@env_key, @raise_if_missing_key = env_key, raise_if_missing_key
|
34
|
+
end
|
35
|
+
|
36
|
+
def key
|
37
|
+
read_env_key || read_key_file || handle_missing_key
|
38
|
+
end
|
39
|
+
|
40
|
+
def read
|
41
|
+
if !key.nil? && content_path.exist?
|
42
|
+
decrypt content_path.binread
|
43
|
+
else
|
44
|
+
raise MissingContentError, content_path
|
45
|
+
end
|
46
|
+
end
|
47
|
+
|
48
|
+
def write(contents)
|
49
|
+
IO.binwrite "#{content_path}.tmp", encrypt(contents)
|
50
|
+
FileUtils.mv "#{content_path}.tmp", content_path
|
51
|
+
end
|
52
|
+
|
53
|
+
def change(&block)
|
54
|
+
writing read, &block
|
55
|
+
end
|
56
|
+
|
57
|
+
|
58
|
+
private
|
59
|
+
def writing(contents)
|
60
|
+
tmp_file = "#{content_path.basename}.#{Process.pid}"
|
61
|
+
tmp_path = Pathname.new File.join(Dir.tmpdir, tmp_file)
|
62
|
+
tmp_path.binwrite contents
|
63
|
+
|
64
|
+
yield tmp_path
|
65
|
+
|
66
|
+
updated_contents = tmp_path.binread
|
67
|
+
|
68
|
+
write(updated_contents) if updated_contents != contents
|
69
|
+
ensure
|
70
|
+
FileUtils.rm(tmp_path) if tmp_path.exist?
|
71
|
+
end
|
72
|
+
|
73
|
+
|
74
|
+
def encrypt(contents)
|
75
|
+
encryptor.encrypt_and_sign contents
|
76
|
+
end
|
77
|
+
|
78
|
+
def decrypt(contents)
|
79
|
+
encryptor.decrypt_and_verify contents
|
80
|
+
end
|
81
|
+
|
82
|
+
def encryptor
|
83
|
+
@encryptor ||= ActiveSupport::MessageEncryptor.new([ key ].pack("H*"), cipher: CIPHER)
|
84
|
+
end
|
85
|
+
|
86
|
+
|
87
|
+
def read_env_key
|
88
|
+
ENV[env_key]
|
89
|
+
end
|
90
|
+
|
91
|
+
def read_key_file
|
92
|
+
key_path.binread.strip if key_path.exist?
|
93
|
+
end
|
94
|
+
|
95
|
+
def handle_missing_key
|
96
|
+
raise MissingKeyError, key_path: key_path, env_key: env_key if raise_if_missing_key
|
97
|
+
end
|
98
|
+
end
|
99
|
+
end
|
@@ -1,3 +1,5 @@
|
|
1
|
+
# frozen_string_literal: true
|
2
|
+
|
1
3
|
module ActiveSupport
|
2
4
|
# Returns the version of the currently loaded Active Support as a <tt>Gem::Version</tt>.
|
3
5
|
def self.gem_version
|
@@ -6,8 +8,8 @@ module ActiveSupport
|
|
6
8
|
|
7
9
|
module VERSION
|
8
10
|
MAJOR = 5
|
9
|
-
MINOR =
|
10
|
-
TINY =
|
11
|
+
MINOR = 2
|
12
|
+
TINY = 0
|
11
13
|
PRE = nil
|
12
14
|
|
13
15
|
STRING = [MAJOR, MINOR, TINY, PRE].compact.join(".")
|
data/lib/active_support/gzip.rb
CHANGED
@@ -1,3 +1,5 @@
|
|
1
|
+
# frozen_string_literal: true
|
2
|
+
|
1
3
|
require "active_support/core_ext/hash/keys"
|
2
4
|
require "active_support/core_ext/hash/reverse_merge"
|
3
5
|
|
@@ -215,6 +217,19 @@ module ActiveSupport
|
|
215
217
|
indices.collect { |key| self[convert_key(key)] }
|
216
218
|
end
|
217
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
|
+
|
218
233
|
# Returns a shallow copy of the hash.
|
219
234
|
#
|
220
235
|
# hash = ActiveSupport::HashWithIndifferentAccess.new({ a: { b: 'b' } })
|
@@ -245,11 +260,13 @@ module ActiveSupport
|
|
245
260
|
def reverse_merge(other_hash)
|
246
261
|
super(self.class.new(other_hash))
|
247
262
|
end
|
263
|
+
alias_method :with_defaults, :reverse_merge
|
248
264
|
|
249
265
|
# Same semantics as +reverse_merge+ but modifies the receiver in-place.
|
250
266
|
def reverse_merge!(other_hash)
|
251
|
-
|
267
|
+
super(self.class.new(other_hash))
|
252
268
|
end
|
269
|
+
alias_method :with_defaults!, :reverse_merge!
|
253
270
|
|
254
271
|
# Replaces the contents of this hash with other_hash.
|
255
272
|
#
|
@@ -289,6 +306,29 @@ module ActiveSupport
|
|
289
306
|
dup.tap { |hash| hash.transform_values!(*args, &block) }
|
290
307
|
end
|
291
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
|
+
|
292
332
|
def compact
|
293
333
|
dup.tap(&:compact!)
|
294
334
|
end
|
data/lib/active_support/i18n.rb
CHANGED
@@ -1,3 +1,5 @@
|
|
1
|
+
# frozen_string_literal: true
|
2
|
+
|
1
3
|
require "active_support/core_ext/hash/deep_merge"
|
2
4
|
require "active_support/core_ext/hash/except"
|
3
5
|
require "active_support/core_ext/hash/slice"
|
@@ -10,4 +12,4 @@ end
|
|
10
12
|
require "active_support/lazy_load_hooks"
|
11
13
|
|
12
14
|
ActiveSupport.run_load_hooks(:i18n)
|
13
|
-
I18n.load_path <<
|
15
|
+
I18n.load_path << File.expand_path("locale/en.yml", __dir__)
|
@@ -1,3 +1,5 @@
|
|
1
|
+
# frozen_string_literal: true
|
2
|
+
|
1
3
|
require "active_support"
|
2
4
|
require "active_support/file_update_checker"
|
3
5
|
require "active_support/core_ext/array/wrap"
|
@@ -42,7 +44,7 @@ module I18n
|
|
42
44
|
case setting
|
43
45
|
when :railties_load_path
|
44
46
|
reloadable_paths = value
|
45
|
-
app.config.i18n.load_path.unshift(*value.
|
47
|
+
app.config.i18n.load_path.unshift(*value.flat_map(&:existent))
|
46
48
|
when :load_path
|
47
49
|
I18n.load_path += value
|
48
50
|
else
|
@@ -58,7 +60,7 @@ module I18n
|
|
58
60
|
directories = watched_dirs_with_extensions(reloadable_paths)
|
59
61
|
reloader = app.config.file_watcher.new(I18n.load_path.dup, directories) do
|
60
62
|
I18n.load_path.keep_if { |p| File.exist?(p) }
|
61
|
-
I18n.load_path |= reloadable_paths.
|
63
|
+
I18n.load_path |= reloadable_paths.flat_map(&:existent)
|
62
64
|
|
63
65
|
I18n.reload!
|
64
66
|
end
|
@@ -66,10 +68,6 @@ module I18n
|
|
66
68
|
app.reloaders << reloader
|
67
69
|
app.reloader.to_run do
|
68
70
|
reloader.execute_if_updated { require_unload_lock! }
|
69
|
-
# TODO: remove the following line as soon as the return value of
|
70
|
-
# callbacks is ignored, that is, returning `false` does not
|
71
|
-
# display a deprecation warning or halts the callback chain.
|
72
|
-
true
|
73
71
|
end
|
74
72
|
reloader.execute
|
75
73
|
|
@@ -1,7 +1,10 @@
|
|
1
|
+
# frozen_string_literal: true
|
2
|
+
|
1
3
|
require "concurrent/map"
|
2
4
|
require "active_support/core_ext/array/prepend_and_append"
|
3
5
|
require "active_support/core_ext/regexp"
|
4
6
|
require "active_support/i18n"
|
7
|
+
require "active_support/deprecation"
|
5
8
|
|
6
9
|
module ActiveSupport
|
7
10
|
module Inflector
|
@@ -65,16 +68,21 @@ module ActiveSupport
|
|
65
68
|
end
|
66
69
|
|
67
70
|
attr_reader :plurals, :singulars, :uncountables, :humans, :acronyms, :acronym_regex
|
71
|
+
deprecate :acronym_regex
|
72
|
+
|
73
|
+
attr_reader :acronyms_camelize_regex, :acronyms_underscore_regex # :nodoc:
|
68
74
|
|
69
75
|
def initialize
|
70
|
-
@plurals, @singulars, @uncountables, @humans, @acronyms
|
76
|
+
@plurals, @singulars, @uncountables, @humans, @acronyms = [], [], Uncountables.new, [], {}
|
77
|
+
define_acronym_regex_patterns
|
71
78
|
end
|
72
79
|
|
73
80
|
# Private, for the test suite.
|
74
81
|
def initialize_dup(orig) # :nodoc:
|
75
|
-
%w(plurals singulars uncountables humans acronyms
|
82
|
+
%w(plurals singulars uncountables humans acronyms).each do |scope|
|
76
83
|
instance_variable_set("@#{scope}", orig.send(scope).dup)
|
77
84
|
end
|
85
|
+
define_acronym_regex_patterns
|
78
86
|
end
|
79
87
|
|
80
88
|
# Specifies a new acronym. An acronym must be specified as it will appear
|
@@ -128,7 +136,7 @@ module ActiveSupport
|
|
128
136
|
# camelize 'mcdonald' # => 'McDonald'
|
129
137
|
def acronym(word)
|
130
138
|
@acronyms[word.downcase] = word
|
131
|
-
|
139
|
+
define_acronym_regex_patterns
|
132
140
|
end
|
133
141
|
|
134
142
|
# Specifies a new pluralization rule and its replacement. The rule can
|
@@ -219,10 +227,18 @@ module ActiveSupport
|
|
219
227
|
case scope
|
220
228
|
when :all
|
221
229
|
@plurals, @singulars, @uncountables, @humans = [], [], Uncountables.new, []
|
222
|
-
|
230
|
+
else
|
223
231
|
instance_variable_set "@#{scope}", []
|
224
232
|
end
|
225
233
|
end
|
234
|
+
|
235
|
+
private
|
236
|
+
|
237
|
+
def define_acronym_regex_patterns
|
238
|
+
@acronym_regex = @acronyms.empty? ? /(?=a)b/ : /#{@acronyms.values.join("|")}/
|
239
|
+
@acronyms_camelize_regex = /^(?:#{@acronym_regex}(?=\b|[A-Z_])|\w)/
|
240
|
+
@acronyms_underscore_regex = /(?:(?<=([A-Za-z\d]))|\b)(#{@acronym_regex})(?=\b|[^a-z])/
|
241
|
+
end
|
226
242
|
end
|
227
243
|
|
228
244
|
# Yields a singleton instance of Inflector::Inflections so you can specify
|
@@ -1,3 +1,5 @@
|
|
1
|
+
# frozen_string_literal: true
|
2
|
+
|
1
3
|
require "active_support/inflections"
|
2
4
|
require "active_support/core_ext/regexp"
|
3
5
|
|
@@ -28,7 +30,7 @@ module ActiveSupport
|
|
28
30
|
# pluralize('CamelOctopus') # => "CamelOctopi"
|
29
31
|
# pluralize('ley', :es) # => "leyes"
|
30
32
|
def pluralize(word, locale = :en)
|
31
|
-
apply_inflections(word, inflections(locale).plurals)
|
33
|
+
apply_inflections(word, inflections(locale).plurals, locale)
|
32
34
|
end
|
33
35
|
|
34
36
|
# The reverse of #pluralize, returns the singular form of a word in a
|
@@ -45,7 +47,7 @@ module ActiveSupport
|
|
45
47
|
# singularize('CamelOctopi') # => "CamelOctopus"
|
46
48
|
# singularize('leyes', :es) # => "ley"
|
47
49
|
def singularize(word, locale = :en)
|
48
|
-
apply_inflections(word, inflections(locale).singulars)
|
50
|
+
apply_inflections(word, inflections(locale).singulars, locale)
|
49
51
|
end
|
50
52
|
|
51
53
|
# Converts strings to UpperCamelCase.
|
@@ -69,7 +71,7 @@ module ActiveSupport
|
|
69
71
|
if uppercase_first_letter
|
70
72
|
string = string.sub(/^[a-z\d]*/) { |match| inflections.acronyms[match] || match.capitalize }
|
71
73
|
else
|
72
|
-
string = string.sub(
|
74
|
+
string = string.sub(inflections.acronyms_camelize_regex) { |match| match.downcase }
|
73
75
|
end
|
74
76
|
string.gsub!(/(?:_|(\/))([a-z\d]*)/i) { "#{$1}#{inflections.acronyms[$2] || $2.capitalize}" }
|
75
77
|
string.gsub!("/".freeze, "::".freeze)
|
@@ -90,7 +92,7 @@ module ActiveSupport
|
|
90
92
|
def underscore(camel_cased_word)
|
91
93
|
return camel_cased_word unless /[A-Z-]|::/.match?(camel_cased_word)
|
92
94
|
word = camel_cased_word.to_s.gsub("::".freeze, "/".freeze)
|
93
|
-
word.gsub!(
|
95
|
+
word.gsub!(inflections.acronyms_underscore_regex) { "#{$1 && '_'.freeze }#{$2.downcase}" }
|
94
96
|
word.gsub!(/([A-Z\d]+)([A-Z][a-z])/, '\1_\2'.freeze)
|
95
97
|
word.gsub!(/([a-z\d])([A-Z])/, '\1_\2'.freeze)
|
96
98
|
word.tr!("-".freeze, "_".freeze)
|
@@ -108,33 +110,38 @@ module ActiveSupport
|
|
108
110
|
# * Replaces underscores with spaces, if any.
|
109
111
|
# * Downcases all words except acronyms.
|
110
112
|
# * Capitalizes the first word.
|
111
|
-
#
|
112
113
|
# The capitalization of the first word can be turned off by setting the
|
113
114
|
# +:capitalize+ option to false (default is true).
|
114
115
|
#
|
115
|
-
#
|
116
|
-
#
|
117
|
-
#
|
118
|
-
# humanize('
|
116
|
+
# The trailing '_id' can be kept and capitalized by setting the
|
117
|
+
# optional parameter +keep_id_suffix+ to true (default is false).
|
118
|
+
#
|
119
|
+
# humanize('employee_salary') # => "Employee salary"
|
120
|
+
# humanize('author_id') # => "Author"
|
121
|
+
# humanize('author_id', capitalize: false) # => "author"
|
122
|
+
# humanize('_id') # => "Id"
|
123
|
+
# humanize('author_id', keep_id_suffix: true) # => "Author Id"
|
119
124
|
#
|
120
125
|
# If "SSL" was defined to be an acronym:
|
121
126
|
#
|
122
127
|
# humanize('ssl_error') # => "SSL error"
|
123
128
|
#
|
124
|
-
def humanize(lower_case_and_underscored_word,
|
129
|
+
def humanize(lower_case_and_underscored_word, capitalize: true, keep_id_suffix: false)
|
125
130
|
result = lower_case_and_underscored_word.to_s.dup
|
126
131
|
|
127
132
|
inflections.humans.each { |(rule, replacement)| break if result.sub!(rule, replacement) }
|
128
133
|
|
129
134
|
result.sub!(/\A_+/, "".freeze)
|
130
|
-
|
135
|
+
unless keep_id_suffix
|
136
|
+
result.sub!(/_id\z/, "".freeze)
|
137
|
+
end
|
131
138
|
result.tr!("_".freeze, " ".freeze)
|
132
139
|
|
133
140
|
result.gsub!(/([a-z\d]*)/i) do |match|
|
134
|
-
"#{inflections.acronyms[match] || match.downcase}"
|
141
|
+
"#{inflections.acronyms[match.downcase] || match.downcase}"
|
135
142
|
end
|
136
143
|
|
137
|
-
if
|
144
|
+
if capitalize
|
138
145
|
result.sub!(/\A\w/) { |match| match.upcase }
|
139
146
|
end
|
140
147
|
|
@@ -154,14 +161,21 @@ module ActiveSupport
|
|
154
161
|
# create a nicer looking title. +titleize+ is meant for creating pretty
|
155
162
|
# output. It is not used in the Rails internals.
|
156
163
|
#
|
164
|
+
# The trailing '_id','Id'.. can be kept and capitalized by setting the
|
165
|
+
# optional parameter +keep_id_suffix+ to true.
|
166
|
+
# By default, this parameter is false.
|
167
|
+
#
|
157
168
|
# +titleize+ is also aliased as +titlecase+.
|
158
169
|
#
|
159
|
-
# titleize('man from the boondocks')
|
160
|
-
# titleize('x-men: the last stand')
|
161
|
-
# titleize('TheManWithoutAPast')
|
162
|
-
# titleize('raiders_of_the_lost_ark')
|
163
|
-
|
164
|
-
|
170
|
+
# titleize('man from the boondocks') # => "Man From The Boondocks"
|
171
|
+
# titleize('x-men: the last stand') # => "X Men: The Last Stand"
|
172
|
+
# titleize('TheManWithoutAPast') # => "The Man Without A Past"
|
173
|
+
# titleize('raiders_of_the_lost_ark') # => "Raiders Of The Lost Ark"
|
174
|
+
# titleize('string_ending_with_id', keep_id_suffix: true) # => "String Ending With Id"
|
175
|
+
def titleize(word, keep_id_suffix: false)
|
176
|
+
humanize(underscore(word), keep_id_suffix: keep_id_suffix).gsub(/\b(?<!\w['’`])[a-z]/) do |match|
|
177
|
+
match.capitalize
|
178
|
+
end
|
165
179
|
end
|
166
180
|
|
167
181
|
# Creates the name of a table like Rails does for models to table names.
|
@@ -336,7 +350,7 @@ module ActiveSupport
|
|
336
350
|
when 1; "st"
|
337
351
|
when 2; "nd"
|
338
352
|
when 3; "rd"
|
339
|
-
|
353
|
+
else "th"
|
340
354
|
end
|
341
355
|
end
|
342
356
|
end
|
@@ -375,12 +389,15 @@ module ActiveSupport
|
|
375
389
|
|
376
390
|
# Applies inflection rules for +singularize+ and +pluralize+.
|
377
391
|
#
|
378
|
-
#
|
379
|
-
#
|
380
|
-
|
392
|
+
# If passed an optional +locale+ parameter, the uncountables will be
|
393
|
+
# found for that locale.
|
394
|
+
#
|
395
|
+
# apply_inflections('post', inflections.plurals, :en) # => "posts"
|
396
|
+
# apply_inflections('posts', inflections.singulars, :en) # => "post"
|
397
|
+
def apply_inflections(word, rules, locale = :en)
|
381
398
|
result = word.to_s.dup
|
382
399
|
|
383
|
-
if word.empty? || inflections.uncountables.uncountable?(result)
|
400
|
+
if word.empty? || inflections(locale).uncountables.uncountable?(result)
|
384
401
|
result
|
385
402
|
else
|
386
403
|
rules.each { |(rule, replacement)| break if result.sub!(rule, replacement) }
|
@@ -1,3 +1,5 @@
|
|
1
|
+
# frozen_string_literal: true
|
2
|
+
|
1
3
|
require "active_support/core_ext/string/multibyte"
|
2
4
|
require "active_support/i18n"
|
3
5
|
|
@@ -59,26 +61,33 @@ module ActiveSupport
|
|
59
61
|
def transliterate(string, replacement = "?".freeze)
|
60
62
|
raise ArgumentError, "Can only transliterate strings. Received #{string.class.name}" unless string.is_a?(String)
|
61
63
|
|
62
|
-
I18n.transliterate(
|
63
|
-
ActiveSupport::Multibyte::Unicode.
|
64
|
-
|
64
|
+
I18n.transliterate(
|
65
|
+
ActiveSupport::Multibyte::Unicode.normalize(
|
66
|
+
ActiveSupport::Multibyte::Unicode.tidy_bytes(string), :c),
|
67
|
+
replacement: replacement)
|
65
68
|
end
|
66
69
|
|
67
70
|
# Replaces special characters in a string so that it may be used as part of
|
68
71
|
# a 'pretty' URL.
|
69
72
|
#
|
70
73
|
# parameterize("Donald E. Knuth") # => "donald-e-knuth"
|
71
|
-
# parameterize("^
|
74
|
+
# parameterize("^très|Jolie-- ") # => "tres-jolie"
|
72
75
|
#
|
73
|
-
# To use a custom separator, override the
|
76
|
+
# To use a custom separator, override the +separator+ argument.
|
74
77
|
#
|
75
78
|
# parameterize("Donald E. Knuth", separator: '_') # => "donald_e_knuth"
|
76
|
-
# parameterize("^
|
79
|
+
# parameterize("^très|Jolie__ ", separator: '_') # => "tres_jolie"
|
77
80
|
#
|
78
|
-
# To preserve the case of the characters in a string, use the
|
81
|
+
# To preserve the case of the characters in a string, use the +preserve_case+ argument.
|
79
82
|
#
|
80
83
|
# parameterize("Donald E. Knuth", preserve_case: true) # => "Donald-E-Knuth"
|
81
|
-
# parameterize("^
|
84
|
+
# parameterize("^très|Jolie-- ", preserve_case: true) # => "tres-Jolie"
|
85
|
+
#
|
86
|
+
# It preserves dashes and underscores unless they are used as separators:
|
87
|
+
#
|
88
|
+
# parameterize("^très|Jolie__ ") # => "tres-jolie__"
|
89
|
+
# parameterize("^très|Jolie-- ", separator: "_") # => "tres_jolie--"
|
90
|
+
# parameterize("^très_Jolie-- ", separator: ".") # => "tres_jolie--"
|
82
91
|
#
|
83
92
|
def parameterize(string, separator: "-", preserve_case: false)
|
84
93
|
# Replace accented chars with their ASCII equivalents.
|
data/lib/active_support/json.rb
CHANGED