activesupport 4.2.11.1 → 6.0.3.1
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 +399 -411
- data/MIT-LICENSE +2 -2
- data/README.rdoc +7 -7
- data/lib/active_support/actionable_error.rb +48 -0
- data/lib/active_support/all.rb +5 -3
- data/lib/active_support/array_inquirer.rb +48 -0
- data/lib/active_support/backtrace_cleaner.rb +34 -6
- data/lib/active_support/benchmarkable.rb +6 -4
- data/lib/active_support/builder.rb +3 -1
- data/lib/active_support/cache/file_store.rb +58 -53
- data/lib/active_support/cache/mem_cache_store.rb +95 -91
- data/lib/active_support/cache/memory_store.rb +39 -36
- data/lib/active_support/cache/null_store.rb +11 -7
- data/lib/active_support/cache/redis_cache_store.rb +493 -0
- data/lib/active_support/cache/strategy/local_cache.rb +75 -42
- data/lib/active_support/cache/strategy/local_cache_middleware.rb +10 -9
- data/lib/active_support/cache.rb +331 -217
- data/lib/active_support/callbacks.rb +650 -592
- data/lib/active_support/concern.rb +35 -6
- data/lib/active_support/concurrency/load_interlock_aware_monitor.rb +35 -0
- data/lib/active_support/concurrency/share_lock.rb +226 -0
- data/lib/active_support/configurable.rb +13 -14
- data/lib/active_support/core_ext/array/access.rb +41 -1
- data/lib/active_support/core_ext/array/conversions.rb +24 -20
- 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 +11 -18
- data/lib/active_support/core_ext/array/inquiry.rb +19 -0
- data/lib/active_support/core_ext/array/prepend_and_append.rb +4 -6
- data/lib/active_support/core_ext/array/wrap.rb +7 -4
- data/lib/active_support/core_ext/array.rb +9 -6
- data/lib/active_support/core_ext/benchmark.rb +3 -1
- data/lib/active_support/core_ext/big_decimal/conversions.rb +10 -12
- data/lib/active_support/core_ext/big_decimal.rb +3 -1
- data/lib/active_support/core_ext/class/attribute.rb +45 -31
- data/lib/active_support/core_ext/class/attribute_accessors.rb +3 -1
- data/lib/active_support/core_ext/class/subclasses.rb +20 -6
- data/lib/active_support/core_ext/class.rb +4 -3
- 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 +17 -14
- data/lib/active_support/core_ext/date/conversions.rb +25 -23
- data/lib/active_support/core_ext/date/zones.rb +4 -2
- data/lib/active_support/core_ext/date.rb +6 -4
- data/lib/active_support/core_ext/date_and_time/calculations.rb +154 -65
- data/lib/active_support/core_ext/date_and_time/compatibility.rb +4 -3
- data/lib/active_support/core_ext/date_and_time/zones.rb +12 -13
- 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 +37 -19
- data/lib/active_support/core_ext/date_time/compatibility.rb +8 -6
- data/lib/active_support/core_ext/date_time/conversions.rb +16 -13
- data/lib/active_support/core_ext/date_time.rb +7 -5
- data/lib/active_support/core_ext/digest/uuid.rb +7 -5
- data/lib/active_support/core_ext/digest.rb +3 -0
- data/lib/active_support/core_ext/enumerable.rb +114 -22
- data/lib/active_support/core_ext/file/atomic.rb +38 -31
- data/lib/active_support/core_ext/file.rb +3 -1
- data/lib/active_support/core_ext/hash/compact.rb +4 -23
- data/lib/active_support/core_ext/hash/conversions.rb +62 -41
- data/lib/active_support/core_ext/hash/deep_merge.rb +9 -13
- data/lib/active_support/core_ext/hash/deep_transform_values.rb +46 -0
- data/lib/active_support/core_ext/hash/except.rb +12 -9
- data/lib/active_support/core_ext/hash/indifferent_access.rb +4 -3
- data/lib/active_support/core_ext/hash/keys.rb +19 -42
- data/lib/active_support/core_ext/hash/reverse_merge.rb +5 -2
- data/lib/active_support/core_ext/hash/slice.rb +5 -27
- data/lib/active_support/core_ext/hash/transform_values.rb +4 -22
- data/lib/active_support/core_ext/hash.rb +10 -9
- data/lib/active_support/core_ext/integer/inflections.rb +3 -1
- data/lib/active_support/core_ext/integer/multiple.rb +3 -1
- data/lib/active_support/core_ext/integer/time.rb +11 -18
- data/lib/active_support/core_ext/integer.rb +5 -3
- data/lib/active_support/core_ext/kernel/concern.rb +5 -1
- data/lib/active_support/core_ext/kernel/reporting.rb +4 -84
- data/lib/active_support/core_ext/kernel/singleton_class.rb +2 -0
- data/lib/active_support/core_ext/kernel.rb +5 -5
- data/lib/active_support/core_ext/load_error.rb +3 -22
- data/lib/active_support/core_ext/marshal.rb +8 -8
- 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 +46 -46
- data/lib/active_support/core_ext/module/attribute_accessors_per_thread.rb +144 -0
- data/lib/active_support/core_ext/module/concerning.rb +11 -12
- data/lib/active_support/core_ext/module/delegation.rb +133 -30
- data/lib/active_support/core_ext/module/deprecation.rb +4 -2
- data/lib/active_support/core_ext/module/introspection.rb +44 -19
- data/lib/active_support/core_ext/module/reachable.rb +5 -7
- data/lib/active_support/core_ext/module/redefine_method.rb +40 -0
- data/lib/active_support/core_ext/module/remove_method.rb +8 -3
- data/lib/active_support/core_ext/module.rb +13 -11
- data/lib/active_support/core_ext/name_error.rb +22 -2
- data/lib/active_support/core_ext/numeric/bytes.rb +22 -0
- data/lib/active_support/core_ext/numeric/conversions.rb +129 -136
- data/lib/active_support/core_ext/numeric/inquiry.rb +5 -0
- data/lib/active_support/core_ext/numeric/time.rb +35 -23
- data/lib/active_support/core_ext/numeric.rb +5 -3
- data/lib/active_support/core_ext/object/acts_like.rb +12 -1
- data/lib/active_support/core_ext/object/blank.rb +27 -3
- 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 +13 -93
- 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 +51 -20
- data/lib/active_support/core_ext/object/to_param.rb +3 -1
- data/lib/active_support/core_ext/object/to_query.rb +10 -5
- data/lib/active_support/core_ext/object/try.rb +81 -23
- data/lib/active_support/core_ext/object/with_options.rb +16 -3
- data/lib/active_support/core_ext/object.rb +14 -13
- data/lib/active_support/core_ext/range/compare_range.rb +76 -0
- data/lib/active_support/core_ext/range/conversions.rb +37 -15
- data/lib/active_support/core_ext/range/each.rb +18 -17
- data/lib/active_support/core_ext/range/include_range.rb +7 -21
- 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 +7 -4
- data/lib/active_support/core_ext/regexp.rb +2 -0
- data/lib/active_support/core_ext/securerandom.rb +45 -0
- data/lib/active_support/core_ext/string/access.rb +16 -6
- data/lib/active_support/core_ext/string/behavior.rb +3 -1
- data/lib/active_support/core_ext/string/conversions.rb +7 -4
- data/lib/active_support/core_ext/string/exclude.rb +2 -0
- data/lib/active_support/core_ext/string/filters.rb +48 -6
- data/lib/active_support/core_ext/string/indent.rb +6 -4
- data/lib/active_support/core_ext/string/inflections.rb +66 -24
- data/lib/active_support/core_ext/string/inquiry.rb +3 -1
- data/lib/active_support/core_ext/string/multibyte.rb +16 -7
- data/lib/active_support/core_ext/string/output_safety.rb +93 -40
- data/lib/active_support/core_ext/string/starts_ends_with.rb +2 -0
- data/lib/active_support/core_ext/string/strip.rb +6 -5
- data/lib/active_support/core_ext/string/zones.rb +4 -2
- data/lib/active_support/core_ext/string.rb +15 -13
- data/lib/active_support/core_ext/time/acts_like.rb +3 -1
- data/lib/active_support/core_ext/time/calculations.rb +115 -52
- data/lib/active_support/core_ext/time/compatibility.rb +4 -2
- 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/time.rb +7 -6
- data/lib/active_support/core_ext/uri.rb +6 -7
- data/lib/active_support/core_ext.rb +3 -1
- data/lib/active_support/current_attributes.rb +203 -0
- data/lib/active_support/dependencies/autoload.rb +2 -0
- data/lib/active_support/dependencies/interlock.rb +57 -0
- data/lib/active_support/dependencies/zeitwerk_integration.rb +117 -0
- data/lib/active_support/dependencies.rb +208 -166
- data/lib/active_support/deprecation/behaviors.rb +44 -11
- 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 +61 -21
- data/lib/active_support/deprecation/proxy_wrappers.rb +81 -30
- data/lib/active_support/deprecation/reporting.rb +32 -12
- data/lib/active_support/deprecation.rb +12 -9
- data/lib/active_support/descendants_tracker.rb +57 -9
- data/lib/active_support/digest.rb +20 -0
- data/lib/active_support/duration/iso8601_parser.rb +123 -0
- data/lib/active_support/duration/iso8601_serializer.rb +53 -0
- data/lib/active_support/duration.rb +315 -40
- data/lib/active_support/encrypted_configuration.rb +45 -0
- data/lib/active_support/encrypted_file.rb +100 -0
- data/lib/active_support/evented_file_update_checker.rb +234 -0
- data/lib/active_support/execution_wrapper.rb +129 -0
- data/lib/active_support/executor.rb +8 -0
- data/lib/active_support/file_update_checker.rb +62 -37
- data/lib/active_support/gem_version.rb +6 -4
- data/lib/active_support/gzip.rb +7 -5
- data/lib/active_support/hash_with_indifferent_access.rb +129 -30
- data/lib/active_support/i18n.rb +9 -6
- data/lib/active_support/i18n_railtie.rb +50 -14
- data/lib/active_support/inflections.rb +13 -11
- data/lib/active_support/inflector/inflections.rb +58 -13
- data/lib/active_support/inflector/methods.rb +159 -145
- data/lib/active_support/inflector/transliterate.rb +84 -34
- data/lib/active_support/inflector.rb +7 -5
- data/lib/active_support/json/decoding.rb +32 -30
- data/lib/active_support/json/encoding.rb +17 -60
- data/lib/active_support/json.rb +4 -2
- data/lib/active_support/key_generator.rb +11 -43
- data/lib/active_support/lazy_load_hooks.rb +53 -20
- data/lib/active_support/locale/en.rb +33 -0
- data/lib/active_support/locale/en.yml +2 -0
- data/lib/active_support/log_subscriber/test_helper.rb +14 -12
- data/lib/active_support/log_subscriber.rb +44 -19
- data/lib/active_support/logger.rb +9 -23
- data/lib/active_support/logger_silence.rb +32 -14
- data/lib/active_support/logger_thread_safe_level.rb +32 -8
- data/lib/active_support/message_encryptor.rb +166 -53
- data/lib/active_support/message_verifier.rb +149 -16
- data/lib/active_support/messages/metadata.rb +72 -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 +56 -63
- data/lib/active_support/multibyte/unicode.rb +56 -290
- data/lib/active_support/multibyte.rb +4 -2
- data/lib/active_support/notifications/fanout.rb +109 -22
- data/lib/active_support/notifications/instrumenter.rb +107 -16
- data/lib/active_support/notifications.rb +51 -10
- data/lib/active_support/number_helper/number_converter.rb +16 -15
- data/lib/active_support/number_helper/number_to_currency_converter.rb +14 -15
- data/lib/active_support/number_helper/number_to_delimited_converter.rb +11 -4
- data/lib/active_support/number_helper/number_to_human_converter.rb +13 -10
- data/lib/active_support/number_helper/number_to_human_size_converter.rb +11 -9
- data/lib/active_support/number_helper/number_to_percentage_converter.rb +5 -1
- data/lib/active_support/number_helper/number_to_phone_converter.rb +15 -5
- data/lib/active_support/number_helper/number_to_rounded_converter.rb +25 -57
- data/lib/active_support/number_helper/rounding_helper.rb +66 -0
- data/lib/active_support/number_helper.rb +105 -68
- data/lib/active_support/option_merger.rb +24 -4
- data/lib/active_support/ordered_hash.rb +7 -5
- data/lib/active_support/ordered_options.rb +27 -5
- data/lib/active_support/parameter_filter.rb +128 -0
- data/lib/active_support/per_thread_registry.rb +9 -4
- data/lib/active_support/proxy_object.rb +2 -0
- data/lib/active_support/rails.rb +10 -8
- data/lib/active_support/railtie.rb +43 -9
- data/lib/active_support/reloader.rb +130 -0
- data/lib/active_support/rescuable.rb +108 -53
- data/lib/active_support/security_utils.rb +15 -11
- data/lib/active_support/string_inquirer.rb +11 -4
- data/lib/active_support/subscriber.rb +74 -30
- data/lib/active_support/tagged_logging.rb +25 -13
- data/lib/active_support/test_case.rb +107 -44
- data/lib/active_support/testing/assertions.rb +151 -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 +13 -10
- data/lib/active_support/testing/file_fixtures.rb +38 -0
- data/lib/active_support/testing/isolation.rb +35 -26
- data/lib/active_support/testing/method_call_assertions.rb +70 -0
- data/lib/active_support/testing/parallelization.rb +134 -0
- data/lib/active_support/testing/setup_and_teardown.rb +13 -8
- data/lib/active_support/testing/stream.rb +43 -0
- data/lib/active_support/testing/tagged_logging.rb +3 -1
- data/lib/active_support/testing/time_helpers.rb +84 -20
- data/lib/active_support/time.rb +14 -12
- data/lib/active_support/time_with_zone.rb +179 -39
- data/lib/active_support/values/time_zone.rb +203 -63
- data/lib/active_support/version.rb +3 -1
- data/lib/active_support/xml_mini/jdom.rb +116 -115
- data/lib/active_support/xml_mini/libxml.rb +16 -13
- data/lib/active_support/xml_mini/libxmlsax.rb +15 -14
- data/lib/active_support/xml_mini/nokogiri.rb +14 -12
- data/lib/active_support/xml_mini/nokogirisax.rb +14 -13
- data/lib/active_support/xml_mini/rexml.rb +11 -9
- data/lib/active_support/xml_mini.rb +38 -46
- data/lib/active_support.rb +13 -11
- metadata +84 -26
- data/lib/active_support/concurrency/latch.rb +0 -27
- data/lib/active_support/core_ext/big_decimal/yaml_conversions.rb +0 -16
- 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/agnostics.rb +0 -11
- data/lib/active_support/core_ext/kernel/debugger.rb +0 -10
- data/lib/active_support/core_ext/module/method_transplanting.rb +0 -13
- 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
- data/lib/active_support/values/unicode_tables.dat +0 -0
data/MIT-LICENSE
CHANGED
@@ -1,4 +1,4 @@
|
|
1
|
-
Copyright (c) 2005-
|
1
|
+
Copyright (c) 2005-2019 David Heinemeier Hansson
|
2
2
|
|
3
3
|
Permission is hereby granted, free of charge, to any person obtaining
|
4
4
|
a copy of this software and associated documentation files (the
|
@@ -17,4 +17,4 @@ MERCHANTABILITY, FITNESS FOR A PARTICULAR PURPOSE AND
|
|
17
17
|
NONINFRINGEMENT. IN NO EVENT SHALL THE AUTHORS OR COPYRIGHT HOLDERS BE
|
18
18
|
LIABLE FOR ANY CLAIM, DAMAGES OR OTHER LIABILITY, WHETHER IN AN ACTION
|
19
19
|
OF CONTRACT, TORT OR OTHERWISE, ARISING FROM, OUT OF OR IN CONNECTION
|
20
|
-
WITH THE SOFTWARE OR THE USE OR OTHER DEALINGS IN THE SOFTWARE.
|
20
|
+
WITH THE SOFTWARE OR THE USE OR OTHER DEALINGS IN THE SOFTWARE.
|
data/README.rdoc
CHANGED
@@ -5,36 +5,36 @@ extensions that were found useful for the Rails framework. These additions
|
|
5
5
|
reside in this package so they can be loaded as needed in Ruby projects
|
6
6
|
outside of Rails.
|
7
7
|
|
8
|
+
You can read more about the extensions in the {Active Support Core Extensions}[https://edgeguides.rubyonrails.org/active_support_core_extensions.html] guide.
|
8
9
|
|
9
10
|
== Download and installation
|
10
11
|
|
11
12
|
The latest version of Active Support can be installed with RubyGems:
|
12
13
|
|
13
|
-
|
14
|
+
$ gem install activesupport
|
14
15
|
|
15
16
|
Source code can be downloaded as part of the Rails project on GitHub:
|
16
17
|
|
17
|
-
* https://github.com/rails/rails/tree/
|
18
|
+
* https://github.com/rails/rails/tree/master/activesupport
|
18
19
|
|
19
20
|
|
20
21
|
== License
|
21
22
|
|
22
23
|
Active Support is released under the MIT license:
|
23
24
|
|
24
|
-
*
|
25
|
+
* https://opensource.org/licenses/MIT
|
25
26
|
|
26
27
|
|
27
28
|
== Support
|
28
29
|
|
29
30
|
API documentation is at:
|
30
31
|
|
31
|
-
*
|
32
|
+
* https://api.rubyonrails.org
|
32
33
|
|
33
|
-
Bug reports
|
34
|
+
Bug reports for the Ruby on Rails project can be filed here:
|
34
35
|
|
35
36
|
* https://github.com/rails/rails/issues
|
36
37
|
|
37
38
|
Feature requests should be discussed on the rails-core mailing list here:
|
38
39
|
|
39
|
-
* https://
|
40
|
-
|
40
|
+
* https://discuss.rubyonrails.org/c/rubyonrails-core
|
@@ -0,0 +1,48 @@
|
|
1
|
+
# frozen_string_literal: true
|
2
|
+
|
3
|
+
module ActiveSupport
|
4
|
+
# Actionable errors let's you define actions to resolve an error.
|
5
|
+
#
|
6
|
+
# To make an error actionable, include the <tt>ActiveSupport::ActionableError</tt>
|
7
|
+
# module and invoke the +action+ class macro to define the action. An action
|
8
|
+
# needs a name and a block to execute.
|
9
|
+
module ActionableError
|
10
|
+
extend Concern
|
11
|
+
|
12
|
+
class NonActionable < StandardError; end
|
13
|
+
|
14
|
+
included do
|
15
|
+
class_attribute :_actions, default: {}
|
16
|
+
end
|
17
|
+
|
18
|
+
def self.actions(error) # :nodoc:
|
19
|
+
case error
|
20
|
+
when ActionableError, -> it { Class === it && it < ActionableError }
|
21
|
+
error._actions
|
22
|
+
else
|
23
|
+
{}
|
24
|
+
end
|
25
|
+
end
|
26
|
+
|
27
|
+
def self.dispatch(error, name) # :nodoc:
|
28
|
+
actions(error).fetch(name).call
|
29
|
+
rescue KeyError
|
30
|
+
raise NonActionable, "Cannot find action \"#{name}\""
|
31
|
+
end
|
32
|
+
|
33
|
+
module ClassMethods
|
34
|
+
# Defines an action that can resolve the error.
|
35
|
+
#
|
36
|
+
# class PendingMigrationError < MigrationError
|
37
|
+
# include ActiveSupport::ActionableError
|
38
|
+
#
|
39
|
+
# action "Run pending migrations" do
|
40
|
+
# ActiveRecord::Tasks::DatabaseTasks.migrate
|
41
|
+
# end
|
42
|
+
# end
|
43
|
+
def action(name, &block)
|
44
|
+
_actions[name] = block
|
45
|
+
end
|
46
|
+
end
|
47
|
+
end
|
48
|
+
end
|
data/lib/active_support/all.rb
CHANGED
@@ -0,0 +1,48 @@
|
|
1
|
+
# frozen_string_literal: true
|
2
|
+
|
3
|
+
module ActiveSupport
|
4
|
+
# Wrapping an array in an +ArrayInquirer+ gives a friendlier way to check
|
5
|
+
# its string-like contents:
|
6
|
+
#
|
7
|
+
# variants = ActiveSupport::ArrayInquirer.new([:phone, :tablet])
|
8
|
+
#
|
9
|
+
# variants.phone? # => true
|
10
|
+
# variants.tablet? # => true
|
11
|
+
# variants.desktop? # => false
|
12
|
+
class ArrayInquirer < Array
|
13
|
+
# Passes each element of +candidates+ collection to ArrayInquirer collection.
|
14
|
+
# The method returns true if any element from the ArrayInquirer collection
|
15
|
+
# is equal to the stringified or symbolized form of any element in the +candidates+ collection.
|
16
|
+
#
|
17
|
+
# If +candidates+ collection is not given, method returns true.
|
18
|
+
#
|
19
|
+
# variants = ActiveSupport::ArrayInquirer.new([:phone, :tablet])
|
20
|
+
#
|
21
|
+
# variants.any? # => true
|
22
|
+
# variants.any?(:phone, :tablet) # => true
|
23
|
+
# variants.any?('phone', 'desktop') # => true
|
24
|
+
# variants.any?(:desktop, :watch) # => false
|
25
|
+
def any?(*candidates)
|
26
|
+
if candidates.none?
|
27
|
+
super
|
28
|
+
else
|
29
|
+
candidates.any? do |candidate|
|
30
|
+
include?(candidate.to_sym) || include?(candidate.to_s)
|
31
|
+
end
|
32
|
+
end
|
33
|
+
end
|
34
|
+
|
35
|
+
private
|
36
|
+
def respond_to_missing?(name, include_private = false)
|
37
|
+
(name[-1] == "?") || super
|
38
|
+
end
|
39
|
+
|
40
|
+
def method_missing(name, *args)
|
41
|
+
if name[-1] == "?"
|
42
|
+
any?(name[0..-2])
|
43
|
+
else
|
44
|
+
super
|
45
|
+
end
|
46
|
+
end
|
47
|
+
end
|
48
|
+
end
|
@@ -1,3 +1,5 @@
|
|
1
|
+
# frozen_string_literal: true
|
2
|
+
|
1
3
|
module ActiveSupport
|
2
4
|
# Backtraces often include many lines that are not relevant for the context
|
3
5
|
# under review. This makes it hard to find the signal amongst the backtrace
|
@@ -12,9 +14,9 @@ module ActiveSupport
|
|
12
14
|
# is to exclude the output of a noisy library from the backtrace, so that you
|
13
15
|
# can focus on the rest.
|
14
16
|
#
|
15
|
-
# bc = BacktraceCleaner.new
|
17
|
+
# bc = ActiveSupport::BacktraceCleaner.new
|
16
18
|
# bc.add_filter { |line| line.gsub(Rails.root.to_s, '') } # strip the Rails.root prefix
|
17
|
-
# bc.add_silencer { |line| line =~ /
|
19
|
+
# bc.add_silencer { |line| line =~ /puma|rubygems/ } # skip any lines from puma or rubygems
|
18
20
|
# bc.clean(exception.backtrace) # perform the cleanup
|
19
21
|
#
|
20
22
|
# To reconfigure an existing BacktraceCleaner (like the default one in Rails)
|
@@ -25,10 +27,13 @@ module ActiveSupport
|
|
25
27
|
# of the backtrace, you can call <tt>BacktraceCleaner#remove_filters!</tt>
|
26
28
|
# These two methods will give you a completely untouched backtrace.
|
27
29
|
#
|
28
|
-
# Inspired by the Quiet Backtrace gem by
|
30
|
+
# Inspired by the Quiet Backtrace gem by thoughtbot.
|
29
31
|
class BacktraceCleaner
|
30
32
|
def initialize
|
31
33
|
@filters, @silencers = [], []
|
34
|
+
add_gem_filter
|
35
|
+
add_gem_silencer
|
36
|
+
add_stdlib_silencer
|
32
37
|
end
|
33
38
|
|
34
39
|
# Returns the backtrace after all filters and silencers have been run
|
@@ -59,8 +64,8 @@ module ActiveSupport
|
|
59
64
|
# Adds a silencer from the block provided. If the silencer returns +true+
|
60
65
|
# for a given line, it will be excluded from the clean backtrace.
|
61
66
|
#
|
62
|
-
# # Will reject all lines that include the word "
|
63
|
-
# backtrace_cleaner.add_silencer { |line| line =~ /
|
67
|
+
# # Will reject all lines that include the word "puma", like "/gems/puma/server.rb" or "/app/my_puma_server/rb"
|
68
|
+
# backtrace_cleaner.add_silencer { |line| line =~ /puma/ }
|
64
69
|
def add_silencer(&block)
|
65
70
|
@silencers << block
|
66
71
|
end
|
@@ -80,6 +85,25 @@ module ActiveSupport
|
|
80
85
|
end
|
81
86
|
|
82
87
|
private
|
88
|
+
FORMATTED_GEMS_PATTERN = /\A[^\/]+ \([\w.]+\) /
|
89
|
+
|
90
|
+
def add_gem_filter
|
91
|
+
gems_paths = (Gem.path | [Gem.default_dir]).map { |p| Regexp.escape(p) }
|
92
|
+
return if gems_paths.empty?
|
93
|
+
|
94
|
+
gems_regexp = %r{(#{gems_paths.join('|')})/(bundler/)?gems/([^/]+)-([\w.]+)/(.*)}
|
95
|
+
gems_result = '\3 (\4) \5'
|
96
|
+
add_filter { |line| line.sub(gems_regexp, gems_result) }
|
97
|
+
end
|
98
|
+
|
99
|
+
def add_gem_silencer
|
100
|
+
add_silencer { |line| FORMATTED_GEMS_PATTERN.match?(line) }
|
101
|
+
end
|
102
|
+
|
103
|
+
def add_stdlib_silencer
|
104
|
+
add_silencer { |line| line.start_with?(RbConfig::CONFIG["rubylibdir"]) }
|
105
|
+
end
|
106
|
+
|
83
107
|
def filter_backtrace(backtrace)
|
84
108
|
@filters.each do |f|
|
85
109
|
backtrace = backtrace.map { |line| f.call(line) }
|
@@ -97,7 +121,11 @@ module ActiveSupport
|
|
97
121
|
end
|
98
122
|
|
99
123
|
def noise(backtrace)
|
100
|
-
backtrace
|
124
|
+
backtrace.select do |line|
|
125
|
+
@silencers.any? do |s|
|
126
|
+
s.call(line)
|
127
|
+
end
|
128
|
+
end
|
101
129
|
end
|
102
130
|
end
|
103
131
|
end
|
@@ -1,5 +1,7 @@
|
|
1
|
-
|
2
|
-
|
1
|
+
# frozen_string_literal: true
|
2
|
+
|
3
|
+
require "active_support/core_ext/benchmark"
|
4
|
+
require "active_support/core_ext/hash/keys"
|
3
5
|
|
4
6
|
module ActiveSupport
|
5
7
|
module Benchmarkable
|
@@ -38,8 +40,8 @@ module ActiveSupport
|
|
38
40
|
options[:level] ||= :info
|
39
41
|
|
40
42
|
result = nil
|
41
|
-
ms = Benchmark.ms { result = options[:silence] ? silence { yield } : yield }
|
42
|
-
logger.send(options[:level],
|
43
|
+
ms = Benchmark.ms { result = options[:silence] ? logger.silence { yield } : yield }
|
44
|
+
logger.send(options[:level], "%s (%.1fms)" % [ message, ms ])
|
43
45
|
result
|
44
46
|
else
|
45
47
|
yield
|
@@ -1,7 +1,9 @@
|
|
1
|
-
|
2
|
-
|
3
|
-
require
|
4
|
-
require
|
1
|
+
# frozen_string_literal: true
|
2
|
+
|
3
|
+
require "active_support/core_ext/marshal"
|
4
|
+
require "active_support/core_ext/file/atomic"
|
5
|
+
require "active_support/core_ext/string/conversions"
|
6
|
+
require "uri/common"
|
5
7
|
|
6
8
|
module ActiveSupport
|
7
9
|
module Cache
|
@@ -10,34 +12,39 @@ module ActiveSupport
|
|
10
12
|
# FileStore implements the Strategy::LocalCache strategy which implements
|
11
13
|
# an in-memory cache inside of a block.
|
12
14
|
class FileStore < Store
|
15
|
+
prepend Strategy::LocalCache
|
13
16
|
attr_reader :cache_path
|
14
17
|
|
15
18
|
DIR_FORMATTER = "%03X"
|
16
19
|
FILENAME_MAX_SIZE = 228 # max filename size on file system is 255, minus room for timestamp and random characters appended by Tempfile (used by atomic write)
|
17
20
|
FILEPATH_MAX_SIZE = 900 # max is 1024, plus some room
|
18
|
-
|
21
|
+
GITKEEP_FILES = [".gitkeep", ".keep"].freeze
|
19
22
|
|
20
23
|
def initialize(cache_path, options = nil)
|
21
24
|
super(options)
|
22
25
|
@cache_path = cache_path.to_s
|
23
|
-
|
26
|
+
end
|
27
|
+
|
28
|
+
# Advertise cache versioning support.
|
29
|
+
def self.supports_cache_versioning?
|
30
|
+
true
|
24
31
|
end
|
25
32
|
|
26
33
|
# Deletes all items from the cache. In this case it deletes all the entries in the specified
|
27
|
-
# file store directory except for .gitkeep. Be careful which directory is specified in your
|
34
|
+
# file store directory except for .keep or .gitkeep. Be careful which directory is specified in your
|
28
35
|
# config file when using +FileStore+ because everything in that directory will be deleted.
|
29
36
|
def clear(options = nil)
|
30
|
-
root_dirs = Dir.
|
31
|
-
FileUtils.rm_r(root_dirs.collect{|f| File.join(cache_path, f)})
|
37
|
+
root_dirs = (Dir.children(cache_path) - GITKEEP_FILES)
|
38
|
+
FileUtils.rm_r(root_dirs.collect { |f| File.join(cache_path, f) })
|
39
|
+
rescue Errno::ENOENT, Errno::ENOTEMPTY
|
32
40
|
end
|
33
41
|
|
34
42
|
# Preemptively iterates through all stored keys and removes the ones which have expired.
|
35
43
|
def cleanup(options = nil)
|
36
44
|
options = merged_options(options)
|
37
45
|
search_dir(cache_path) do |fname|
|
38
|
-
|
39
|
-
|
40
|
-
delete_entry(key, options) if entry && entry.expired?
|
46
|
+
entry = read_entry(fname, **options)
|
47
|
+
delete_entry(fname, **options) if entry && entry.expired?
|
41
48
|
end
|
42
49
|
end
|
43
50
|
|
@@ -59,57 +66,50 @@ module ActiveSupport
|
|
59
66
|
matcher = key_matcher(matcher, options)
|
60
67
|
search_dir(cache_path) do |path|
|
61
68
|
key = file_path_key(path)
|
62
|
-
delete_entry(
|
69
|
+
delete_entry(path, **options) if key.match(matcher)
|
63
70
|
end
|
64
71
|
end
|
65
72
|
end
|
66
73
|
|
67
|
-
|
68
|
-
|
69
|
-
|
70
|
-
|
71
|
-
if File.exist?(file_name)
|
72
|
-
File.open(file_name) { |f| Marshal.load(f) }
|
74
|
+
private
|
75
|
+
def read_entry(key, **options)
|
76
|
+
if File.exist?(key)
|
77
|
+
File.open(key) { |f| Marshal.load(f) }
|
73
78
|
end
|
74
79
|
rescue => e
|
75
80
|
logger.error("FileStoreError (#{e}): #{e.message}") if logger
|
76
81
|
nil
|
77
82
|
end
|
78
83
|
|
79
|
-
def write_entry(key, entry, options)
|
80
|
-
|
81
|
-
|
82
|
-
|
83
|
-
File.atomic_write(file_name, cache_path) {|f| Marshal.dump(entry, f)}
|
84
|
+
def write_entry(key, entry, **options)
|
85
|
+
return false if options[:unless_exist] && File.exist?(key)
|
86
|
+
ensure_cache_path(File.dirname(key))
|
87
|
+
File.atomic_write(key, cache_path) { |f| Marshal.dump(entry, f) }
|
84
88
|
true
|
85
89
|
end
|
86
90
|
|
87
|
-
def delete_entry(key, options)
|
88
|
-
|
89
|
-
if File.exist?(file_name)
|
91
|
+
def delete_entry(key, **options)
|
92
|
+
if File.exist?(key)
|
90
93
|
begin
|
91
|
-
File.delete(
|
92
|
-
delete_empty_directories(File.dirname(
|
94
|
+
File.delete(key)
|
95
|
+
delete_empty_directories(File.dirname(key))
|
93
96
|
true
|
94
97
|
rescue => e
|
95
98
|
# Just in case the error was caused by another process deleting the file first.
|
96
|
-
raise e if File.exist?(
|
99
|
+
raise e if File.exist?(key)
|
97
100
|
false
|
98
101
|
end
|
99
102
|
end
|
100
103
|
end
|
101
104
|
|
102
|
-
private
|
103
105
|
# Lock a file for a block so only one process can modify it at a time.
|
104
|
-
def lock_file(file_name, &block)
|
106
|
+
def lock_file(file_name, &block)
|
105
107
|
if File.exist?(file_name)
|
106
|
-
File.open(file_name,
|
107
|
-
|
108
|
-
|
109
|
-
|
110
|
-
|
111
|
-
f.flock File::LOCK_UN
|
112
|
-
end
|
108
|
+
File.open(file_name, "r+") do |f|
|
109
|
+
f.flock File::LOCK_EX
|
110
|
+
yield
|
111
|
+
ensure
|
112
|
+
f.flock File::LOCK_UN
|
113
113
|
end
|
114
114
|
else
|
115
115
|
yield
|
@@ -117,24 +117,30 @@ module ActiveSupport
|
|
117
117
|
end
|
118
118
|
|
119
119
|
# Translate a key into a file path.
|
120
|
-
def
|
121
|
-
|
122
|
-
|
120
|
+
def normalize_key(key, options)
|
121
|
+
key = super
|
122
|
+
fname = URI.encode_www_form_component(key)
|
123
|
+
|
124
|
+
if fname.size > FILEPATH_MAX_SIZE
|
125
|
+
fname = ActiveSupport::Digest.hexdigest(key)
|
123
126
|
end
|
124
127
|
|
125
|
-
fname = URI.encode_www_form_component(key)
|
126
128
|
hash = Zlib.adler32(fname)
|
127
129
|
hash, dir_1 = hash.divmod(0x1000)
|
128
130
|
dir_2 = hash.modulo(0x1000)
|
129
|
-
fname_paths = []
|
130
131
|
|
131
132
|
# Make sure file name doesn't exceed file system limits.
|
132
|
-
|
133
|
-
fname_paths
|
134
|
-
|
135
|
-
|
133
|
+
if fname.length < FILENAME_MAX_SIZE
|
134
|
+
fname_paths = fname
|
135
|
+
else
|
136
|
+
fname_paths = []
|
137
|
+
begin
|
138
|
+
fname_paths << fname[0, FILENAME_MAX_SIZE]
|
139
|
+
fname = fname[FILENAME_MAX_SIZE..-1]
|
140
|
+
end until fname.blank?
|
141
|
+
end
|
136
142
|
|
137
|
-
File.join(cache_path, DIR_FORMATTER % dir_1, DIR_FORMATTER % dir_2,
|
143
|
+
File.join(cache_path, DIR_FORMATTER % dir_1, DIR_FORMATTER % dir_2, fname_paths)
|
138
144
|
end
|
139
145
|
|
140
146
|
# Translate a file path into a key.
|
@@ -146,7 +152,7 @@ module ActiveSupport
|
|
146
152
|
# Delete empty directories in the cache.
|
147
153
|
def delete_empty_directories(dir)
|
148
154
|
return if File.realpath(dir) == File.realpath(cache_path)
|
149
|
-
if Dir.
|
155
|
+
if Dir.children(dir).empty?
|
150
156
|
Dir.delete(dir) rescue nil
|
151
157
|
delete_empty_directories(File.dirname(dir))
|
152
158
|
end
|
@@ -159,8 +165,7 @@ module ActiveSupport
|
|
159
165
|
|
160
166
|
def search_dir(dir, &callback)
|
161
167
|
return if !File.exist?(dir)
|
162
|
-
Dir.
|
163
|
-
next if EXCLUDED_DIRS.include?(d)
|
168
|
+
Dir.each_child(dir) do |d|
|
164
169
|
name = File.join(dir, d)
|
165
170
|
if File.directory?(name)
|
166
171
|
search_dir(name, &callback)
|
@@ -173,7 +178,7 @@ module ActiveSupport
|
|
173
178
|
# Modifies the amount of an already existing integer value that is stored in the cache.
|
174
179
|
# If the key is not found nothing is done.
|
175
180
|
def modify_value(name, amount, options)
|
176
|
-
file_name =
|
181
|
+
file_name = normalize_key(name, options)
|
177
182
|
|
178
183
|
lock_file(file_name) do
|
179
184
|
options = merged_options(options)
|