summaryrefslogtreecommitdiffstats
path: root/nbb/nbblib/commands.py
diff options
context:
space:
mode:
Diffstat (limited to 'nbb/nbblib/commands.py')
-rw-r--r--nbb/nbblib/commands.py234
1 files changed, 234 insertions, 0 deletions
diff --git a/nbb/nbblib/commands.py b/nbb/nbblib/commands.py
new file mode 100644
index 0000000..9fcb038
--- /dev/null
+++ b/nbb/nbblib/commands.py
@@ -0,0 +1,234 @@
+import os
+
+from nbblib.package import *
+from nbblib.plugins import *
+from nbblib.progutils import *
+from nbblib.vcs import *
+from nbblib.bs import *
+
+
+def adjust_doc(doc):
+ """Remove common whitespace at beginning of doc string lines"""
+ if not doc: return doc
+ i = 0
+ for i in range(len(doc)):
+ if doc[i] not in " \t":
+ break
+ prefix = doc[:i]
+ rest_doc = doc[i:]
+ almost_doc = rest_doc.replace("\n%s" % prefix, "\n")
+ i = -1
+ while almost_doc[i] == '\n':
+ i = i - 1
+ return almost_doc[:i]
+
+
+class CommandLineError(Exception):
+ def __init__(self, message, *args):
+ super(CommandLineError, self).__init__()
+ if args:
+ self.msg = message % args
+ else:
+ self.msg = message
+ def __str__(self):
+ return "Command line error: %s" % self.msg
+
+
+########################################################################
+# Command plugin system
+########################################################################
+
+class Command(object):
+ """
+ Mount point for plugins which refer to commands that can be performed.
+
+ Plugins implementing this reference should provide the following
+ interface:
+
+ name attribute
+ The text to be displayed, describing the version control system
+ summary attribute
+ Short (less than 50 chars) command summary line
+ usage attribute
+ Usage string (defaults to '')
+
+ validate_args(*args, **kwargs) function
+ Must raise CommandLineError() if it encounters invalid arguments in cmdargs
+ run() function
+ Actually run the function
+
+ FFF(*args, **kwargs)
+ *args are the arguments from the command line
+ **kwargs are additional parameters from within the program
+ """
+ __metaclass__ = GenericPluginMeta
+
+ usage = ''
+
+ def __init__(self, *args, **kwargs):
+ self.validate_args(*args, **kwargs)
+ self.args = args
+ self.kwargs = kwargs
+ self.context = kwargs['context']
+
+ def run(self):
+ """Run the command"""
+ raise NotImplementedError()
+
+ def validate_args(self, *args, **kwargs):
+ """Validate command line arguments"""
+ print "Command: ", self.name
+ print "*args: ", args
+ print "**kwargs:", kwargs
+ if len(args) > 0:
+ raise CommandLineError("'%s' command takes no parameters", self.name)
+
+ def __str__(self):
+ return "Command(%s, %s)" % (self.cmd_name, self.cmdargs)
+
+
+class HelpCommand(Command):
+ """\
+ If the optional <command> is given, print the help for <command>.
+ Else, print a list of commands and general help.
+ """
+
+ name = 'help'
+ summary = 'print help text'
+ usage = '[<command>]'
+
+ def validate_args(self, *args, **kwargs):
+ if len(args) == 1 and args[0] not in Command.plugins.keys():
+ raise CommandLineError("'%s' is an invalid command name", args[0])
+ elif len(args) > 1:
+ raise CommandLineError("'%s' command only takes one optional parameter", self.name)
+
+ def _print_command_list(self):
+ print "List of commands:"
+ keys = Command.plugins.keys()
+ keys.sort()
+ for k in keys:
+ print "\t%-15s\t%s" % (k, Command.plugins[k].summary)
+
+ def _print_command_help(self, cmd):
+ """print help for command cmd"""
+ c = Command.plugins[cmd]
+ print "Purpose:", c.summary
+ if c.usage:
+ print "Usage: ", self.context.prog, cmd, c.usage
+ else:
+ print "Usage: ", self.context.prog, cmd
+ if hasattr(c, '__doc__'):
+ if c.__doc__:
+ print
+ print adjust_doc(c.__doc__)
+
+ def run(self):
+ if len(self.args) == 0:
+ self._print_command_list()
+ elif len(self.args) == 1:
+ self._print_command_help(self.args[0])
+ else:
+ assert(False)
+
+
+class InternalConfigCommand(Command):
+ name = 'internal-config'
+ summary = 'print internal program configuration'
+ def run(self):
+ print "Source tree types:", ", ".join(VCSourceTree.plugins.keys())
+ print "Build system types:", ", ".join(BSSourceTree.plugins.keys())
+ print "Commands:", ", ".join(Command.plugins.keys())
+
+
+class SourceClassCommand(Command):
+ """Base class for commands acting on source trees"""
+ def __init__(self, *args, **kwargs):
+ super(SourceClassCommand, self).__init__(*args, **kwargs)
+ context = kwargs['context']
+ srcdir = os.getcwd()
+ absdir = os.path.abspath(srcdir)
+ self.vcs_sourcetree = VCSourceTree.detect(absdir, context)
+ if context.verbose:
+ print "vcs_sourcetree", str(self.vcs_sourcetree)
+ assert(self.vcs_sourcetree)
+ cfg = self.vcs_sourcetree.config
+ self.bs_sourcetree = BSSourceTree.detect(self.vcs_sourcetree, context)
+ if context.verbose:
+ print "bs_sourcetree", str(self.bs_sourcetree)
+ print "CONFIG", cfg
+ print " ", "srcdir", cfg.srcdir
+ print " ", "builddir", cfg.builddir
+ print " ", "installdir", cfg.installdir
+
+
+class BuildTestCommand(SourceClassCommand):
+ name = 'build-test'
+ summary = 'simple build test'
+ def run(self):
+ self.bs_sourcetree.init()
+ self.bs_sourcetree.configure()
+ self.bs_sourcetree.build()
+ self.bs_sourcetree.install()
+
+
+class ConfigCommand(SourceClassCommand):
+ name = 'config'
+ summary = 'set/get config values'
+ usage = '(srcdir|builddir|installdir)'
+
+ def validate_args(self, *args, **kwargs):
+ items = ('srcdir', 'builddir', 'installdir', )
+ if len(args) == 0:
+ raise CommandLineError("'%s' requires at least one parameter (%s)", self.name,
+ ', '.join(items))
+ elif len(args) == 1 and args[0] in items:
+ pass
+ elif len(args) == 2 and args[0] in items:
+ if args[0] in ('srcdir', ):
+ raise CommandLineError("'%s' command cannot change 'srcdir'", self.name)
+ else:
+ pass
+ else:
+ raise CommandLineError("'%s' requires less or different parameters", self.name)
+
+ def run(self):
+ git_get_items = ('builddir', 'installdir', 'srcdir')
+ git_set_items = ('builddir', 'installdir', )
+ if len(self.args) == 1:
+ if self.args[0] in git_get_items:
+ print getattr(self.vcs_sourcetree.config, self.args[0])
+ else:
+ assert(False)
+ elif len(self.args) == 2:
+ if self.args[0] == 'builddir':
+ self.vcs_sourcetree.config.builddir = self.args[1]
+ elif self.args[0] == 'installdir':
+ self.vcs_sourcetree.config.installdir = self.args[1]
+ else:
+ assert(False)
+ else:
+ assert(False)
+
+
+########################################################################
+# Commands
+########################################################################
+
+class NBB_Command(object):
+ def __init__(self, cmd, cmdargs, context):
+ if Command.plugins.has_key(cmd):
+ try:
+ c = Command.plugins[cmd](*cmdargs, **{'context':context})
+ c.run()
+ except CommandLineError, e:
+ print "%(prog)s: Fatal:" % context, e
+ sys.exit(2)
+ except ProgramRunError, e:
+ print "%(prog)s: Fatal:" % context, e
+ print "Program aborted."
+ else:
+ print "Fatal: Unknown command '%s'" % cmd
+ raise NotImplementedError()
+ return
+