lib/gli/app_support.rb in gli-2.5.6 vs lib/gli/app_support.rb in gli-2.6.0.rc1

- old
+ new

@@ -25,10 +25,11 @@ @error_block = false @pre_block = false @post_block = false @default_command = :help @around_block = nil + @subcommand_option_handling_strategy = :legacy clear_nexts end # Get an array of commands, ordered by when they were declared def commands_declaration_order # :nodoc: @@ -50,48 +51,46 @@ # +args+:: the command line ARGV array # # Returns a number that would be a reasonable exit code def run(args) #:nodoc: args = args.dup if @preserve_argv - command = nil + the_command = nil begin override_defaults_based_on_config(parse_config) add_help_switch_if_needed(switches) - global_options,command,options,arguments = GLIOptionParser.new(commands,flags,switches,accepts,@default_command).parse_options(args) + gli_option_parser = GLIOptionParser.new(commands, + flags, + switches, + accepts, + @default_command, + self.subcommand_option_handling_strategy) - copy_options_to_aliased_versions(global_options,command,options) + parsing_result = gli_option_parser.parse_options(args) + parsing_result.convert_to_openstruct! if @use_openstruct - global_options = convert_to_openstruct_if_needed(global_options) - options = convert_to_openstruct_if_needed(options) + the_command = parsing_result.command - if proceed?(global_options,command,options,arguments) - call_command(command,global_options,options,arguments) - end + call_command(parsing_result) if proceed?(parsing_result) 0 rescue Exception => ex - handle_exception(ex,command) + if the_command.nil? && ex.respond_to?(:command_in_context) + the_command = ex.command_in_context + end + handle_exception(ex,the_command) end end # Return the name of the config file; mostly useful for generating help docs def config_file_name #:nodoc: @config_file end - def accepts #:nodoc: @accepts ||= {} - end - # Copies all options in both global_options and options to keys for the aliases of those flags. - # For example, if a flag works with either -f or --flag, this will copy the value from [:f] to [:flag] - # to allow the user to access the options by any alias - def copy_options_to_aliased_versions(global_options,command,options) # :nodoc: - copy_options_to_aliases(global_options) - command.copy_options_to_aliases(options) end def parse_config # :nodoc: config = { 'commands' => {}, @@ -170,12 +169,17 @@ def override_command_defaults(command_list,config) command_list.each do |command_name,command| next if command_name == :initconfig || command.nil? command_config = (config['commands'] || {})[command_name] || {} - override_default(command.topmost_ancestor.flags,command_config) - override_default(command.topmost_ancestor.switches,command_config) + if @subcommand_option_handling_strategy == :legacy + override_default(command.topmost_ancestor.flags,command_config) + override_default(command.topmost_ancestor.switches,command_config) + else + override_default(command.flags,command_config) + override_default(command.switches,command_config) + end override_command_defaults(command.commands,command_config) end end @@ -183,17 +187,23 @@ tokens.each do |name,token| token.default_value=config[name] if config[name] end end + def subcommand_option_handling_strategy + @subcommand_option_handling_strategy || :legacy + end + private def handle_exception(ex,command) if regular_error_handling?(ex) output_error_message(ex) if ex.kind_of?(OptionParser::ParseError) || ex.kind_of?(BadCommandLine) - commands[:help] and commands[:help].execute({},{},command.nil? ? [] : [command.name.to_s]) + if commands[:help] + commands[:help].execute({},{},command.nil? ? [] : [command.name.to_s]) + end end end raise ex if ENV['GLI_DEBUG'] == 'true' @@ -208,17 +218,11 @@ end end def no_message_given?(ex) ex.message == ex.class.name - end - # Possibly returns a copy of the passed-in Hash as an instance of GLI::Option. - # By default, it will *not*. However by putting <tt>use_openstruct true</tt> - # in your CLI definition, it will - def convert_to_openstruct_if_needed(options) # :nodoc: - @use_openstruct ? Options.new(options) : options end def add_help_switch_if_needed(switches) help_switch_exists = switches.values.find { |switch| (Array(switch.aliases) + [switch.name]).find { |an_alias| @@ -231,15 +235,15 @@ end end # True if we should proceed with executing the command; this calls # the pre block if it's defined - def proceed?(global_options,command,options,arguments) #:nodoc: - if command && command.skips_pre + def proceed?(parsing_result) #:nodoc: + if parsing_result.command && parsing_result.command.skips_pre true else - pre_block.call(global_options,command,options,arguments) + pre_block.call(*parsing_result) end end # Returns true if we should proceed with GLI's basic error handling. # This calls the error block if the user provided one @@ -255,11 +259,15 @@ # +ex+:: The exception we caught that launched the error handling routines def error_message(ex) #:nodoc: "error: #{ex.message}" end - def call_command(command,global_options,options,arguments) - arguments = arguments.map { |arg| arg.dup } # unfreeze + def call_command(parsing_result) + command = parsing_result.command + global_options = parsing_result.global_options + options = parsing_result.command_options + arguments = parsing_result.arguments.map { |arg| arg.dup } # unfreeze + code = lambda { command.execute(global_options,options,arguments) } nested_arounds = unless command.skips_around around_blocks.inject do |outer_around, inner_around| lambda { |go,c,o,a, code1| inner = lambda { inner_around.call(go,c,o,a, code1) }