mixlib-cli 1.5.0 → 1.6.0

This diff represents the content of publicly available package versions that have been released to one of the supported registries. The information contained in this diff is provided for informational purposes only and reflects changes between package versions as they appear in their respective public registries.
checksums.yaml CHANGED
@@ -1,7 +1,7 @@
1
1
  ---
2
2
  SHA1:
3
- metadata.gz: c9f4e332532d344f5c62289e8d814c40b7dc1483
4
- data.tar.gz: 8e1da896405b03061d5e3038e926173251adcb61
3
+ metadata.gz: d2d8c52004fea1ccbbacc8cc9eb27c90319169a7
4
+ data.tar.gz: 02c491e6efbd0311e961fabdfa5104cac182f906
5
5
  SHA512:
6
- metadata.gz: 9530b5336675f3086ddc608eb467e96de001533f769d6f237ac1560668befce1bf4323486160faa2bc36dfdac6b9b28ca182bc51ee5d0aa944bc65984b5ef25b
7
- data.tar.gz: 790307a0522b70171925d00cf47b7fdad02409505f18558fd5021e7edba38a583603fd0797620d0ff9837fcfc6b44405ba80bfcc769165594de74dcaa9e35bd9
6
+ metadata.gz: f0ebca3acd4ff265dc86b78ad542b2400260167345d6d05334359e2e4e575160d26ccaa905e42cc36e8eaecf373ed5f7b6eafc6d0f0e72c8dd9541d6749e4cda
7
+ data.tar.gz: 08c9482a936d10feea1f968effa75beba3f7f0911fa63dbf16755da7d0f674df9f64622f2941050ea7a16ed71efd4b963b7715956b819f67362469668b0d7d71
data/Gemfile ADDED
@@ -0,0 +1,3 @@
1
+ source "https://rubygems.org"
2
+
3
+ gemspec
data/NOTICE CHANGED
@@ -1,27 +1,26 @@
1
1
  Mixin::CLI NOTICE
2
2
  =================
3
3
 
4
- Developed at Opscode (http://www.opscode.com).
4
+ Developed at Chef (http://www.chef.io).
5
5
 
6
- * Copyright 2009, Opscode, Inc. <legal@opscode.com>
6
+
7
+ * Copyright 2009-2016, Chef Software, Inc. <legal@chef.io>
7
8
 
8
9
  Mixin::CLI incorporates code from Chef. The Chef notice file follows:
9
10
 
10
11
  Chef NOTICE
11
12
  ===========
12
13
 
13
- Developed at Opscode (http://www.opscode.com).
14
+ Developed at Chef (http://www.chef.io).
14
15
 
15
16
  Contributors and Copyright holders:
16
17
 
17
- * Copyright 2008, Adam Jacob <adam@opscode.com>
18
+ * Copyright 2008, Adam Jacob <adam@chef.io>
18
19
  * Copyright 2008, Arjuna Christensen <aj@hjksolutions.com>
19
20
  * Copyright 2008, Bryan McLellan <btm@loftninjas.org>
20
21
  * Copyright 2008, Ezra Zygmuntowicz <ezra@engineyard.com>
21
22
  * Copyright 2009, Sean Cribbs <seancribbs@gmail.com>
22
- * Copyright 2009, Christopher Brown <cb@opscode.com>
23
+ * Copyright 2009, Christopher Brown <cb@chef.io>
23
24
  * Copyright 2009, Thom May <thom@clearairturbulence.org>
24
25
 
25
26
  Chef incorporates code modified from Open4 (http://www.codeforpeople.com/lib/ruby/open4/), which was written by Ara T. Howard.
26
-
27
- Chef incorporates code modified from Merb (http://www.merbivore.com), which is Copyright (c) 2008 Engine Yard.
@@ -0,0 +1,109 @@
1
+ # Mixlib::CLI
2
+
3
+ [![Build Status Master](https://travis-ci.org/chef/mixlib-cli.svg?branch=master)](https://travis-ci.org/chef/mixlib-cli) [![Gem Version](https://badge.fury.io/rb/mixlib-cli.svg)](https://badge.fury.io/rb/mixlib-cli)
4
+
5
+ Mixlib::CLI provides a class-based command line option parsing object, like the one used in Chef, Ohai and Relish. To use in your project:
6
+
7
+ ```ruby
8
+ require 'rubygems'
9
+ require 'mixlib/cli'
10
+
11
+ class MyCLI
12
+ include Mixlib::CLI
13
+
14
+ option :config_file,
15
+ :short => "-c CONFIG",
16
+ :long => "--config CONFIG",
17
+ :default => 'config.rb',
18
+ :description => "The configuration file to use"
19
+
20
+ option :log_level,
21
+ :short => "-l LEVEL",
22
+ :long => "--log_level LEVEL",
23
+ :description => "Set the log level (debug, info, warn, error, fatal)",
24
+ :required => true,
25
+ :in => ['debug', 'info', 'warn', 'error', 'fatal'],
26
+ :proc => Proc.new { |l| l.to_sym }
27
+
28
+ option :help,
29
+ :short => "-h",
30
+ :long => "--help",
31
+ :description => "Show this message",
32
+ :on => :tail,
33
+ :boolean => true,
34
+ :show_options => true,
35
+ :exit => 0
36
+
37
+ end
38
+
39
+ # ARGV = [ '-c', 'foo.rb', '-l', 'debug' ]
40
+ cli = MyCLI.new
41
+ cli.parse_options
42
+ cli.config[:config_file] # 'foo.rb'
43
+ cli.config[:log_level] # :debug
44
+ ```
45
+
46
+ If you are using this in conjunction with Mixlib::Config, you can do something like this (building on the above definition):
47
+
48
+ ```ruby
49
+ class MyConfig
50
+ extend(Mixlib::Config)
51
+
52
+ log_level :info
53
+ config_file "default.rb"
54
+ end
55
+
56
+ class MyCLI
57
+ def run(argv=ARGV)
58
+ parse_options(argv)
59
+ MyConfig.merge!(config)
60
+ end
61
+ end
62
+
63
+ c = MyCLI.new
64
+ # ARGV = [ '-l', 'debug' ]
65
+ c.run
66
+ MyConfig[:log_level] # :debug
67
+ ```
68
+
69
+ Available arguments to 'option':
70
+
71
+ - `:short`: The short option, just like from optparse. Example: "-l LEVEL"
72
+ - `:long`: The long option, just like from optparse. Example: "--level LEVEL"
73
+ - `:description`: The description for this item, just like from optparse.
74
+ - `:default`: A default value for this option
75
+ - `:required`: Prints a message informing the user of the missing requirement, and exits. Default is false.
76
+ - `:on`: Set to :tail to appear at the end, or `:head`: to appear at the top.
77
+ - `:boolean:`: If this option takes no arguments, set this to true.
78
+ - `:show_options`: If you want the option list printed when this option is called, set this to true.
79
+ - `:exit`: Exit your program with the exit code when this option is specified. Example: 0
80
+ - `:proc`: If set, the configuration value will be set to the return value of this proc.
81
+ - `:in`: An array containing the list of accepted values
82
+
83
+ If you need access to the leftover options that aren't captured in the config, you can get at them through +cli_arguments+ (referring to the above definition of MyCLI).
84
+
85
+ ```ruby
86
+ # ARGV = [ '-c', 'foo.rb', '-l', 'debug', 'file1', 'file2', 'file3' ]
87
+ cli = MyCLI.new
88
+ cli.parse_options
89
+ cli.cli_arguments # [ 'file1', 'file2', 'file3' ]
90
+ ```
91
+
92
+ ## LICENSE:
93
+
94
+ - Copyright:: Copyright (c) 2008-2016 Chef Software, Inc.
95
+ - License:: Apache License, Version 2.0
96
+
97
+ ```text
98
+ Licensed under the Apache License, Version 2.0 (the "License");
99
+ you may not use this file except in compliance with the License.
100
+ You may obtain a copy of the License at
101
+
102
+ http://www.apache.org/licenses/LICENSE-2.0
103
+
104
+ Unless required by applicable law or agreed to in writing, software
105
+ distributed under the License is distributed on an "AS IS" BASIS,
106
+ WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied.
107
+ See the License for the specific language governing permissions and
108
+ limitations under the License.
109
+ ```
data/Rakefile CHANGED
@@ -1,8 +1,8 @@
1
- require 'bundler'
2
- require 'rubygems'
3
- require 'rubygems/package_task'
4
- require 'rdoc/task'
5
- require 'rspec/core/rake_task'
1
+ require "bundler"
2
+ require "rubygems"
3
+ require "rubygems/package_task"
4
+ require "rdoc/task"
5
+ require "rspec/core/rake_task"
6
6
 
7
7
  Bundler::GemHelper.install_tasks
8
8
 
@@ -10,14 +10,24 @@ task :default => :spec
10
10
 
11
11
  desc "Run specs"
12
12
  RSpec::Core::RakeTask.new(:spec) do |spec|
13
- spec.pattern = 'spec/**/*_spec.rb'
13
+ spec.pattern = "spec/**/*_spec.rb"
14
14
  end
15
15
 
16
16
  gem_spec = eval(File.read("mixlib-cli.gemspec"))
17
17
 
18
18
  RDoc::Task.new do |rdoc|
19
- rdoc.rdoc_dir = 'rdoc'
19
+ rdoc.rdoc_dir = "rdoc"
20
20
  rdoc.title = "mixlib-cli #{gem_spec.version}"
21
- rdoc.rdoc_files.include('README*')
22
- rdoc.rdoc_files.include('lib/**/*.rb')
21
+ rdoc.rdoc_files.include("README*")
22
+ rdoc.rdoc_files.include("lib/**/*.rb")
23
+ end
24
+
25
+ begin
26
+ require "chefstyle"
27
+ require "rubocop/rake_task"
28
+ RuboCop::RakeTask.new(:style) do |task|
29
+ task.options += ["--display-cop-names", "--no-color"]
30
+ end
31
+ rescue LoadError
32
+ puts "chefstyle/rubocop is not available. gem install chefstyle to do style checking."
23
33
  end
@@ -16,7 +16,7 @@
16
16
  # limitations under the License.
17
17
  #
18
18
 
19
- require 'optparse'
19
+ require "optparse"
20
20
 
21
21
  module Mixlib
22
22
 
@@ -38,8 +38,46 @@ module Mixlib
38
38
  # #parse_options. After calling this method, the attribute #config will
39
39
  # contain a hash of `:option_name => value` pairs.
40
40
  module CLI
41
- module ClassMethods
42
41
 
42
+ module InheritMethods
43
+ def inherited(receiver)
44
+ receiver.options = deep_dup(self.options)
45
+ receiver.extend(Mixlib::CLI::InheritMethods)
46
+ end
47
+
48
+ # object:: Instance to clone
49
+ # This method will return a "deep clone" of the provided
50
+ # `object`. If the provided `object` is an enumerable type the
51
+ # contents will be iterated and cloned as well.
52
+ def deep_dup(object)
53
+ cloned_object = object.respond_to?(:dup) ? object.dup : object
54
+ if cloned_object.kind_of?(Enumerable)
55
+ if cloned_object.kind_of?(Hash)
56
+ new_hash = cloned_object.class.new
57
+ cloned_object.each do |key, value|
58
+ cloned_key = deep_dup(key)
59
+ cloned_value = deep_dup(value)
60
+ new_hash[cloned_key] = cloned_value
61
+ end
62
+ cloned_object.replace(new_hash)
63
+ else
64
+ cloned_object.map! do |shallow_instance|
65
+ deep_dup(shallow_instance)
66
+ end
67
+ end
68
+ end
69
+ cloned_object
70
+ rescue TypeError
71
+ # Symbol will happily provide a `#dup` method even though
72
+ # attempts to clone it will result in an exception (atoms!).
73
+ # So if we run into an issue of TypeErrors, just return the
74
+ # original object as we gave our "best effort"
75
+ object
76
+ end
77
+
78
+ end
79
+
80
+ module ClassMethods
43
81
  # When this setting is set to +true+, default values supplied to the
44
82
  # mixlib-cli DSL will be stored in a separate Hash
45
83
  def use_separate_default_options(true_or_false)
@@ -47,7 +85,7 @@ module Mixlib
47
85
  end
48
86
 
49
87
  def use_separate_defaults?
50
- @separate_default_options || false
88
+ @separate_default_options ||= false
51
89
  end
52
90
 
53
91
  # Add a command line option.
@@ -92,7 +130,7 @@ module Mixlib
92
130
  #
93
131
  # === Returns
94
132
  # @banner<String>:: The current banner
95
- def banner(bstring=nil)
133
+ def banner(bstring = nil)
96
134
  if bstring
97
135
  @banner = bstring
98
136
  else
@@ -149,7 +187,7 @@ module Mixlib
149
187
  @opt_parser = nil
150
188
 
151
189
  # Set the banner
152
- @banner = self.class.banner
190
+ @banner = self.class.banner
153
191
 
154
192
  # Dupe the class options for this instance
155
193
  klass_options = self.class.options
@@ -170,6 +208,7 @@ module Mixlib
170
208
  config_opts[:proc] ||= nil
171
209
  config_opts[:show_options] ||= false
172
210
  config_opts[:exit] ||= nil
211
+ config_opts[:in] ||= nil
173
212
 
174
213
  if config_opts.has_key?(:default)
175
214
  defaults_container[config_key] = config_opts[:default]
@@ -186,7 +225,7 @@ module Mixlib
186
225
  #
187
226
  # === Returns
188
227
  # argv<Array>:: Returns any un-parsed elements.
189
- def parse_options(argv=ARGV)
228
+ def parse_options(argv = ARGV)
190
229
  argv = argv.dup
191
230
  opt_parser.parse!(argv)
192
231
 
@@ -198,13 +237,23 @@ module Mixlib
198
237
  puts @opt_parser
199
238
  exit 2
200
239
  end
240
+ if opt_value[:in]
241
+ unless opt_value[:in].kind_of?(Array)
242
+ raise(ArgumentError, "Options config key :in must receive an Array")
243
+ end
244
+ if !opt_value[:in].include?(config[opt_key])
245
+ reqarg = opt_value[:short] || opt_value[:long]
246
+ puts "#{reqarg}: #{config[opt_key]} is not included in the list ['#{opt_value[:in].join("', '")}'] "
247
+ puts @opt_parser
248
+ exit 2
249
+ end
250
+ end
201
251
  end
202
252
 
203
253
  @cli_arguments = argv
204
254
  argv
205
255
  end
206
256
 
207
-
208
257
  # The option parser generated from the mixlib-cli DSL. +opt_parser+ can be
209
258
  # used to print a help message including the banner and any CLI options via
210
259
  # `puts opt_parser`.
@@ -220,15 +269,15 @@ module Mixlib
220
269
  opt_args = build_option_arguments(opt_val)
221
270
 
222
271
  opt_method = case opt_val[:on]
223
- when :on
224
- :on
225
- when :tail
226
- :on_tail
227
- when :head
228
- :on_head
229
- else
230
- raise ArgumentError, "You must pass :on, :tail, or :head to :on"
231
- end
272
+ when :on
273
+ :on
274
+ when :tail
275
+ :on_tail
276
+ when :head
277
+ :on_head
278
+ else
279
+ raise ArgumentError, "You must pass :on, :tail, or :head to :on"
280
+ end
232
281
 
233
282
  parse_block =
234
283
  Proc.new() do |c|
@@ -250,10 +299,10 @@ module Mixlib
250
299
 
251
300
  arguments << opt_setting[:short] if opt_setting.has_key?(:short)
252
301
  arguments << opt_setting[:long] if opt_setting.has_key?(:long)
253
-
254
302
  if opt_setting.has_key?(:description)
255
303
  description = opt_setting[:description]
256
304
  description << " (required)" if opt_setting[:required]
305
+ description << " (included in ['#{opt_setting[:in].join("', '")}'])" if opt_setting[:in]
257
306
  arguments << description
258
307
  end
259
308
 
@@ -262,6 +311,7 @@ module Mixlib
262
311
 
263
312
  def self.included(receiver)
264
313
  receiver.extend(Mixlib::CLI::ClassMethods)
314
+ receiver.extend(Mixlib::CLI::InheritMethods)
265
315
  end
266
316
 
267
317
  end
@@ -1,6 +1,5 @@
1
1
  module Mixlib
2
2
  module CLI
3
- VERSION = "1.5.0"
3
+ VERSION = "1.6.0"
4
4
  end
5
5
  end
6
-
@@ -0,0 +1,27 @@
1
+ $:.unshift(File.dirname(__FILE__) + "/lib")
2
+ require "mixlib/cli/version"
3
+
4
+ Gem::Specification.new do |s|
5
+ s.name = "mixlib-cli"
6
+ s.version = Mixlib::CLI::VERSION
7
+ s.platform = Gem::Platform::RUBY
8
+ s.has_rdoc = true
9
+ s.extra_rdoc_files = ["README.md", "LICENSE", "NOTICE"]
10
+ s.summary = "A simple mixin for CLI interfaces, including option parsing"
11
+ s.description = s.summary
12
+ s.author = "Chef Software, Inc."
13
+ s.email = "info@chef.io"
14
+ s.homepage = "https://www.chef.io"
15
+ s.license = "Apache-2.0"
16
+
17
+ # Uncomment this to add a dependency
18
+ #s.add_dependency "mixlib-log"
19
+ s.add_development_dependency "rake", "< 11.0"
20
+ s.add_development_dependency "rspec", "~> 2.14"
21
+ s.add_development_dependency "rdoc"
22
+ s.add_development_dependency "chefstyle", "~> 0.3"
23
+
24
+ s.require_path = "lib"
25
+ s.files = %w{LICENSE README.md Gemfile Rakefile NOTICE} + Dir.glob("*.gemspec") +
26
+ Dir.glob("{lib,spec}/**/*", File::FNM_DOTMATCH).reject { |f| File.directory?(f) }
27
+ end
@@ -27,21 +27,21 @@ describe Mixlib::CLI do
27
27
  describe "class method" do
28
28
  describe "option" do
29
29
  it "should allow you to set a config option with a hash" do
30
- TestCLI.option(:config_file, :short => '-c CONFIG').should == { :short => '-c CONFIG' }
30
+ TestCLI.option(:config_file, :short => "-c CONFIG").should == { :short => "-c CONFIG" }
31
31
  end
32
32
  end
33
33
 
34
34
  describe "options" do
35
35
  it "should return the current options hash" do
36
- TestCLI.option(:config_file, :short => '-c CONFIG')
37
- TestCLI.options.should == { :config_file => { :short => '-c CONFIG' } }
36
+ TestCLI.option(:config_file, :short => "-c CONFIG")
37
+ TestCLI.options.should == { :config_file => { :short => "-c CONFIG" } }
38
38
  end
39
39
  end
40
40
 
41
41
  describe "options=" do
42
42
  it "should allow you to set the full options with a single hash" do
43
- TestCLI.options = { :config_file => { :short => '-c CONFIG' } }
44
- TestCLI.options.should == { :config_file => { :short => '-c CONFIG' } }
43
+ TestCLI.options = { :config_file => { :short => "-c CONFIG" } }
44
+ TestCLI.options.should == { :config_file => { :short => "-c CONFIG" } }
45
45
  end
46
46
  end
47
47
 
@@ -79,8 +79,9 @@ describe Mixlib::CLI do
79
79
  :required => false,
80
80
  :proc => nil,
81
81
  :show_options => false,
82
- :exit => nil
83
- }
82
+ :exit => nil,
83
+ :in => nil,
84
+ },
84
85
  }
85
86
  end
86
87
 
@@ -134,8 +135,8 @@ describe Mixlib::CLI do
134
135
  it "should set the corresponding config value for non-boolean arguments" do
135
136
  TestCLI.option(:config_file, :short => "-c CONFIG")
136
137
  @cli = TestCLI.new
137
- @cli.parse_options([ '-c', 'foo.rb' ])
138
- @cli.config[:config_file].should == 'foo.rb'
138
+ @cli.parse_options([ "-c", "foo.rb" ])
139
+ @cli.config[:config_file].should == "foo.rb"
139
140
  end
140
141
 
141
142
  it "should set the corresponding config value according to a supplied proc" do
@@ -151,14 +152,14 @@ describe Mixlib::CLI do
151
152
  it "should set the corresponding config value to true for boolean arguments" do
152
153
  TestCLI.option(:i_am_boolean, :short => "-i", :boolean => true)
153
154
  @cli = TestCLI.new
154
- @cli.parse_options([ '-i' ])
155
+ @cli.parse_options([ "-i" ])
155
156
  @cli.config[:i_am_boolean].should == true
156
157
  end
157
158
 
158
159
  it "should set the corresponding config value to false when a boolean is prefixed with --no" do
159
160
  TestCLI.option(:i_am_boolean, :long => "--[no-]bool", :boolean => true)
160
161
  @cli = TestCLI.new
161
- @cli.parse_options([ '--no-bool' ])
162
+ @cli.parse_options([ "--no-bool" ])
162
163
  @cli.config[:i_am_boolean].should == false
163
164
  end
164
165
 
@@ -174,6 +175,32 @@ describe Mixlib::CLI do
174
175
  lambda { @cli.parse_options([]) }.should raise_error(SystemExit)
175
176
  end
176
177
 
178
+ it "should exit if option is not included in the list" do
179
+ TestCLI.option(:inclusion, :short => "-i val", :in => %w{one two})
180
+ @cli = TestCLI.new
181
+ lambda { @cli.parse_options(["-i", "three"]) }.should raise_error(SystemExit)
182
+ end
183
+
184
+ it "should raise ArgumentError if options key :in is not an array" do
185
+ TestCLI.option(:inclusion, :short => "-i val", :in => "foo")
186
+ @cli = TestCLI.new
187
+ lambda { @cli.parse_options(["-i", "three"]) }.should raise_error(ArgumentError)
188
+ end
189
+
190
+ it "should not exit if option is included in the list" do
191
+ TestCLI.option(:inclusion, :short => "-i val", :in => %w{one two})
192
+ @cli = TestCLI.new
193
+ @cli.parse_options(["-i", "one"])
194
+ @cli.config[:inclusion].should == "one"
195
+ end
196
+
197
+ it "should change description if :in key is specified" do
198
+ TestCLI.option(:inclusion, :short => "-i val", :in => %w{one two}, :description => "desc")
199
+ @cli = TestCLI.new
200
+ @cli.parse_options(["-i", "one"])
201
+ @cli.options[:inclusion][:description].should == "desc (included in ['one', 'two'])"
202
+ end
203
+
177
204
  it "should not exit if a required option is specified" do
178
205
  TestCLI.option(:require_me, :short => "-r", :boolean => true, :required => true)
179
206
  @cli = TestCLI.new
@@ -199,17 +226,17 @@ describe Mixlib::CLI do
199
226
  TestCLI.option(:config_file, :short => "-c CONFIG")
200
227
  @cli = TestCLI.new
201
228
  argv_old = ARGV.dup
202
- ARGV.replace ['-c','foo.rb']
229
+ ARGV.replace ["-c", "foo.rb"]
203
230
  @cli.parse_options()
204
- ARGV.should == ['-c','foo.rb']
231
+ ARGV.should == ["-c", "foo.rb"]
205
232
  ARGV.replace argv_old
206
233
  end
207
234
 
208
235
  it "should preserve and return any un-parsed elements" do
209
236
  TestCLI.option(:party, :short => "-p LOCATION")
210
237
  @cli = TestCLI.new
211
- @cli.parse_options([ 'easy', '-p', 'opscode', 'hard' ]).should == ['easy', 'hard']
212
- @cli.cli_arguments.should == ['easy', 'hard']
238
+ @cli.parse_options([ "easy", "-p", "opscode", "hard" ]).should == %w{easy hard}
239
+ @cli.cli_arguments.should == %w{easy hard}
213
240
  end
214
241
  end
215
242
  end
@@ -228,15 +255,62 @@ describe Mixlib::CLI do
228
255
  end
229
256
 
230
257
  it "sets parsed values on the `config` hash" do
231
- @cli.parse_options(%w[-D not-default])
258
+ @cli.parse_options(%w{-D not-default})
232
259
  @cli.default_config[:defaulter].should == "this is the default"
233
260
  @cli.config[:defaulter].should == "not-default"
234
261
  end
235
262
 
236
263
  end
237
264
 
238
- end
265
+ context "when subclassed" do
266
+ before do
267
+ TestCLI.options = { :arg1 => { :boolean => true } }
268
+ end
269
+
270
+ it "should retain previously defined options from parent" do
271
+ class T1 < TestCLI
272
+ option :arg2, :boolean => true
273
+ end
274
+ T1.options[:arg1].should be_a(Hash)
275
+ T1.options[:arg2].should be_a(Hash)
276
+ TestCLI.options[:arg2].should be_nil
277
+ end
278
+
279
+ it "should not be able to modify parent classes options" do
280
+ class T2 < TestCLI
281
+ option :arg2, :boolean => true
282
+ end
283
+ T2.options[:arg1][:boolean] = false
284
+ T2.options[:arg1][:boolean].should be_false
285
+ TestCLI.options[:arg1][:boolean].should be_true
286
+ end
287
+
288
+ it "should pass its options onto child" do
289
+ class T3 < TestCLI
290
+ option :arg2, :boolean => true
291
+ end
292
+ class T4 < T3
293
+ option :arg3, :boolean => true
294
+ end
295
+ 3.times do |i|
296
+ T4.options["arg#{i + 1}".to_sym].should be_a(Hash)
297
+ end
298
+ end
239
299
 
300
+ it "should also work with an option that's an array" do
301
+ class T5 < TestCLI
302
+ option :arg2, :default => []
303
+ end
304
+
305
+ class T6 < T5
306
+ end
307
+
308
+ T6.options[:arg2].should be_a(Hash)
309
+ end
310
+
311
+ end
312
+
313
+ end
240
314
 
241
315
  # option :config_file,
242
316
  # :short => "-c CONFIG",
@@ -1,9 +1,15 @@
1
- $TESTING=true
2
- $:.push File.join(File.dirname(__FILE__), '..', 'lib')
1
+ $TESTING = true
2
+ $:.push File.join(File.dirname(__FILE__), "..", "lib")
3
3
 
4
- require 'mixlib/cli'
4
+ require "mixlib/cli"
5
5
 
6
6
  class TestCLI
7
7
  include Mixlib::CLI
8
8
  end
9
9
 
10
+ RSpec.configure do |config|
11
+ config.filter_run :focus => true
12
+ config.run_all_when_everything_filtered = true
13
+ config.treat_symbols_as_metadata_keys_with_true_values = true
14
+ config.warnings = true
15
+ end
metadata CHANGED
@@ -1,76 +1,93 @@
1
1
  --- !ruby/object:Gem::Specification
2
2
  name: mixlib-cli
3
3
  version: !ruby/object:Gem::Version
4
- version: 1.5.0
4
+ version: 1.6.0
5
5
  platform: ruby
6
6
  authors:
7
- - Opscode, Inc.
7
+ - Chef Software, Inc.
8
8
  autorequire:
9
9
  bindir: bin
10
10
  cert_chain: []
11
- date: 2014-04-25 00:00:00.000000000 Z
11
+ date: 2016-05-05 00:00:00.000000000 Z
12
12
  dependencies:
13
13
  - !ruby/object:Gem::Dependency
14
14
  name: rake
15
15
  requirement: !ruby/object:Gem::Requirement
16
16
  requirements:
17
- - - '>='
17
+ - - "<"
18
18
  - !ruby/object:Gem::Version
19
- version: '0'
19
+ version: '11.0'
20
20
  type: :development
21
21
  prerelease: false
22
22
  version_requirements: !ruby/object:Gem::Requirement
23
23
  requirements:
24
- - - '>='
24
+ - - "<"
25
25
  - !ruby/object:Gem::Version
26
- version: '0'
26
+ version: '11.0'
27
27
  - !ruby/object:Gem::Dependency
28
28
  name: rspec
29
29
  requirement: !ruby/object:Gem::Requirement
30
30
  requirements:
31
- - - '>='
31
+ - - "~>"
32
32
  - !ruby/object:Gem::Version
33
- version: '0'
33
+ version: '2.14'
34
34
  type: :development
35
35
  prerelease: false
36
36
  version_requirements: !ruby/object:Gem::Requirement
37
37
  requirements:
38
- - - '>='
38
+ - - "~>"
39
39
  - !ruby/object:Gem::Version
40
- version: '0'
40
+ version: '2.14'
41
41
  - !ruby/object:Gem::Dependency
42
42
  name: rdoc
43
43
  requirement: !ruby/object:Gem::Requirement
44
44
  requirements:
45
- - - '>='
45
+ - - ">="
46
46
  - !ruby/object:Gem::Version
47
47
  version: '0'
48
48
  type: :development
49
49
  prerelease: false
50
50
  version_requirements: !ruby/object:Gem::Requirement
51
51
  requirements:
52
- - - '>='
52
+ - - ">="
53
53
  - !ruby/object:Gem::Version
54
54
  version: '0'
55
+ - !ruby/object:Gem::Dependency
56
+ name: chefstyle
57
+ requirement: !ruby/object:Gem::Requirement
58
+ requirements:
59
+ - - "~>"
60
+ - !ruby/object:Gem::Version
61
+ version: '0.3'
62
+ type: :development
63
+ prerelease: false
64
+ version_requirements: !ruby/object:Gem::Requirement
65
+ requirements:
66
+ - - "~>"
67
+ - !ruby/object:Gem::Version
68
+ version: '0.3'
55
69
  description: A simple mixin for CLI interfaces, including option parsing
56
- email: info@opscode.com
70
+ email: info@chef.io
57
71
  executables: []
58
72
  extensions: []
59
73
  extra_rdoc_files:
60
- - README.rdoc
74
+ - README.md
61
75
  - LICENSE
62
76
  - NOTICE
63
77
  files:
78
+ - Gemfile
64
79
  - LICENSE
65
- - README.rdoc
66
- - Rakefile
67
80
  - NOTICE
68
- - lib/mixlib/cli/version.rb
81
+ - README.md
82
+ - Rakefile
69
83
  - lib/mixlib/cli.rb
84
+ - lib/mixlib/cli/version.rb
85
+ - mixlib-cli.gemspec
70
86
  - spec/mixlib/cli_spec.rb
71
87
  - spec/spec_helper.rb
72
- homepage: http://www.opscode.com
73
- licenses: []
88
+ homepage: https://www.chef.io
89
+ licenses:
90
+ - Apache-2.0
74
91
  metadata: {}
75
92
  post_install_message:
76
93
  rdoc_options: []
@@ -78,19 +95,18 @@ require_paths:
78
95
  - lib
79
96
  required_ruby_version: !ruby/object:Gem::Requirement
80
97
  requirements:
81
- - - '>='
98
+ - - ">="
82
99
  - !ruby/object:Gem::Version
83
100
  version: '0'
84
101
  required_rubygems_version: !ruby/object:Gem::Requirement
85
102
  requirements:
86
- - - '>='
103
+ - - ">="
87
104
  - !ruby/object:Gem::Version
88
105
  version: '0'
89
106
  requirements: []
90
107
  rubyforge_project:
91
- rubygems_version: 2.0.3
108
+ rubygems_version: 2.4.5.1
92
109
  signing_key:
93
110
  specification_version: 4
94
111
  summary: A simple mixin for CLI interfaces, including option parsing
95
112
  test_files: []
96
- has_rdoc: true
@@ -1,84 +0,0 @@
1
- == Mixlib::CLI
2
-
3
- Mixlib::CLI provides a class-based command line option parsing object, like the one used in Chef, Ohai and Relish. To use in your project:
4
-
5
- require 'rubygems'
6
- require 'mixlib/cli'
7
-
8
- class MyCLI
9
- include Mixlib::CLI
10
-
11
- option :config_file,
12
- :short => "-c CONFIG",
13
- :long => "--config CONFIG",
14
- :default => 'config.rb',
15
- :description => "The configuration file to use"
16
-
17
- option :log_level,
18
- :short => "-l LEVEL",
19
- :long => "--log_level LEVEL",
20
- :description => "Set the log level (debug, info, warn, error, fatal)",
21
- :required => true,
22
- :proc => Proc.new { |l| l.to_sym }
23
-
24
- option :help,
25
- :short => "-h",
26
- :long => "--help",
27
- :description => "Show this message",
28
- :on => :tail,
29
- :boolean => true,
30
- :show_options => true,
31
- :exit => 0
32
-
33
- end
34
-
35
- # ARGV = [ '-c', 'foo.rb', '-l', 'debug' ]
36
- cli = MyCLI.new
37
- cli.parse_options
38
- cli.config[:config_file] # 'foo.rb'
39
- cli.config[:log_level] # :debug
40
-
41
- If you are using this in conjunction with Mixlib::Config, you can do something like this (building on the above definition):
42
-
43
- class MyConfig
44
- extend(Mixlib::Config)
45
-
46
- log_level :info
47
- config_file "default.rb"
48
- end
49
-
50
- class MyCLI
51
- def run(argv=ARGV)
52
- parse_options(argv)
53
- MyConfig.merge!(config)
54
- end
55
- end
56
-
57
- c = MyCLI.new
58
- # ARGV = [ '-l', 'debug' ]
59
- c.run
60
- MyConfig[:log_level] # :debug
61
-
62
- Available arguments to 'option':
63
-
64
- :short:: The short option, just like from optparse. Example: "-l LEVEL"
65
- :long:: The long option, just like from optparse. Example: "--level LEVEL"
66
- :description:: The description for this item, just like from optparse.
67
- :default:: A default value for this option
68
- :required:: Prints a message informing the user of the missing requirement, and exits. Default is false.
69
- :on:: Set to :tail to appear at the end, or :head to appear at the top.
70
- :boolean:: If this option takes no arguments, set this to true.
71
- :show_options:: If you want the option list printed when this option is called, set this to true.
72
- :exit:: Exit your program with the exit code when this option is specified. Example: 0
73
- :proc:: If set, the configuration value will be set to the return value of this proc.
74
-
75
- === New in 1.2.2
76
-
77
- :required works, and we now support Ruby-style boolean option negation
78
- (e.g. '--no-cookie' will set 'cookie' to false if the option is boolean)
79
-
80
- === New in 1.2.0
81
-
82
- We no longer destructively manipulate ARGV.
83
-
84
- Have fun!