const_conf 0.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 +7 -0
- data/Gemfile +5 -0
- data/LICENSE +19 -0
- data/README.md +789 -0
- data/Rakefile +35 -0
- data/const_conf.gemspec +35 -0
- data/lib/const_conf/dir_plugin.rb +175 -0
- data/lib/const_conf/env_dir_extension.rb +83 -0
- data/lib/const_conf/errors.rb +93 -0
- data/lib/const_conf/file_plugin.rb +33 -0
- data/lib/const_conf/json_plugin.rb +12 -0
- data/lib/const_conf/railtie.rb +13 -0
- data/lib/const_conf/setting.rb +382 -0
- data/lib/const_conf/setting_accessor.rb +103 -0
- data/lib/const_conf/tree.rb +265 -0
- data/lib/const_conf/version.rb +8 -0
- data/lib/const_conf/yaml_plugin.rb +30 -0
- data/lib/const_conf.rb +401 -0
- data/spec/assets/.env/API_KEY +1 -0
- data/spec/assets/config.json +3 -0
- data/spec/assets/config.yml +1 -0
- data/spec/assets/config_env.yml +7 -0
- data/spec/const_conf/dir_plugin_spec.rb +249 -0
- data/spec/const_conf/env_dir_extension_spec.rb +59 -0
- data/spec/const_conf/file_plugin_spec.rb +173 -0
- data/spec/const_conf/json_plugin_spec.rb +64 -0
- data/spec/const_conf/setting_accessor_spec.rb +114 -0
- data/spec/const_conf/setting_spec.rb +628 -0
- data/spec/const_conf/tree_spec.rb +185 -0
- data/spec/const_conf/yaml_plugin_spec.rb +84 -0
- data/spec/const_conf_spec.rb +216 -0
- data/spec/spec_helper.rb +140 -0
- metadata +240 -0
data/Rakefile
ADDED
@@ -0,0 +1,35 @@
|
|
1
|
+
# vim: set filetype=ruby et sw=2 ts=2:
|
2
|
+
|
3
|
+
require 'gem_hadar'
|
4
|
+
|
5
|
+
GemHadar do
|
6
|
+
name 'const_conf'
|
7
|
+
module_type :module
|
8
|
+
author 'Florian Frank'
|
9
|
+
email 'flori@ping.de'
|
10
|
+
homepage 'https://github.com/flori/const_conf'
|
11
|
+
summary 'Clean DSL for config settings with validation and Rails integration'
|
12
|
+
description <<~EOT
|
13
|
+
ConstConf is a Ruby configuration library that manages settings
|
14
|
+
through environment variables, files, and directories with comprehensive
|
15
|
+
validation and Rails integration.
|
16
|
+
EOT
|
17
|
+
test_dir 'spec'
|
18
|
+
ignore '.*.sw[pon]', 'pkg', 'Gemfile.lock', '.AppleDouble', '.bundle',
|
19
|
+
'.yardoc', 'doc', 'tags', 'coverage'
|
20
|
+
package_ignore '.all_images.yml', '.gitignore', 'VERSION', '.utilsrc',
|
21
|
+
'.github', *Dir['.contexts/*']
|
22
|
+
readme 'README.md'
|
23
|
+
|
24
|
+
dependency 'tins', '~> 1.42'
|
25
|
+
dependency 'rails', '~> 8'
|
26
|
+
dependency 'json', '~> 2.0'
|
27
|
+
dependency 'complex_config', '~> 0.22'
|
28
|
+
development_dependency 'debug'
|
29
|
+
development_dependency 'rspec', '~> 3.13'
|
30
|
+
development_dependency 'context_spook', '~> 0.3'
|
31
|
+
development_dependency 'all_images', '~> 0.6'
|
32
|
+
development_dependency 'simplecov', '~> 0.22'
|
33
|
+
|
34
|
+
licenses << 'MIT'
|
35
|
+
end
|
data/const_conf.gemspec
ADDED
@@ -0,0 +1,35 @@
|
|
1
|
+
# -*- encoding: utf-8 -*-
|
2
|
+
# stub: const_conf 0.0.0 ruby lib
|
3
|
+
|
4
|
+
Gem::Specification.new do |s|
|
5
|
+
s.name = "const_conf".freeze
|
6
|
+
s.version = "0.0.0".freeze
|
7
|
+
|
8
|
+
s.required_rubygems_version = Gem::Requirement.new(">= 0".freeze) if s.respond_to? :required_rubygems_version=
|
9
|
+
s.require_paths = ["lib".freeze]
|
10
|
+
s.authors = ["Florian Frank".freeze]
|
11
|
+
s.date = "1980-01-02"
|
12
|
+
s.description = "ConstConf is a Ruby configuration library that manages settings\nthrough environment variables, files, and directories with comprehensive\nvalidation and Rails integration.\n".freeze
|
13
|
+
s.email = "flori@ping.de".freeze
|
14
|
+
s.extra_rdoc_files = ["README.md".freeze, "lib/const_conf.rb".freeze, "lib/const_conf/dir_plugin.rb".freeze, "lib/const_conf/env_dir_extension.rb".freeze, "lib/const_conf/errors.rb".freeze, "lib/const_conf/file_plugin.rb".freeze, "lib/const_conf/json_plugin.rb".freeze, "lib/const_conf/railtie.rb".freeze, "lib/const_conf/setting.rb".freeze, "lib/const_conf/setting_accessor.rb".freeze, "lib/const_conf/tree.rb".freeze, "lib/const_conf/version.rb".freeze, "lib/const_conf/yaml_plugin.rb".freeze]
|
15
|
+
s.files = ["Gemfile".freeze, "LICENSE".freeze, "README.md".freeze, "Rakefile".freeze, "const_conf.gemspec".freeze, "lib/const_conf.rb".freeze, "lib/const_conf/dir_plugin.rb".freeze, "lib/const_conf/env_dir_extension.rb".freeze, "lib/const_conf/errors.rb".freeze, "lib/const_conf/file_plugin.rb".freeze, "lib/const_conf/json_plugin.rb".freeze, "lib/const_conf/railtie.rb".freeze, "lib/const_conf/setting.rb".freeze, "lib/const_conf/setting_accessor.rb".freeze, "lib/const_conf/tree.rb".freeze, "lib/const_conf/version.rb".freeze, "lib/const_conf/yaml_plugin.rb".freeze, "spec/assets/.env/API_KEY".freeze, "spec/assets/config.json".freeze, "spec/assets/config.yml".freeze, "spec/assets/config_env.yml".freeze, "spec/const_conf/dir_plugin_spec.rb".freeze, "spec/const_conf/env_dir_extension_spec.rb".freeze, "spec/const_conf/file_plugin_spec.rb".freeze, "spec/const_conf/json_plugin_spec.rb".freeze, "spec/const_conf/setting_accessor_spec.rb".freeze, "spec/const_conf/setting_spec.rb".freeze, "spec/const_conf/tree_spec.rb".freeze, "spec/const_conf/yaml_plugin_spec.rb".freeze, "spec/const_conf_spec.rb".freeze, "spec/spec_helper.rb".freeze]
|
16
|
+
s.homepage = "https://github.com/flori/const_conf".freeze
|
17
|
+
s.licenses = ["MIT".freeze]
|
18
|
+
s.rdoc_options = ["--title".freeze, "ConstConf - Clean DSL for config settings with validation and Rails integration".freeze, "--main".freeze, "README.md".freeze]
|
19
|
+
s.rubygems_version = "3.6.9".freeze
|
20
|
+
s.summary = "Clean DSL for config settings with validation and Rails integration".freeze
|
21
|
+
s.test_files = ["spec/const_conf/dir_plugin_spec.rb".freeze, "spec/const_conf/env_dir_extension_spec.rb".freeze, "spec/const_conf/file_plugin_spec.rb".freeze, "spec/const_conf/json_plugin_spec.rb".freeze, "spec/const_conf/setting_accessor_spec.rb".freeze, "spec/const_conf/setting_spec.rb".freeze, "spec/const_conf/tree_spec.rb".freeze, "spec/const_conf/yaml_plugin_spec.rb".freeze, "spec/const_conf_spec.rb".freeze, "spec/spec_helper.rb".freeze]
|
22
|
+
|
23
|
+
s.specification_version = 4
|
24
|
+
|
25
|
+
s.add_development_dependency(%q<gem_hadar>.freeze, ["~> 2.1".freeze])
|
26
|
+
s.add_development_dependency(%q<debug>.freeze, [">= 0".freeze])
|
27
|
+
s.add_development_dependency(%q<rspec>.freeze, ["~> 3.13".freeze])
|
28
|
+
s.add_development_dependency(%q<context_spook>.freeze, ["~> 0.3".freeze])
|
29
|
+
s.add_development_dependency(%q<all_images>.freeze, ["~> 0.6".freeze])
|
30
|
+
s.add_development_dependency(%q<simplecov>.freeze, ["~> 0.22".freeze])
|
31
|
+
s.add_runtime_dependency(%q<tins>.freeze, ["~> 1.42".freeze])
|
32
|
+
s.add_runtime_dependency(%q<rails>.freeze, ["~> 8".freeze])
|
33
|
+
s.add_runtime_dependency(%q<json>.freeze, ["~> 2.0".freeze])
|
34
|
+
s.add_runtime_dependency(%q<complex_config>.freeze, ["~> 0.22".freeze])
|
35
|
+
end
|
@@ -0,0 +1,175 @@
|
|
1
|
+
# A module that provides functionality for reading file contents from
|
2
|
+
# configuration directories, supporting XDG Base Directory Specification
|
3
|
+
# compliance.
|
4
|
+
#
|
5
|
+
# The DirPlugin extends the ConstConf::Setting class to enable configuration
|
6
|
+
# settings that are sourced from files within named directories. This allows
|
7
|
+
# for more complex and secure configuration management, particularly useful for
|
8
|
+
# storing sensitive data or structured configs in files rather than environment
|
9
|
+
# variables.
|
10
|
+
#
|
11
|
+
# @example Basic usage with file reading
|
12
|
+
# module APP
|
13
|
+
# include ConstConf
|
14
|
+
# plugin ConstConf::DirPlugin
|
15
|
+
#
|
16
|
+
# CONFIG_FILE = set do
|
17
|
+
# description 'Configuration from file'
|
18
|
+
# default dir('myapp', 'config.yaml')
|
19
|
+
# decoding { |s| YAML.load(s) }
|
20
|
+
# end
|
21
|
+
# end
|
22
|
+
#
|
23
|
+
# @example XDG-compliant directory structure
|
24
|
+
# module APP
|
25
|
+
# include ConstConf
|
26
|
+
# plugin ConstConf::DirPlugin
|
27
|
+
#
|
28
|
+
# XDG_CONFIG_HOME = set do
|
29
|
+
# description 'XDG Config HOME'
|
30
|
+
# prefix ''
|
31
|
+
# end
|
32
|
+
#
|
33
|
+
# API_KEY = set do
|
34
|
+
# description 'API Key from XDG config'
|
35
|
+
# default dir('myapp', 'api_key.txt', env_var: APP::XDG_CONFIG_HOME?)
|
36
|
+
# end
|
37
|
+
# end
|
38
|
+
#
|
39
|
+
# @see ConstConf::Setting
|
40
|
+
module ConstConf::DirPlugin
|
41
|
+
# A configuration directory handler that provides methods for deriving
|
42
|
+
# directory paths, joining paths, and reading file contents from a specified
|
43
|
+
# directory structure.
|
44
|
+
#
|
45
|
+
# The ConfigDir class is designed to work with the XDG Base Directory
|
46
|
+
# Specification and supports reading files from directories with optional
|
47
|
+
# environment variable configuration for the root path. It provides a clean
|
48
|
+
# interface for accessing configuration files in a structured way.
|
49
|
+
class ConfigDir
|
50
|
+
# Initializes a new instance with a name and environment variable
|
51
|
+
# configuration.
|
52
|
+
#
|
53
|
+
# @param name [String] the name used to derive the directory path
|
54
|
+
# @param root_path [String, nil] the root path to use for deriving the directory path
|
55
|
+
# @param env_var [String, nil] the environment variable value to use
|
56
|
+
# @param env_var_name [String, nil] the name of the environment variable to look up
|
57
|
+
#
|
58
|
+
# @raise [ArgumentError] if env_var and env_var_name were given.
|
59
|
+
def initialize(name, root_path: nil, env_var:, env_var_name: nil)
|
60
|
+
!env_var.nil? && !env_var_name.nil? and
|
61
|
+
raise ArgumentError,
|
62
|
+
"need either the value of an env_var or the name env_var_name of an env_var"
|
63
|
+
if env_var.nil? && !env_var_name.nil?
|
64
|
+
env_var = ENV[env_var_name]
|
65
|
+
end
|
66
|
+
root_path ||= env_var
|
67
|
+
@directory_path = derive_directory_path(name, root_path)
|
68
|
+
end
|
69
|
+
|
70
|
+
# Returns the string representation of the configuration directory path.
|
71
|
+
#
|
72
|
+
# @return [ String ] the path of the configuration directory as a string
|
73
|
+
def to_s
|
74
|
+
@directory_path.to_s
|
75
|
+
end
|
76
|
+
|
77
|
+
# Joins the directory path with the given path and returns the combined
|
78
|
+
# result.
|
79
|
+
#
|
80
|
+
# @param path [ String ] the path to be joined with the directory path
|
81
|
+
#
|
82
|
+
# @return [ Pathname ] the combined path as a Pathname object
|
83
|
+
def join(path)
|
84
|
+
@directory_path + path
|
85
|
+
end
|
86
|
+
alias + join
|
87
|
+
|
88
|
+
# Reads the content of a file at the given path within the configuration
|
89
|
+
# directory.
|
90
|
+
#
|
91
|
+
# If the file exists, it returns the file's content as a string encoded in
|
92
|
+
# UTF-8. If a block is given and the file exists, it opens the file and
|
93
|
+
# yields to the block.
|
94
|
+
# If the file does not exist and a default value is provided, it returns
|
95
|
+
# the default. If a block is given and the file does not exist, it yields a
|
96
|
+
# StringIO object containing
|
97
|
+
# the default value to the block.
|
98
|
+
#
|
99
|
+
# @param path [ String ] the path to the file relative to the configuration
|
100
|
+
# directory
|
101
|
+
# @param default [ String, nil ] the default value to return if the file
|
102
|
+
# does not exist
|
103
|
+
#
|
104
|
+
# @yield [ io ]
|
105
|
+
#
|
106
|
+
# @return [ String, nil ] the content of the file or the default value if
|
107
|
+
# the file does not exist
|
108
|
+
def read(path, default: nil, required: false, &block)
|
109
|
+
full_path = join(path)
|
110
|
+
if File.exist?(full_path)
|
111
|
+
if block
|
112
|
+
File.open(full_path, &block)
|
113
|
+
else
|
114
|
+
File.read(full_path, encoding: 'UTF-8')
|
115
|
+
end
|
116
|
+
else
|
117
|
+
required and raise ConstConf::RequiredValueNotConfigured,
|
118
|
+
"require file at #{full_path.to_s.inspect}"
|
119
|
+
if default && block
|
120
|
+
block.(StringIO.new(default))
|
121
|
+
else
|
122
|
+
default
|
123
|
+
end
|
124
|
+
end
|
125
|
+
end
|
126
|
+
|
127
|
+
private
|
128
|
+
|
129
|
+
# Derives the full directory path by combining the root path and the given
|
130
|
+
# name.
|
131
|
+
#
|
132
|
+
# @param name [ String ] the name of the directory to be appended to the root path
|
133
|
+
# @param root_path [ String, nil ] the root path to use; if nil, the default root path is used
|
134
|
+
#
|
135
|
+
# @return [ Pathname ] the combined directory path as a Pathname object
|
136
|
+
def derive_directory_path(name, root_path)
|
137
|
+
root = if path = root_path
|
138
|
+
Pathname.new(path)
|
139
|
+
else
|
140
|
+
Pathname.new(default_root_path)
|
141
|
+
end
|
142
|
+
root + name
|
143
|
+
end
|
144
|
+
|
145
|
+
# Returns the default configuration directory path based on the HOME
|
146
|
+
# environment variable.
|
147
|
+
#
|
148
|
+
# This method constructs and returns a Pathname object pointing to the
|
149
|
+
# standard configuration directory location, which is typically
|
150
|
+
# $HOME/.config.
|
151
|
+
#
|
152
|
+
# @return [ Pathname ] the default configuration directory path
|
153
|
+
def default_root_path
|
154
|
+
Pathname.new(ENV.fetch('HOME')) + '.config'
|
155
|
+
end
|
156
|
+
end
|
157
|
+
|
158
|
+
# The dir method creates and reads a configuration directory setting.
|
159
|
+
#
|
160
|
+
# This method initializes a ConfigDir instance with the provided name and
|
161
|
+
# environment variable configuration, then reads the directory path with
|
162
|
+
# optional default and required validation settings.
|
163
|
+
#
|
164
|
+
# @param name [String] the name of the configuration directory
|
165
|
+
# @param path [String] the filesystem path to the directory
|
166
|
+
# @param env_var [String, nil] the environment variable name to use for configuration
|
167
|
+
# @param env_var_name [String, nil] the full environment variable name to use
|
168
|
+
# @param default [Object] the default value to use when no configuration is provided
|
169
|
+
# @param required [Boolean] whether the directory path is required to exist
|
170
|
+
#
|
171
|
+
# @return [Object] the result of reading path from the directory name
|
172
|
+
def dir(name, path, env_var: nil, env_var_name: nil, default: nil, required: false)
|
173
|
+
ConfigDir.new(name, env_var:, env_var_name:).read(path, default:, required:)
|
174
|
+
end
|
175
|
+
end
|
@@ -0,0 +1,83 @@
|
|
1
|
+
# An extension that enables loading environment variable values from files in
|
2
|
+
# a directory structure, where each file's basename becomes an environment
|
3
|
+
# variable name.
|
4
|
+
#
|
5
|
+
# This extension is particularly useful for implementing a pattern, where each
|
6
|
+
# environment variable is stored in its own file with the same name as the
|
7
|
+
# variable. For example:
|
8
|
+
#
|
9
|
+
# ./env/DATABASE_URL # contains: postgresql://localhost/myapp
|
10
|
+
# ./env/API_KEY # contains: sk-1234567890abcdef1234567890abcdef
|
11
|
+
#
|
12
|
+
# Usage:
|
13
|
+
# module AppConfig
|
14
|
+
# include ConstConf
|
15
|
+
#
|
16
|
+
# description 'Application Configuration'
|
17
|
+
#
|
18
|
+
# module EnvDir
|
19
|
+
# extend ConstConf::EnvDirExtension
|
20
|
+
#
|
21
|
+
# description 'All variables loaded from .env directory'
|
22
|
+
#
|
23
|
+
# # Load all environment variables from .env/*
|
24
|
+
# load_dotenv_dir('.env/*') {}
|
25
|
+
# end
|
26
|
+
# end
|
27
|
+
#
|
28
|
+
# The loaded settings are automatically:
|
29
|
+
# - Marked as sensitive (since they might contain secrets)
|
30
|
+
# - Required (files must exist to be loaded)
|
31
|
+
# - Chomped to remove trailing whitespace
|
32
|
+
# - Named using the file basename in uppercase and without a prefix.
|
33
|
+
#
|
34
|
+
# This extension works well alongside manually-defined settings, if you put it
|
35
|
+
# into a nested module at the end of your ConstConf config. Settings defined
|
36
|
+
# explicitly with `set do` blocks before this module take precedence over
|
37
|
+
# auto-loaded ones, allowing for a hybrid approach where critical configuration
|
38
|
+
# is documented and validated, while additional environment variables can be
|
39
|
+
# loaded automatically from files.
|
40
|
+
#
|
41
|
+
# The loaded settings appear in AppConfig.view() with proper descriptions
|
42
|
+
# showing their source file locations, making it easy to see what configuration
|
43
|
+
# is being used.
|
44
|
+
module ConstConf::EnvDirExtension
|
45
|
+
include ConstConf::FilePlugin
|
46
|
+
|
47
|
+
# Loads environment variable values from dotenv-style files into
|
48
|
+
# configuration constants.
|
49
|
+
#
|
50
|
+
# This method processes glob patterns to find files, reads their content
|
51
|
+
# using the FilePlugin, and defines configuration settings for each file's
|
52
|
+
# content. It automatically creates constants with uppercase names based on
|
53
|
+
# the filename and configures them as required and sensitive settings with
|
54
|
+
# chomped values.
|
55
|
+
#
|
56
|
+
# @param globs [Array<String>] glob patterns to match files containing environment variables
|
57
|
+
# @yield [ binding ] yields the binding of the caller to allow evaluation in the correct context
|
58
|
+
# @yieldparam binding [Binding] the binding to evaluate constants in
|
59
|
+
def load_dotenv_dir(*globs, &block)
|
60
|
+
block or raise ArgumentError, '&block argument is required'
|
61
|
+
globs.each do |glob|
|
62
|
+
Dir[glob].each do |path|
|
63
|
+
my_file = file(path, required: true)
|
64
|
+
eval('self', block.__send__(:binding)).class_eval do
|
65
|
+
name = File.basename(path).upcase
|
66
|
+
const_set(
|
67
|
+
name,
|
68
|
+
set do
|
69
|
+
prefix ''
|
70
|
+
description "Value of #{name.inspect} from #{File.dirname(path).inspect}"
|
71
|
+
default my_file
|
72
|
+
decode(&:chomp)
|
73
|
+
required true
|
74
|
+
sensitive true
|
75
|
+
end
|
76
|
+
)
|
77
|
+
rescue ConstConf::SettingAlreadyDefined
|
78
|
+
end
|
79
|
+
end
|
80
|
+
end
|
81
|
+
self
|
82
|
+
end
|
83
|
+
end
|
@@ -0,0 +1,93 @@
|
|
1
|
+
# A module that defines custom exception classes for configuration-related
|
2
|
+
# errors in the ConstConf system. ConstConf::Errors is then included in
|
3
|
+
# ConstConf.
|
4
|
+
#
|
5
|
+
# This module provides a hierarchy of exception classes that are used
|
6
|
+
# throughout the ConstConf configuration management library to signal various
|
7
|
+
# types of configuration issues, such as missing required values or
|
8
|
+
# descriptions. These exceptions help ensure that applications using ConstConf
|
9
|
+
# are properly configured and can handle configuration errors gracefully.
|
10
|
+
#
|
11
|
+
# @example Handling configuration errors
|
12
|
+
# begin
|
13
|
+
# # Code that may raise a ConstConf::ConfigurationError
|
14
|
+
# rescue ConstConf::ConfigurationError => e
|
15
|
+
# # Handle the configuration error appropriately
|
16
|
+
# end
|
17
|
+
module ConstConf::Errors
|
18
|
+
# A base exception class for configuration-related errors in the ConstConf module.
|
19
|
+
#
|
20
|
+
# This class serves as the parent class for all custom exceptions raised within
|
21
|
+
# the ConstConf configuration management system. It provides a common ancestor
|
22
|
+
# for exception handling and allows for specific configuration error types to
|
23
|
+
# be distinguished from general errors.
|
24
|
+
#
|
25
|
+
# @example Handling a configuration error
|
26
|
+
# begin
|
27
|
+
# # Code that may raise a ConstConf::ConfigurationError
|
28
|
+
# rescue ConstConf::ConfigurationError => e
|
29
|
+
# # Handle the configuration error appropriately
|
30
|
+
# end
|
31
|
+
class ConfigurationError < StandardError; end
|
32
|
+
|
33
|
+
# A custom exception class used to signal that a required configuration value
|
34
|
+
# has not been provided.
|
35
|
+
#
|
36
|
+
# This exception is raised when a configuration setting marked as required
|
37
|
+
# has not been configured with a valid value, helping to ensure that
|
38
|
+
# essential application settings are properly defined before runtime.
|
39
|
+
#
|
40
|
+
# @example Handling a required configuration error
|
41
|
+
# begin
|
42
|
+
# # Code that may raise RequiredValueNotConfigured
|
43
|
+
# rescue RequiredValueNotConfigured => e
|
44
|
+
# # Handle the missing required configuration
|
45
|
+
# end
|
46
|
+
class RequiredValueNotConfigured < ConfigurationError ; end
|
47
|
+
|
48
|
+
# A custom exception class used to signal that a required configuration
|
49
|
+
# description has not been provided.
|
50
|
+
#
|
51
|
+
# This exception is raised when essential application settings are not
|
52
|
+
# properly documented before runtime.
|
53
|
+
#
|
54
|
+
# @example Handling a required description error
|
55
|
+
# begin
|
56
|
+
# # Code that may raise RequiredDescriptionNotConfigured
|
57
|
+
# rescue RequiredDescriptionNotConfigured => e
|
58
|
+
# # Handle the missing required configuration description
|
59
|
+
# end
|
60
|
+
class RequiredDescriptionNotConfigured < ConfigurationError ; end
|
61
|
+
|
62
|
+
# A custom exception class raised when a configuration setting is defined
|
63
|
+
# more than once in the ConstConf system.
|
64
|
+
#
|
65
|
+
# This exception is used to prevent duplicate configuration settings from
|
66
|
+
# being registered, ensuring that each environment variable name maps to a
|
67
|
+
# single configuration value within a given module hierarchy.
|
68
|
+
#
|
69
|
+
# @example Handling a duplicate setting definition
|
70
|
+
# begin
|
71
|
+
# # Code that would cause a SettingAlreadyDefined error
|
72
|
+
# rescue ConstConf::SettingAlreadyDefined => e
|
73
|
+
# # Handle the duplicate setting appropriately
|
74
|
+
# end
|
75
|
+
class SettingAlreadyDefined < ConfigurationError; end
|
76
|
+
|
77
|
+
# A custom exception class raised when a configuration setting's confirmation
|
78
|
+
# check fails.
|
79
|
+
#
|
80
|
+
# This exception is used to signal that a configuration setting has failed its
|
81
|
+
# confirmation check, which is a custom validation logic defined for the setting.
|
82
|
+
# It inherits from ConfigurationError and is part of the error handling mechanism
|
83
|
+
# within the ConstConf system to ensure settings meet specific criteria beyond
|
84
|
+
# basic required and default value checks.
|
85
|
+
#
|
86
|
+
# @example Handling a setting check failure
|
87
|
+
# begin
|
88
|
+
# # Code that may raise SettingCheckFailed
|
89
|
+
# rescue ConstConf::SettingCheckFailed => e
|
90
|
+
# # Handle the failed validation check appropriately
|
91
|
+
# end
|
92
|
+
class SettingCheckFailed < ConfigurationError; end
|
93
|
+
end
|
@@ -0,0 +1,33 @@
|
|
1
|
+
# A module that provides functionality for reading file contents as
|
2
|
+
# configuration values.
|
3
|
+
#
|
4
|
+
# The FilePlugin module extends the ConstConf::Setting class to enable
|
5
|
+
# configuration settings that are sourced from file contents rather than
|
6
|
+
# environment variables. This allows for more complex configuration data, such
|
7
|
+
# as SSL certificates or API keys, to be loaded from files and used within the
|
8
|
+
# application's configuration system.
|
9
|
+
module ConstConf::FilePlugin
|
10
|
+
# Reads the content of a file and returns it as a string.
|
11
|
+
#
|
12
|
+
# This method attempts to read the contents of a file specified by the given
|
13
|
+
# path. If the file exists, its content is returned as a string. If the file
|
14
|
+
# does not exist and the required flag is set to true, a
|
15
|
+
# RequiredValueNotConfigured exception is raised.
|
16
|
+
#
|
17
|
+
# @param path [String] the filesystem path to the file to be read
|
18
|
+
# @param required [Boolean] whether the file is required to exist, defaults to false
|
19
|
+
#
|
20
|
+
# @return [String, nil] the content of the file if it exists, or nil if it
|
21
|
+
# doesn't and required is false
|
22
|
+
#
|
23
|
+
# @raise [ConstConf::RequiredValueNotConfigured] if the file does not exist
|
24
|
+
# and required is true
|
25
|
+
def file(path, required: false)
|
26
|
+
if File.exist?(path)
|
27
|
+
File.read(path)
|
28
|
+
elsif required
|
29
|
+
raise ConstConf::RequiredValueNotConfigured,
|
30
|
+
"file required at path #{path.to_s.inspect}"
|
31
|
+
end
|
32
|
+
end
|
33
|
+
end
|
@@ -0,0 +1,12 @@
|
|
1
|
+
require 'json'
|
2
|
+
|
3
|
+
module ConstConf::JSONPlugin
|
4
|
+
def json(path, required: false, object_class: JSON::GenericObject)
|
5
|
+
if File.exist?(path)
|
6
|
+
JSON.load_file(path, object_class:)
|
7
|
+
elsif required
|
8
|
+
raise ConstConf::RequiredValueNotConfigured,
|
9
|
+
"JSON file required at path #{path.to_s.inspect}"
|
10
|
+
end
|
11
|
+
end
|
12
|
+
end
|
@@ -0,0 +1,13 @@
|
|
1
|
+
# A Railtie implementation that integrates ConstConf with Rails application
|
2
|
+
# initialization.
|
3
|
+
#
|
4
|
+
# This class ensures that configuration settings defined through ConstConf are
|
5
|
+
# properly reloaded and synchronized when the Rails application prepares its
|
6
|
+
# configuration, maintaining thread safety during the process.
|
7
|
+
#
|
8
|
+
# @example
|
9
|
+
# This Railtie is automatically included in a Rails application when the
|
10
|
+
# ConstConf gem is loaded, requiring no explicit usage in application code.
|
11
|
+
class ConstConf::Railtie < Rails::Railtie
|
12
|
+
config.to_prepare { ConstConf.reload }
|
13
|
+
end
|