1
0
mirror of https://github.com/openSUSE/osc.git synced 2025-02-02 17:56:15 +01:00

- reworked the plugin loading mechanism

Using the "old" exec approach isn't possible anymore because it'll break all
plugins which aren't compatible with python3 (for instance the usage of
python2's "print" statement will lead to an error). In order to circumvent
this problem we do the following:

- import the plugin/module
- update the module's global symbol table with the "globals()" of the
  commandline module
- bind the module's "do_*" functions to the "Osc" class

This basically mimics the old "exec" semantics.
This commit is contained in:
Marcus Huewe 2013-06-13 19:57:34 +02:00
parent d618c53bfe
commit b6c9505274

View File

@ -10,6 +10,8 @@ from . import conf
from . import oscerr from . import oscerr
import sys import sys
import time import time
import imp
import inspect
try: try:
from urllib.parse import urlsplit from urllib.parse import urlsplit
from urllib.error import HTTPError from urllib.error import HTTPError
@ -75,6 +77,9 @@ class Osc(cmdln.Cmdln):
man_footer = MAN_FOOTER man_footer = MAN_FOOTER
def __init__(self, *args, **kwargs): def __init__(self, *args, **kwargs):
# the plugins have to be loaded before the
# superclass' __init__ method is called
self._load_plugins()
cmdln.Cmdln.__init__(self, *args, **kwargs) cmdln.Cmdln.__init__(self, *args, **kwargs)
cmdln.Cmdln.do_help.aliases.append('h') cmdln.Cmdln.do_help.aliases.append('h')
sys.stderr = safewriter.SafeWriter(sys.stderr) sys.stderr = safewriter.SafeWriter(sys.stderr)
@ -7900,22 +7905,28 @@ Please submit there instead, or use --nodevelproject to force direct submission.
print('done. Please check the state of the wc (via \'osc status %s\').' % i) print('done. Please check the state of the wc (via \'osc status %s\').' % i)
else: else:
print('osc: working copy \'%s\' is not inconsistent' % i, file=sys.stderr) print('osc: working copy \'%s\' is not inconsistent' % i, file=sys.stderr)
# fini!
###############################################################################
# load subcommands plugged-in locally def _load_plugins(self):
plugin_dirs = [ plugin_dirs = [
'/usr/lib/osc-plugins', '/usr/lib/osc-plugins',
'/usr/local/lib/osc-plugins', '/usr/local/lib/osc-plugins',
'/var/lib/osc-plugins', # Kept for backward compatibility '/var/lib/osc-plugins', # Kept for backward compatibility
os.path.expanduser('~/.osc-plugins')] os.path.expanduser('~/.osc-plugins')]
for plugin_dir in plugin_dirs: for plugin_dir in plugin_dirs:
if os.path.isdir(plugin_dir): if not os.path.isdir(plugin_dir):
continue
for extfile in os.listdir(plugin_dir): for extfile in os.listdir(plugin_dir):
if not extfile.endswith('.py'): if not extfile.endswith('.py'):
continue continue
try: try:
exec(open(os.path.join(plugin_dir, extfile)).read()) modname = os.path.splitext(extfile)[0]
mod = imp.load_source(modname, os.path.join(plugin_dir, extfile))
# restore the old exec semantic
mod.__dict__.update(globals())
for name in dir(mod):
func = getattr(mod, name)
if name.startswith('do_') and inspect.isfunction(func):
setattr(self.__class__, name, func)
except SyntaxError as e: except SyntaxError as e:
if (os.environ.get('OSC_PLUGIN_FAIL_IGNORE')): if (os.environ.get('OSC_PLUGIN_FAIL_IGNORE')):
print("%s: %s\n" % (os.path.join(plugin_dir, extfile), e), file=sys.stderr) print("%s: %s\n" % (os.path.join(plugin_dir, extfile), e), file=sys.stderr)
@ -7926,5 +7937,7 @@ Please submit there instead, or use --nodevelproject to force direct submission.
print("\n Try 'env OSC_PLUGIN_FAIL_IGNORE=1 osc ...'", file=sys.stderr) print("\n Try 'env OSC_PLUGIN_FAIL_IGNORE=1 osc ...'", file=sys.stderr)
sys.exit(1) sys.exit(1)
# fini!
###############################################################################
# vim: sw=4 et # vim: sw=4 et