
Security News
Deno 2.2 Improves Dependency Management and Expands Node.js Compatibility
Deno 2.2 enhances Node.js compatibility, improves dependency management, adds OpenTelemetry support, and expands linting and task automation for developers.
Provides convenient interface for managing configuration parameters for modules, classes and instances. Requires Ruby version >= 2.1.
To add to an application, add this line to your application's Gemfile:
gem 'configuru'
To add to a gem, add the following line to your gemspec file:
Gem::Specification.new do |spec|
...
spec.add_dependency 'configuru'
...
end
And then execute:
$ bundle
Or install it yourself as:
$ gem install configuru
This gem allows to add convenient configuration API to modules, classes and instances in your gem or application. It is intentially designed to minimize "behind-the-scenes auto-magic" and yet keep it easy to use and the calling code concise.
Here is an example of how Configuru can be used to provide configuration for MyClass
:
require 'configuru'
class MyClass
include Configuru::Configurable
provide_configuration
def_config_param :secret_key, make_string: true, default: (ENV['SECRET_KEY_'] || '???')
def_config_param :color, default: :green,
convert: ->(val) { raise "Huh?" unless [:red,:green].include?(val); val }
def_config_param :percentage, make_float:true, min:0, max:100, default:100
def initialize(options,&block)
configure(options,&block)
configuration.lock
end
end
my_inst = MyClass.new do |config|
config.secret_key = "VERY-SECR-ETKY"
config.color = :red
config.options_source = "/my/path/to/file/with/options.yml"
end
my_inst.configuration.color #=> :red
my_inst.configuration.secret_key #=> "VERY-SECR-ETKY"
my_inst.configuration.percentage #=> 100
To make your class or module configurable you need to do two things:
include Configuru::Configurable
provide_configuration
with an optional parameter as defined below: provide_configuration :base # Using one of these three options will add configuration API
provide_configuration :class # only to your class/module. The individual instances of that class
provide_configuration :module # will not be given any configuration API.
provide_configuration :instances # Using one of these two options will add configuration API to
provide_configuration :instance # individual instances of the class, but not for the class itself.
provide_configuration # Using these options will add configuration API both to the class
provide_configuration :all # and to the instances of that class
The class module, inside which you called provide_configuration
, will get a def_config_param
method for defining possible configuration parameters. This method takes a parameter name and various options for it:
Provide default value for the configuration parameter. The value is evaluated at the time def_config_param
is called. The checks and conversions specified for the parameter (see below) are not applied to the default value.
def_config_param :some_name, default: ""
Prevent the parameter from changing once configuration is locked (see section "Locking configuration" below)
def_config_param :some_name, lockable: true
When setting, check that the value is not nil or not empty. "Not empty" means that both .nil?
and .empty?
for it return false
. Raise ArgumentError exception if the check fails.
def_config_param :some_name, not_nil: true # Check for "not nil"
def_config_param :some_name, not_empty: true # Check for "not empty"
When setting, check that the value is of a certain type (is_a?
returns true). If an array of types is passed, the value must be of any of the types from that array. Raise ArgumentError exception if the check fails.
def_config_param :some_name, must_be: String
def_config_param :some_name, must_be: [IO,File,StringIO]
When setting, perform duck-type-checking. Check that the value resonds to a certain method. If an array of method names is passed, the value must respond to all specified methods. Raise ArgumentError exception if the check fails.
def_config_param :some_name, must_respond_to: :read
def_config_param :some_name, must_respond_to: [:read,:seek]
When setting, convert the value to a specific type
def_config_param :some_name, make_hash: true # Hash(value)
def_config_param :some_name, make_array: true # Array(value)
def_config_param :some_name, make_string: true # String(value)
def_config_param :some_name, make_int: true # value.to_i
def_config_param :some_name, make_float: true # value.to_f
def_config_param :some_name, make_bool: true # !!value
When setting, check that the value is within the specified boundaries. Raise ArgumentError exception if the check fails.
def_config_param :some_name, max: 10 # Raise exception if trying to set value > 10
def_config_param :some_name, min: 0.01 # Raise exception if trying to set value < 0.01
def_config_param :some_name, in: ('a'..'z') # Raise exception unless ('a'..'z').include?(value)
When setting, perform call the conversion method. The original value is passed as the only parameter. The method should either return the converted value, or raise some exception. If a symbol is passed, the method with that name is called on the object under configuration.
class MyClass {
def_config_param :some_name1, convert: :some_conversion
def_config_param :some_name2, convert: ->(x) { x.abs }
}
my_inst = MyClass.new
my_inst.configure( some_name1: "abc" ) # will call my_inst.some_conversion("abc") and assign the result to some_name1 parameter
A single parameter may have several checks and conversions associated with it. If several are defined, they will be applied in the order they are defined in the list above. For example, if the parameter is defined as
class MyClass {
include Configuru::Configurable
provide_configuration :class
def_config_param :myparam, lockable: true, not_nil: true, make_int: true, in: (-3..3), convert: ->(x) { x.abs }
}
If you call MyClass.configure( myparam: "-1" )
then Configuru will:
MyClass.configuration
is not locked yet (and raise exception if it is).myparam
configuration parameter.In this case (unless the configuration was locked) the parameter will eventually be set to 1.
The object that you made configurable using provide_configuration
will get a configuration
method that returns its configuration object. The configuration object has all the parameters defined through def_config_param
as its attributes and allows reading and writing them. The same parameter can be set several times, and each later value replaces the one set earlier.
require 'configuru'
class MyClass
include Configuru::Configurable
provide_configuration :instance
def_config_param :secret_key, make_string: true, default: (ENV['SECRET_KEY_'] || '???')
def_config_param :color, default: :green,
convert: ->(val) { raise "Huh?" unless [:red,:green].include?(val); val }
def_config_param :percentage, make_float:true, min:0, max:100, default:100
end
my_inst = MyClass.new
my_inst.configuration.secret_key = "VERY-SECR-ETKY"
my_inst.configuration.color = :red
my_inst.configuration.color #=> :red
my_inst.configuration.secret_key #=> "VERY-SECR-ETKY"
my_inst.configuration.percentage #=> 100
The object that you made configurable using provide_configuration
also gets a configure
convenience method. The method allows you to either provide configuration parameters as a hash or call the provided block with the configuration object.
require 'configuru'
class MyClass
include Configuru::Configurable
provide_configuration :instance
def_config_param :secret_key, make_string: true, default: (ENV['SECRET_KEY_'] || '???')
def_config_param :color, default: :green,
convert: ->(val) { raise "Huh?" unless [:red,:green].include?(val); val }
def_config_param :percentage, make_float:true, min:0, max:100, default:100
end
my_inst = MyClass.new
# Setting parameters using Hash
my_inst.configure secret_key: "VERY-SECR-ETKY", color: :red
# Setting parameters using the block called on the configuration object
my_inst.configure do |config|
config.secret_key = "VERY-SECR-ETKY"
config.color = :red
end
It is also possible to use Hash and block in the same call to configure. In this case first the Hash will be precessed, then the block will be called. So, any values set in the block will supersede the values set through Hash.
my_inst.configure(color: :red) do |config|
config.secret_key = "VERY-SECR-ETKY"
end
The configuration object can also read configuration from a YAML file using options_source=
call on the configuration object or options_source
key in the Hash provided to configure. The options_source=
can be called several times for a configuration object, and the parameters will be loaded from files in the order they are called. The file reading can also be nested: YAML files themselves may have the options_source
parameter defined inside. As with direct parameter setting, if a parameter is set several times in multiple files, the latest value replaces all previous values.
require 'configuru'
class MyClass
include Configuru::Configurable
provide_configuration :instance
# bunch of def_config_param calls ...
end
my_inst = MyClass.new
# Directly call on the configuraton object - this will load the parameters from the three
# files in the order they are specified
my_inst.configuration.options_source = "/my/path/to/file/with/options1.yml"
my_inst.configuration.options_source = "/my/path/to/file/with/options2.yml"
my_inst.configure do |config|
config.options_source = "/my/path/to/file/with/options3.yml"
end
# Or, pass it as a part of Hash to configure
my_inst.configure options_source: "/my/path/to/file/with/options1.yml"
Using options_source
may be combined with directly setting the parameters. And, again, the values provided later overwrite previously provided values for the same parameter.
my_inst = MyClass.new do |config|
config.secret_key = "VERY-SECR-ETKY"
config.color = :red
config.options_source = "/my/path/to/file/with/options.yml" # will overwrite color and secret_key if defined in YAML
end
The configuration object also has a lock
method. Calling this method prevents the parameters defined as lockable from further changes. The parameters, for which the lockable
option was not set, are not affected. Locking is useful if you somehow cache configuration parameters in other parts of your application/gem, and further changes to the parameter will not affect the configuration behavior.
For example, if one of your parameters is a database name or an AWS access key, once you use this parameter at the beginning of your applicaton to establish connection to the database or get access to your AWS resources, further changes to it won't make your application to reconnect to a different database or start accessing AWS using a different set of credentials. In this case, locking helps to catch configuraton bugs, when the parameter is set or changed too late.
Locking affects all parameters marked as lockable
. There is no locking at individual parameter level.
If a lockable parameter is accessed after lock
has been called, ArgumentError
is raised.
require 'configuru'
class MyClass
include Configuru::Configurable
provide_configuration :instance
def_config_param :database, lockable: true
end
my_inst = MyClass.new
my_inst.configuration.database = 'db_production'
my_inst.configuration.lock
my_inst.configuration.database = 'db_staging' # Raises ArgumentError
It is also possible to unlock the parameters after they were locked by calling lock(false)
. Using the previous example:
my_inst.configuration.database = 'db_production'
my_inst.configuration.lock
my_inst.configuration.database = 'db_staging' # Raises ArgumentError
my_inst.configuration.lock(false)
my_inst.configuration.database = 'db_development' # Works fine
Both lock
and lock(false)
can be called several times. But there is no counter: after calling lock
multiple times, a single lock(false)
would unlock all parameters.
Semantic versioning (http://semver.org/spec/v2.0.0.html) is used.
For a version number MAJOR.MINOR.PATCH, unless MAJOR is 0:
Major version "zero" (0.y.z) is for initial development. Anything may change at any time. The public API should not be considered stable.
Requires Ruby version >= 2.1
The following features may be included in the future versions of this gem, if a need for them is identified. If you'd like to see one of these features or something else implemented in Configuru, please let the authors know.
git checkout -b my-new-feature
)git commit -am 'Add some feature'
)git push origin my-new-feature
)FAQs
Unknown package
We found that configuru demonstrated a not healthy version release cadence and project activity because the last version was released a year ago. It has 1 open source maintainer collaborating on the project.
Did you know?
Socket for GitHub automatically highlights issues in each pull request and monitors the health of all your open source dependencies. Discover the contents of your packages and block harmful activity before you install or update your dependencies.
Security News
Deno 2.2 enhances Node.js compatibility, improves dependency management, adds OpenTelemetry support, and expands linting and task automation for developers.
Security News
React's CRA deprecation announcement sparked community criticism over framework recommendations, leading to quick updates acknowledging build tools like Vite as valid alternatives.
Security News
Ransomware payment rates hit an all-time low in 2024 as law enforcement crackdowns, stronger defenses, and shifting policies make attacks riskier and less profitable.