* code a proper pre-parser to get command line args before invoking
command-specific parser
This commit is contained in:
+48
-15
@@ -20,37 +20,70 @@ from pisi.cli.commands import *
|
|||||||
class ParserError(Exception):
|
class ParserError(Exception):
|
||||||
pass
|
pass
|
||||||
|
|
||||||
class Parser(OptionParser):
|
|
||||||
|
class PreParser(OptionParser):
|
||||||
|
"""consumes any options, and finds arguments from command line"""
|
||||||
|
|
||||||
def __init__(self, version):
|
def __init__(self, version):
|
||||||
OptionParser.__init__(self, usage=usage_text, version=version)
|
OptionParser.__init__(self, usage=usage_text, version=version)
|
||||||
|
|
||||||
def error(self, msg):
|
def error(self, msg):
|
||||||
raise ParserError, msg
|
raise ParserError, msg
|
||||||
|
|
||||||
|
def parse_args(self, args=None):
|
||||||
|
self.rargs = self._get_args(args)
|
||||||
|
self._process_args()
|
||||||
|
return self.args
|
||||||
|
|
||||||
|
def _process_args(self):
|
||||||
|
args = []
|
||||||
|
rargs = self.rargs
|
||||||
|
if not self.allow_interspersed_args:
|
||||||
|
first_arg = False
|
||||||
|
while rargs:
|
||||||
|
arg = rargs[0]
|
||||||
|
def option():
|
||||||
|
if not self.allow_interspersed_args and first_arg:
|
||||||
|
self.error('Options must precede non-option arguments')
|
||||||
|
del rargs[0]
|
||||||
|
return
|
||||||
|
# We handle bare "--" explicitly, and bare "-" is handled by the
|
||||||
|
# standard arg handler since the short arg case ensures that the
|
||||||
|
# len of the opt string is greater than 1.
|
||||||
|
if arg == "--":
|
||||||
|
del rargs[0]
|
||||||
|
break
|
||||||
|
elif arg[0:2] == "--":
|
||||||
|
# process a single long option (possibly with value(s))
|
||||||
|
option()
|
||||||
|
elif arg[:1] == "-" and len(arg) > 1:
|
||||||
|
# process a cluster of short options (possibly with
|
||||||
|
# value(s) for the last one only)
|
||||||
|
option()
|
||||||
|
else: # then it must be an argument
|
||||||
|
args.append(arg)
|
||||||
|
del rargs[0]
|
||||||
|
self.args = args
|
||||||
|
|
||||||
|
|
||||||
class PisiCLI(object):
|
class PisiCLI(object):
|
||||||
|
|
||||||
def __init__(self):
|
def __init__(self):
|
||||||
# first construct a parser for common options
|
# first construct a parser for common options
|
||||||
# this is really dummy
|
# this is really dummy
|
||||||
self.parser = Parser(version="%prog " + pisi.__version__)
|
self.parser = PreParser(version="%prog " + pisi.__version__)
|
||||||
#self.parser.allow_interspersed_args = False
|
|
||||||
|
|
||||||
cmd = ""
|
|
||||||
try:
|
try:
|
||||||
(options, args) = self.parser.parse_args()
|
args = self.parser.parse_args()
|
||||||
if len(args)==0:
|
if len(args)==0: # more explicit than using IndexError
|
||||||
|
print 'No command given'
|
||||||
self.die()
|
self.die()
|
||||||
cmd = args[0]
|
cmd_name = args[0]
|
||||||
|
|
||||||
except IndexError:
|
|
||||||
self.die()
|
|
||||||
except ParserError:
|
except ParserError:
|
||||||
# fully expected :) let's see if we got an argument
|
print 'Command line parsing error'
|
||||||
if len(self.parser.rargs)==0:
|
self.die()
|
||||||
self.die()
|
|
||||||
cmd = self.parser.rargs[0]
|
|
||||||
|
|
||||||
self.command = Command.get_command(cmd)
|
self.command = Command.get_command(cmd_name)
|
||||||
if not self.command:
|
if not self.command:
|
||||||
print "Unrecognized command: ", cmd
|
print "Unrecognized command: ", cmd
|
||||||
self.die()
|
self.die()
|
||||||
|
|||||||
Reference in New Issue
Block a user