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.8".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.
251 252 253 |
# File 'lib/mixlib/cli.rb', line 251 def @banner end |
#cli_arguments ⇒ Object
Any arguments which were not parsed and placed in “config”–the leftovers.
247 248 249 |
# File 'lib/mixlib/cli.rb', line 247 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.
236 237 238 |
# File 'lib/mixlib/cli.rb', line 236 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.
244 245 246 |
# File 'lib/mixlib/cli.rb', line 244 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.
223 224 225 |
# File 'lib/mixlib/cli.rb', line 223 def @options end |
Class Method Details
.included(receiver) ⇒ Object
448 449 450 451 |
# File 'lib/mixlib/cli.rb', line 448 def self.included(receiver) receiver.extend(Mixlib::CLI::ClassMethods) receiver.extend(Mixlib::CLI::InheritMethods) end |
Instance Method Details
#build_option_arguments(opt_setting) ⇒ Object
432 433 434 435 436 437 438 439 440 441 442 443 444 445 446 |
# File 'lib/mixlib/cli.rb', line 432 def build_option_arguments(opt_setting) arguments = [] 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.
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 428 429 430 |
# File 'lib/mixlib/cli.rb', line 394 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 :)
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 294 295 |
# File 'lib/mixlib/cli.rb', line 260 def initialize(*args) @options = {} @config = {} @default_config = {} @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.
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 385 386 387 |
# File 'lib/mixlib/cli.rb', line 344 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.
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 335 336 337 |
# File 'lib/mixlib/cli.rb', line 304 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].is_a?(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 |