
Security News
New Website “Is It Really FOSS?” Tracks Transparency in Open Source Distribution Models
A new site reviews software projects to reveal if they’re truly FOSS, making complex licensing and distribution models easy to understand.
h1. Configliere
Configliere provides discreet configuration for ruby scripts.
bq. So, Consigliere of mine, I think you should tell your Don what everyone knows. -- Don Corleone
You've got a script. It's got some settings. Some settings are for this module, some are for that module. Most of them don't change. Except on your laptop, where the paths are different. Or when you're in production mode. Or when you're testing from the command line.
Configliere manages settings from many sources: static constants, simple config files, environment variables, commandline options, straight ruby. You don't have to predefine anything, but you can ask configliere to type-convert, require, document or password-obscure any of its fields. Basically: Settings go in, the right thing happens.
!https://secure.travis-ci.org/mrflip/configliere.png?branch=master(Build Status)!:http://travis-ci.org/mrflip/configliere
h2. Example
Here's a simple example, using params from a config file and the command line. In the script:
#/usr/bin/env ruby require 'configliere' Settings.use :commandline # Supply defaults inline. Settings({ :dest_time => '11-05-1955', :delorean => { :power_source => 'plutonium', :roads_needed => true, }, :username => 'marty', }) # Pre-defining params isn't required, but it's easy and expressive to do so: Settings.define :dest_time, :type => DateTime, :description => "Target date" # This defines a 'deep key': it controls Settings[:delorean][:roads_needed] Settings.define 'delorean.roads_needed', :type => :boolean # The settings in this file will be merged with the above Settings.read './examples/simple_script.yaml' # resolve! the settings: load the commandline, do type conversion, etc. Settings.resolve! p Settings
We'll override some of the defaults with a config file, in this case ./examples/simple_script.yaml
# Settings for return :dest_time: 11-05-1985 :delorean: :power_source: 1.21 jiggawatts
Output, when run with commandline parameters as shown:
./time_machine.rb --username=doc_brown --delorean.roads_needed="" --delorean.power_source="Mr. Fusion" {:delorean => {:power_source=>"Mr. Fusion", :roads_needed=>nil}, :username=>"doc_brown", :dest_time=>#}
For an extensive usage in production, see the "wukong gem.":http://github.com/mrflip/wukong
h2. Notice
Configliere 4.x now has 100% spec coverage, more powerful commandline handling, zero required dependencies. However, it also strips out several obscure features and much magical code, which breaks said obscure features and magic-dependent code. See the "CHANGELOG.":CHANGELOG.textile for details as you upgrade.
h2. Design goals:
$ cat ./shorty.rb require 'configliere' Settings.use(:commandline).resolve! p [Settings, Settings.rest] $ ./shorty.rb --foo=bar go [{:foo=>"bar"}, ["go"]]
Be willing to sit down with the Five Families. Takes settings from (at your option): ** Pre-defined defaults from constants ** Simple config files ** Environment variables ** Commandline options and git-style command runners ** Ruby block (called when all other options are in place)
Don't go outside the family. Has no dependencies and requires almost no code in your script. Configliere makes no changes to standard ruby classes.
Offer discreet counsel. Configliere offers many features, but only loads the code you request explicitly by calling @use@.
Don't mess with my crew. Settings for a model over here can be done independently of settings for a model over there, and don't require asking the boss to set something up. You centralize configuration values while distributing configuration definition:
# In lib/handler/mysql.rb Settings.define :mysql_host, :type => String, :description => "MySQL db hostname", :default => 'localhost' # In app/routes/homepage.rb Settings.define :background_color, :description => "Homepage background color" # In config/app.yaml --- :background_color: '#eee' :mysql_host: 'brains.infochimps.com'
You can decentralize even more by giving modules their own config files or separate Configliere::Param objects.
fuhgeddaboudit.
h2. Settings structure
A Configliere settings object is just a (mostly-)normal hash.
You can define static defaults in your module
Settings({ :dest_time => '11-05-1955', :fluxcapacitor => { :speed => 88, }, :delorean => { :power_source => 'plutonium', :roads_needed => true, }, :username => 'marty', :password => '', })
All simple keys should be symbols. Retrieve the settings as:
# hash keys Settings[:dest_time] #=> '11-05-1955' # deep keys Settings[:delorean][:power_source] #=> 'plutonium' Settings[:delorean][:missing] #=> nil Settings[:delorean][:missing][:fail] #=> raises an error # dotted keys resolve to deep keys Settings['delorean.power_source'] #=> 'plutonium' Settings['delorean.missing'] #=> nil Settings['delorean.missing.fail'] #=> nil # method-like (no deep keys tho, and you have to #define the param; see below) Settings.dest_time #=> '11-05-1955'
h2. Configuration files
Call @Settings.read(filename)@ to read a YAML config file.
# Settings for version II. :dest_time: 11-05-2015 :delorean: :power_source: Mr. Fusion :roads_needed: ~
If a bare filename (no '/') is given, configliere looks for the file in @Configliere::DEFAULT_CONFIG_DIR@ (normally ~/.configliere). Otherwise it loads the given file.
Settings.read('/etc/time_machine.yaml') # looks in /etc/time_machine.yaml Settings.read('time_machine.yaml') # looks in ~/.configliere/time_machine.yaml
As you can see, you're free to use as many config files as you like. Loading a config file sets values immediately, so later-loaded files win out over earlier-loaded ones.
You can save configuration too:
Settings.save!('/etc/time_machine.yaml') # overwrites /etc/time_machine.yaml Settings.save!('time_machine.yaml') # overwrites ~/.configliere/time_machine.yaml
h2. Command-line parameters
# Head back time_machine --delorean.power_source='1.21 jiggawatt lightning strike' --dest_time=11-05-1985 # (in the time_machine script:) Settings.use(:commandline) Settings.resolve!
Interpretation of command-line parameters:
./my_cmd --filename=bar
good, ./my_cmd --filename bar
bad.Settings.define :filename, :flag => "f"
allows you to say ./my_cmd -f=bar
.Here are some things you don't get:
Settings.define :file, :type => Array
and give a simple comma-separated list.Commandline parameters are demonstrated in "examples/simple_script.rb":http://github.com/mrflip/configliere/tree/master/examples/simple_script.rb and "examples/env_var_script.rb":http://github.com/mrflip/configliere/tree/master/examples/env_var_script.rb
h2. Defined Parameters
You don't have to pre-define parameters, but you can:
Settings.define :dest_time, :type => DateTime, :description => 'Arrival time' Settings.define 'delorean.power_source', :env_var => 'POWER_SOURCE', :description => 'Delorean subsytem supplying power to the Flux Capacitor.' Settings.define :password, :required => true, :encrypted => true
Defined parameters are demonstrated in most of the "example scripts":http://github.com/mrflip/configliere/tree/master/examples
h3. Description
If you define a param's description, besides nicely documenting it within your code the description will be stuffed into the output when the --help commandline option is invoked.
$ ./examples/simple_script usage: simple_script.rb [...--param=val...] Params: --delorean.roads_needed delorean.roads_needed --dest_time=DateTime Date to travel to [Default: 11-05-1955]
h3. Type Conversion
Parameters defined with a @:type@ and will be type-converted when you call @Settings.resolve!@.
Settings.define :dest_time, :type => DateTime Settings.define :fugeddaboudit, :type => Array Settings :fugeddaboudit => 'badabing,badaboom,hey', :dest_time => '11-05-1955' Settings.resolve! Settings[:fugeddaboudit] #=> ['badabing', 'badaboom', 'hey'] Settings[:dest_time] #=> #
Configliere can coerce parameter values to Integer, Float, :boolean, Symbol, Array, Date and DateTime.
h3. Required Parameters
Any required parameter found to be nil raise an error (listing all missing params) when you call Settings.resolve! (See "examples/env_var_script.rb":http://github.com/mrflip/configliere/tree/master/examples/env_var_script.rb)
h3. Environment Variables
Settings.define :dest_time, :env_var => 'DEST_TIME' Settings.define :environment, :env_var => 'RACK_ENV'
h3. Encrypted Parameters
Define a param to be encrypted and invoke Settings.save!. It will use Settings.encrypt_pass (or the ENCRYPT_PASS environment variable) to encrypt the data when it is saved to disk. (see "examples/encrypted_script.rb":http://github.com/mrflip/configliere/tree/master/examples/encrypted_script.rb)
Settings.use :encrypted Settings.define 'amazon.api.key', :encrypted => true Settings 'amazon.api.key' => 'fnord'
In this example, the hash saved to disk will contain @{ :amazon => { :api => { :encrypted_key => "...encrypted val..." } } }@. After reading from disk, #resolve! will recover its original value: @{ :amazon => { :api => { :key => "fnord" } } }@.
bq. There are two kinds of cryptography in this world: cryptography that will stop your kid sister from reading your files, and cryptography that will stop major governments from reading your files. This book is about the latter. -- Preface to Applied Cryptography by Bruce Schneier
Configliere provides the former.
Anyone with access to the script, its config files and its normal launch environment can recover the plaintext password; but it at least doesn't appear when you cat the file while giving a presentation.
h2. Ruby Block
Settings.use :config_block Settings.finally do |c| c.dest_time = (Time.now + 60) if c.username == 'einstein' # you can use hash syntax too c[:dest_time] = (Time.now + 60) if c[:username] == 'einstein' end # # ... rest of setup ... # Settings.resolve! # the finally blocks will be called in order
Configliere 'finally' blocks are invoked when you call @resolve!@. They're guaranteed to be called at the end of the resolve chain, and before the validate chain.
Config blocks are demonstrated in "examples/config_block.rb":http://github.com/mrflip/configliere/tree/master/examples/config_block.rb
h2. Shortcut syntax for deep keys
You can use a 'dotted key' like 'delorean.power_source' as simple notation for a deep key: @Settings['delorean.power_source']@ is equivalent to @Settings[:delorean][:power_source]@. You can use a dotted key in any simple reference:
Settings['delorean.power_source'] = "Mr. Fusion" Settings[:delorean][:power_source] #=> "Mr. Fusion" Settings.delete('delorean.power_source') #=> "Mr. Fusion" Settings #=> { :delorean => {} }
Intermediate keys "auto-vivify" (automatically create any intervening hashes):
Settings['one.two.three'] = "To tha Fo'" # Settings is { :one => { :two => { :three => "To tha Fo'" } }, :delorean => { :power_source => "Mr. Fusion" }
h2. Independent Settings
All of the above examples use the global variable @Settings@, defined in configliere.rb. It really works fine in practice, even where several systems intersect. You're free to define your own settings universe though:
class Wolfman def config @config ||= Configliere::Param.new.use(:commandline).defaults({ :moon => 'full', :nards => true, }) end end teen_wolf = Wolfman.new teen_wolf.config.defaults(:give_me => 'keg of beer') teen_wolf.config #=> {:moon=>"full", :nards=>true, :give_me=>"keg of beer" } Settings #=> {}
Values in here don't overlap with the Settings object or any other settings universe. However, every one that pulls in commandline params gets a full copy of the commandline params.
h2. Project info
h3. Note on Patches/Pull Requests
h3. Copyright
Copyright (c) 2010 mrflip. See LICENSE for details.
FAQs
Unknown package
We found that configliere 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
A new site reviews software projects to reveal if they’re truly FOSS, making complex licensing and distribution models easy to understand.
Security News
Astral unveils pyx, a Python-native package registry in beta, designed to speed installs, enhance security, and integrate deeply with uv.
Security News
The Latio podcast explores how static and runtime reachability help teams prioritize exploitable vulnerabilities and streamline AppSec workflows.