activesupport 1.2.4 → 8.1.2
This diff represents the content of publicly available package versions that have been released to one of the supported registries. The information contained in this diff is provided for informational purposes only and reflects changes between package versions as they appear in their respective public registries.
- checksums.yaml +7 -0
- data/CHANGELOG.md +505 -0
- data/MIT-LICENSE +20 -0
- data/README.rdoc +40 -0
- data/lib/active_support/actionable_error.rb +50 -0
- data/lib/active_support/all.rb +5 -0
- data/lib/active_support/array_inquirer.rb +50 -0
- data/lib/active_support/backtrace_cleaner.rb +234 -0
- data/lib/active_support/benchmark.rb +21 -0
- data/lib/active_support/benchmarkable.rb +53 -0
- data/lib/active_support/broadcast_logger.rb +238 -0
- data/lib/active_support/builder.rb +8 -0
- data/lib/active_support/cache/coder.rb +153 -0
- data/lib/active_support/cache/entry.rb +134 -0
- data/lib/active_support/cache/file_store.rb +244 -0
- data/lib/active_support/cache/mem_cache_store.rb +288 -0
- data/lib/active_support/cache/memory_store.rb +264 -0
- data/lib/active_support/cache/null_store.rb +62 -0
- data/lib/active_support/cache/redis_cache_store.rb +498 -0
- data/lib/active_support/cache/serializer_with_fallback.rb +152 -0
- data/lib/active_support/cache/strategy/local_cache.rb +246 -0
- data/lib/active_support/cache/strategy/local_cache_middleware.rb +45 -0
- data/lib/active_support/cache.rb +1170 -0
- data/lib/active_support/callbacks.rb +960 -0
- data/lib/active_support/class_attribute.rb +33 -0
- data/lib/active_support/code_generator.rb +79 -0
- data/lib/active_support/concern.rb +217 -0
- data/lib/active_support/concurrency/load_interlock_aware_monitor.rb +18 -0
- data/lib/active_support/concurrency/null_lock.rb +13 -0
- data/lib/active_support/concurrency/share_lock.rb +225 -0
- data/lib/active_support/concurrency/thread_monitor.rb +55 -0
- data/lib/active_support/configurable.rb +193 -0
- data/lib/active_support/configuration_file.rb +60 -0
- data/lib/active_support/continuous_integration.rb +145 -0
- data/lib/active_support/core_ext/array/access.rb +100 -0
- data/lib/active_support/core_ext/array/conversions.rb +209 -26
- data/lib/active_support/core_ext/array/extract.rb +21 -0
- data/lib/active_support/core_ext/array/extract_options.rb +31 -0
- data/lib/active_support/core_ext/array/grouping.rb +109 -0
- data/lib/active_support/core_ext/array/inquiry.rb +19 -0
- data/lib/active_support/core_ext/array/wrap.rb +48 -0
- data/lib/active_support/core_ext/array.rb +8 -4
- data/lib/active_support/core_ext/benchmark.rb +6 -0
- data/lib/active_support/core_ext/big_decimal/conversions.rb +14 -0
- data/lib/active_support/core_ext/big_decimal.rb +3 -0
- data/lib/active_support/core_ext/class/attribute.rb +137 -0
- data/lib/active_support/core_ext/class/attribute_accessors.rb +6 -0
- data/lib/active_support/core_ext/class/subclasses.rb +24 -0
- data/lib/active_support/core_ext/class.rb +4 -0
- data/lib/active_support/core_ext/date/acts_like.rb +10 -0
- data/lib/active_support/core_ext/date/blank.rb +18 -0
- data/lib/active_support/core_ext/date/calculations.rb +161 -0
- data/lib/active_support/core_ext/date/conversions.rb +95 -28
- data/lib/active_support/core_ext/date/zones.rb +8 -0
- data/lib/active_support/core_ext/date.rb +6 -5
- data/lib/active_support/core_ext/date_and_time/calculations.rb +374 -0
- data/lib/active_support/core_ext/date_and_time/compatibility.rb +23 -0
- data/lib/active_support/core_ext/date_and_time/zones.rb +40 -0
- data/lib/active_support/core_ext/date_time/acts_like.rb +16 -0
- data/lib/active_support/core_ext/date_time/blank.rb +18 -0
- data/lib/active_support/core_ext/date_time/calculations.rb +215 -0
- data/lib/active_support/core_ext/date_time/compatibility.rb +16 -0
- data/lib/active_support/core_ext/date_time/conversions.rb +108 -0
- data/lib/active_support/core_ext/date_time.rb +7 -0
- data/lib/active_support/core_ext/digest/uuid.rb +76 -0
- data/lib/active_support/core_ext/digest.rb +3 -0
- data/lib/active_support/core_ext/enumerable.rb +277 -7
- data/lib/active_support/core_ext/erb/util.rb +201 -0
- data/lib/active_support/core_ext/file/atomic.rb +72 -0
- data/lib/active_support/core_ext/file.rb +3 -0
- data/lib/active_support/core_ext/hash/conversions.rb +262 -0
- data/lib/active_support/core_ext/hash/deep_merge.rb +43 -0
- data/lib/active_support/core_ext/hash/deep_transform_values.rb +46 -0
- data/lib/active_support/core_ext/hash/except.rb +12 -0
- data/lib/active_support/core_ext/hash/indifferent_access.rb +19 -55
- data/lib/active_support/core_ext/hash/keys.rb +134 -44
- data/lib/active_support/core_ext/hash/reverse_merge.rb +22 -22
- data/lib/active_support/core_ext/hash/slice.rb +27 -0
- data/lib/active_support/core_ext/hash.rb +9 -8
- data/lib/active_support/core_ext/integer/inflections.rb +29 -13
- data/lib/active_support/core_ext/integer/multiple.rb +12 -0
- data/lib/active_support/core_ext/integer/time.rb +22 -0
- data/lib/active_support/core_ext/integer.rb +4 -6
- data/lib/active_support/core_ext/kernel/concern.rb +14 -0
- data/lib/active_support/core_ext/kernel/reporting.rb +45 -0
- data/lib/active_support/core_ext/kernel/singleton_class.rb +8 -0
- data/lib/active_support/core_ext/kernel.rb +4 -78
- data/lib/active_support/core_ext/load_error.rb +6 -35
- data/lib/active_support/core_ext/module/aliasing.rb +31 -0
- data/lib/active_support/core_ext/module/anonymous.rb +30 -0
- data/lib/active_support/core_ext/module/attr_internal.rb +48 -0
- data/lib/active_support/core_ext/module/attribute_accessors.rb +214 -0
- data/lib/active_support/core_ext/module/attribute_accessors_per_thread.rb +175 -0
- data/lib/active_support/core_ext/module/concerning.rb +140 -0
- data/lib/active_support/core_ext/module/delegation.rb +225 -0
- data/lib/active_support/core_ext/module/deprecation.rb +25 -0
- data/lib/active_support/core_ext/module/introspection.rb +65 -0
- data/lib/active_support/core_ext/module/redefine_method.rb +40 -0
- data/lib/active_support/core_ext/module/remove_method.rb +17 -0
- data/lib/active_support/core_ext/module.rb +13 -0
- data/lib/active_support/core_ext/name_error.rb +59 -0
- data/lib/active_support/core_ext/numeric/bytes.rb +73 -42
- data/lib/active_support/core_ext/numeric/conversions.rb +145 -0
- data/lib/active_support/core_ext/numeric/time.rb +64 -57
- data/lib/active_support/core_ext/numeric.rb +4 -6
- data/lib/active_support/core_ext/object/acts_like.rb +45 -0
- data/lib/active_support/core_ext/object/blank.rb +199 -0
- data/lib/active_support/core_ext/object/conversions.rb +6 -0
- data/lib/active_support/core_ext/object/deep_dup.rb +71 -0
- data/lib/active_support/core_ext/object/duplicable.rb +69 -0
- data/lib/active_support/core_ext/object/inclusion.rb +37 -0
- data/lib/active_support/core_ext/object/instance_variables.rb +32 -0
- data/lib/active_support/core_ext/object/json.rb +267 -0
- data/lib/active_support/core_ext/object/to_param.rb +3 -0
- data/lib/active_support/core_ext/object/to_query.rb +93 -0
- data/lib/active_support/core_ext/object/try.rb +158 -0
- data/lib/active_support/core_ext/object/with.rb +46 -0
- data/lib/active_support/core_ext/object/with_options.rb +101 -0
- data/lib/active_support/core_ext/object.rb +17 -0
- data/lib/active_support/core_ext/pathname/blank.rb +20 -0
- data/lib/active_support/core_ext/pathname/existence.rb +23 -0
- data/lib/active_support/core_ext/pathname.rb +4 -0
- data/lib/active_support/core_ext/range/compare_range.rb +57 -0
- data/lib/active_support/core_ext/range/conversions.rb +58 -17
- data/lib/active_support/core_ext/range/overlap.rb +40 -0
- data/lib/active_support/core_ext/range/sole.rb +17 -0
- data/lib/active_support/core_ext/range.rb +5 -4
- data/lib/active_support/core_ext/regexp.rb +14 -0
- data/lib/active_support/core_ext/securerandom.rb +57 -0
- data/lib/active_support/core_ext/string/access.rb +93 -56
- data/lib/active_support/core_ext/string/behavior.rb +8 -0
- data/lib/active_support/core_ext/string/conversions.rb +57 -16
- data/lib/active_support/core_ext/string/exclude.rb +13 -0
- data/lib/active_support/core_ext/string/filters.rb +151 -0
- data/lib/active_support/core_ext/string/indent.rb +45 -0
- data/lib/active_support/core_ext/string/inflections.rb +297 -54
- data/lib/active_support/core_ext/string/inquiry.rb +16 -0
- data/lib/active_support/core_ext/string/multibyte.rb +67 -0
- data/lib/active_support/core_ext/string/output_safety.rb +235 -0
- data/lib/active_support/core_ext/string/starts_ends_with.rb +4 -18
- data/lib/active_support/core_ext/string/strip.rb +27 -0
- data/lib/active_support/core_ext/string/zones.rb +16 -0
- data/lib/active_support/core_ext/string.rb +14 -10
- data/lib/active_support/core_ext/symbol/starts_ends_with.rb +6 -0
- data/lib/active_support/core_ext/symbol.rb +3 -0
- data/lib/active_support/core_ext/thread/backtrace/location.rb +7 -0
- data/lib/active_support/core_ext/time/acts_like.rb +10 -0
- data/lib/active_support/core_ext/time/calculations.rb +358 -153
- data/lib/active_support/core_ext/time/compatibility.rb +15 -0
- data/lib/active_support/core_ext/time/conversions.rb +69 -30
- data/lib/active_support/core_ext/time/zones.rb +97 -0
- data/lib/active_support/core_ext/time.rb +6 -6
- data/lib/active_support/core_ext.rb +5 -1
- data/lib/active_support/current_attributes/test_helper.rb +13 -0
- data/lib/active_support/current_attributes.rb +243 -0
- data/lib/active_support/deep_mergeable.rb +53 -0
- data/lib/active_support/delegation.rb +183 -0
- data/lib/active_support/dependencies/autoload.rb +72 -0
- data/lib/active_support/dependencies/interlock.rb +55 -0
- data/lib/active_support/dependencies/require_dependency.rb +28 -0
- data/lib/active_support/dependencies.rb +84 -222
- data/lib/active_support/deprecation/behaviors.rb +148 -0
- data/lib/active_support/deprecation/constant_accessor.rb +74 -0
- data/lib/active_support/deprecation/deprecators.rb +104 -0
- data/lib/active_support/deprecation/disallowed.rb +54 -0
- data/lib/active_support/deprecation/method_wrappers.rb +68 -0
- data/lib/active_support/deprecation/proxy_wrappers.rb +189 -0
- data/lib/active_support/deprecation/reporting.rb +162 -0
- data/lib/active_support/deprecation.rb +81 -0
- data/lib/active_support/deprecator.rb +7 -0
- data/lib/active_support/descendants_tracker.rb +112 -0
- data/lib/active_support/digest.rb +22 -0
- data/lib/active_support/duration/iso8601_parser.rb +123 -0
- data/lib/active_support/duration/iso8601_serializer.rb +64 -0
- data/lib/active_support/duration.rb +524 -0
- data/lib/active_support/editor.rb +70 -0
- data/lib/active_support/encrypted_configuration.rb +126 -0
- data/lib/active_support/encrypted_file.rb +133 -0
- data/lib/active_support/environment_inquirer.rb +40 -0
- data/lib/active_support/error_reporter/test_helper.rb +15 -0
- data/lib/active_support/error_reporter.rb +318 -0
- data/lib/active_support/event_reporter/test_helper.rb +32 -0
- data/lib/active_support/event_reporter.rb +592 -0
- data/lib/active_support/evented_file_update_checker.rb +185 -0
- data/lib/active_support/execution_context/test_helper.rb +13 -0
- data/lib/active_support/execution_context.rb +110 -0
- data/lib/active_support/execution_wrapper.rb +150 -0
- data/lib/active_support/executor/test_helper.rb +7 -0
- data/lib/active_support/executor.rb +8 -0
- data/lib/active_support/file_update_checker.rb +166 -0
- data/lib/active_support/fork_tracker.rb +43 -0
- data/lib/active_support/gem_version.rb +17 -0
- data/lib/active_support/gzip.rb +41 -0
- data/lib/active_support/hash_with_indifferent_access.rb +464 -0
- data/lib/active_support/html_safe_translation.rb +56 -0
- data/lib/active_support/i18n.rb +17 -0
- data/lib/active_support/i18n_railtie.rb +140 -0
- data/lib/active_support/inflections.rb +68 -49
- data/lib/active_support/inflector/inflections.rb +290 -0
- data/lib/active_support/inflector/methods.rb +387 -0
- data/lib/active_support/inflector/transliterate.rb +147 -0
- data/lib/active_support/inflector.rb +7 -164
- data/lib/active_support/isolated_execution_state.rb +76 -0
- data/lib/active_support/json/decoding.rb +78 -0
- data/lib/active_support/json/encoding.rb +256 -0
- data/lib/active_support/json.rb +4 -0
- data/lib/active_support/key_generator.rb +66 -0
- data/lib/active_support/lazy_load_hooks.rb +107 -0
- data/lib/active_support/locale/en.rb +33 -0
- data/lib/active_support/locale/en.yml +141 -0
- data/lib/active_support/log_subscriber/test_helper.rb +106 -0
- data/lib/active_support/log_subscriber.rb +188 -0
- data/lib/active_support/logger.rb +55 -0
- data/lib/active_support/logger_silence.rb +21 -0
- data/lib/active_support/logger_thread_safe_level.rb +50 -0
- data/lib/active_support/message_encryptor.rb +374 -0
- data/lib/active_support/message_encryptors.rb +193 -0
- data/lib/active_support/message_pack/cache_serializer.rb +23 -0
- data/lib/active_support/message_pack/extensions.rb +310 -0
- data/lib/active_support/message_pack/serializer.rb +63 -0
- data/lib/active_support/message_pack.rb +50 -0
- data/lib/active_support/message_verifier.rb +377 -0
- data/lib/active_support/message_verifiers.rb +189 -0
- data/lib/active_support/messages/codec.rb +65 -0
- data/lib/active_support/messages/metadata.rb +146 -0
- data/lib/active_support/messages/rotation_configuration.rb +23 -0
- data/lib/active_support/messages/rotation_coordinator.rb +102 -0
- data/lib/active_support/messages/rotator.rb +69 -0
- data/lib/active_support/messages/serializer_with_fallback.rb +158 -0
- data/lib/active_support/multibyte/chars.rb +188 -0
- data/lib/active_support/multibyte/unicode.rb +42 -0
- data/lib/active_support/multibyte.rb +27 -0
- data/lib/active_support/notifications/fanout.rb +467 -0
- data/lib/active_support/notifications/instrumenter.rb +240 -0
- data/lib/active_support/notifications.rb +281 -0
- data/lib/active_support/number_helper/number_converter.rb +190 -0
- data/lib/active_support/number_helper/number_to_currency_converter.rb +46 -0
- data/lib/active_support/number_helper/number_to_delimited_converter.rb +30 -0
- data/lib/active_support/number_helper/number_to_human_converter.rb +69 -0
- data/lib/active_support/number_helper/number_to_human_size_converter.rb +60 -0
- data/lib/active_support/number_helper/number_to_percentage_converter.rb +16 -0
- data/lib/active_support/number_helper/number_to_phone_converter.rb +60 -0
- data/lib/active_support/number_helper/number_to_rounded_converter.rb +59 -0
- data/lib/active_support/number_helper/rounding_helper.rb +46 -0
- data/lib/active_support/number_helper.rb +479 -0
- data/lib/active_support/option_merger.rb +38 -0
- data/lib/active_support/ordered_hash.rb +50 -0
- data/lib/active_support/ordered_options.rb +141 -25
- data/lib/active_support/parameter_filter.rb +157 -0
- data/lib/active_support/rails.rb +26 -0
- data/lib/active_support/railtie.rb +180 -0
- data/lib/active_support/reloader.rb +138 -0
- data/lib/active_support/rescuable.rb +176 -0
- data/lib/active_support/secure_compare_rotator.rb +58 -0
- data/lib/active_support/security_utils.rb +38 -0
- data/lib/active_support/string_inquirer.rb +35 -0
- data/lib/active_support/structured_event_subscriber.rb +99 -0
- data/lib/active_support/subscriber.rb +141 -0
- data/lib/active_support/syntax_error_proxy.rb +67 -0
- data/lib/active_support/tagged_logging.rb +157 -0
- data/lib/active_support/test_case.rb +365 -0
- data/lib/active_support/testing/assertions.rb +369 -0
- data/lib/active_support/testing/autorun.rb +10 -0
- data/lib/active_support/testing/constant_lookup.rb +51 -0
- data/lib/active_support/testing/constant_stubbing.rb +54 -0
- data/lib/active_support/testing/declarative.rb +28 -0
- data/lib/active_support/testing/deprecation.rb +82 -0
- data/lib/active_support/testing/error_reporter_assertions.rb +124 -0
- data/lib/active_support/testing/event_reporter_assertions.rb +227 -0
- data/lib/active_support/testing/file_fixtures.rb +38 -0
- data/lib/active_support/testing/isolation.rb +121 -0
- data/lib/active_support/testing/method_call_assertions.rb +69 -0
- data/lib/active_support/testing/notification_assertions.rb +92 -0
- data/lib/active_support/testing/parallelization/server.rb +98 -0
- data/lib/active_support/testing/parallelization/worker.rb +107 -0
- data/lib/active_support/testing/parallelization.rb +79 -0
- data/lib/active_support/testing/parallelize_executor.rb +81 -0
- data/lib/active_support/testing/setup_and_teardown.rb +57 -0
- data/lib/active_support/testing/stream.rb +41 -0
- data/lib/active_support/testing/tagged_logging.rb +27 -0
- data/lib/active_support/testing/tests_without_assertions.rb +19 -0
- data/lib/active_support/testing/time_helpers.rb +273 -0
- data/lib/active_support/time.rb +20 -0
- data/lib/active_support/time_with_zone.rb +613 -0
- data/lib/active_support/values/time_zone.rb +599 -158
- data/lib/active_support/version.rb +7 -6
- data/lib/active_support/xml_mini/jdom.rb +175 -0
- data/lib/active_support/xml_mini/libxml.rb +80 -0
- data/lib/active_support/xml_mini/libxmlsax.rb +83 -0
- data/lib/active_support/xml_mini/nokogiri.rb +83 -0
- data/lib/active_support/xml_mini/nokogirisax.rb +86 -0
- data/lib/active_support/xml_mini/rexml.rb +137 -0
- data/lib/active_support/xml_mini.rb +212 -0
- data/lib/active_support.rb +122 -10
- metadata +524 -93
- data/CHANGELOG +0 -283
- data/lib/active_support/binding_of_caller.rb +0 -84
- data/lib/active_support/breakpoint.rb +0 -523
- data/lib/active_support/class_attribute_accessors.rb +0 -57
- data/lib/active_support/class_inheritable_attributes.rb +0 -117
- data/lib/active_support/clean_logger.rb +0 -36
- data/lib/active_support/core_ext/blank.rb +0 -38
- data/lib/active_support/core_ext/cgi/escape_skipping_slashes.rb +0 -14
- data/lib/active_support/core_ext/cgi.rb +0 -5
- data/lib/active_support/core_ext/exception.rb +0 -29
- data/lib/active_support/core_ext/integer/even_odd.rb +0 -24
- data/lib/active_support/core_ext/object_and_class.rb +0 -44
- data/lib/active_support/module_attribute_accessors.rb +0 -57
- data/lib/active_support/whiny_nil.rb +0 -38
|
@@ -0,0 +1,193 @@
|
|
|
1
|
+
# frozen_string_literal: true
|
|
2
|
+
|
|
3
|
+
ActiveSupport.deprecator.warn <<~MSG
|
|
4
|
+
ActiveSupport::Configurable is deprecated without replacement, and will be removed in Rails 8.2.
|
|
5
|
+
|
|
6
|
+
You can emulate the previous behavior with `class_attribute`.
|
|
7
|
+
MSG
|
|
8
|
+
|
|
9
|
+
require "active_support/concern"
|
|
10
|
+
require "active_support/ordered_options"
|
|
11
|
+
|
|
12
|
+
module ActiveSupport
|
|
13
|
+
# = Active Support \Configurable
|
|
14
|
+
#
|
|
15
|
+
# Configurable provides a <tt>config</tt> method to store and retrieve
|
|
16
|
+
# configuration options as an OrderedOptions.
|
|
17
|
+
module Configurable
|
|
18
|
+
extend ActiveSupport::Concern
|
|
19
|
+
|
|
20
|
+
class Configuration < ActiveSupport::InheritableOptions
|
|
21
|
+
def compile_methods!
|
|
22
|
+
self.class.compile_methods!(keys)
|
|
23
|
+
end
|
|
24
|
+
|
|
25
|
+
# Compiles reader methods so we don't have to go through method_missing.
|
|
26
|
+
def self.compile_methods!(keys)
|
|
27
|
+
keys.reject { |m| method_defined?(m) }.each do |key|
|
|
28
|
+
class_eval <<-RUBY, __FILE__, __LINE__ + 1
|
|
29
|
+
def #{key}; _get(#{key.inspect}); end
|
|
30
|
+
RUBY
|
|
31
|
+
end
|
|
32
|
+
end
|
|
33
|
+
end
|
|
34
|
+
|
|
35
|
+
module ClassMethods
|
|
36
|
+
# Reads and writes attributes from a configuration OrderedOptions.
|
|
37
|
+
#
|
|
38
|
+
# require "active_support/configurable"
|
|
39
|
+
#
|
|
40
|
+
# class User
|
|
41
|
+
# include ActiveSupport::Configurable
|
|
42
|
+
# end
|
|
43
|
+
#
|
|
44
|
+
# User.config.allowed_access = true
|
|
45
|
+
# User.config.level = 1
|
|
46
|
+
#
|
|
47
|
+
# User.config.allowed_access # => true
|
|
48
|
+
# User.config.level # => 1
|
|
49
|
+
def config
|
|
50
|
+
@_config ||= if respond_to?(:superclass) && superclass.respond_to?(:config)
|
|
51
|
+
superclass.config.inheritable_copy
|
|
52
|
+
else
|
|
53
|
+
# create a new "anonymous" class that will host the compiled reader methods
|
|
54
|
+
Class.new(Configuration).new
|
|
55
|
+
end
|
|
56
|
+
end
|
|
57
|
+
|
|
58
|
+
# Configure values from within the passed block.
|
|
59
|
+
#
|
|
60
|
+
# require "active_support/configurable"
|
|
61
|
+
#
|
|
62
|
+
# class User
|
|
63
|
+
# include ActiveSupport::Configurable
|
|
64
|
+
# end
|
|
65
|
+
#
|
|
66
|
+
# User.allowed_access # => nil
|
|
67
|
+
#
|
|
68
|
+
# User.configure do |config|
|
|
69
|
+
# config.allowed_access = true
|
|
70
|
+
# end
|
|
71
|
+
#
|
|
72
|
+
# User.allowed_access # => true
|
|
73
|
+
def configure
|
|
74
|
+
yield config
|
|
75
|
+
end
|
|
76
|
+
|
|
77
|
+
# Allows you to add shortcut so that you don't have to refer to attribute
|
|
78
|
+
# through config. Also look at the example for config to contrast.
|
|
79
|
+
#
|
|
80
|
+
# Defines both class and instance config accessors.
|
|
81
|
+
#
|
|
82
|
+
# class User
|
|
83
|
+
# include ActiveSupport::Configurable
|
|
84
|
+
# config_accessor :allowed_access
|
|
85
|
+
# end
|
|
86
|
+
#
|
|
87
|
+
# User.allowed_access # => nil
|
|
88
|
+
# User.allowed_access = false
|
|
89
|
+
# User.allowed_access # => false
|
|
90
|
+
#
|
|
91
|
+
# user = User.new
|
|
92
|
+
# user.allowed_access # => false
|
|
93
|
+
# user.allowed_access = true
|
|
94
|
+
# user.allowed_access # => true
|
|
95
|
+
#
|
|
96
|
+
# User.allowed_access # => false
|
|
97
|
+
#
|
|
98
|
+
# The attribute name must be a valid method name in Ruby.
|
|
99
|
+
#
|
|
100
|
+
# class User
|
|
101
|
+
# include ActiveSupport::Configurable
|
|
102
|
+
# config_accessor :"1_Badname"
|
|
103
|
+
# end
|
|
104
|
+
# # => NameError: invalid config attribute name
|
|
105
|
+
#
|
|
106
|
+
# To omit the instance writer method, pass <tt>instance_writer: false</tt>.
|
|
107
|
+
# To omit the instance reader method, pass <tt>instance_reader: false</tt>.
|
|
108
|
+
#
|
|
109
|
+
# class User
|
|
110
|
+
# include ActiveSupport::Configurable
|
|
111
|
+
# config_accessor :allowed_access, instance_reader: false, instance_writer: false
|
|
112
|
+
# end
|
|
113
|
+
#
|
|
114
|
+
# User.allowed_access = false
|
|
115
|
+
# User.allowed_access # => false
|
|
116
|
+
#
|
|
117
|
+
# User.new.allowed_access = true # => NoMethodError
|
|
118
|
+
# User.new.allowed_access # => NoMethodError
|
|
119
|
+
#
|
|
120
|
+
# Or pass <tt>instance_accessor: false</tt>, to omit both instance methods.
|
|
121
|
+
#
|
|
122
|
+
# class User
|
|
123
|
+
# include ActiveSupport::Configurable
|
|
124
|
+
# config_accessor :allowed_access, instance_accessor: false
|
|
125
|
+
# end
|
|
126
|
+
#
|
|
127
|
+
# User.allowed_access = false
|
|
128
|
+
# User.allowed_access # => false
|
|
129
|
+
#
|
|
130
|
+
# User.new.allowed_access = true # => NoMethodError
|
|
131
|
+
# User.new.allowed_access # => NoMethodError
|
|
132
|
+
#
|
|
133
|
+
# Also you can pass <tt>default</tt> or a block to set up the attribute with a default value.
|
|
134
|
+
#
|
|
135
|
+
# class User
|
|
136
|
+
# include ActiveSupport::Configurable
|
|
137
|
+
# config_accessor :allowed_access, default: false
|
|
138
|
+
# config_accessor :hair_colors do
|
|
139
|
+
# [:brown, :black, :blonde, :red]
|
|
140
|
+
# end
|
|
141
|
+
# end
|
|
142
|
+
#
|
|
143
|
+
# User.allowed_access # => false
|
|
144
|
+
# User.hair_colors # => [:brown, :black, :blonde, :red]
|
|
145
|
+
def config_accessor(*names, instance_reader: true, instance_writer: true, instance_accessor: true, default: nil) # :doc:
|
|
146
|
+
names.each do |name|
|
|
147
|
+
raise NameError.new("invalid config attribute name") unless /\A[_A-Za-z]\w*\z/.match?(name)
|
|
148
|
+
|
|
149
|
+
reader, reader_line = "def #{name}; config.#{name}; end", __LINE__
|
|
150
|
+
writer, writer_line = "def #{name}=(value); config.#{name} = value; end", __LINE__
|
|
151
|
+
|
|
152
|
+
singleton_class.class_eval reader, __FILE__, reader_line
|
|
153
|
+
singleton_class.class_eval writer, __FILE__, writer_line
|
|
154
|
+
|
|
155
|
+
if instance_accessor
|
|
156
|
+
class_eval reader, __FILE__, reader_line if instance_reader
|
|
157
|
+
class_eval writer, __FILE__, writer_line if instance_writer
|
|
158
|
+
end
|
|
159
|
+
|
|
160
|
+
send("#{name}=", block_given? ? yield : default)
|
|
161
|
+
end
|
|
162
|
+
end
|
|
163
|
+
private :config_accessor
|
|
164
|
+
|
|
165
|
+
private
|
|
166
|
+
def inherited(subclass)
|
|
167
|
+
super
|
|
168
|
+
subclass.class_eval do
|
|
169
|
+
@_config = nil
|
|
170
|
+
end
|
|
171
|
+
end
|
|
172
|
+
end
|
|
173
|
+
|
|
174
|
+
# Reads and writes attributes from a configuration OrderedOptions.
|
|
175
|
+
#
|
|
176
|
+
# require "active_support/configurable"
|
|
177
|
+
#
|
|
178
|
+
# class User
|
|
179
|
+
# include ActiveSupport::Configurable
|
|
180
|
+
# end
|
|
181
|
+
#
|
|
182
|
+
# user = User.new
|
|
183
|
+
#
|
|
184
|
+
# user.config.allowed_access = true
|
|
185
|
+
# user.config.level = 1
|
|
186
|
+
#
|
|
187
|
+
# user.config.allowed_access # => true
|
|
188
|
+
# user.config.level # => 1
|
|
189
|
+
def config
|
|
190
|
+
@_config ||= self.class.config.inheritable_copy
|
|
191
|
+
end
|
|
192
|
+
end
|
|
193
|
+
end
|
|
@@ -0,0 +1,60 @@
|
|
|
1
|
+
# frozen_string_literal: true
|
|
2
|
+
|
|
3
|
+
module ActiveSupport
|
|
4
|
+
# Reads a YAML configuration file, evaluating any ERB, then
|
|
5
|
+
# parsing the resulting YAML.
|
|
6
|
+
#
|
|
7
|
+
# Warns in case of YAML confusing characters, like invisible
|
|
8
|
+
# non-breaking spaces.
|
|
9
|
+
class ConfigurationFile # :nodoc:
|
|
10
|
+
class FormatError < StandardError; end
|
|
11
|
+
|
|
12
|
+
def initialize(content_path)
|
|
13
|
+
@content_path = content_path.to_s
|
|
14
|
+
@content = read content_path
|
|
15
|
+
end
|
|
16
|
+
|
|
17
|
+
def self.parse(content_path, **options)
|
|
18
|
+
new(content_path).parse(**options)
|
|
19
|
+
end
|
|
20
|
+
|
|
21
|
+
def parse(context: nil, **options)
|
|
22
|
+
source = @content.include?("<%") ? render(context) : @content
|
|
23
|
+
|
|
24
|
+
if source == @content
|
|
25
|
+
if YAML.respond_to?(:unsafe_load)
|
|
26
|
+
YAML.unsafe_load_file(@content_path, **options) || {}
|
|
27
|
+
else
|
|
28
|
+
YAML.load_file(@content_path, **options) || {}
|
|
29
|
+
end
|
|
30
|
+
else
|
|
31
|
+
if YAML.respond_to?(:unsafe_load)
|
|
32
|
+
YAML.unsafe_load(source, **options) || {}
|
|
33
|
+
else
|
|
34
|
+
YAML.load(source, **options) || {}
|
|
35
|
+
end
|
|
36
|
+
end
|
|
37
|
+
rescue Psych::SyntaxError => error
|
|
38
|
+
raise "YAML syntax error occurred while parsing #{@content_path}. " \
|
|
39
|
+
"Please note that YAML must be consistently indented using spaces. Tabs are not allowed. " \
|
|
40
|
+
"Error: #{error.message}"
|
|
41
|
+
end
|
|
42
|
+
|
|
43
|
+
private
|
|
44
|
+
def read(content_path)
|
|
45
|
+
require "yaml" unless defined?(YAML)
|
|
46
|
+
|
|
47
|
+
File.read(content_path).tap do |content|
|
|
48
|
+
if content.include?("\u00A0")
|
|
49
|
+
warn "#{content_path} contains invisible non-breaking spaces, you may want to remove those"
|
|
50
|
+
end
|
|
51
|
+
end
|
|
52
|
+
end
|
|
53
|
+
|
|
54
|
+
def render(context)
|
|
55
|
+
require "erb" unless defined?(ERB)
|
|
56
|
+
erb = ERB.new(@content).tap { |e| e.filename = @content_path }
|
|
57
|
+
context ? erb.result(context) : erb.result
|
|
58
|
+
end
|
|
59
|
+
end
|
|
60
|
+
end
|
|
@@ -0,0 +1,145 @@
|
|
|
1
|
+
# frozen_string_literal: true
|
|
2
|
+
|
|
3
|
+
module ActiveSupport
|
|
4
|
+
# Provides a DSL for declaring a continuous integration workflow that can be run either locally or in the cloud.
|
|
5
|
+
# Each step is timed, reports success/error, and is aggregated into a collective report that reports total runtime,
|
|
6
|
+
# as well as whether the entire run was successful or not.
|
|
7
|
+
#
|
|
8
|
+
# Example:
|
|
9
|
+
#
|
|
10
|
+
# ActiveSupport::ContinuousIntegration.run do
|
|
11
|
+
# step "Setup", "bin/setup --skip-server"
|
|
12
|
+
# step "Style: Ruby", "bin/rubocop"
|
|
13
|
+
# step "Security: Gem audit", "bin/bundler-audit"
|
|
14
|
+
# step "Tests: Rails", "bin/rails test test:system"
|
|
15
|
+
#
|
|
16
|
+
# if success?
|
|
17
|
+
# step "Signoff: Ready for merge and deploy", "gh signoff"
|
|
18
|
+
# else
|
|
19
|
+
# failure "Skipping signoff; CI failed.", "Fix the issues and try again."
|
|
20
|
+
# end
|
|
21
|
+
# end
|
|
22
|
+
#
|
|
23
|
+
# Starting with Rails 8.1, a default `bin/ci` and `config/ci.rb` file are created to provide out-of-the-box CI.
|
|
24
|
+
class ContinuousIntegration
|
|
25
|
+
COLORS = {
|
|
26
|
+
banner: "\033[1;32m", # Green
|
|
27
|
+
title: "\033[1;35m", # Purple
|
|
28
|
+
subtitle: "\033[1;90m", # Medium Gray
|
|
29
|
+
error: "\033[1;31m", # Red
|
|
30
|
+
success: "\033[1;32m" # Green
|
|
31
|
+
}
|
|
32
|
+
|
|
33
|
+
attr_reader :results
|
|
34
|
+
|
|
35
|
+
# Perform a CI run. Execute each step, show their results and runtime, and exit with a non-zero status if there are any failures.
|
|
36
|
+
#
|
|
37
|
+
# Pass an optional title, subtitle, and a block that declares the steps to be executed.
|
|
38
|
+
#
|
|
39
|
+
# Sets the CI environment variable to "true" to allow for conditional behavior in the app, like enabling eager loading and disabling logging.
|
|
40
|
+
#
|
|
41
|
+
# Example:
|
|
42
|
+
#
|
|
43
|
+
# ActiveSupport::ContinuousIntegration.run do
|
|
44
|
+
# step "Setup", "bin/setup --skip-server"
|
|
45
|
+
# step "Style: Ruby", "bin/rubocop"
|
|
46
|
+
# step "Security: Gem audit", "bin/bundler-audit"
|
|
47
|
+
# step "Tests: Rails", "bin/rails test test:system"
|
|
48
|
+
#
|
|
49
|
+
# if success?
|
|
50
|
+
# step "Signoff: Ready for merge and deploy", "gh signoff"
|
|
51
|
+
# else
|
|
52
|
+
# failure "Skipping signoff; CI failed.", "Fix the issues and try again."
|
|
53
|
+
# end
|
|
54
|
+
# end
|
|
55
|
+
def self.run(title = "Continuous Integration", subtitle = "Running tests, style checks, and security audits", &block)
|
|
56
|
+
new.tap do |ci|
|
|
57
|
+
ENV["CI"] = "true"
|
|
58
|
+
ci.heading title, subtitle, padding: false
|
|
59
|
+
ci.report(title, &block)
|
|
60
|
+
abort unless ci.success?
|
|
61
|
+
end
|
|
62
|
+
end
|
|
63
|
+
|
|
64
|
+
def initialize
|
|
65
|
+
@results = []
|
|
66
|
+
end
|
|
67
|
+
|
|
68
|
+
# Declare a step with a title and a command. The command can either be given as a single string or as multiple
|
|
69
|
+
# strings that will be passed to `system` as individual arguments (and therefore correctly escaped for paths etc).
|
|
70
|
+
#
|
|
71
|
+
# Examples:
|
|
72
|
+
#
|
|
73
|
+
# step "Setup", "bin/setup"
|
|
74
|
+
# step "Single test", "bin/rails", "test", "--name", "test_that_is_one"
|
|
75
|
+
def step(title, *command)
|
|
76
|
+
heading title, command.join(" "), type: :title
|
|
77
|
+
report(title) { results << system(*command) }
|
|
78
|
+
end
|
|
79
|
+
|
|
80
|
+
# Returns true if all steps were successful.
|
|
81
|
+
def success?
|
|
82
|
+
results.all?
|
|
83
|
+
end
|
|
84
|
+
|
|
85
|
+
# Display an error heading with the title and optional subtitle to reflect that the run failed.
|
|
86
|
+
def failure(title, subtitle = nil)
|
|
87
|
+
heading title, subtitle, type: :error
|
|
88
|
+
end
|
|
89
|
+
|
|
90
|
+
# Display a colorized heading followed by an optional subtitle.
|
|
91
|
+
#
|
|
92
|
+
# Examples:
|
|
93
|
+
#
|
|
94
|
+
# heading "Smoke Testing", "End-to-end tests verifying key functionality", padding: false
|
|
95
|
+
# heading "Skipping video encoding tests", "Install FFmpeg to run these tests", type: :error
|
|
96
|
+
#
|
|
97
|
+
# See ActiveSupport::ContinuousIntegration::COLORS for a complete list of options.
|
|
98
|
+
def heading(heading, subtitle = nil, type: :banner, padding: true)
|
|
99
|
+
echo "#{padding ? "\n\n" : ""}#{heading}", type: type
|
|
100
|
+
echo "#{subtitle}#{padding ? "\n" : ""}", type: :subtitle if subtitle
|
|
101
|
+
end
|
|
102
|
+
|
|
103
|
+
# Echo text to the terminal in the color corresponding to the type of the text.
|
|
104
|
+
#
|
|
105
|
+
# Examples:
|
|
106
|
+
#
|
|
107
|
+
# echo "This is going to be green!", type: :success
|
|
108
|
+
# echo "This is going to be red!", type: :error
|
|
109
|
+
#
|
|
110
|
+
# See ActiveSupport::ContinuousIntegration::COLORS for a complete list of options.
|
|
111
|
+
def echo(text, type:)
|
|
112
|
+
puts colorize(text, type)
|
|
113
|
+
end
|
|
114
|
+
|
|
115
|
+
# :nodoc:
|
|
116
|
+
def report(title, &block)
|
|
117
|
+
Signal.trap("INT") { abort colorize(:error, "\n❌ #{title} interrupted") }
|
|
118
|
+
|
|
119
|
+
ci = self.class.new
|
|
120
|
+
elapsed = timing { ci.instance_eval(&block) }
|
|
121
|
+
|
|
122
|
+
if ci.success?
|
|
123
|
+
echo "\n✅ #{title} passed in #{elapsed}", type: :success
|
|
124
|
+
else
|
|
125
|
+
echo "\n❌ #{title} failed in #{elapsed}", type: :error
|
|
126
|
+
end
|
|
127
|
+
|
|
128
|
+
results.concat ci.results
|
|
129
|
+
ensure
|
|
130
|
+
Signal.trap("INT", "-")
|
|
131
|
+
end
|
|
132
|
+
|
|
133
|
+
private
|
|
134
|
+
def timing
|
|
135
|
+
started_at = Time.now.to_f
|
|
136
|
+
yield
|
|
137
|
+
min, sec = (Time.now.to_f - started_at).divmod(60)
|
|
138
|
+
"#{"#{min}m" if min > 0}%.2fs" % sec
|
|
139
|
+
end
|
|
140
|
+
|
|
141
|
+
def colorize(text, type)
|
|
142
|
+
"#{COLORS.fetch(type)}#{text}\033[0m"
|
|
143
|
+
end
|
|
144
|
+
end
|
|
145
|
+
end
|
|
@@ -0,0 +1,100 @@
|
|
|
1
|
+
# frozen_string_literal: true
|
|
2
|
+
|
|
3
|
+
class Array
|
|
4
|
+
# Returns the tail of the array from +position+.
|
|
5
|
+
#
|
|
6
|
+
# %w( a b c d ).from(0) # => ["a", "b", "c", "d"]
|
|
7
|
+
# %w( a b c d ).from(2) # => ["c", "d"]
|
|
8
|
+
# %w( a b c d ).from(10) # => []
|
|
9
|
+
# %w().from(0) # => []
|
|
10
|
+
# %w( a b c d ).from(-2) # => ["c", "d"]
|
|
11
|
+
# %w( a b c ).from(-10) # => []
|
|
12
|
+
def from(position)
|
|
13
|
+
self[position, length] || []
|
|
14
|
+
end
|
|
15
|
+
|
|
16
|
+
# Returns the beginning of the array up to +position+.
|
|
17
|
+
#
|
|
18
|
+
# %w( a b c d ).to(0) # => ["a"]
|
|
19
|
+
# %w( a b c d ).to(2) # => ["a", "b", "c"]
|
|
20
|
+
# %w( a b c d ).to(10) # => ["a", "b", "c", "d"]
|
|
21
|
+
# %w().to(0) # => []
|
|
22
|
+
# %w( a b c d ).to(-2) # => ["a", "b", "c"]
|
|
23
|
+
# %w( a b c ).to(-10) # => []
|
|
24
|
+
def to(position)
|
|
25
|
+
if position >= 0
|
|
26
|
+
take position + 1
|
|
27
|
+
else
|
|
28
|
+
self[0..position]
|
|
29
|
+
end
|
|
30
|
+
end
|
|
31
|
+
|
|
32
|
+
# Returns a new array that includes the passed elements.
|
|
33
|
+
#
|
|
34
|
+
# [ 1, 2, 3 ].including(4, 5) # => [ 1, 2, 3, 4, 5 ]
|
|
35
|
+
# [ [ 0, 1 ] ].including([ [ 1, 0 ] ]) # => [ [ 0, 1 ], [ 1, 0 ] ]
|
|
36
|
+
def including(*elements)
|
|
37
|
+
self + elements.flatten(1)
|
|
38
|
+
end
|
|
39
|
+
|
|
40
|
+
# Returns a copy of the Array excluding the specified elements.
|
|
41
|
+
#
|
|
42
|
+
# ["David", "Rafael", "Aaron", "Todd"].excluding("Aaron", "Todd") # => ["David", "Rafael"]
|
|
43
|
+
# [ [ 0, 1 ], [ 1, 0 ] ].excluding([ [ 1, 0 ] ]) # => [ [ 0, 1 ] ]
|
|
44
|
+
#
|
|
45
|
+
# Note: This is an optimization of <tt>Enumerable#excluding</tt> that uses <tt>Array#-</tt>
|
|
46
|
+
# instead of <tt>Array#reject</tt> for performance reasons.
|
|
47
|
+
def excluding(*elements)
|
|
48
|
+
self - elements.flatten(1)
|
|
49
|
+
end
|
|
50
|
+
alias :without :excluding
|
|
51
|
+
|
|
52
|
+
# Equal to <tt>self[1]</tt>.
|
|
53
|
+
#
|
|
54
|
+
# %w( a b c d e ).second # => "b"
|
|
55
|
+
def second
|
|
56
|
+
self[1]
|
|
57
|
+
end
|
|
58
|
+
|
|
59
|
+
# Equal to <tt>self[2]</tt>.
|
|
60
|
+
#
|
|
61
|
+
# %w( a b c d e ).third # => "c"
|
|
62
|
+
def third
|
|
63
|
+
self[2]
|
|
64
|
+
end
|
|
65
|
+
|
|
66
|
+
# Equal to <tt>self[3]</tt>.
|
|
67
|
+
#
|
|
68
|
+
# %w( a b c d e ).fourth # => "d"
|
|
69
|
+
def fourth
|
|
70
|
+
self[3]
|
|
71
|
+
end
|
|
72
|
+
|
|
73
|
+
# Equal to <tt>self[4]</tt>.
|
|
74
|
+
#
|
|
75
|
+
# %w( a b c d e ).fifth # => "e"
|
|
76
|
+
def fifth
|
|
77
|
+
self[4]
|
|
78
|
+
end
|
|
79
|
+
|
|
80
|
+
# Equal to <tt>self[41]</tt>. Also known as accessing "the reddit".
|
|
81
|
+
#
|
|
82
|
+
# (1..42).to_a.forty_two # => 42
|
|
83
|
+
def forty_two
|
|
84
|
+
self[41]
|
|
85
|
+
end
|
|
86
|
+
|
|
87
|
+
# Equal to <tt>self[-3]</tt>.
|
|
88
|
+
#
|
|
89
|
+
# %w( a b c d e ).third_to_last # => "c"
|
|
90
|
+
def third_to_last
|
|
91
|
+
self[-3]
|
|
92
|
+
end
|
|
93
|
+
|
|
94
|
+
# Equal to <tt>self[-2]</tt>.
|
|
95
|
+
#
|
|
96
|
+
# %w( a b c d e ).second_to_last # => "d"
|
|
97
|
+
def second_to_last
|
|
98
|
+
self[-2]
|
|
99
|
+
end
|
|
100
|
+
end
|