ultra_settings 0.0.1.rc1 → 1.0.0
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 +4 -4
- data/README.md +320 -2
- data/VERSION +1 -1
- data/app/application.css +85 -0
- data/app/application.js +19 -0
- data/app/index.html.erb +93 -0
- data/app/layout.css +27 -0
- data/app/layout.html.erb +21 -0
- data/lib/ultra_settings/coerce.rb +98 -0
- data/lib/ultra_settings/configuration.rb +378 -79
- data/lib/ultra_settings/field.rb +57 -88
- data/lib/ultra_settings/rack_app.rb +21 -0
- data/lib/ultra_settings/railtie.rb +33 -0
- data/lib/ultra_settings/version.rb +5 -0
- data/lib/ultra_settings/web_view.rb +38 -0
- data/lib/ultra_settings/yaml_config.rb +78 -0
- data/lib/ultra_settings.rb +167 -74
- data/ultra_settings.gemspec +3 -4
- metadata +18 -35
data/lib/ultra_settings/field.rb
CHANGED
@@ -5,51 +5,41 @@ module UltraSettings
|
|
5
5
|
class Field
|
6
6
|
attr_reader :name
|
7
7
|
attr_reader :type
|
8
|
+
attr_reader :description
|
8
9
|
attr_reader :default
|
9
10
|
attr_reader :default_if
|
10
11
|
attr_reader :env_var
|
11
|
-
attr_reader :
|
12
|
+
attr_reader :runtime_setting
|
12
13
|
attr_reader :yaml_key
|
13
|
-
attr_reader :env_var_prefix
|
14
|
-
attr_reader :env_var_upcase
|
15
|
-
attr_reader :setting_prefix
|
16
|
-
attr_reader :setting_upcase
|
17
14
|
|
18
15
|
# @param name [String, Symbol] The name of the field.
|
19
16
|
# @param type [Symbol] The type of the field.
|
17
|
+
# @param description [String] The description of the field.
|
20
18
|
# @param default [Object] The default value of the field.
|
21
19
|
# @param default_if [Proc] A proc that returns true if the default value should be used.
|
22
20
|
# @param env_var [String, Symbol] The name of the environment variable to use for the field.
|
23
|
-
# @param
|
21
|
+
# @param runtime_setting [String, Symbol] The name of the setting to use for the field.
|
24
22
|
# @param yaml_key [String, Symbol] The name of the YAML key to use for the field.
|
25
|
-
# @param env_var_prefix [String, Symbol] The prefix to use for the environment variable name.
|
26
|
-
# @param env_var_upcase [Boolean] Whether or not to upcase the environment variable name.
|
27
|
-
# @param setting_prefix [String, Symbol] The prefix to use for the setting name.
|
28
|
-
# @param setting_upcase [Boolean] Whether or not to upcase the setting name.
|
29
23
|
def initialize(
|
30
24
|
name:,
|
31
25
|
type: :string,
|
26
|
+
description: nil,
|
32
27
|
default: nil,
|
33
28
|
default_if: nil,
|
34
29
|
env_var: nil,
|
35
|
-
|
30
|
+
runtime_setting: nil,
|
36
31
|
yaml_key: nil,
|
37
|
-
|
38
|
-
env_var_upcase: true,
|
39
|
-
setting_prefix: nil,
|
40
|
-
setting_upcase: false
|
32
|
+
static: false
|
41
33
|
)
|
42
|
-
@name =
|
34
|
+
@name = name.to_s.freeze
|
43
35
|
@type = type.to_sym
|
44
|
-
@
|
36
|
+
@description = description&.to_s&.freeze
|
37
|
+
@default = Coerce.coerce_value(default, @type).freeze
|
45
38
|
@default_if = default_if
|
46
|
-
@env_var =
|
47
|
-
@
|
48
|
-
@yaml_key =
|
49
|
-
@
|
50
|
-
@env_var_upcase = !!env_var_upcase
|
51
|
-
@setting_prefix = frozen_string(setting_prefix)
|
52
|
-
@setting_upcase = !!setting_upcase
|
39
|
+
@env_var = env_var&.to_s&.freeze
|
40
|
+
@runtime_setting = runtime_setting&.to_s&.freeze
|
41
|
+
@yaml_key = yaml_key&.to_s&.freeze
|
42
|
+
@static = !!static
|
53
43
|
end
|
54
44
|
|
55
45
|
# Get the value for the field from the passed in state.
|
@@ -58,85 +48,64 @@ module UltraSettings
|
|
58
48
|
# @param settings [#[]] The runtime settings.
|
59
49
|
# @param yaml_config [#[]] The YAML configuration.
|
60
50
|
def value(env: nil, settings: nil, yaml_config: nil)
|
61
|
-
|
62
|
-
val = coerce_value(val).freeze
|
63
|
-
val = @default if use_default?(val)
|
64
|
-
val
|
51
|
+
fetch_value_and_source(env: env, settings: settings, yaml_config: yaml_config).first
|
65
52
|
end
|
66
53
|
|
67
|
-
|
68
|
-
|
69
|
-
|
70
|
-
|
71
|
-
|
72
|
-
|
73
|
-
|
74
|
-
|
75
|
-
|
76
|
-
end
|
54
|
+
# Get the source for the field from the passed in state.
|
55
|
+
#
|
56
|
+
# @param env [Hash] The environment variables.
|
57
|
+
# @param settings [Hash] The runtime settings.
|
58
|
+
# @param yaml_config [Hash] The YAML configuration.
|
59
|
+
# @return [Symbol, nil] The source of the value (:env, :settings, or :yaml).
|
60
|
+
def source(env: nil, settings: nil, yaml_config: nil)
|
61
|
+
fetch_value_and_source(env: env, settings: settings, yaml_config: yaml_config).last
|
62
|
+
end
|
77
63
|
|
78
|
-
|
79
|
-
|
80
|
-
|
81
|
-
|
64
|
+
# Coerce the passed in value to the type of the field.
|
65
|
+
#
|
66
|
+
# @param value [Object] The value to coerce.
|
67
|
+
# @return [Object] The coerced value.
|
68
|
+
def coerce(value)
|
69
|
+
Coerce.coerce_value(value, @type)
|
70
|
+
end
|
82
71
|
|
83
|
-
|
72
|
+
# Returns true if the field is static.
|
73
|
+
#
|
74
|
+
# @return [Boolean]
|
75
|
+
def static?
|
76
|
+
@static
|
84
77
|
end
|
85
78
|
|
86
|
-
|
87
|
-
|
79
|
+
private
|
80
|
+
|
81
|
+
def fetch_value_and_source(env:, settings:, yaml_config:)
|
82
|
+
source = nil
|
88
83
|
|
89
|
-
|
90
|
-
|
91
|
-
|
92
|
-
|
93
|
-
value
|
94
|
-
|
95
|
-
|
96
|
-
|
97
|
-
|
98
|
-
|
99
|
-
|
100
|
-
|
101
|
-
value.to_s.to_sym
|
84
|
+
value = env[env_var] if env && env_var
|
85
|
+
value = nil if value == ""
|
86
|
+
if value.nil?
|
87
|
+
value = settings[runtime_setting] if settings && runtime_setting
|
88
|
+
value = nil if value == ""
|
89
|
+
if value.nil?
|
90
|
+
value = yaml_value(yaml_config)
|
91
|
+
value = nil if value == ""
|
92
|
+
source = :yaml unless value.nil?
|
93
|
+
else
|
94
|
+
source = :settings
|
95
|
+
end
|
102
96
|
else
|
103
|
-
|
97
|
+
source = :env
|
104
98
|
end
|
105
|
-
end
|
106
99
|
|
107
|
-
|
108
|
-
var_name = env_var
|
109
|
-
if var_name.nil?
|
110
|
-
var_name = "#{env_var_prefix}#{name}"
|
111
|
-
var_name = var_name.upcase if env_var_upcase
|
112
|
-
end
|
113
|
-
env[var_name.to_s]
|
114
|
-
end
|
100
|
+
value = coerce(value).freeze
|
115
101
|
|
116
|
-
|
117
|
-
var_name = setting_name
|
118
|
-
if var_name.nil?
|
119
|
-
var_name = "#{setting_prefix}#{name}"
|
120
|
-
var_name = var_name.upcase if setting_upcase
|
121
|
-
end
|
122
|
-
settings[var_name.to_s]
|
102
|
+
[value, source]
|
123
103
|
end
|
124
104
|
|
125
105
|
def yaml_value(yaml_config)
|
126
|
-
|
127
|
-
yaml_config[key.to_s]
|
128
|
-
end
|
129
|
-
|
130
|
-
def use_default?(value)
|
131
|
-
if value && @default_if
|
132
|
-
@default_if.call(value)
|
133
|
-
else
|
134
|
-
value.nil?
|
135
|
-
end
|
136
|
-
end
|
106
|
+
return nil unless yaml_config && yaml_key
|
137
107
|
|
138
|
-
|
139
|
-
value&.to_s&.dup&.freeze
|
108
|
+
yaml_config[yaml_key]
|
140
109
|
end
|
141
110
|
end
|
142
111
|
end
|
@@ -0,0 +1,21 @@
|
|
1
|
+
# frozen_string_literal: true
|
2
|
+
|
3
|
+
module UltraSettings
|
4
|
+
# Rack application for displaying the current settings in an HTML page.
|
5
|
+
# No setting values are displayed, but you should still add some
|
6
|
+
# sort of authentication if you want to use this in production.
|
7
|
+
class RackApp
|
8
|
+
def call(env)
|
9
|
+
[200, {"content-type" => "text/html; charset=utf8"}, [webview.render_settings]]
|
10
|
+
end
|
11
|
+
|
12
|
+
private
|
13
|
+
|
14
|
+
def webview
|
15
|
+
if ENV.fetch("RAILS_ENV", ENV.fetch("RACK_ENV", "development")) == "development"
|
16
|
+
@webview = nil
|
17
|
+
end
|
18
|
+
@webview ||= WebView.new
|
19
|
+
end
|
20
|
+
end
|
21
|
+
end
|
@@ -0,0 +1,33 @@
|
|
1
|
+
# frozen_string_literal: true
|
2
|
+
|
3
|
+
module UltraSettings
|
4
|
+
# Railtie to automatically configure settings for Rails applications.
|
5
|
+
# By default this will automatically load any configuration classes in the
|
6
|
+
# app/configurations directory. This can be customized by setting the
|
7
|
+
# `config.ultra_settings.auto_load_directories` option.
|
8
|
+
class Railtie < Rails::Railtie
|
9
|
+
config.ultra_settings = ActiveSupport::OrderedOptions.new
|
10
|
+
config.ultra_settings.auto_load_directories = [File.join("app", "configurations")]
|
11
|
+
|
12
|
+
config.before_configuration do
|
13
|
+
UltraSettings.yaml_config_env = Rails.env
|
14
|
+
UltraSettings.yaml_config_path = Rails.root.join("config")
|
15
|
+
end
|
16
|
+
|
17
|
+
# Automatically register any configuration classes in the app/configurations
|
18
|
+
# directory. The path to load can be customized by setting the
|
19
|
+
# `config.ultra_settings.auto_load_directory` option.
|
20
|
+
config.after_initialize do
|
21
|
+
Array(Rails.application.config.ultra_settings.auto_load_directories).each do |directory|
|
22
|
+
next unless directory
|
23
|
+
|
24
|
+
app_config_dir = Rails.root.join(directory)
|
25
|
+
app_config_dir.glob("**/*_configuration.rb").each do |file_path|
|
26
|
+
config_name = file_path.basename("_configuration.rb")
|
27
|
+
class_name = file_path.relative_path_from(app_config_dir).to_s.chomp(".rb").classify
|
28
|
+
UltraSettings.add(config_name, class_name)
|
29
|
+
end
|
30
|
+
end
|
31
|
+
end
|
32
|
+
end
|
33
|
+
end
|
@@ -0,0 +1,38 @@
|
|
1
|
+
# frozen_string_literal: true
|
2
|
+
|
3
|
+
module UltraSettings
|
4
|
+
# Helper class for rendering the settings information in an HTML page.
|
5
|
+
class WebView
|
6
|
+
attr_reader :css
|
7
|
+
|
8
|
+
def initialize
|
9
|
+
@index_template = erb_template("index.html.erb")
|
10
|
+
@layout_template = erb_template("layout.html.erb")
|
11
|
+
@layout_css = read_app_file("layout.css")
|
12
|
+
@css = read_app_file("application.css")
|
13
|
+
@javascript = read_app_file("application.js")
|
14
|
+
end
|
15
|
+
|
16
|
+
def render_settings
|
17
|
+
@layout_template.result(binding)
|
18
|
+
end
|
19
|
+
|
20
|
+
def content
|
21
|
+
@index_template.result(binding)
|
22
|
+
end
|
23
|
+
|
24
|
+
private
|
25
|
+
|
26
|
+
def erb_template(path)
|
27
|
+
ERB.new(read_app_file(path))
|
28
|
+
end
|
29
|
+
|
30
|
+
def read_app_file(path)
|
31
|
+
File.read(File.join(app_dir, path))
|
32
|
+
end
|
33
|
+
|
34
|
+
def app_dir
|
35
|
+
File.expand_path(File.join("..", "..", "app"), __dir__)
|
36
|
+
end
|
37
|
+
end
|
38
|
+
end
|
@@ -0,0 +1,78 @@
|
|
1
|
+
# frozen_string_literal: true
|
2
|
+
|
3
|
+
module UltraSettings
|
4
|
+
# Helper class to load YAML configuration files. Any ERB markup in the YAML
|
5
|
+
# file will be evaluated. The YAML file should be structured like this:
|
6
|
+
#
|
7
|
+
# ```yaml
|
8
|
+
# shared:
|
9
|
+
# foo: bar
|
10
|
+
# bar: baz
|
11
|
+
#
|
12
|
+
# development:
|
13
|
+
# bar: qux
|
14
|
+
# biz: buz
|
15
|
+
#
|
16
|
+
# test:
|
17
|
+
# bar: qix
|
18
|
+
# biz: biz
|
19
|
+
# ```
|
20
|
+
#
|
21
|
+
# The section with the key matching the environment name is merged into
|
22
|
+
# the shared section. In this example, the development environment would
|
23
|
+
# have the following configuration:
|
24
|
+
#
|
25
|
+
# ```ruby
|
26
|
+
# {
|
27
|
+
# "foo" => "bar",
|
28
|
+
# "bar" => "qux",
|
29
|
+
# "biz" => "buz"
|
30
|
+
# }
|
31
|
+
# ```
|
32
|
+
#
|
33
|
+
# In addition, the keys are flattened into a one level deep hash with dots
|
34
|
+
# separating the keys.
|
35
|
+
class YamlConfig
|
36
|
+
def initialize(path, environment)
|
37
|
+
yaml = load_yaml(path)
|
38
|
+
@config = environment_config(yaml, environment)
|
39
|
+
end
|
40
|
+
|
41
|
+
def to_h
|
42
|
+
@config
|
43
|
+
end
|
44
|
+
|
45
|
+
private
|
46
|
+
|
47
|
+
def load_yaml(path)
|
48
|
+
yaml = File.read(path)
|
49
|
+
|
50
|
+
if yaml.include?("<%")
|
51
|
+
yaml = ERB.new(yaml).result
|
52
|
+
end
|
53
|
+
|
54
|
+
hash = YAML.load(yaml) # rubocop:disable Security/YAMLLoad
|
55
|
+
hash = {} unless hash.is_a?(Hash)
|
56
|
+
hash
|
57
|
+
end
|
58
|
+
|
59
|
+
def environment_config(yaml, environment)
|
60
|
+
shared = flatten_hash(yaml.fetch("shared", {}))
|
61
|
+
env = flatten_hash(yaml.fetch(environment, {}))
|
62
|
+
shared.merge(env)
|
63
|
+
end
|
64
|
+
|
65
|
+
def flatten_hash(hash, prefix = nil)
|
66
|
+
hash.each_with_object({}) do |(key, value), result|
|
67
|
+
key = key.to_s
|
68
|
+
key = "#{prefix}.#{key}" if prefix
|
69
|
+
|
70
|
+
if value.is_a?(Hash)
|
71
|
+
result.merge!(flatten_hash(value, key))
|
72
|
+
else
|
73
|
+
result[key] = value
|
74
|
+
end
|
75
|
+
end
|
76
|
+
end
|
77
|
+
end
|
78
|
+
end
|
data/lib/ultra_settings.rb
CHANGED
@@ -1,9 +1,22 @@
|
|
1
1
|
# frozen_string_literal: true
|
2
2
|
|
3
|
-
require "
|
3
|
+
require "erb"
|
4
|
+
require "yaml"
|
5
|
+
require "time"
|
6
|
+
require "pathname"
|
7
|
+
require "singleton"
|
4
8
|
|
5
9
|
require_relative "ultra_settings/configuration"
|
10
|
+
require_relative "ultra_settings/coerce"
|
6
11
|
require_relative "ultra_settings/field"
|
12
|
+
require_relative "ultra_settings/rack_app"
|
13
|
+
require_relative "ultra_settings/web_view"
|
14
|
+
require_relative "ultra_settings/yaml_config"
|
15
|
+
require_relative "ultra_settings/version"
|
16
|
+
|
17
|
+
if defined?(Rails::Railtie)
|
18
|
+
require_relative "ultra_settings/railtie"
|
19
|
+
end
|
7
20
|
|
8
21
|
# This is the root namespace for UltraSettings. You can add configurations to
|
9
22
|
# this namespace using the add method.
|
@@ -12,12 +25,11 @@ require_relative "ultra_settings/field"
|
|
12
25
|
# UltraSettings.add(:test)
|
13
26
|
# UltraSettings.test # => TestConfiguration.instance
|
14
27
|
module UltraSettings
|
28
|
+
VALID_NAME__PATTERN = /\A[a-z_][a-zA-Z0-9_]*\z/
|
29
|
+
|
15
30
|
@configurations = {}
|
16
31
|
@mutex = Mutex.new
|
17
32
|
|
18
|
-
class NonStaticValueError < StandardError
|
19
|
-
end
|
20
|
-
|
21
33
|
class << self
|
22
34
|
# Adds a configuration to the root namespace. The configuration will be
|
23
35
|
# available as a method on the UltraSettings module with the provide name.
|
@@ -29,15 +41,15 @@ module UltraSettings
|
|
29
41
|
# @return [void]
|
30
42
|
def add(name, klass = nil)
|
31
43
|
name = name.to_s
|
32
|
-
unless name.match?(
|
44
|
+
unless name.match?(VALID_NAME__PATTERN)
|
33
45
|
raise ArgementError.new("Invalid configuration name: #{name.inspect}")
|
34
46
|
end
|
35
47
|
|
36
48
|
class_name = klass&.to_s
|
37
|
-
class_name ||= "#{name
|
49
|
+
class_name ||= "#{classify(name)}Configuration"
|
38
50
|
|
39
51
|
@mutex.synchronize do
|
40
|
-
@configurations
|
52
|
+
@configurations[name] = class_name
|
41
53
|
|
42
54
|
eval <<-RUBY, binding, __FILE__, __LINE__ + 1 # rubocop:disable Security/Eval
|
43
55
|
def #{name}
|
@@ -45,93 +57,158 @@ module UltraSettings
|
|
45
57
|
end
|
46
58
|
RUBY
|
47
59
|
end
|
60
|
+
end
|
48
61
|
|
49
|
-
|
50
|
-
|
51
|
-
|
52
|
-
|
53
|
-
|
54
|
-
|
55
|
-
|
56
|
-
Configuration.environment_variables_disabled = !!value
|
57
|
-
end
|
62
|
+
# Returns true if the provided class has been added as a configuration.
|
63
|
+
#
|
64
|
+
# @param class_name [Class, String] The name of the configuration class.
|
65
|
+
# @return [Boolean]
|
66
|
+
def include?(class_name)
|
67
|
+
@configurations.values.collect(&:to_s).include?(class_name.to_s)
|
68
|
+
end
|
58
69
|
|
59
|
-
|
60
|
-
|
61
|
-
|
62
|
-
|
63
|
-
|
64
|
-
|
65
|
-
|
66
|
-
|
67
|
-
|
70
|
+
# Control if settings can be loaded from environment variables. By default
|
71
|
+
# environment variables are enabled. This can also be disabled on
|
72
|
+
# individual Configuration classes.
|
73
|
+
#
|
74
|
+
# @param value [Boolean] Whether or not to load settings from environment variables.
|
75
|
+
# @return [void]
|
76
|
+
def environment_variables_disabled=(value)
|
77
|
+
Configuration.environment_variables_disabled = !!value
|
78
|
+
end
|
68
79
|
|
69
|
-
|
70
|
-
|
71
|
-
|
72
|
-
|
73
|
-
|
74
|
-
|
75
|
-
|
76
|
-
|
77
|
-
|
80
|
+
# Control if settings can be loaded from runtime settings. By default
|
81
|
+
# runtime settings are enabled. This can also be disabled on individual
|
82
|
+
# Configuration classes.
|
83
|
+
#
|
84
|
+
# @param value [Boolean] Whether or not to load settings from runtime settings.
|
85
|
+
# @return [void]
|
86
|
+
def runtime_settings_disabled=(value)
|
87
|
+
Configuration.runtime_settings_disabled = !!value
|
88
|
+
end
|
78
89
|
|
79
|
-
|
80
|
-
|
81
|
-
|
82
|
-
|
83
|
-
|
84
|
-
|
85
|
-
|
86
|
-
|
90
|
+
# Control if settings can be loaded from YAML configuration files. By
|
91
|
+
# default YAML configuration is enabled. This can also be disabled on
|
92
|
+
# individual Configuration classes.
|
93
|
+
#
|
94
|
+
# @param value [Boolean] Whether or not to load settings from YAML configuration.
|
95
|
+
# @return [void]
|
96
|
+
def yaml_config_disabled=(value)
|
97
|
+
Configuration.yaml_config_disabled = !!value
|
98
|
+
end
|
87
99
|
|
88
|
-
|
89
|
-
|
90
|
-
|
91
|
-
|
92
|
-
|
93
|
-
|
94
|
-
|
100
|
+
# Set the environment to use when loading YAML configuration files.
|
101
|
+
# In a Rails application this will be the current Rails environment.
|
102
|
+
# Defaults to "development".
|
103
|
+
#
|
104
|
+
# @param value [String] The environment name to use.
|
105
|
+
def yaml_config_env=(value)
|
106
|
+
Configuration.yaml_config_env = value
|
107
|
+
end
|
95
108
|
|
96
|
-
|
97
|
-
|
98
|
-
|
99
|
-
|
100
|
-
|
101
|
-
|
102
|
-
|
103
|
-
|
109
|
+
# Set the delimiter to use when determining environment variable names.
|
110
|
+
# By default this is an underscore.
|
111
|
+
#
|
112
|
+
# @param value [String] The delimiter to use.
|
113
|
+
# @return [void]
|
114
|
+
def env_var_delimiter=(value)
|
115
|
+
Configuration.env_var_delimiter = value.to_s
|
116
|
+
end
|
117
|
+
|
118
|
+
# Set the delimiter to use when determining setting names. By default
|
119
|
+
# this is a period.
|
120
|
+
#
|
121
|
+
# @param value [String] The delimiter to use.
|
122
|
+
def runtime_setting_delimiter=(value)
|
123
|
+
Configuration.runtime_setting_delimiter = value.to_s
|
124
|
+
end
|
125
|
+
|
126
|
+
# Control if environment variable names should be upcased. By default
|
127
|
+
# this is true.
|
128
|
+
#
|
129
|
+
# @param value [Boolean] Whether or not to upcase environment variable names.
|
130
|
+
# @return [void]
|
131
|
+
def env_var_upcase=(value)
|
132
|
+
Configuration.env_var_upcase = !!value
|
133
|
+
end
|
134
|
+
|
135
|
+
# Control if setting names should be upcased. By default this is false.
|
136
|
+
#
|
137
|
+
# @param value [Boolean] Whether or not to upcase setting names.
|
138
|
+
# @return [void]
|
139
|
+
def runtime_setting_upcase=(value)
|
140
|
+
Configuration.runtime_setting_upcase = !!value
|
141
|
+
end
|
142
|
+
|
143
|
+
# Set the directory to use when loading YAML configuration files.
|
144
|
+
# In a Rails application this will be the config directory.
|
145
|
+
# Otherwise it will be the current working directory.
|
146
|
+
#
|
147
|
+
# @param value [String, Pathname] The directory to use.
|
148
|
+
# @return [void]
|
149
|
+
def yaml_config_path=(value)
|
150
|
+
Configuration.yaml_config_path = value.to_s
|
151
|
+
end
|
152
|
+
|
153
|
+
# Set the object to use for runtime settings. This can be any object that
|
154
|
+
# responds to the [] method. If you are using the `super_settings` gem,
|
155
|
+
# you can set this to `SuperSettings`.
|
156
|
+
attr_writer :runtime_settings
|
104
157
|
|
105
|
-
|
106
|
-
|
107
|
-
|
108
|
-
|
109
|
-
|
110
|
-
|
158
|
+
# Get the object to use for runtime settings.
|
159
|
+
#
|
160
|
+
# @return [Object, nil]
|
161
|
+
# @api private
|
162
|
+
def __runtime_settings__
|
163
|
+
@runtime_settings ||= nil
|
164
|
+
end
|
165
|
+
|
166
|
+
# Explicitly set setting values within a block. This is useful for testing
|
167
|
+
# or other situations where you want hard code a specific set of values.
|
168
|
+
#
|
169
|
+
# @param settings [Hash] The settings to set.
|
170
|
+
# @return [Object] The result of the block.
|
171
|
+
def override!(settings, &block)
|
172
|
+
settings = settings.to_a
|
173
|
+
config_name, values = settings.first
|
174
|
+
config_name = config_name.to_s
|
175
|
+
other_settings = settings[1..-1]
|
176
|
+
|
177
|
+
unless @configurations.include?(config_name)
|
178
|
+
raise ArgumentError.new("Unknown configuration: #{config_name.inspect}")
|
111
179
|
end
|
112
180
|
|
113
|
-
|
114
|
-
|
115
|
-
|
116
|
-
|
117
|
-
|
118
|
-
|
119
|
-
|
181
|
+
config = send(config_name)
|
182
|
+
config.override!(values) do
|
183
|
+
if other_settings.empty?
|
184
|
+
yield
|
185
|
+
else
|
186
|
+
override!(other_settings, &block)
|
187
|
+
end
|
120
188
|
end
|
121
189
|
end
|
122
190
|
|
191
|
+
# Get the names of all of the configurations that have been added.
|
192
|
+
#
|
193
|
+
# @return [Array<String>] The names of the configurations.
|
194
|
+
# @api private
|
195
|
+
def __configuration_names__
|
196
|
+
@configurations.keys
|
197
|
+
end
|
198
|
+
|
123
199
|
private
|
124
200
|
|
125
201
|
# Load a configuration class.
|
126
202
|
def __load_config__(name, class_name)
|
127
203
|
klass = @configurations[name]
|
128
204
|
|
129
|
-
|
130
|
-
|
205
|
+
# Hook for Rails development mode to reload the configuration class.
|
206
|
+
if klass && defined?(Rails.configuration.cache_classes) && !Rails.configuration.cache_classes
|
207
|
+
klass = class_name if klass != constantize(class_name)
|
131
208
|
end
|
132
209
|
|
133
|
-
|
134
|
-
klass = class_name
|
210
|
+
if klass.is_a?(String)
|
211
|
+
klass = constantize(class_name)
|
135
212
|
@mutex.synchronize do
|
136
213
|
unless klass < Configuration
|
137
214
|
raise TypeError.new("Configuration class #{class_name} does not inherit from UltraSettings::Configuration")
|
@@ -142,5 +219,21 @@ module UltraSettings
|
|
142
219
|
|
143
220
|
klass.instance
|
144
221
|
end
|
222
|
+
|
223
|
+
def classify(name)
|
224
|
+
# Use the Rails classify method if it is available since it will
|
225
|
+
# handle custom inflections.
|
226
|
+
if name.respond_to?(:classify)
|
227
|
+
name.classify
|
228
|
+
else
|
229
|
+
name.split("_").map(&:capitalize).join.gsub("/", "::")
|
230
|
+
end
|
231
|
+
end
|
232
|
+
|
233
|
+
def constantize(class_name)
|
234
|
+
class_name.split("::").reduce(Object) do |mod, name|
|
235
|
+
mod.const_get(name)
|
236
|
+
end
|
237
|
+
end
|
145
238
|
end
|
146
239
|
end
|