lib/cmdparse.rb in cmdparse-2.0.1 vs lib/cmdparse.rb in cmdparse-2.0.2
- old
+ new
@@ -1,9 +1,9 @@
#
#--
#
-# $Id: cmdparse.rb 398 2006-04-05 14:13:43Z thomas $
+# $Id: cmdparse.rb 416 2006-06-17 19:32:55Z thomas $
#
# cmdparse: advanced command line parser supporting commands
# Copyright (C) 2004 Thomas Leitner
#
# This program is free software; you can redistribute it and/or modify it under the terms of the GNU
@@ -23,11 +23,11 @@
# Namespace module for cmdparse.
module CmdParse
# The version of this cmdparse implemention
- VERSION = [2, 0, 1]
+ VERSION = [2, 0, 2]
# Base class for all cmdparse errors.
class ParseError < RuntimeError
@@ -101,11 +101,23 @@
end
# Require default option parser wrapper
require 'cmdparse/wrappers/optparse'
+ # Command Hash - will return partial key matches as well if there is a single
+ # non-ambigous matching key
+ class CommandHash < Hash
+ def []( cmd_name )
+ super or begin
+ possible = keys.select {|key| key =~ /^#{cmd_name}.*/ }
+ fetch( possible[0] ) if possible.size == 1
+ end
+ end
+
+ end
+
# Base class for the commands. This class implements all needed methods so that it can be used by
# the +CommandParser+ class.
class Command
# The name of the command
@@ -129,19 +141,27 @@
# Returns the list of commands for this command.
attr_reader :commands
# Initializes the command called +name+. The parameter +has_commands+ specifies if this command
- # takes other commands as argument.
- def initialize( name, has_commands )
+ # takes other commands as argument. The optional argument +partial_commands+ specifies, if
+ # partial command matching should be used.
+ def initialize( name, has_commands, partial_commands = false )
@name = name
@options = ParserWrapper.new
@has_commands = has_commands
- @commands = {}
+ @commands = Hash.new
@default_command = nil
+ use_partial_commands( partial_commands )
end
+ def use_partial_commands( use_partial )
+ temp = ( use_partial ? CommandHash.new : Hash.new )
+ temp.update( @commands )
+ @commands = temp
+ end
+
# Returns +true+ if this command supports sub commands.
def has_commands?
@has_commands
end
@@ -270,11 +290,11 @@
def execute( args )
if args.length > 0
cmd = commandparser.main_command
arg = args.shift
- while !arg.nil? && cmd.commands.keys.include?( arg )
+ while !arg.nil? && cmd.commands[ arg ]
cmd = cmd.commands[arg]
arg = args.shift
end
if arg.nil?
cmd.show_help
@@ -290,10 +310,11 @@
#######
private
#######
def show_program_help
+ puts commandparser.banner + "\n" if commandparser.banner
puts "Usage: #{commandparser.program_name} [options] COMMAND [options] [COMMAND [options] ...] [args]"
puts ""
list_commands( 1, commandparser.main_command )
puts ""
puts commandparser.main_command.options.summarize
@@ -329,20 +350,24 @@
end
def execute( args )
version = commandparser.program_version
version = version.join( '.' ) if version.instance_of?( Array )
+ puts commandparser.banner + "\n" if commandparser.banner
puts version
exit
end
end
# The main class for creating a command based CLI program.
class CommandParser
+ # A standard banner for help & version screens
+ attr_accessor :banner
+
# The top level command representing the program itself.
attr_reader :main_command
# The name of the program.
attr_accessor :program_name
@@ -352,14 +377,16 @@
# Are Exceptions be handled gracefully? I.e. by printing error message and the help screen?
attr_reader :handle_exceptions
# Create a new CommandParser object. The optional argument +handleExceptions+ specifies if the
- # object should handle exceptions gracefully.
- def initialize( handleExceptions = false )
+ # object should handle exceptions gracefully. Set +partial_commands+ to +true+, if you want
+ # partial command matching for the top level commands.
+ def initialize( handleExceptions = false, partial_commands = false )
@main_command = Command.new( 'mainCommand', true )
@main_command.super_command = self
+ @main_command.use_partial_commands( partial_commands )
@program_name = $0
@program_version = "0.0.0"
@handle_exceptions = handleExceptions
end
@@ -400,10 +427,10 @@
raise NoCommandGivenError
else
cmdName = command.default_command
end
else
- raise InvalidCommandError.new( cmdName ) unless command.commands.include?( cmdName )
+ raise InvalidCommandError.new( cmdName ) unless command.commands[ cmdName ]
end
command = command.commands[cmdName]
level += 1
else