Module: Mixlib::CLI
- Defined in:
- lib/mixlib/cli.rb,
lib/mixlib/cli/version.rb,
lib/mixlib/cli/formatter.rb
Overview
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; ClassMethods#banner, which defines the “usage” banner; and ClassMethods#deprecated_option, which defines a deprecated command-line option.
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.
Defined Under Namespace
Modules: ClassMethods, InheritMethods Classes: Formatter
Constant Summary collapse
- VERSION =
"2.1.1".freeze
Instance Attribute Summary collapse
-
#banner ⇒ Object
Banner for the option parser.
-
#cli_arguments ⇒ Object
Any arguments which were not parsed and placed in “config”–the leftovers.
-
#config ⇒ Object
A Hash containing the values supplied by command line options.
-
#default_config ⇒ Object
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).
-
#options ⇒ Object
Gives the command line options definition as configured in the DSL.
Class Method Summary collapse
Instance Method Summary collapse
- #build_option_arguments(opt_setting) ⇒ Object
-
#handle_deprecated_options(show_deprecations) ⇒ Object
Iterates through options declared as deprecated, maps values to their replacement options, and prints deprecation warnings.
-
#initialize(*args) ⇒ Object
Create a new Mixlib::CLI class.
-
#opt_parser ⇒ Object
The option parser generated from the mixlib-cli DSL.
-
#parse_options(argv = ARGV, show_deprecations: true) ⇒ Object
Parses an array, by default ARGV, for command line options (as configured at the class level).
Instance Attribute Details
#banner ⇒ Object
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.
249 250 251 |
# File 'lib/mixlib/cli.rb', line 249 def @banner end |
#cli_arguments ⇒ Object
Any arguments which were not parsed and placed in “config”–the leftovers.
245 246 247 |
# File 'lib/mixlib/cli.rb', line 245 def cli_arguments @cli_arguments end |
#config ⇒ Object
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.
234 235 236 |
# File 'lib/mixlib/cli.rb', line 234 def config @config end |
#default_config ⇒ Object
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.
242 243 244 |
# File 'lib/mixlib/cli.rb', line 242 def default_config @default_config end |
#options ⇒ Object
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.
221 222 223 |
# File 'lib/mixlib/cli.rb', line 221 def @options end |
Class Method Details
.included(receiver) ⇒ Object
445 446 447 448 |
# File 'lib/mixlib/cli.rb', line 445 def self.included(receiver) receiver.extend(Mixlib::CLI::ClassMethods) receiver.extend(Mixlib::CLI::InheritMethods) end |
Instance Method Details
#build_option_arguments(opt_setting) ⇒ Object
429 430 431 432 433 434 435 436 437 438 439 440 441 442 443 |
# File 'lib/mixlib/cli.rb', line 429 def build_option_arguments(opt_setting) arguments = Array.new arguments << opt_setting[:short] if opt_setting[:short] arguments << opt_setting[:long] if opt_setting[:long] if opt_setting.key?(:description) description = opt_setting[:description].dup description << " (required)" if opt_setting[:required] description << " (valid options: #{Formatter.friendly_opt_list(opt_setting[:in])})" if opt_setting[:in] opt_setting[:description] = description arguments << description end arguments end |
#handle_deprecated_options(show_deprecations) ⇒ Object
Iterates through options declared as deprecated, maps values to their replacement options, and prints deprecation warnings.
391 392 393 394 395 396 397 398 399 400 401 402 403 404 405 406 407 408 409 410 411 412 413 414 415 416 417 418 419 420 421 422 423 424 425 426 427 |
# File 'lib/mixlib/cli.rb', line 391 def (show_deprecations) merge_in_values = {} config.each_key do |opt_key| opt_cfg = [opt_key] # Deprecated entries do not have defaults so no matter what # separate_default_options are set, if we see a 'config' # entry that contains a deprecated indicator, then the option was # explicitly provided by the caller. # # opt_cfg may not exist if an inheriting application # has directly inserted values info config. next unless opt_cfg && opt_cfg[:deprecated] replacement_key = opt_cfg[:replacement] if replacement_key # This is the value passed into the deprecated flag. We'll use # the declared value mapper (defaults to return the same value if caller hasn't # provided a mapper). deprecated_val = config[opt_key] # We can't modify 'config' since we're iterating it, apply updates # at the end. merge_in_values[replacement_key] = opt_cfg[:value_mapper].call(deprecated_val) config.delete(opt_key) unless opt_cfg[:keep] end # Warn about the deprecation. if show_deprecations # Description is also the deprecation message. display_name = CLI::Formatter.combined_option_display_name(opt_cfg[:short], opt_cfg[:long]) puts "#{display_name}: #{opt_cfg[:description]}" end end config.merge!(merge_in_values) nil end |
#initialize(*args) ⇒ Object
Create a new Mixlib::CLI class. If you override this, make sure you call super!
Parameters
- *args<Array>
-
The array of arguments passed to the initializer
Returns
- object<Mixlib::Config>
-
Returns an instance of whatever you wanted :)
258 259 260 261 262 263 264 265 266 267 268 269 270 271 272 273 274 275 276 277 278 279 280 281 282 283 284 285 286 287 288 289 290 291 292 293 |
# File 'lib/mixlib/cli.rb', line 258 def initialize(*args) @options = Hash.new @config = Hash.new @default_config = Hash.new @opt_parser = nil # Set the banner @banner = self.class. # Dupe the class options for this instance = self.class. .keys.inject(@options) { |memo, key| memo[key] = [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 config_opts[:boolean] ||= false config_opts[:required] ||= false config_opts[:proc] ||= nil config_opts[:show_options] ||= false config_opts[:exit] ||= nil config_opts[:in] ||= nil if config_opts.key?(:default) defaults_container[config_key] = config_opts[:default] end end super(*args) end |
#opt_parser ⇒ Object
The option parser generated from the mixlib-cli DSL. opt_parser
can be used to print a help message including the banner and any CLI options via ‘puts opt_parser`.
Returns
- opt_parser<OptionParser>
-
The option parser object.
341 342 343 344 345 346 347 348 349 350 351 352 353 354 355 356 357 358 359 360 361 362 363 364 365 366 367 368 369 370 371 372 373 374 375 376 377 378 379 380 381 382 383 384 |
# File 'lib/mixlib/cli.rb', line 341 def opt_parser @opt_parser ||= OptionParser.new do |opts| # Set the banner opts. = # Create new options .sort { |a, b| a[0].to_s <=> b[0].to_s }.each do |opt_key, opt_val| opt_args = build_option_arguments(opt_val) opt_method = case opt_val[:on] when :on :on when :tail :on_tail when :head :on_head else raise ArgumentError, "You must pass :on, :tail, or :head to :on" end parse_block = Proc.new() do |c| config[opt_key] = if opt_val[:proc] if opt_val[:proc].arity == 2 # New hotness to allow for reducer-style procs. opt_val[:proc].call(c, config[opt_key]) else # Older single-argument proc. opt_val[:proc].call(c) end else # No proc. c end puts opts if opt_val[:show_options] exit opt_val[:exit] if opt_val[:exit] end full_opt = [ opt_method ] opt_args.inject(full_opt) { |memo, arg| memo << arg; memo } full_opt << parse_block opts.send(*full_opt) end end end |
#parse_options(argv = ARGV, show_deprecations: true) ⇒ Object
Parses an array, by default ARGV, for command line options (as configured at the class level).
Parameters
- argv<Array>
-
The array of arguments to parse; defaults to ARGV
Returns
- argv<Array>
-
Returns any un-parsed elements.
302 303 304 305 306 307 308 309 310 311 312 313 314 315 316 317 318 319 320 321 322 323 324 325 326 327 328 329 330 331 332 333 334 |
# File 'lib/mixlib/cli.rb', line 302 def (argv = ARGV, show_deprecations: true) argv = argv.dup opt_parser.parse!(argv) # Do this before our custom validations, so that custom # validations apply to any converted deprecation values; # but after parse! so that everything is populated. (show_deprecations) # Deal with any required values .each do |opt_key, opt_config| if opt_config[:required] && !config.key?(opt_key) reqarg = opt_config[:short] || opt_config[:long] puts "You must supply #{reqarg}!" puts @opt_parser exit 2 end if opt_config[:in] unless opt_config[:in].kind_of?(Array) raise(ArgumentError, "Options config key :in must receive an Array") end if config[opt_key] && !opt_config[:in].include?(config[opt_key]) reqarg = Formatter.combined_option_display_name(opt_config[:short], opt_config[:long]) puts "#{reqarg}: #{config[opt_key]} is not one of the allowed values: #{Formatter.friendly_opt_list(opt_config[:in])}" # TODO - get rid of this. nobody wants to be spammed with a ton of information, particularly since we just told them the exact problem and how to fix it. puts @opt_parser exit 2 end end end @cli_arguments = argv argv end |