summaryrefslogtreecommitdiff
diff options
context:
space:
mode:
authordanielsdeleo <dan@opscode.com>2013-01-09 17:07:33 -0800
committerdanielsdeleo <dan@opscode.com>2013-01-09 17:07:33 -0800
commitfdce32889d07ede9a9e8d7b61bc547fc03c80979 (patch)
treedfb450726c87f75023b34c4e89fb6c2beb85c952
parentec107485588901683cd649655ef65e744a9c1d96 (diff)
parentea80b5df1d34c6e6dea73330e7f8c253974aad8d (diff)
downloadmixlib-cli-fdce32889d07ede9a9e8d7b61bc547fc03c80979.tar.gz
Merge branch 'CHEF-3497'
-rw-r--r--lib/mixlib/cli.rb76
-rw-r--r--spec/mixlib/cli_spec.rb23
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