SkillAgentSearch skills...

Configliere

Wise, discreet configuration for ruby scripts: integrate config files, environment variables and command line with no fuss

Install / Use

/learn @infochimps-labs/Configliere
About this skill

Quality Score

0/100

Supported Platforms

Universal

README

h1. Configliere

This repository has moved: "infodhimps-platform/configliere":https://github.com/infochimps-platform/configliere All further code work and gems will take place in the above repo, not here.

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:

<pre> #/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 </pre>

We'll override some of the defaults with a config file, in this case ./examples/simple_script.yaml

<pre> # Settings for return :dest_time: 11-05-1985 :delorean: :power_source: 1.21 jiggawatts </pre>

Output, when run with commandline parameters as shown:

<pre> ./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=>#<DateTime: 1985-05-11T00:00:00+00:00>} </pre>

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:

  • Omerta (Code of Silence). Most commandline parsers force you to pre-define all your parameters in a centralized and wordy syntax. In configliere, you don't have to pre-define anything -- commandline parameters map directly to values in the Configliere hash. Here's all you need to have full-fledged commandline params:
<pre> $ cat ./shorty.rb require 'configliere' Settings.use(:commandline).resolve! p [Settings, Settings.rest] $ ./shorty.rb --foo=bar go [{:foo=>"bar"}, ["go"]] </pre>
  • 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:

<pre> # 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' </pre>

You can decentralize even more by giving modules their own config files or separate Configliere::Param objects.

  • Can hide your assets. Rather than storing passwords and API keys in plain sight, configliere has a protection racket that can obscure values when stored to disk.

fuhgeddaboudit.

h2. Settings structure

A Configliere settings object is just a (mostly-)normal hash.

You can define static defaults in your module

<pre> Settings({ :dest_time => '11-05-1955', :fluxcapacitor => { :speed => 88, }, :delorean => { :power_source => 'plutonium', :roads_needed => true, }, :username => 'marty', :password => '', }) </pre>

All simple keys should be symbols. Retrieve the settings as:

<pre> # 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' </pre>

h2. Configuration files

Call @Settings.read(filename)@ to read a YAML config file.

<pre> # Settings for version II. :dest_time: 11-05-2015 :delorean: :power_source: Mr. Fusion :roads_needed: ~ </pre>

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.

<pre> Settings.read('/etc/time_machine.yaml') # looks in /etc/time_machine.yaml Settings.read('time_machine.yaml') # looks in ~/.configliere/time_machine.yaml </pre>

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:

<pre> Settings.save!('/etc/time_machine.yaml') # overwrites /etc/time_machine.yaml Settings.save!('time_machine.yaml') # overwrites ~/.configliere/time_machine.yaml </pre>

h2. Command-line parameters

<pre> # 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! </pre>

Interpretation of command-line parameters:

  • name-val params: @--param=val@ sets @Configliere[:param]@ to val. You must use the '=' in there: <code>./my_cmd --filename=bar</code> good, <code>./my_cmd --filename bar</code> bad.
  • boolean params: @--param@ sets @Configliere[:param]@ to be true. @--param=""@ sets @Configliere[:param]@ to be nil.
  • single-char flags: Define a flag for a variable: <code>Settings.define :filename, :flag => "f"</code> allows you to say <code>./my_cmd -f=bar</code>.
  • scoped params: A dot within a parameter name scopes that parameter: @--group.sub_group.param=val@ sets @Configliere[:group][:subgroup][:param]@ to val (and similarly for boolean parameters). ** Only @[\w.]+@ are accepted in parameter names. '-' is currently accepted but causes a warning.
  • Settings.rest: anything else is stored, in order, in @Settings.rest@.
  • stop marker: a @--@ alone stops parameter processing and tosses all remaining params (not including the @--@) into Settings.rest.

Here are some things you don't get:

  • Configliere doesn't complain about un-@define@'d commandline argvs. However, it does store each undefine'd argv (when resolve! is called) into @unknown_argvs@, so you can decide what to do about it.
  • Apart from converting @''@ (an explicit blank string) to @nil@, no type coercion is performed on parameters unless requested explicitly (see below).
  • No validation is performed on parameters, but you can insert a middleware with a @validate!()@ method, or use a @:finally@ block.
  • No ordering or multiplicity is preserved: you can't say @--file=this --file=that@. Instead, define the param as an array <code>Settings.define :file, :type => Array</code> 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:

<pre> 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 </pre>
  • @:description@: documents a param.
  • @:type@: converts params to a desired form.
  • @:required@: marks params required.
  • @:encrypted@: marks params to be obscured when saved to disk. See [#Encrypted Parameter
View on GitHub
GitHub Stars122
CategoryDevelopment
Updated2y ago
Forks9

Languages

Ruby

Security Score

65/100

Audited on Dec 4, 2023

No findings