diff options
author | danielsdeleo <dan@opscode.com> | 2013-01-09 17:07:33 -0800 |
---|---|---|
committer | danielsdeleo <dan@opscode.com> | 2013-01-09 17:07:33 -0800 |
commit | fdce32889d07ede9a9e8d7b61bc547fc03c80979 (patch) | |
tree | dfb450726c87f75023b34c4e89fb6c2beb85c952 | |
parent | ec107485588901683cd649655ef65e744a9c1d96 (diff) | |
parent | ea80b5df1d34c6e6dea73330e7f8c253974aad8d (diff) | |
download | mixlib-cli-fdce32889d07ede9a9e8d7b61bc547fc03c80979.tar.gz |
Merge branch 'CHEF-3497'
-rw-r--r-- | lib/mixlib/cli.rb | 76 | ||||
-rw-r--r-- | spec/mixlib/cli_spec.rb | 23 |
2 files changed, 96 insertions, 3 deletions
diff --git a/lib/mixlib/cli.rb b/lib/mixlib/cli.rb index 4b8275f..bdaabdb 100644 --- a/lib/mixlib/cli.rb +++ b/lib/mixlib/cli.rb @@ -19,8 +19,37 @@ require 'optparse' module Mixlib + + # == Mixlib::CLI + # Adds a DSL for defining command line options and methods for parsing those + # options to the including class. + # + # Mixlib::CLI does some setup in #initialize, so the including class must + # call `super()` if it defines a custom initializer. + # + # === DSL + # When included, Mixlib::CLI also extends the including class with its + # ClassMethods, which define the DSL. The primary methods of the DSL are + # ClassMethods#option, which defines a command line option, and + # ClassMethods#banner, which defines the "usage" banner. + # + # === Parsing + # Command line options are parsed by calling the instance method + # #parse_options. After calling this method, the attribute #config will + # contain a hash of `:option_name => value` pairs. module CLI module ClassMethods + + # When this setting is set to +true+, default values supplied to the + # mixlib-cli DSL will be stored in a separate Hash + def use_separate_default_options(true_or_false) + @separate_default_options = true_or_false + end + + def use_separate_defaults? + @separate_default_options || false + end + # Add a command line option. # # === Parameters @@ -73,7 +102,41 @@ module Mixlib end end - attr_accessor :options, :config, :banner, :opt_parser + # Gives the command line options definition as configured in the DSL. These + # are used by #parse_options to generate the option parsing code. To get + # the values supplied by the user, see #config. + attr_accessor :options + + # A Hash containing the values supplied by command line options. + # + # The behavior and contents of this Hash vary depending on whether + # ClassMethods#use_separate_default_options is enabled. + # ==== use_separate_default_options *disabled* + # After initialization, +config+ will contain any default values defined + # via the mixlib-config DSL. When #parse_options is called, user-supplied + # values (from ARGV) will be merged in. + # ==== use_separate_default_options *enabled* + # After initialization, this will be an empty hash. When #parse_options is + # called, +config+ is populated *only* with user-supplied values. + attr_accessor :config + + # If ClassMethods#use_separate_default_options is enabled, this will be a + # Hash containing key value pairs of `:option_name => default_value` + # (populated during object initialization). + # + # If use_separate_default_options is disabled, it will always be an empty + # hash. + attr_accessor :default_config + + # Banner for the option parser. If the option parser is printed, e.g., by + # `puts opt_parser`, this string will be used as the first line. + attr_accessor :banner + + # The option parser generated from the mixlib-cli DSL. Set to nil on + # initialize; when #parse_options is called +opt_parser+ is set to an + # instance of OptionParser. +opt_parser+ can be used to print a help + # message including the banner and any CLI options via `puts opt_parser`. + attr_accessor :opt_parser # Create a new Mixlib::CLI class. If you override this, make sure you call super! # @@ -85,6 +148,8 @@ module Mixlib def initialize(*args) @options = Hash.new @config = Hash.new + @default_config = Hash.new + @opt_parser = nil # Set the banner @banner = self.class.banner @@ -93,6 +158,13 @@ module Mixlib klass_options = self.class.options klass_options.keys.inject(@options) { |memo, key| memo[key] = klass_options[key].dup; memo } + # If use_separate_defaults? is on, default values go in @default_config + defaults_container = if self.class.use_separate_defaults? + @default_config + else + @config + end + # Set the default configuration values for this instance @options.each do |config_key, config_opts| config_opts[:on] ||= :on @@ -103,7 +175,7 @@ module Mixlib config_opts[:exit] ||= nil if config_opts.has_key?(:default) - @config[config_key] = config_opts[:default] + defaults_container[config_key] = config_opts[:default] end end diff --git a/spec/mixlib/cli_spec.rb b/spec/mixlib/cli_spec.rb index 46ec1cf..39740b4 100644 --- a/spec/mixlib/cli_spec.rb +++ b/spec/mixlib/cli_spec.rb @@ -57,7 +57,7 @@ describe Mixlib::CLI do end end - describe "instance methods" do + context "when configured with default single-config-hash behavior" do before(:each) do @cli = TestCLI.new @@ -214,6 +214,27 @@ describe Mixlib::CLI do end end + context "when configured to separate default options" do + before do + TestCLI.use_separate_default_options true + TestCLI.option(:defaulter, :short => "-D SOMETHING", :default => "this is the default") + @cli = TestCLI.new + end + + it "sets default values on the `default` hash" do + @cli.parse_options([]) + @cli.default_config[:defaulter].should == "this is the default" + @cli.config[:defaulter].should be_nil + end + + it "sets parsed values on the `config` hash" do + @cli.parse_options(%w[-D not-default]) + @cli.default_config[:defaulter].should == "this is the default" + @cli.config[:defaulter].should == "not-default" + end + + end + end |