lib/gli.rb in gli-1.1.3 vs lib/gli.rb in gli-1.2.0
- old
+ new
@@ -24,10 +24,11 @@
# Reset the GLI module internal data structures; mostly for testing
def reset
switches.clear
flags.clear
commands.clear
+ @@version = nil
@@config_file = nil
clear_nexts
end
# describe the next switch, flag, or command. This should be a
@@ -44,18 +45,22 @@
# set the default value of the next flag
def default_value(val); @@next_default_value = val; end
# Create a flag, which is a switch that takes an argument
def flag(*names)
- flag = Flag.new([names].flatten,@@next_desc,@@next_arg_name,@@next_default_value,@@next_long_desc)
+ names = [names].flatten
+ verify_unused(names,flags,switches,"in global options")
+ flag = Flag.new(names,@@next_desc,@@next_arg_name,@@next_default_value,@@next_long_desc)
flags[flag.name] = flag
clear_nexts
end
# Create a switch
def switch(*names)
- switch = Switch.new([names].flatten,@@next_desc,@@next_long_desc)
+ names = [names].flatten
+ verify_unused(names,flags,switches,"in global options")
+ switch = Switch.new(names,@@next_desc,@@next_long_desc)
switches[switch.name] = switch
clear_nexts
end
# Sets the config file. If not an absolute path
@@ -101,18 +106,24 @@
# prints out a message)
def on_error(&a_proc)
@@error_block = a_proc
end
+ # Indicate the version of your application
+ def version(version)
+ @@version = version
+ end
+
# Runs whatever command is needed based on the arguments.
def run(args)
rdoc = RDocCommand.new
commands[:rdoc] = rdoc if !commands[:rdoc]
- commands[:help] = DefaultHelpCommand.new(rdoc) if !commands[:help]
+ commands[:help] = DefaultHelpCommand.new(@@version,rdoc) if !commands[:help]
begin
config = parse_config
global_options,command,options,arguments = parse_options(args,config)
+ copy_options_to_aliased_versions(global_options,command,options)
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)
@@ -121,15 +132,44 @@
rescue Exception => ex
regular_error_handling = true
regular_error_handling = @@error_block.call(ex) if @@error_block
if regular_error_handling
- puts "error: #{ex.message}"
+ $stderr.puts "error: #{ex.message}"
end
end
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)
+ copy_options_to_aliases(global_options,self)
+ copy_options_to_aliases(options,command)
+ end
+
+ # For each option in options, copies its value to keys for the aliases of the flags or
+ # switches in gli_like
+ #
+ # options - Hash of options parsed from command line; this is an I/O param
+ # gli_like - Object resonding to flags and switches in the same way that GLI or a Command instance do
+ def copy_options_to_aliases(options,gli_like)
+ new_options = {}
+ options.each do |key,value|
+ if gli_like.flags[key] && gli_like.flags[key].aliases
+ gli_like.flags[key].aliases.each do |alias_name|
+ new_options[alias_name] = value
+ end
+ elsif gli_like.switches[key] && gli_like.switches[key].aliases
+ gli_like.switches[key].aliases.each do |alias_name|
+ new_options[alias_name] = value
+ end
+ end
+ end
+ options.merge!(new_options)
+ 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) }
@@ -318,6 +358,24 @@
return command if (command.aliases && command.aliases.include?(sym))
end
nil
end
+ # Checks that the names passed in have not been used in another flag or option
+ def verify_unused(names,flags,switches,context)
+ names.each do |name|
+ verify_unused_in_option(name,flags,"flag",context)
+ verify_unused_in_option(name,switches,"switch",context)
+ end
+ end
+
+ private
+
+ def verify_unused_in_option(name,option_like,type,context)
+ raise ArgumentError.new("#{name} has already been specified as a #{type} #{context}") if option_like[name]
+ option_like.each do |one_option_name,one_option|
+ if one_option.aliases
+ raise ArgumentError.new("#{name} has already been specified as an alias of #{type} #{one_option_name} #{context}") if one_option.aliases.include? name
+ end
+ end
+ end
end