lib/gli.rb in gli-1.0.0 vs lib/gli.rb in gli-1.1.0
- old
+ new
@@ -3,29 +3,33 @@
require 'gli/switch.rb'
require 'gli/flag.rb'
require 'gli/options.rb'
require 'support/help.rb'
require 'support/rdoc.rb'
+require 'support/initconfig.rb'
+require 'etc'
# A means to define and parse a command line interface that works as
# Git's does, in that you specify global options, a command name, command
# specific options, and then command arguments.
module GLI
extend self
- VERSION = '0.3.0'
+ VERSION = '1.0.0'
@@program_name = $0.split(/\//)[-1]
@@post_block = nil
@@pre_block = nil
@@error_block = nil
+ @@config_file = nil
# Reset the GLI module internal data structures; mostly for testing
def reset
switches.clear
flags.clear
commands.clear
+ @@config_file = nil
clear_nexts
end
# describe the next switch, flag, or command. This should be a
# short, one-line description
@@ -52,10 +56,22 @@
switch = Switch.new([names].flatten,@@next_desc,@@next_long_desc)
switches[switch.name] = switch
clear_nexts
end
+ # Sets the config file. If not an absolute path
+ # sets the path to the user's home directory
+ def config_file(filename)
+ if filename =~ /^\//
+ @@config_file = filename
+ else
+ @@config_file = Etc.getpwuid.dir + '/' + filename
+ end
+ commands[:initconfig] = InitConfig.new(@@config_file)
+ @@config_file
+ end
+
# Define a command.
def command(*names)
command = Command.new([names].flatten,@@next_desc,@@next_arg_name,@@next_long_desc)
commands[command.name] = command
yield command
@@ -91,11 +107,12 @@
def run(args)
rdoc = RDocCommand.new
commands[:rdoc] = rdoc if !commands[:rdoc]
commands[:help] = DefaultHelpCommand.new(rdoc) if !commands[:help]
begin
- global_options,command,options,arguments = parse_options(args)
+ config = parse_config
+ global_options,command,options,arguments = parse_options(args,config)
proceed = true
proceed = @@pre_block.call(global_options,command,options,arguments) if @@pre_block
if proceed
command = commands[:help] if !command
command.execute(global_options,options,arguments)
@@ -109,10 +126,20 @@
puts "error: #{ex.message}"
end
end
end
+ def parse_config
+ return nil if @@config_file.nil?
+ require 'yaml'
+ if File.exist?(@@config_file)
+ File.open(@@config_file) { |f| YAML::load(f) }
+ else
+ {}
+ end
+ end
+
def program_name(override=nil)
if override
@@program_name = override
end
@@program_name
@@ -121,12 +148,18 @@
# Returns an array of four values:
# * global options (as a Hash)
# * Command
# * command options (as a Hash)
# * arguments (as an Array)
- def parse_options(args)
- global_options,command,options,arguments = parse_options_helper(args.clone,Options.new,nil,Options.new,Array.new)
+ def parse_options(args,config=nil)
+ command_configs = {}
+ if config.nil?
+ config = {}
+ else
+ command_configs = config.delete(GLI::InitConfig::COMMANDS_KEY) if !config.nil?
+ end
+ global_options,command,options,arguments = parse_options_helper(args.clone,config,nil,Options.new,Array.new,command_configs)
flags.each { |name,flag| global_options[name] = flag.default_value if !global_options[name] }
command.flags.each { |name,flag| options[name] = flag.default_value if !options[name] }
return [global_options,command,options,arguments]
end
@@ -162,10 +195,11 @@
# [args] the arguments that have yet to be processed
# [global_options] the global options hash
# [command] the Command that has been identified (or nil if not identified yet)
# [command_options] options for Command
# [arguments] the arguments for Command
+ # [command_configs] the configuration file for all commands, used as defaults
#
# This works by finding the first non-switch/flag argument, and taking that sublist and trying to pick out
# flags and switches. After this is done, one of the following is true:
# * the sublist is empty - in this case, go again, as there might be more flags to parse
# * the sublist has a flag left in it - unknown flag; we bail
@@ -174,20 +208,25 @@
# This sort of does the same thing in two phases; in the first phase, the command hasn't been identified, so
# we are looking for global switches and flags, ending when we get the command.
#
# Once the command has been found, we start looking for command-specific flags and switches.
# When those have been found, we know the rest of the argument list is arguments for the command
- def parse_options_helper(args,global_options,command,command_options,arguments)
+ def parse_options_helper(args,global_options,command,command_options,arguments,command_configs)
non_flag_i = find_non_flag_index(args)
all_flags = false
if non_flag_i == 0
# no flags
if !command
command_name = args.shift
command = find_command(command_name)
raise "Unknown command '#{command_name}'" if !command
- return parse_options_helper(args,global_options,command,command_options,arguments)
+ return parse_options_helper(args,
+ global_options,
+ command,
+ default_command_options(command,command_configs),
+ arguments,
+ command_configs)
else
return global_options,command,command_options,arguments + args
end
elsif non_flag_i == -1
all_flags = true
@@ -222,11 +261,11 @@
if try_me.empty?
return [global_options,command,command_options,arguments] if rest.empty?
# If we have no more options we've parsed them all
# and rest may have more
- return parse_options_helper(rest,global_options,command,command_options,arguments)
+ return parse_options_helper(rest,global_options,command,command_options,arguments,command_configs)
else
if command
check = rest
check = rest + try_me if all_flags
check.each() do |arg|
@@ -243,13 +282,22 @@
raise "Unknown argument #{command_name}" if command_name =~ /^\-/
command = find_command(command_name)
raise "Unknown command '#{command_name}'" if !command
- return parse_options_helper(rest,global_options,command,command_options,arguments)
+ return parse_options_helper(rest,
+ global_options,
+ command,
+ default_command_options(command,command_configs),
+ arguments,
+ command_configs)
end
end
+ end
+
+ def default_command_options(command,command_configs)
+ options = (command_configs && command_configs[command.name.to_sym]) || {}
end
def find_command(name)
sym = name.to_sym
return commands[name.to_sym] if commands[sym]