activesupport 5.2.4.rc1 → 6.0.0.rc2
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 +312 -428
- data/MIT-LICENSE +1 -1
- data/README.rdoc +3 -2
- data/lib/active_support.rb +2 -1
- data/lib/active_support/actionable_error.rb +48 -0
- data/lib/active_support/backtrace_cleaner.rb +28 -1
- data/lib/active_support/cache.rb +45 -23
- data/lib/active_support/cache/file_store.rb +22 -22
- data/lib/active_support/cache/mem_cache_store.rb +5 -0
- data/lib/active_support/cache/memory_store.rb +7 -2
- data/lib/active_support/cache/null_store.rb +5 -0
- data/lib/active_support/cache/redis_cache_store.rb +36 -9
- data/lib/active_support/callbacks.rb +16 -5
- data/lib/active_support/concern.rb +24 -1
- data/lib/active_support/configurable.rb +7 -11
- data/lib/active_support/core_ext/array.rb +1 -1
- data/lib/active_support/core_ext/array/access.rb +18 -6
- data/lib/active_support/core_ext/array/extract.rb +21 -0
- data/lib/active_support/core_ext/array/prepend_and_append.rb +2 -6
- data/lib/active_support/core_ext/class/attribute.rb +11 -16
- data/lib/active_support/core_ext/class/subclasses.rb +1 -1
- data/lib/active_support/core_ext/date/calculations.rb +6 -5
- data/lib/active_support/core_ext/date_and_time/calculations.rb +24 -47
- data/lib/active_support/core_ext/date_time/calculations.rb +1 -1
- data/lib/active_support/core_ext/enumerable.rb +97 -73
- data/lib/active_support/core_ext/hash.rb +1 -2
- data/lib/active_support/core_ext/hash/compact.rb +2 -26
- data/lib/active_support/core_ext/hash/deep_transform_values.rb +46 -0
- data/lib/active_support/core_ext/hash/except.rb +1 -1
- data/lib/active_support/core_ext/hash/keys.rb +0 -29
- data/lib/active_support/core_ext/hash/slice.rb +3 -25
- data/lib/active_support/core_ext/hash/transform_values.rb +2 -29
- data/lib/active_support/core_ext/integer/multiple.rb +1 -1
- data/lib/active_support/core_ext/kernel.rb +0 -1
- data/lib/active_support/core_ext/load_error.rb +1 -1
- data/lib/active_support/core_ext/module.rb +0 -1
- data/lib/active_support/core_ext/module/attribute_accessors.rb +7 -10
- data/lib/active_support/core_ext/module/attribute_accessors_per_thread.rb +13 -19
- data/lib/active_support/core_ext/module/delegation.rb +27 -7
- data/lib/active_support/core_ext/module/introspection.rb +37 -13
- data/lib/active_support/core_ext/module/reachable.rb +1 -6
- data/lib/active_support/core_ext/module/redefine_method.rb +8 -17
- data/lib/active_support/core_ext/numeric.rb +0 -1
- data/lib/active_support/core_ext/numeric/conversions.rb +124 -128
- data/lib/active_support/core_ext/numeric/inquiry.rb +2 -25
- data/lib/active_support/core_ext/object/blank.rb +1 -2
- data/lib/active_support/core_ext/object/duplicable.rb +7 -114
- data/lib/active_support/core_ext/object/json.rb +1 -0
- data/lib/active_support/core_ext/object/try.rb +15 -7
- data/lib/active_support/core_ext/object/with_options.rb +1 -1
- data/lib/active_support/core_ext/range/compare_range.rb +22 -13
- data/lib/active_support/core_ext/range/conversions.rb +31 -29
- data/lib/active_support/core_ext/range/include_range.rb +6 -0
- data/lib/active_support/core_ext/regexp.rb +0 -4
- data/lib/active_support/core_ext/securerandom.rb +23 -3
- data/lib/active_support/core_ext/string/access.rb +8 -0
- data/lib/active_support/core_ext/string/filters.rb +42 -1
- data/lib/active_support/core_ext/string/inflections.rb +7 -2
- data/lib/active_support/core_ext/string/multibyte.rb +4 -3
- data/lib/active_support/core_ext/string/output_safety.rb +61 -5
- data/lib/active_support/core_ext/string/strip.rb +3 -1
- data/lib/active_support/core_ext/time/calculations.rb +31 -2
- data/lib/active_support/core_ext/uri.rb +1 -0
- data/lib/active_support/current_attributes.rb +8 -0
- data/lib/active_support/dependencies.rb +56 -14
- data/lib/active_support/dependencies/zeitwerk_integration.rb +99 -0
- data/lib/active_support/deprecation.rb +1 -1
- data/lib/active_support/deprecation/behaviors.rb +1 -1
- data/lib/active_support/deprecation/method_wrappers.rb +8 -20
- data/lib/active_support/deprecation/proxy_wrappers.rb +24 -5
- data/lib/active_support/descendants_tracker.rb +56 -9
- data/lib/active_support/duration.rb +4 -3
- data/lib/active_support/duration/iso8601_parser.rb +2 -3
- data/lib/active_support/duration/iso8601_serializer.rb +3 -4
- data/lib/active_support/encrypted_configuration.rb +0 -4
- data/lib/active_support/encrypted_file.rb +2 -1
- data/lib/active_support/evented_file_update_checker.rb +39 -9
- data/lib/active_support/execution_wrapper.rb +1 -0
- data/lib/active_support/gem_version.rb +4 -4
- data/lib/active_support/hash_with_indifferent_access.rb +22 -18
- data/lib/active_support/i18n.rb +1 -0
- data/lib/active_support/i18n_railtie.rb +9 -1
- data/lib/active_support/inflector/inflections.rb +1 -4
- data/lib/active_support/inflector/methods.rb +15 -27
- data/lib/active_support/inflector/transliterate.rb +20 -17
- data/lib/active_support/json/decoding.rb +23 -23
- data/lib/active_support/json/encoding.rb +6 -2
- data/lib/active_support/key_generator.rb +0 -32
- data/lib/active_support/lazy_load_hooks.rb +5 -1
- data/lib/active_support/locale/en.rb +31 -0
- data/lib/active_support/log_subscriber.rb +31 -8
- data/lib/active_support/logger.rb +0 -15
- data/lib/active_support/logger_silence.rb +28 -12
- data/lib/active_support/logger_thread_safe_level.rb +27 -6
- data/lib/active_support/message_encryptor.rb +3 -5
- data/lib/active_support/message_verifier.rb +3 -3
- data/lib/active_support/multibyte/chars.rb +29 -48
- data/lib/active_support/multibyte/unicode.rb +44 -281
- data/lib/active_support/notifications.rb +41 -4
- data/lib/active_support/notifications/fanout.rb +98 -13
- data/lib/active_support/notifications/instrumenter.rb +79 -8
- data/lib/active_support/number_helper.rb +7 -0
- data/lib/active_support/number_helper/number_to_currency_converter.rb +2 -2
- data/lib/active_support/number_helper/number_to_delimited_converter.rb +3 -1
- data/lib/active_support/number_helper/number_to_human_converter.rb +3 -1
- data/lib/active_support/number_helper/number_to_human_size_converter.rb +3 -1
- data/lib/active_support/number_helper/number_to_percentage_converter.rb +3 -1
- data/lib/active_support/number_helper/number_to_phone_converter.rb +2 -0
- data/lib/active_support/number_helper/number_to_rounded_converter.rb +5 -3
- data/lib/active_support/ordered_options.rb +1 -1
- data/lib/active_support/parameter_filter.rb +124 -0
- data/lib/active_support/rails.rb +0 -6
- data/lib/active_support/reloader.rb +4 -5
- data/lib/active_support/security_utils.rb +1 -1
- data/lib/active_support/subscriber.rb +65 -26
- data/lib/active_support/tagged_logging.rb +13 -4
- data/lib/active_support/test_case.rb +91 -0
- data/lib/active_support/testing/assertions.rb +15 -1
- data/lib/active_support/testing/deprecation.rb +0 -1
- data/lib/active_support/testing/file_fixtures.rb +2 -0
- data/lib/active_support/testing/isolation.rb +2 -2
- data/lib/active_support/testing/method_call_assertions.rb +28 -1
- data/lib/active_support/testing/parallelization.rb +128 -0
- data/lib/active_support/testing/stream.rb +1 -1
- data/lib/active_support/testing/time_helpers.rb +7 -7
- data/lib/active_support/time_with_zone.rb +15 -5
- data/lib/active_support/values/time_zone.rb +12 -7
- data/lib/active_support/xml_mini.rb +2 -9
- data/lib/active_support/xml_mini/jdom.rb +2 -2
- data/lib/active_support/xml_mini/libxml.rb +2 -2
- data/lib/active_support/xml_mini/libxmlsax.rb +4 -4
- data/lib/active_support/xml_mini/nokogiri.rb +2 -2
- data/lib/active_support/xml_mini/nokogirisax.rb +3 -3
- data/lib/active_support/xml_mini/rexml.rb +2 -2
- metadata +34 -9
- data/lib/active_support/core_ext/kernel/agnostics.rb +0 -13
- data/lib/active_support/values/unicode_tables.dat +0 -0
data/MIT-LICENSE
CHANGED
data/README.rdoc
CHANGED
@@ -5,6 +5,7 @@ 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
|
|
@@ -14,7 +15,7 @@ The latest version of Active Support can be installed with RubyGems:
|
|
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
|
@@ -28,7 +29,7 @@ Active Support is released under the MIT license:
|
|
28
29
|
|
29
30
|
API documentation is at:
|
30
31
|
|
31
|
-
*
|
32
|
+
* https://api.rubyonrails.org
|
32
33
|
|
33
34
|
Bug reports for the Ruby on Rails project can be filed here:
|
34
35
|
|
data/lib/active_support.rb
CHANGED
@@ -1,7 +1,7 @@
|
|
1
1
|
# frozen_string_literal: true
|
2
2
|
|
3
3
|
#--
|
4
|
-
# Copyright (c) 2005-
|
4
|
+
# Copyright (c) 2005-2019 David Heinemeier Hansson
|
5
5
|
#
|
6
6
|
# Permission is hereby granted, free of charge, to any person obtaining
|
7
7
|
# a copy of this software and associated documentation files (the
|
@@ -34,6 +34,7 @@ module ActiveSupport
|
|
34
34
|
extend ActiveSupport::Autoload
|
35
35
|
|
36
36
|
autoload :Concern
|
37
|
+
autoload :ActionableError
|
37
38
|
autoload :CurrentAttributes
|
38
39
|
autoload :Dependencies
|
39
40
|
autoload :DescendantsTracker
|
@@ -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
|
@@ -31,6 +31,9 @@ module ActiveSupport
|
|
31
31
|
class BacktraceCleaner
|
32
32
|
def initialize
|
33
33
|
@filters, @silencers = [], []
|
34
|
+
add_gem_filter
|
35
|
+
add_gem_silencer
|
36
|
+
add_stdlib_silencer
|
34
37
|
end
|
35
38
|
|
36
39
|
# Returns the backtrace after all filters and silencers have been run
|
@@ -82,6 +85,26 @@ module ActiveSupport
|
|
82
85
|
end
|
83
86
|
|
84
87
|
private
|
88
|
+
|
89
|
+
FORMATTED_GEMS_PATTERN = /\A[^\/]+ \([\w.]+\) /
|
90
|
+
|
91
|
+
def add_gem_filter
|
92
|
+
gems_paths = (Gem.path | [Gem.default_dir]).map { |p| Regexp.escape(p) }
|
93
|
+
return if gems_paths.empty?
|
94
|
+
|
95
|
+
gems_regexp = %r{(#{gems_paths.join('|')})/(bundler/)?gems/([^/]+)-([\w.]+)/(.*)}
|
96
|
+
gems_result = '\3 (\4) \5'
|
97
|
+
add_filter { |line| line.sub(gems_regexp, gems_result) }
|
98
|
+
end
|
99
|
+
|
100
|
+
def add_gem_silencer
|
101
|
+
add_silencer { |line| FORMATTED_GEMS_PATTERN.match?(line) }
|
102
|
+
end
|
103
|
+
|
104
|
+
def add_stdlib_silencer
|
105
|
+
add_silencer { |line| line.start_with?(RbConfig::CONFIG["rubylibdir"]) }
|
106
|
+
end
|
107
|
+
|
85
108
|
def filter_backtrace(backtrace)
|
86
109
|
@filters.each do |f|
|
87
110
|
backtrace = backtrace.map { |line| f.call(line) }
|
@@ -99,7 +122,11 @@ module ActiveSupport
|
|
99
122
|
end
|
100
123
|
|
101
124
|
def noise(backtrace)
|
102
|
-
backtrace
|
125
|
+
backtrace.select do |line|
|
126
|
+
@silencers.any? do |s|
|
127
|
+
s.call(line)
|
128
|
+
end
|
129
|
+
end
|
103
130
|
end
|
104
131
|
end
|
105
132
|
end
|
data/lib/active_support/cache.rb
CHANGED
@@ -229,6 +229,14 @@ module ActiveSupport
|
|
229
229
|
# ask whether you should force a cache write. Otherwise, it's clearer to
|
230
230
|
# just call <tt>Cache#write</tt>.
|
231
231
|
#
|
232
|
+
# Setting <tt>skip_nil: true</tt> will not cache nil result:
|
233
|
+
#
|
234
|
+
# cache.fetch('foo') { nil }
|
235
|
+
# cache.fetch('bar', skip_nil: true) { nil }
|
236
|
+
# cache.exist?('foo') # => true
|
237
|
+
# cache.exist?('bar') # => false
|
238
|
+
#
|
239
|
+
#
|
232
240
|
# Setting <tt>compress: false</tt> disables compression of the cache entry.
|
233
241
|
#
|
234
242
|
# Setting <tt>:expires_in</tt> will set an expiration time on the cache.
|
@@ -333,8 +341,9 @@ module ActiveSupport
|
|
333
341
|
# the cache with the given key, then that data is returned. Otherwise,
|
334
342
|
# +nil+ is returned.
|
335
343
|
#
|
336
|
-
# Note, if data was written with the <tt>:expires_in
|
337
|
-
# both of these conditions are applied before
|
344
|
+
# Note, if data was written with the <tt>:expires_in</tt> or
|
345
|
+
# <tt>:version</tt> options, both of these conditions are applied before
|
346
|
+
# the data is returned.
|
338
347
|
#
|
339
348
|
# Options are passed to the underlying cache implementation.
|
340
349
|
def read(name, options = nil)
|
@@ -402,8 +411,6 @@ module ActiveSupport
|
|
402
411
|
# to the cache. If you do not want to write the cache when the cache is
|
403
412
|
# not found, use #read_multi.
|
404
413
|
#
|
405
|
-
# Options are passed to the underlying cache implementation.
|
406
|
-
#
|
407
414
|
# Returns a hash with the data for each of the names. For example:
|
408
415
|
#
|
409
416
|
# cache.write("bim", "bam")
|
@@ -413,6 +420,17 @@ module ActiveSupport
|
|
413
420
|
# # => { "bim" => "bam",
|
414
421
|
# # "unknown_key" => "Fallback value for key: unknown_key" }
|
415
422
|
#
|
423
|
+
# Options are passed to the underlying cache implementation. For example:
|
424
|
+
#
|
425
|
+
# cache.fetch_multi("fizz", expires_in: 5.seconds) do |key|
|
426
|
+
# "buzz"
|
427
|
+
# end
|
428
|
+
# # => {"fizz"=>"buzz"}
|
429
|
+
# cache.read("fizz")
|
430
|
+
# # => "buzz"
|
431
|
+
# sleep(6)
|
432
|
+
# cache.read("fizz")
|
433
|
+
# # => nil
|
416
434
|
def fetch_multi(*names)
|
417
435
|
raise ArgumentError, "Missing block: `Cache#fetch_multi` requires a block." unless block_given?
|
418
436
|
|
@@ -420,18 +438,18 @@ module ActiveSupport
|
|
420
438
|
options = merged_options(options)
|
421
439
|
|
422
440
|
instrument :read_multi, names, options do |payload|
|
423
|
-
read_multi_entries(names, options)
|
424
|
-
|
425
|
-
|
441
|
+
reads = read_multi_entries(names, options)
|
442
|
+
writes = {}
|
443
|
+
ordered = names.each_with_object({}) do |name, hash|
|
444
|
+
hash[name] = reads.fetch(name) { writes[name] = yield(name) }
|
445
|
+
end
|
426
446
|
|
427
|
-
|
447
|
+
payload[:hits] = reads.keys
|
448
|
+
payload[:super_operation] = :fetch_multi
|
428
449
|
|
429
|
-
|
430
|
-
results[name] = writes[name] = yield(name)
|
431
|
-
end
|
450
|
+
write_multi(writes, options)
|
432
451
|
|
433
|
-
|
434
|
-
end
|
452
|
+
ordered
|
435
453
|
end
|
436
454
|
end
|
437
455
|
|
@@ -474,7 +492,7 @@ module ActiveSupport
|
|
474
492
|
#
|
475
493
|
# Options are passed to the underlying cache implementation.
|
476
494
|
#
|
477
|
-
#
|
495
|
+
# Some implementations may not support this method.
|
478
496
|
def delete_matched(matcher, options = nil)
|
479
497
|
raise NotImplementedError.new("#{self.class.name} does not support delete_matched")
|
480
498
|
end
|
@@ -483,7 +501,7 @@ module ActiveSupport
|
|
483
501
|
#
|
484
502
|
# Options are passed to the underlying cache implementation.
|
485
503
|
#
|
486
|
-
#
|
504
|
+
# Some implementations may not support this method.
|
487
505
|
def increment(name, amount = 1, options = nil)
|
488
506
|
raise NotImplementedError.new("#{self.class.name} does not support increment")
|
489
507
|
end
|
@@ -492,7 +510,7 @@ module ActiveSupport
|
|
492
510
|
#
|
493
511
|
# Options are passed to the underlying cache implementation.
|
494
512
|
#
|
495
|
-
#
|
513
|
+
# Some implementations may not support this method.
|
496
514
|
def decrement(name, amount = 1, options = nil)
|
497
515
|
raise NotImplementedError.new("#{self.class.name} does not support decrement")
|
498
516
|
end
|
@@ -501,7 +519,7 @@ module ActiveSupport
|
|
501
519
|
#
|
502
520
|
# Options are passed to the underlying cache implementation.
|
503
521
|
#
|
504
|
-
#
|
522
|
+
# Some implementations may not support this method.
|
505
523
|
def cleanup(options = nil)
|
506
524
|
raise NotImplementedError.new("#{self.class.name} does not support cleanup")
|
507
525
|
end
|
@@ -511,7 +529,7 @@ module ActiveSupport
|
|
511
529
|
#
|
512
530
|
# The options hash is passed to the underlying cache implementation.
|
513
531
|
#
|
514
|
-
#
|
532
|
+
# Some implementations may not support this method.
|
515
533
|
def clear(options = nil)
|
516
534
|
raise NotImplementedError.new("#{self.class.name} does not support clear")
|
517
535
|
end
|
@@ -587,9 +605,13 @@ module ActiveSupport
|
|
587
605
|
# Merges the default options with ones specific to a method call.
|
588
606
|
def merged_options(call_options)
|
589
607
|
if call_options
|
590
|
-
options.
|
608
|
+
if options.empty?
|
609
|
+
call_options
|
610
|
+
else
|
611
|
+
options.merge(call_options)
|
612
|
+
end
|
591
613
|
else
|
592
|
-
options
|
614
|
+
options
|
593
615
|
end
|
594
616
|
end
|
595
617
|
|
@@ -634,7 +656,7 @@ module ActiveSupport
|
|
634
656
|
if key.size > 1
|
635
657
|
key = key.collect { |element| expanded_key(element) }
|
636
658
|
else
|
637
|
-
key = key.first
|
659
|
+
key = expanded_key(key.first)
|
638
660
|
end
|
639
661
|
when Hash
|
640
662
|
key = key.sort_by { |k, _| k.to_s }.collect { |k, v| "#{k}=#{v}" }
|
@@ -685,7 +707,7 @@ module ActiveSupport
|
|
685
707
|
end
|
686
708
|
|
687
709
|
def get_entry_value(entry, name, options)
|
688
|
-
instrument(:fetch_hit, name, options) {}
|
710
|
+
instrument(:fetch_hit, name, options) { }
|
689
711
|
entry.value
|
690
712
|
end
|
691
713
|
|
@@ -694,7 +716,7 @@ module ActiveSupport
|
|
694
716
|
yield(name)
|
695
717
|
end
|
696
718
|
|
697
|
-
write(name, result, options)
|
719
|
+
write(name, result, options) unless result.nil? && options[:skip_nil]
|
698
720
|
result
|
699
721
|
end
|
700
722
|
end
|
@@ -18,7 +18,6 @@ module ActiveSupport
|
|
18
18
|
DIR_FORMATTER = "%03X"
|
19
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)
|
20
20
|
FILEPATH_MAX_SIZE = 900 # max is 1024, plus some room
|
21
|
-
EXCLUDED_DIRS = [".", ".."].freeze
|
22
21
|
GITKEEP_FILES = [".gitkeep", ".keep"].freeze
|
23
22
|
|
24
23
|
def initialize(cache_path, options = nil)
|
@@ -26,11 +25,16 @@ module ActiveSupport
|
|
26
25
|
@cache_path = cache_path.to_s
|
27
26
|
end
|
28
27
|
|
28
|
+
# Advertise cache versioning support.
|
29
|
+
def self.supports_cache_versioning?
|
30
|
+
true
|
31
|
+
end
|
32
|
+
|
29
33
|
# Deletes all items from the cache. In this case it deletes all the entries in the specified
|
30
34
|
# file store directory except for .keep or .gitkeep. Be careful which directory is specified in your
|
31
35
|
# config file when using +FileStore+ because everything in that directory will be deleted.
|
32
36
|
def clear(options = nil)
|
33
|
-
root_dirs =
|
37
|
+
root_dirs = (Dir.children(cache_path) - GITKEEP_FILES)
|
34
38
|
FileUtils.rm_r(root_dirs.collect { |f| File.join(cache_path, f) })
|
35
39
|
rescue Errno::ENOENT
|
36
40
|
end
|
@@ -103,12 +107,10 @@ module ActiveSupport
|
|
103
107
|
def lock_file(file_name, &block)
|
104
108
|
if File.exist?(file_name)
|
105
109
|
File.open(file_name, "r+") do |f|
|
106
|
-
|
107
|
-
|
108
|
-
|
109
|
-
|
110
|
-
f.flock File::LOCK_UN
|
111
|
-
end
|
110
|
+
f.flock File::LOCK_EX
|
111
|
+
yield
|
112
|
+
ensure
|
113
|
+
f.flock File::LOCK_UN
|
112
114
|
end
|
113
115
|
else
|
114
116
|
yield
|
@@ -127,15 +129,19 @@ module ActiveSupport
|
|
127
129
|
hash = Zlib.adler32(fname)
|
128
130
|
hash, dir_1 = hash.divmod(0x1000)
|
129
131
|
dir_2 = hash.modulo(0x1000)
|
130
|
-
fname_paths = []
|
131
132
|
|
132
133
|
# Make sure file name doesn't exceed file system limits.
|
133
|
-
|
134
|
-
fname_paths
|
135
|
-
|
136
|
-
|
134
|
+
if fname.length < FILENAME_MAX_SIZE
|
135
|
+
fname_paths = fname
|
136
|
+
else
|
137
|
+
fname_paths = []
|
138
|
+
begin
|
139
|
+
fname_paths << fname[0, FILENAME_MAX_SIZE]
|
140
|
+
fname = fname[FILENAME_MAX_SIZE..-1]
|
141
|
+
end until fname.blank?
|
142
|
+
end
|
137
143
|
|
138
|
-
File.join(cache_path, DIR_FORMATTER % dir_1, DIR_FORMATTER % dir_2,
|
144
|
+
File.join(cache_path, DIR_FORMATTER % dir_1, DIR_FORMATTER % dir_2, fname_paths)
|
139
145
|
end
|
140
146
|
|
141
147
|
# Translate a file path into a key.
|
@@ -147,7 +153,7 @@ module ActiveSupport
|
|
147
153
|
# Delete empty directories in the cache.
|
148
154
|
def delete_empty_directories(dir)
|
149
155
|
return if File.realpath(dir) == File.realpath(cache_path)
|
150
|
-
if
|
156
|
+
if Dir.children(dir).empty?
|
151
157
|
Dir.delete(dir) rescue nil
|
152
158
|
delete_empty_directories(File.dirname(dir))
|
153
159
|
end
|
@@ -160,8 +166,7 @@ module ActiveSupport
|
|
160
166
|
|
161
167
|
def search_dir(dir, &callback)
|
162
168
|
return if !File.exist?(dir)
|
163
|
-
Dir.
|
164
|
-
next if EXCLUDED_DIRS.include?(d)
|
169
|
+
Dir.each_child(dir) do |d|
|
165
170
|
name = File.join(dir, d)
|
166
171
|
if File.directory?(name)
|
167
172
|
search_dir(name, &callback)
|
@@ -186,11 +191,6 @@ module ActiveSupport
|
|
186
191
|
end
|
187
192
|
end
|
188
193
|
end
|
189
|
-
|
190
|
-
# Exclude entries from source directory
|
191
|
-
def exclude_from(source, excludes)
|
192
|
-
Dir.entries(source).reject { |f| excludes.include?(f) }
|
193
|
-
end
|
194
194
|
end
|
195
195
|
end
|
196
196
|
end
|
@@ -30,6 +30,11 @@ module ActiveSupport
|
|
30
30
|
@pruning = false
|
31
31
|
end
|
32
32
|
|
33
|
+
# Advertise cache versioning support.
|
34
|
+
def self.supports_cache_versioning?
|
35
|
+
true
|
36
|
+
end
|
37
|
+
|
33
38
|
# Delete all data stored in a given cache store.
|
34
39
|
def clear(options = nil)
|
35
40
|
synchronize do
|
@@ -57,13 +62,13 @@ module ActiveSupport
|
|
57
62
|
return if pruning?
|
58
63
|
@pruning = true
|
59
64
|
begin
|
60
|
-
start_time =
|
65
|
+
start_time = Concurrent.monotonic_time
|
61
66
|
cleanup
|
62
67
|
instrument(:prune, target_size, from: @cache_size) do
|
63
68
|
keys = synchronize { @key_access.keys.sort { |a, b| @key_access[a].to_f <=> @key_access[b].to_f } }
|
64
69
|
keys.each do |key|
|
65
70
|
delete_entry(key, options)
|
66
|
-
return if @cache_size <= target_size || (max_time &&
|
71
|
+
return if @cache_size <= target_size || (max_time && Concurrent.monotonic_time - start_time > max_time)
|
67
72
|
end
|
68
73
|
end
|
69
74
|
ensure
|