README.md in jeckyl-0.3.7 vs README.md in jeckyl-0.4.0

- old
+ new

@@ -1,14 +1,19 @@ #JECKYL -(a.k.a. Jumpin' Ermin's Configurator for Kwick and easY Linux services) +Jeckyl is a versatile configuration file manager. It provides a simple way of defining +and checking configuration parameters (including defaults) that can then be written as ruby in a config file. +It can also be used to add/override parameters from the command line (using optparse) or +even on the fly through an API. It comes with a handy utility that can generate a default +config file, with comments, from the defined config class and check existing config +files. It even creates a markdown file from the config class to make documentation easier. -Jeckyl can be used to create a parameters hash from a simple config file written in Ruby, having run whatever checks you want -on the file to ensure the values passed in are valid. All you need to do is define a class inheriting from Jeckyl, methods for -each parameter, its default, whatever checking rules are appropriate and even a comment for generating templates etc. -This is then used to parse a Ruby config file and create the parameters hash. Jeckyl -comes complete with a utility to check a config file against a given class and to generate a default file for you to tailor. +Jeckyl can be used for simple parameters or complex structures with multiple calls. It provides +a single place to define and check all inputs so that you don't have to include any parameter +checking anywhere else in your code. Classes can be inherited to add further parameters, and +the config file generated by the jeckyl command is conveniently divided to reflect this. Config +files can also be merged so that multiple config files can be used (e.g. local/per-user/system). **GitHub:** [https://github.com/osburn-sharp/jeckyl](https://github.com/osburn-sharp/jeckyl) **RubyDoc:** [http://rubydoc.info/github/osburn-sharp/jeckyl/frames](http://rubydoc.info/github/osburn-sharp/jeckyl/frames) @@ -20,15 +25,14 @@ Jeckyl comes as a gem. It can be installed in the usual way: gem install jeckyl -That is all you need to do. Type 'jeckyl' to see usage and references to documentation. +That is practically all you need to do. Type 'jeckyl' to see usage and references to documentation. -Jeckyl can be used to set the default location for the config files it processes. This will -be '/etc/jeckyl' unless you set the environment varibale 'JECKYL_CONFIG_DIR' to something else. -This could be done on a system-wide basis by include a file with this variable in /etc/env.d. +Otherwise start coding your jeckyl config file. + ## Getting Started To use Jeckyl, create a new parameter class and add a parameter method for each parameter you want to define in your config files. Think of the name of a parameter and prefix this with `configure_`: @@ -219,22 +223,105 @@ use conf.complement(hash) ({Jeckyl::Config#complement}). For example, the Jellog logger defines a set of logging parameters in Jellog::Config. These may be inherited by another service that adds its own parameters (such as Jerbil): - options = Jerbil::Config.new(my_conf) + all_options = Jerbil::Config.new(my_conf) - log_opts = Jellog::Config.intersection(options) + log_opts = Jellog::Config.intersection(all_options) - jerb_opts = options.complement(log_opts) + jerb_opts = all_options.complement(log_opts) -### Some Internal Methods +### Command Line Options - Jeckyl with Optparse +Jeckyl can also process command line options using optparse. This can be easily done by adding an option +method call to your parameter method, which has the same parameters as optparse: + def configure_param_with_option(param) + option_set = [:none, :some, :all] + default :none + comment "Sets the option type to be one of", + " :none - no options", + " :some - some options", + " :all - all options" + + describe "set the option type" + option "-o", "--option Type", option_set + + a_member_of(param, option_set) + end + +The {Jeckyl::Config#describe describe} method allows a short usage style description +over the longer config-file comment, and the {Jeckyl::Config#option} method receives +the same parameters as the optparse#on method less the description bit. + +Adding this to your parameter method does not actually do anything without then parsing +the options: + + # create a config hash + opts = MyConfig.new + # parse command-line options with the default ARGV + opts.optparse + +The {Jeckyl::Config#optparse optparse} method creates and Optparse object with the +options defined in your parameter methods (ignoring those with no option set), adds +a '-c' option for specifying a config file and a -h option for help. It also parses +the results. + +The {Jeckyl::Config#optparse optparse} method can also yield the real Optparse object +into a block where you can add further options unrelated to Jeckyl. The parse! is done +automatically when the block returns. + + # parse them with some extra options added + opts.optparse do |opts| + # receives the same methods as an optparse object + opts.on('-p', '--pretend', 'Do not do anything for real') do + @pretend = true + end + end + # parse! is done automatically at the end of the block + +This does two things: it updates the parameters with option statements from the command line +and it also adds the options in the block but independent of the config object itself. + +A word about the -c option. This is really only added so that it is shown in the help +results. The option is not used by the optparse method for fairly obvious reasons: the +instance method is applied to a config hash so the config file has already been evaluated. +To use the -c option you need to preprocess the command line with a class method: + + # set the default config file + default_config_file = '/etc/my_app/config_file.rb' + # get the config options, if it exists + argv, config_file = MyConfig.get_config_opt(ARGV,default_config_file) + # now use the config file + @config = MyConfig.new(argv, config_file) + +Note that {Jeckyl::Config.get_config_opt} returns the inputs if there is no option. And +at this time it only looks for '-c', so the bit about '--config' is a lie! + +### Using Parameter methods on the fly + +Jeckyl can also be used without a config file, for example as part of an API where the +inputs are coded in. A config class and parameter methods are defined as usual, including +defaults. On the inside of the API, where you might explicitly check inputs, you instead +call the parameter method: + + # somewhere, a default config hash is created + @config = MyConfig.new + + # later, this is used to check a parameter: + @param = @config.param_with_option(param) + + # if the param does not match the config requirements then an exception is called + +This allows you to blend in config files if required and command line options as well. +The only messy bit is that your API will raise {Jeckyl::ConfigError} unless you trap this and then +convert it to your own local exception. + ### Jeckyl::Config < Hash -Finally, note that Jeckyl::Config is itself a subclass of Hash, and therefore Jeckyl config objects inherit +Finally, note that {Jeckyl::Config} is itself a subclass of Hash, and therefore Jeckyl config objects inherit all hash methods as well! ## The 'jeckyl' Command Jeckyl comes with a simple script: bin/jeckyl to help in creating, checking and documenting parameters. @@ -320,44 +407,48 @@ # define a greeting for the application greeting "Hello" There is no greeting method, so method_missing is called instead. This remembers the name of the "missing" method (:greeting), -calls configure_greeting and stores the results in the instances hash. The main reason for doing this (as opposed to just +calls configure_greeting and stores the results in the instance's hash. The main reason for doing this (as opposed to just calling the method 'greeting') is to enable the evaluation of defaults and comments in the context of each parameter method. All of this is private and therefore under the bonnet. ## Dependencies See the {file:Gemfile} for details of dependencies. -Tested on Ruby 1.8.7. +Tested on Ruby 1.9.3_p547 and 2.0.0_p481 (Gentoo 2.1 not yet unmasked at time of +writing - Oct 2014). Tested with RSpec 3.1.0 - see below. ## Testing Jeckyl -There is an rspec test file to test the whole thing (spec/jeckyl_spec.rb). It uses the test subclass in "../test" and -various config files in "../conf.d". There is another rspec file that tests the config_check function. - +There is an rspec test file to test the whole thing (spec/jeckyl_spec.rb). It uses the test subclass in the "test" directory and +various config files in the "test/conf.d" directory. There is another rspec file that tests the config_check function. ## Why did I bother? Having tried various config file solutions, I had ended up using yaml files, but i found checking them very difficult because they are not very friendly and very sensitive to spacing issues. In looking for yet another alternative, I came across the approach used by Unicorn (the backend web machine I now use for Rails apps). I liked the concept but thought it could be made more general, which resulted in Jeckyl. +The name Jeckyl is one of those silly acronyms that means nothing in particular: +Jumpin' Ermin's Configurator for Kwick and easY Linux services + + ## Bugs etc Details of bugs can be found in {file:Bugs.rdoc} ## Author and Contact I am Robert Sharp and you can contact me on [GitHub](http://github.com/osburn-sharp) ## Copyright and Licence -Copyright (c) 2011-2012 Robert Sharp. +Copyright (c) 2011-2014 Robert Sharp. See {file:LICENCE.rdoc LICENCE} for details of the licence under which Jeckyl is released. ## Warranty