diff options
Diffstat (limited to 'src')
-rw-r--r-- | src/Makefile-files | 1 | ||||
-rw-r--r-- | src/nbblib/__init__.py | 1 | ||||
-rw-r--r-- | src/nbblib/commands.py | 314 | ||||
-rw-r--r-- | src/nbblib/nbbcommands.py | 321 | ||||
-rw-r--r-- | src/nbblib/plugins.py | 81 | ||||
-rw-r--r-- | src/nbblib/progutils.py | 13 | ||||
-rw-r--r-- | src/nbblib/test-plugins.py | 85 |
7 files changed, 420 insertions, 396 deletions
diff --git a/src/Makefile-files b/src/Makefile-files index 7336739..ba4cb50 100644 --- a/src/Makefile-files +++ b/src/Makefile-files @@ -9,6 +9,7 @@ nbblib_PYTHON += src/nbblib/__init__.py nbblib_PYTHON += src/nbblib/bs.py nbblib_PYTHON += src/nbblib/commands.py nbblib_PYTHON += src/nbblib/main.py +nbblib_PYTHON += src/nbblib/nbbcommands.py nbblib_PYTHON += src/nbblib/plugins.py nbblib_PYTHON += src/nbblib/progutils.py nbblib_PYTHON += src/nbblib/vcs.py diff --git a/src/nbblib/__init__.py b/src/nbblib/__init__.py index 47b0375..2e2118a 100644 --- a/src/nbblib/__init__.py +++ b/src/nbblib/__init__.py @@ -1,5 +1,6 @@ import nbblib.bs as bs import nbblib.commands as commands +import nbblib.nbbcommands as nbbcommands import nbblib.plugins as plugins import nbblib.package as package import nbblib.progutils as progutils diff --git a/src/nbblib/commands.py b/src/nbblib/commands.py index 126500b..4064742 100644 --- a/src/nbblib/commands.py +++ b/src/nbblib/commands.py @@ -1,37 +1,15 @@ """\ -nbblib.commands - cmdline command infrastructure and implementation +nbblib.commands - generic cmdline command infrastructure Copyright (C) 2008 Hans Ulrich Niedermann <hun@n-dimensional.de> """ -import os -import sys import logging -import nbblib.package as package import nbblib.plugins as plugins -import nbblib.progutils as progutils -import nbblib.vcs as vcs -import nbblib.bs as bs -__all__ = ['Commander'] - - -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] +__all__ = [] __all__.append('CommandLineError') @@ -129,292 +107,7 @@ class Command(object): 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() - if not keys: - 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))) - print "keys ", keys - print "keys2", keys2 - fmt = "\t%%-%ds\t%%s" % len(keys2[0]) - for k in keys: - print fmt % (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' - 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()) - print "Commands:", ", ".join(Command.plugins.keys()) - - -class SourceClassCommand(Command): - """Base class for commands acting on source trees""" - name = None # abstract command class - def __init__(self, context, *args, **kwargs): - super(SourceClassCommand, self).__init__(context, *args, **kwargs) - - srcdir = os.getcwd() - absdir = os.path.abspath(srcdir) - - self.vcs_sourcetree = vcs.VCSourceTree.detect(context, absdir) - logging.debug("vcs_sourcetree %s", self.vcs_sourcetree) - - self.bs_sourcetree = bs.BSSourceTree.detect(context, - self.vcs_sourcetree) - logging.debug("bs_sourcetree %s", self.bs_sourcetree) - - cfg = self.vcs_sourcetree.config - for x in ('srcdir', 'builddir', 'installdir'): - logging.info("CONFIG %s %s", x, getattr(cfg, x)) - - -class DetectCommand(Command): - name = None - def __init__(self, context, *args, **kwargs): - super(DetectCommand, self).__init__(context, *args, **kwargs) - self.srcdir = os.getcwd() - self.absdir = os.path.abspath(self.srcdir) - validate_args = Command.validate_args_none - - -class DetectVCSCommand(DetectCommand): - name = "detect-vcs" - summary = "detect source tree VCS" - 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): - if self.vcs_sourcetree: - 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, 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, - self.vcs_sourcetree) - logging.debug("bs_sourcetree %s", self.bs_sourcetree) - def run(self): - if self.bs_sourcetree: - 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): - 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() - validate_args = Command.validate_args_none - - -class InitCommand(SourceClassCommand): - name = 'init' - summary = 'initialize buildsystem (e.g. "autoreconf")' - validate_args = Command.validate_args_none - def run(self): - self.bs_sourcetree.init() - - -class ConfigureCommand(SourceClassCommand): - name = 'configure' - summary = 'configure buildsystem (e.g. "./configure")' - validate_args = Command.validate_args_none - def run(self): - self.bs_sourcetree.configure() - - -class BuildCommand(SourceClassCommand): - name = 'build' - summary = 'build from source (e.g. "make")' - validate_args = Command.validate_args_none - def run(self): - self.bs_sourcetree.build() - - -class InstallCommand(SourceClassCommand): - name = 'install' - summary = 'install the built things (e.g. "make install")' - validate_args = Command.validate_args_none - def run(self): - self.bs_sourcetree.install() - - -class MakeCommand(SourceClassCommand): - name = 'make' - summary = 'run make in builddir' - validate_args = Command.validate_args_any - def run(self): - os.chdir(self.bs_sourcetree.config.builddir) - progutils.prog_run(["make"] + list(self.args), - self.context) - - -class GeneralRunCommand(SourceClassCommand): - """Run general command in some branch specific dir - - """ - name = 'run' - summary = 'run some command in branch specific dir' - validate_args = Command.validate_args_any - def __init__(self, context, *args, **kwargs): - super(GeneralRunCommand, self).__init__(context, *args, **kwargs) - self.rundir = None - self.run_in = 'builddir' - if len(self.args): - if self.args[0] == '--srcdir': - self.args = self.args[1:] - self.rundir = self.bs_sourcetree.config.srcdir - self.run_in = 'srcdir' - elif self.args[0] == '--installdir': - self.args = self.args[1:] - self.rundir = self.bs_sourcetree.config.installdir - self.run_in = 'installdir' - elif self.args[0] == '--builddir': - self.args = self.args[1:] - if not self.rundir: - self.rundir = self.bs_sourcetree.config.builddir - def chdir(self): - if os.path.exists(self.rundir): - os.chdir(self.rundir) - else: - raise RuntimeError("The %s directory %s does not exist" - % (self.run_in, repr(self.rundir))) - def run(self): - self.chdir() - progutils.prog_run(list(self.args), self.context) - - -class GeneralShellCommand(GeneralRunCommand): - name = 'sh' - summary = 'run shell in branch specific dir' - def get_shell_prompt(self): - return r",--[Ctrl-d or 'exit' to quit this %s shell for branch '%s']--\n| <%s %s> %s\n\`--[\u@\h \W]\$ " \ - % (self.context.prog, self.vcs_sourcetree.branch_name, - self.context.prog, self.name, self.get_run_in_dir(), ) - def run(self): - self.chdir() - # FIXME: Allow using $SHELL or similar. - progutils.prog_run(['sh'] + list(self.args), self.context, - env_update = {'PS1': self.get_shell_prompt()}) - - -class SrcShellCommand(GeneralShellCommand): - name = 'sh-src' - summary = 'run interactive shell in source dir' - run_in = 'srcdir' - - -class BuildShellCommand(GeneralShellCommand): - name = 'sh-build' - summary = 'run interactive shell in build dir' - run_in = 'builddir' - - -class InstallShellCommand(GeneralShellCommand): - name = 'sh-install' - summary = 'run interactive shell in install dir' - run_in = 'installdir' - - -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' command 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) - - +__all__.append('Commander') class Commander(object): def __init__(self, context, cmd, *cmdargs): @@ -428,4 +121,3 @@ class Commander(object): def run(self): self.command.run() -# End of file. diff --git a/src/nbblib/nbbcommands.py b/src/nbblib/nbbcommands.py new file mode 100644 index 0000000..19d993e --- /dev/null +++ b/src/nbblib/nbbcommands.py @@ -0,0 +1,321 @@ +"""\ +nbblib.nbbcommands - implementation of nbb commands +Copyright (C) 2008 Hans Ulrich Niedermann <hun@n-dimensional.de> +""" + +import sys +import os +import logging + + +import nbblib.package as package +import nbblib.progutils as progutils +import nbblib.vcs as vcs +import nbblib.bs as bs +from nbblib.commands 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 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() + if not keys: + 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))) + print "keys ", keys + print "keys2", keys2 + fmt = "\t%%-%ds\t%%s" % len(keys2[0]) + for k in keys: + print fmt % (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' + 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()) + print "Commands:", ", ".join(Command.plugins.keys()) + + +class SourceClassCommand(Command): + """Base class for commands acting on source trees""" + name = None # abstract command class + def __init__(self, context, *args, **kwargs): + super(SourceClassCommand, self).__init__(context, *args, **kwargs) + + srcdir = os.getcwd() + absdir = os.path.abspath(srcdir) + + self.vcs_sourcetree = vcs.VCSourceTree.detect(context, absdir) + logging.debug("vcs_sourcetree %s", self.vcs_sourcetree) + + self.bs_sourcetree = bs.BSSourceTree.detect(context, + self.vcs_sourcetree) + logging.debug("bs_sourcetree %s", self.bs_sourcetree) + + cfg = self.vcs_sourcetree.config + for x in ('srcdir', 'builddir', 'installdir'): + logging.info("CONFIG %s %s", x, getattr(cfg, x)) + + +class DetectCommand(Command): + name = None + def __init__(self, context, *args, **kwargs): + super(DetectCommand, self).__init__(context, *args, **kwargs) + self.srcdir = os.getcwd() + self.absdir = os.path.abspath(self.srcdir) + validate_args = Command.validate_args_none + + +class DetectVCSCommand(DetectCommand): + name = "detect-vcs" + summary = "detect source tree VCS" + 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): + if self.vcs_sourcetree: + 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, 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, + self.vcs_sourcetree) + logging.debug("bs_sourcetree %s", self.bs_sourcetree) + def run(self): + if self.bs_sourcetree: + 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): + 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() + validate_args = Command.validate_args_none + + +class InitCommand(SourceClassCommand): + name = 'init' + summary = 'initialize buildsystem (e.g. "autoreconf")' + validate_args = Command.validate_args_none + def run(self): + self.bs_sourcetree.init() + + +class ConfigureCommand(SourceClassCommand): + name = 'configure' + summary = 'configure buildsystem (e.g. "./configure")' + validate_args = Command.validate_args_none + def run(self): + self.bs_sourcetree.configure() + + +class BuildCommand(SourceClassCommand): + name = 'build' + summary = 'build from source (e.g. "make")' + validate_args = Command.validate_args_none + def run(self): + self.bs_sourcetree.build() + + +class InstallCommand(SourceClassCommand): + name = 'install' + summary = 'install the built things (e.g. "make install")' + validate_args = Command.validate_args_none + def run(self): + self.bs_sourcetree.install() + + +class MakeCommand(SourceClassCommand): + name = 'make' + summary = 'run make in builddir' + validate_args = Command.validate_args_any + def run(self): + os.chdir(self.bs_sourcetree.config.builddir) + progutils.prog_run(["make"] + list(self.args), + self.context) + + +class GeneralRunCommand(SourceClassCommand): + """Run general command in some branch specific dir + + """ + name = 'run' + summary = 'run some command in branch specific dir' + validate_args = Command.validate_args_any + def __init__(self, context, *args, **kwargs): + super(GeneralRunCommand, self).__init__(context, *args, **kwargs) + self.rundir = None + self.run_in = 'builddir' + if len(self.args): + if self.args[0] == '--srcdir': + self.args = self.args[1:] + self.rundir = self.bs_sourcetree.config.srcdir + self.run_in = 'srcdir' + elif self.args[0] == '--installdir': + self.args = self.args[1:] + self.rundir = self.bs_sourcetree.config.installdir + self.run_in = 'installdir' + elif self.args[0] == '--builddir': + self.args = self.args[1:] + if not self.rundir: + self.rundir = self.bs_sourcetree.config.builddir + def chdir(self): + if os.path.exists(self.rundir): + os.chdir(self.rundir) + else: + raise RuntimeError("The %s directory %s does not exist" + % (self.run_in, repr(self.rundir))) + def run(self): + self.chdir() + progutils.prog_run(list(self.args), self.context) + + +class GeneralShellCommand(GeneralRunCommand): + name = 'sh' + summary = 'run shell in branch specific dir' + def get_shell_prompt(self): + return r",--[Ctrl-d or 'exit' to quit this %s shell for branch '%s']--\n| <%s %s> %s\n\`--[\u@\h \W]\$ " \ + % (self.context.prog, self.vcs_sourcetree.branch_name, + self.context.prog, self.name, self.get_run_in_dir(), ) + def run(self): + self.chdir() + # FIXME: Allow using $SHELL or similar. + progutils.prog_run(['sh'] + list(self.args), self.context, + env_update = {'PS1': self.get_shell_prompt()}) + + +class SrcShellCommand(GeneralShellCommand): + name = 'sh-src' + summary = 'run interactive shell in source dir' + run_in = 'srcdir' + + +class BuildShellCommand(GeneralShellCommand): + name = 'sh-build' + summary = 'run interactive shell in build dir' + run_in = 'builddir' + + +class InstallShellCommand(GeneralShellCommand): + name = 'sh-install' + summary = 'run interactive shell in install dir' + run_in = 'installdir' + + +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' command 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) + + +# End of file. + diff --git a/src/nbblib/plugins.py b/src/nbblib/plugins.py index 784b49e..c37b8a1 100644 --- a/src/nbblib/plugins.py +++ b/src/nbblib/plugins.py @@ -5,7 +5,7 @@ Basic plugin architecture (metaclass tricks) by Marty Alchin from http://gulopine.gamemusic.org/2008/jan/10/simple-plugin-framework/ GenericPluginMeta slightly modified to - - store plugins as dict + - store named plugins as dict - support plugin class hierarchies Extended by GenericDetectPlugin to - support auto-detection of the adequate plugin @@ -315,82 +315,3 @@ class GenericDetectPlugin(object): return matches[matches.keys()[0]] -# Not for __all__ -def selftest(): - - class PluginNoMatchA(PluginNoMatch): - pass - class AmbigousPluginDetectionA(AmbigousPluginDetection): - pass - - - class TestDetectPluginA(GenericDetectPlugin): - __metaclass__ = GenericPluginMeta - no_match_exception = PluginNoMatchA - ambigous_match_exception = AmbigousPluginDetectionA - @classmethod - def validate(cls, obj, context, *args, **kwargs): - logging.debug("Aval") - return False - - - class TestDetectPluginB(GenericDetectPlugin): - __metaclass__ = GenericPluginMeta - - - class TestDetectPluginC(GenericDetectPlugin): - __metaclass__ = GenericPluginMeta - @classmethod - def validate(cls, obj, context, *args, **kwargs): - logging.debug("Cval") - return False - - - class TestDetectPluginA1(TestDetectPluginA): - name = "A1" - class TestDetectPluginA2(TestDetectPluginA): - name = "A2" - class TestDetectPluginA3(TestDetectPluginA): - name = "A3" - - class TestDetectPluginB1(TestDetectPluginB): - name = "B1" - class TestDetectPluginB2(TestDetectPluginB): - name = "B2" - class TestDetectPluginB3(TestDetectPluginB): - name = "B3" - - class TestDetectPluginC1(TestDetectPluginC): - name = "C1" - class TestDetectPluginC2(TestDetectPluginC): - name = "C2" - class TestDetectPluginC3(TestDetectPluginC): - name = "C3" - @classmethod - def validate(cls, obj, context, *args, **kwargs): - logging.debug("C3val") - return True - - ctx = None - - print "GenericPluginMeta", dir(GenericPluginMeta) - print "GenericDetectPlugin", dir(GenericDetectPlugin) - print "TestDetectPluginA", dir(TestDetectPluginA) - print "TestDetectPluginA", dir(TestDetectPluginA) - print "TestDetectPluginB", dir(TestDetectPluginB) - print "TestDetectPluginC", dir(TestDetectPluginC) - - try: - a = TestDetectPluginA.detect(ctx) - except: - logging.error("aaaa", exc_info=True) - - try: - b = TestDetectPluginB.detect(ctx) - except: - logging.error("bbbb", exc_info=True) - - try: - c = TestDetectPluginC.detect(ctx) - except: - logging.error("cccc", exc_info=True) diff --git a/src/nbblib/progutils.py b/src/nbblib/progutils.py index 456405e..0486d99 100644 --- a/src/nbblib/progutils.py +++ b/src/nbblib/progutils.py @@ -7,6 +7,9 @@ import os import subprocess +__all__ = ['prog_stdout', 'prog_retstd', 'ProgramRunError', 'prog_run'] + + def prog_stdout(call_list): """Run program and return stdout (similar to shell backticks)""" p = subprocess.Popen(call_list, @@ -41,13 +44,17 @@ class ProgramRunError(Exception): repr(self.cwd))) -def prog_run(call_list, context): +def prog_run(call_list, context=None, env=None, env_update=None): """Run program showing its output. Raise exception if retcode != 0.""" print "RUN:", call_list print " in", os.getcwd() - if context.dry_run: + if context and context.dry_run: return None - p = subprocess.Popen(call_list) + if not env: + env = os.environ.copy() + if env_update: + env.update(env_update) + p = subprocess.Popen(call_list, env=env) stdout, stderr = p.communicate(input=None) if p.returncode != 0: raise ProgramRunError(call_list, p.returncode, os.getcwd()) diff --git a/src/nbblib/test-plugins.py b/src/nbblib/test-plugins.py index 1187062..aee2d23 100644 --- a/src/nbblib/test-plugins.py +++ b/src/nbblib/test-plugins.py @@ -14,6 +14,87 @@ if True: logging.error("xxx error") -import plugins -plugins.selftest() +from plugins import * + +# Not for __all__ +def selftest(): + + class PluginNoMatchA(PluginNoMatch): + pass + class AmbigousPluginDetectionA(AmbigousPluginDetection): + pass + + + class TestDetectPluginA(GenericDetectPlugin): + __metaclass__ = GenericPluginMeta + no_match_exception = PluginNoMatchA + ambigous_match_exception = AmbigousPluginDetectionA + @classmethod + def validate(cls, obj, context, *args, **kwargs): + logging.debug("Aval") + return False + + + class TestDetectPluginB(GenericDetectPlugin): + __metaclass__ = GenericPluginMeta + + + class TestDetectPluginC(GenericDetectPlugin): + __metaclass__ = GenericPluginMeta + @classmethod + def validate(cls, obj, context, *args, **kwargs): + logging.debug("Cval") + return False + + + class TestDetectPluginA1(TestDetectPluginA): + name = "A1" + class TestDetectPluginA2(TestDetectPluginA): + name = "A2" + class TestDetectPluginA3(TestDetectPluginA): + name = "A3" + + class TestDetectPluginB1(TestDetectPluginB): + name = "B1" + class TestDetectPluginB2(TestDetectPluginB): + name = "B2" + class TestDetectPluginB3(TestDetectPluginB): + name = "B3" + + class TestDetectPluginC1(TestDetectPluginC): + name = "C1" + class TestDetectPluginC2(TestDetectPluginC): + name = "C2" + class TestDetectPluginC3(TestDetectPluginC): + name = "C3" + @classmethod + def validate(cls, obj, context, *args, **kwargs): + logging.debug("C3val") + return True + + ctx = None + + print "GenericPluginMeta", dir(GenericPluginMeta) + print "GenericDetectPlugin", dir(GenericDetectPlugin) + print "TestDetectPluginA", dir(TestDetectPluginA) + print "TestDetectPluginA", dir(TestDetectPluginA) + print "TestDetectPluginB", dir(TestDetectPluginB) + print "TestDetectPluginC", dir(TestDetectPluginC) + + try: + a = TestDetectPluginA.detect(ctx) + except: + logging.error("aaaa", exc_info=True) + + try: + b = TestDetectPluginB.detect(ctx) + except: + logging.error("bbbb", exc_info=True) + + try: + c = TestDetectPluginC.detect(ctx) + except: + logging.error("cccc", exc_info=True) + +selftest() |