summaryrefslogtreecommitdiffstats
path: root/src/nbblib
diff options
context:
space:
mode:
authorHans Ulrich Niedermann <hun@n-dimensional.de>2008-07-03 22:40:29 +0200
committerHans Ulrich Niedermann <hun@n-dimensional.de>2008-07-15 12:28:56 +0200
commit5eff502ced858a7d3a4f3b1c4d44b28e83dc92de (patch)
tree86babcca4fc2a521d5c4f19873c3a2ca6af66eae /src/nbblib
parent4b538e4003103171dacaa7a0ac2bad52432cdfbd (diff)
downloadnbb-5eff502ced858a7d3a4f3b1c4d44b28e83dc92de.tar.gz
nbb-5eff502ced858a7d3a4f3b1c4d44b28e83dc92de.tar.xz
nbb-5eff502ced858a7d3a4f3b1c4d44b28e83dc92de.zip
Rework command framework
Implies catching exceptions in a single place.
Diffstat (limited to 'src/nbblib')
-rw-r--r--src/nbblib/bs.py4
-rw-r--r--src/nbblib/commands.py151
-rw-r--r--src/nbblib/main.py36
3 files changed, 99 insertions, 92 deletions
diff --git a/src/nbblib/bs.py b/src/nbblib/bs.py
index f8f247c..f9215a2 100644
--- a/src/nbblib/bs.py
+++ b/src/nbblib/bs.py
@@ -76,7 +76,9 @@ class BSSourceTree(plugins.GenericDetectPlugin):
class AutomakeSourceTree(BSSourceTree):
+
name = 'automake'
+
def __init__(self, context, vcs_tree):
super(AutomakeSourceTree, self).__init__(context)
srcdir = vcs_tree.tree_root
@@ -130,7 +132,9 @@ class AutomakeSourceTree(BSSourceTree):
class SconsSourceTree(BSSourceTree):
+
name = 'scons'
+
def __init__(self, context, vcs_tree):
super(SconsSourceTree, self).__init__(context)
srcdir = vcs_tree.tree_root
diff --git a/src/nbblib/commands.py b/src/nbblib/commands.py
index e5eab40..2e653b6 100644
--- a/src/nbblib/commands.py
+++ b/src/nbblib/commands.py
@@ -15,7 +15,7 @@ import nbblib.vcs as vcs
import nbblib.bs as bs
-__all__ = []
+__all__ = ['Commander']
def adjust_doc(doc):
@@ -36,18 +36,23 @@ def adjust_doc(doc):
__all__.append('CommandLineError')
class CommandLineError(Exception):
- def __init__(self, message, *args, **kwargs):
+ def __init__(self, message):
super(CommandLineError, self).__init__()
- if args:
- self.msg = message % args
- elif kwargs:
- self.msg = message % kwargs
- else:
- self.msg = message
+ self.msg = message
def __str__(self):
return "Command line error: %s" % self.msg
+__all__.append('UnknownCommand')
+class UnknownCommand(Exception):
+ def __init__(self, context, cmd):
+ super(UnknownCommand, self).__init__()
+ self.prog = context.prog
+ self.cmd = cmd
+ def __str__(self):
+ return "Unknown %(prog)s command '%(cmd)s'" % self.__dict__
+
+
########################################################################
# Command plugin system
########################################################################
@@ -81,27 +86,44 @@ class Command(object):
usage = ''
- def __init__(self, *args, **kwargs):
+ def __init__(self, context, *args, **kwargs):
super(Command, self).__init__()
self.validate_args(*args, **kwargs)
self.args = args
self.kwargs = kwargs
- self.context = kwargs['context']
+ self.context = context
@plugins.abstractmethod
def run(self):
"""Run the command"""
pass
- # Candidate for abstractmethod
- def validate_args(self, *args, **kwargs):
- """Validate command line arguments"""
- print "Command: ", self.name
- print "*args: ", args
- print "**kwargs:", kwargs
- if len(args) > 0:
+ @plugins.abstractmethod
+ def validate_args(self, *cmdargs, **kwargs):
+ """Validate command line arguments: Abstract method.
+
+ May make use of self.context.
+ """
+ pass
+
+ def validate_args_none(self, *cmdargs, **kwargs):
+ """Validate command line arguments: no argument at all"""
+ logging.debug("Command: %s", self.name)
+ logging.debug("*cmdargs: %s", cmdargs)
+ logging.debug("**kwargs: %s", kwargs)
+ if len(cmdargs) > 0:
raise CommandLineError("'%s' command takes no parameters",
self.name)
+ logging.debug("Command match!")
+ return True
+
+ def validate_args_any(self, *cmdargs, **kwargs):
+ """Validate command line arguments: accept any argument"""
+ logging.debug("Command: %s", self.name)
+ logging.debug("*cmdargs: %s", cmdargs)
+ logging.debug("**kwargs: %s", kwargs)
+ logging.debug("Command match!")
+ return True
def __str__(self):
return "Command(%s, %s)" % (self.cmd_name, self.cmdargs)
@@ -127,8 +149,7 @@ class HelpCommand(Command):
print "List of commands:"
keys = Command.plugins.keys()
if not keys:
- print "Error: No commands found."
- sys.exit(2)
+ raise Exception("No commands found. Please lart the developer.")
keys.sort()
keys2 = Command.plugins.keys()
keys2.sort(lambda a,b: cmp(len(b),len(a)))
@@ -163,6 +184,7 @@ class HelpCommand(Command):
class InternalConfigCommand(Command):
name = 'internal-config'
summary = 'print internal program configuration'
+ validate_args = Command.validate_args_none
def run(self):
print "Source tree types:", ", ".join(vcs.VCSourceTree.plugins.keys())
print "Build system types:", ", ".join(bs.BSSourceTree.plugins.keys())
@@ -172,10 +194,9 @@ class InternalConfigCommand(Command):
class SourceClassCommand(Command):
"""Base class for commands acting on source trees"""
name = None # abstract command class
- def __init__(self, *args, **kwargs):
- super(SourceClassCommand, self).__init__(*args, **kwargs)
+ def __init__(self, context, *args, **kwargs):
+ super(SourceClassCommand, self).__init__(context, *args, **kwargs)
- context = kwargs['context']
srcdir = os.getcwd()
absdir = os.path.abspath(srcdir)
@@ -193,20 +214,18 @@ class SourceClassCommand(Command):
class DetectCommand(Command):
name = None
- def __init__(self, *args, **kwargs):
- super(DetectCommand, self).__init__(*args, **kwargs)
- self.context = kwargs['context']
+ def __init__(self, context, *args, **kwargs):
+ super(DetectCommand, self).__init__(context, *args, **kwargs)
self.srcdir = os.getcwd()
self.absdir = os.path.abspath(self.srcdir)
- def validate_args(self, *args, **kwargs):
- pass
+ validate_args = Command.validate_args_none
class DetectVCSCommand(DetectCommand):
name = "detect-vcs"
summary = "detect source tree VCS"
- def __init__(self, *args, **kwargs):
- super(DetectVCSCommand, self).__init__(*args, **kwargs)
+ def __init__(self, context, *args, **kwargs):
+ super(DetectVCSCommand, self).__init__(context, *args, **kwargs)
self.vcs_sourcetree = vcs.VCSourceTree.detect(self.context, self.absdir)
logging.debug("vcs_sourcetree %s", self.vcs_sourcetree)
def run(self):
@@ -214,13 +233,14 @@ class DetectVCSCommand(DetectCommand):
print 'VCS:', self.vcs_sourcetree.name, self.vcs_sourcetree.tree_root
else:
print 'VCS:', 'Not detected'
+ validate_args = Command.validate_args_none
class DetectBSCommand(DetectCommand):
name = "detect-bs"
summary = "detect source tree BS"
- def __init__(self, *args, **kwargs):
- super(DetectBSCommand, self).__init__(*args, **kwargs)
+ def __init__(self, context, *args, **kwargs):
+ super(DetectBSCommand, self).__init__(context, *args, **kwargs)
self.vcs_sourcetree = vcs.VCSourceTree.detect(self.context, self.absdir)
logging.debug("vcs_sourcetree %s", self.vcs_sourcetree)
self.bs_sourcetree = bs.BSSourceTree.detect(self.context,
@@ -231,6 +251,7 @@ class DetectBSCommand(DetectCommand):
print 'BS:', self.bs_sourcetree.name, self.bs_sourcetree.tree_root
else:
print 'BS:', 'Not detected'
+ validate_args = Command.validate_args_none
class BuildTestCommand(SourceClassCommand):
@@ -241,49 +262,37 @@ class BuildTestCommand(SourceClassCommand):
self.bs_sourcetree.configure()
self.bs_sourcetree.build()
self.bs_sourcetree.install()
+ validate_args = Command.validate_args_none
class InitCommand(SourceClassCommand):
name = 'init'
summary = 'initialize buildsystem'
- def validate_args(self, *args, **kwargs):
- """Validate command line arguments"""
- if len(args) > 0:
- raise CommandLineError("'%s' command takes no parameters",
- self.name)
+ validate_args = Command.validate_args_none
def run(self):
self.bs_sourcetree.init()
+
class ConfigureCommand(SourceClassCommand):
name = 'configure'
summary = 'configure buildsystem'
- def validate_args(self, *args, **kwargs):
- """Validate command line arguments"""
- if len(args) > 0:
- raise CommandLineError("'%s' command takes no parameters",
- self.name)
+ validate_args = Command.validate_args_none
def run(self):
self.bs_sourcetree.configure()
+
class BuildCommand(SourceClassCommand):
name = 'build'
summary = 'build from source'
- def validate_args(self, *args, **kwargs):
- """Validate command line arguments"""
- if len(args) > 0:
- raise CommandLineError("'%s' command takes no parameters",
- self.name)
+ validate_args = Command.validate_args_none
def run(self):
self.bs_sourcetree.build()
+
class InstallCommand(SourceClassCommand):
name = 'install'
summary = 'install the built things'
- def validate_args(self, *args, **kwargs):
- """Validate command line arguments"""
- if len(args) > 0:
- raise CommandLineError("'%s' command takes no parameters",
- self.name)
+ validate_args = Command.validate_args_none
def run(self):
self.bs_sourcetree.install()
@@ -291,8 +300,7 @@ class InstallCommand(SourceClassCommand):
class MakeCommand(SourceClassCommand):
name = 'make'
summary = 'run make in builddir'
- def validate_args(self, *args, **kwargs):
- pass
+ validate_args = Command.validate_args_any
def run(self):
os.chdir(self.bs_sourcetree.config.builddir)
progutils.prog_run(["make"] + list(self.args),
@@ -340,34 +348,17 @@ class ConfigCommand(SourceClassCommand):
assert(False)
-########################################################################
-# Commands
-########################################################################
-
+class Commander(object):
-__all__.append('UnknownCommand')
-class UnknownCommand(Exception):
- def __init__(self, cmd):
- super(UnknownCommand, self).__init__()
- self.cmd = cmd
- def __str__(self):
- return "Fatal: Unknown command '%(cmd)s'" % self.__dict__
-
-
-__all__.append('NBB_Command')
-class NBB_Command(object):
- def __init__(self, cmd, cmdargs, context):
+ def __init__(self, context, cmd, *cmdargs):
+ self.context = context
+ logging.debug("Commander() %s %s", cmd, cmdargs)
if cmd in Command.plugins:
- try:
- c = Command.plugins[cmd](*cmdargs, **{'context':context})
- c.run()
- except CommandLineError, e:
- print "%(prog)s: Fatal:" % context, e
- sys.exit(2)
- except progutils.ProgramRunError, e:
- print "%(prog)s: Fatal:" % context, e
- sys.exit(3)
+ self.command = Command.plugins[cmd](context, *cmdargs)
else:
- print "%(prog)s:" % context, UnknownCommand(cmd)
- sys.exit(2)
+ raise UnknownCommand(context, cmd)
+
+ def run(self):
+ self.command.run()
+# End of file.
diff --git a/src/nbblib/main.py b/src/nbblib/main.py
index fabbdad..22c93e3 100644
--- a/src/nbblib/main.py
+++ b/src/nbblib/main.py
@@ -75,6 +75,7 @@ from nbblib import commands
from nbblib import package
from nbblib import plugins
from nbblib import vcs
+from nbblib import progutils
def print_version(context):
@@ -206,14 +207,13 @@ def main(argv):
if len(argv) < 2:
raise commands.CommandLineError(\
- "%(prog)s requires some arguments",
- prog=context.prog)
+ "%(prog)s requires some arguments" % context)
i = 1
while i<len(argv):
if argv[i][0] != '-':
break
- if argv[i] in ('-h', '--help'):
+ elif argv[i] in ('-h', '--help'):
print_help(context)
return
elif argv[i] in ('-V', '--version'):
@@ -225,7 +225,7 @@ def main(argv):
i = i + 1
assert(i<len(argv))
context.bs = argv[i]
- elif argv[i][:6] == '--build-system=':
+ elif argv[i][:15] == '--build-system=':
context.bs = argv[i][6:]
elif argv[i] in ('-v', '--vcs'):
i = i + 1
@@ -236,32 +236,44 @@ def main(argv):
elif argv[i] in ('--info', '--debug'):
pass # acted on in previous stage
else:
- raise commands.CommandLineError('Unknown global option %s' % repr(argv[i]))
- # print "", i, argv[i]
+ raise commands.CommandLineError(\
+ 'Unknown global option %s' % repr(argv[i]))
i = i + 1
+
logging.info("Context: %s", context)
cmd = argv[i]
cmdargs = argv[i+1:]
- nbb = commands.NBB_Command(cmd, cmdargs, context=context)
+
+ cdr = commands.Commander(context, cmd, *cmdargs)
+ cdr.run()
def cmdmain(argv):
try:
main(argv)
logging.shutdown()
+ except commands.CommandLineError, e:
+ logging.error(e)
+ logging.shutdown()
+ sys.exit(2)
+ except commands.UnknownCommand, e:
+ logging.error(e)
+ logging.shutdown()
+ sys.exit(2)
except plugins.PluginNoMatch, e:
+ logging.error(e)
logging.shutdown()
- print e
sys.exit(1)
except plugins.AmbigousPluginDetection, e:
+ logging.error(e)
logging.shutdown()
- print e
sys.exit(1)
- except commands.CommandLineError, e:
+ except progutils.ProgramRunError, e:
+ logging.error(e)
logging.shutdown()
- print e
- sys.exit(2)
+ sys.exit(3)
except SystemExit, e:
+ logging.error("Someone called sys.exit() who should not have", exc_info=e)
logging.shutdown()
raise