From a5549505460ee3d595e5d81cc9175087daa30641 Mon Sep 17 00:00:00 2001 From: Frank Winklmeier <frank.winklmeier@cern.ch> Date: Wed, 15 May 2019 11:38:50 +0200 Subject: [PATCH] acmd: Remove dependency on extensions module Implement a trivial plugin registration to remove the dependency on the `extensions` module. Also remove some unused code and options. Add dependency on `requests` module (from LCG) to ensure the jira plugin works correctly. --- Tools/PyUtils/CMakeLists.txt | 1 + Tools/PyUtils/bin/acmd.py | 37 ++------- Tools/PyUtils/python/acmdlib.py | 101 +++++++---------------- Tools/PyUtils/python/scripts/__init__.py | 33 ++++---- 4 files changed, 55 insertions(+), 117 deletions(-) diff --git a/Tools/PyUtils/CMakeLists.txt b/Tools/PyUtils/CMakeLists.txt index b372e3c30ea..4742e0f294c 100644 --- a/Tools/PyUtils/CMakeLists.txt +++ b/Tools/PyUtils/CMakeLists.txt @@ -12,6 +12,7 @@ atlas_depends_on_subdirs( PUBLIC # External dependencies: find_package( PythonLibs ) +find_package( requests ) find_package( ROOT COMPONENTS Core PyROOT Tree MathCore Hist RIO pthread ) # Install files from the package: diff --git a/Tools/PyUtils/bin/acmd.py b/Tools/PyUtils/bin/acmd.py index 7c3f0e78694..eca71801e94 100755 --- a/Tools/PyUtils/bin/acmd.py +++ b/Tools/PyUtils/bin/acmd.py @@ -1,41 +1,24 @@ #!/usr/bin/env python -# Copyright (C) 2002-2017 CERN for the benefit of the ATLAS collaboration +# Copyright (C) 2002-2019 CERN for the benefit of the ATLAS collaboration # @file PyUtils.acmd # @purpose main command line script for the general purpose athena scripts # @author Sebastien Binet # @date January 2010 -from __future__ import with_statement - -__version__ = "$Revision: 276499 $" __author__ = "Sebastien Binet" __doc__ = "main command line script for the general purpose athena scripts" import PyUtils.acmdlib as acmdlib +import sys def main(): - import PyUtils.scripts + import PyUtils.scripts # noqa: F401 (register all plugins) import PyUtils.Logging as L msg = L.logging.getLogger('Acmd') msg.setLevel(L.logging.INFO) - ## if 0: - ## acmdlib.register_file('acmd_plugins.cfg') - ## else: - ## import os - ## if os.path.exists('acmd_plugins.py'): - ## execfile('acmd_plugins.py') - - commands = {} - plugins = list(acmdlib.ext_plugins.get(group=acmdlib.ACMD_GROUPNAME)) - #print plugins - for i, plugin in enumerate(plugins): - #print i, plugin.name - commands[plugin.name] = plugin - - if 1: - acmdlib._load_commands() + acmdlib.Plugins.loadAll() parser = acmdlib.ACMD_PARSER args = parser.parse_args() @@ -43,7 +26,6 @@ def main(): msg.info('running sub-command [%s]...', args.command) cmd_name = args.command - import sys sys_args = sys.argv[1:] if sys_args[0] != cmd_name: # special case of a sub(sub,...) command: @@ -52,21 +34,18 @@ def main(): idx = sys_args.index(cmd_name) cmd_name = '.'.join(sys_args[:idx+1]) - cmd = commands[cmd_name].load() + cmd = acmdlib.Plugins.load(cmd_name) exitcode = 1 try: - exitcode = cmd(args) + exitcode = cmd.main(args) except Exception: exitcode = 1 - import sys - print sys.exc_info()[0] - print sys.exc_info()[1] + print(sys.exc_info()[0]) + print(sys.exc_info()[1]) raise return exitcode if __name__ == "__main__": - import sys sys.exit(main()) - diff --git a/Tools/PyUtils/python/acmdlib.py b/Tools/PyUtils/python/acmdlib.py index dee104d6bf8..d8120d792dc 100644 --- a/Tools/PyUtils/python/acmdlib.py +++ b/Tools/PyUtils/python/acmdlib.py @@ -1,4 +1,4 @@ -# Copyright (C) 2002-2017 CERN for the benefit of the ATLAS collaboration +# Copyright (C) 2002-2019 CERN for the benefit of the ATLAS collaboration # @file PyUtils.acmdlib # @purpose a library to ease the writing of sub-command scripts @@ -16,14 +16,12 @@ __all__ = [ 'command', 'argument', 'register', - 'register_file', ] ### imports ------------------------------------------------------------------- -import sys -import extensions as ext_plugins import argparse import textwrap +import importlib ### globals ------------------------------------------------------------------- ACMD_GROUPNAME = 'acmdlib.commands' @@ -60,11 +58,7 @@ class Command(object): self.parser = self._make_parser(**kwargs) self._init_arguments() plugin_name = kwargs.get('name') or self.name - register( - plugin_name, - '%s:%s' % (self.fct.__module__, self.fct.__name__) - ) - return + register(plugin_name, self.fct.__module__) @property def name(self): @@ -110,7 +104,6 @@ class Command(object): name = names[idx] if name in node.choices: return node.choices[name] - full_name = ' '.join(names[:idx+1]) args = { 'name' : name, 'help' : 'a group of sub-commands', @@ -137,6 +130,33 @@ class Command(object): pass # Command +class Plugins(object): + """A simple plugin registration. + """ + _plugins = {} + + @classmethod + def register(cls, name, value): + """Register plugin + """ + cls._plugins[name] = value + + @classmethod + def load(cls, name): + """Load given plugin and return it + """ + try: + return importlib.import_module(cls._plugins[name]) + except Exception as err: + print("** could not load command [%s]:\n%s" % (name, err)) + + @classmethod + def loadAll(cls): + """Load all plugins + """ + for k in cls._plugins.keys(): + cls.load(k) + ### functions ----------------------------------------------------------------- def command(*args, **kwargs): @@ -168,63 +188,4 @@ def register(name, value): ex: register('check-file', 'PyUtils.CheckFileLib:fct') """ - group = ACMD_GROUPNAME - return ext_plugins.register(group, name, value) - -def register_file(path): - """Registers a config-like file""" - from ConfigParser import ConfigParser - parser = ConfigParser() - parser.read([path]) - for group in parser.sections(): - for name in parser.options(group): - value = parser.get(group, name) - ext_plugins.register(group, name, value) - -# add a special command to list all registered commands -@command -@argument('-d','--detailed', action='store_true', default=False, - help='print full help of each command') -def list_commands(args): - """a special command to list all the commands 'acmd' can run - """ - cmds = list(ext_plugins.get(group=ACMD_GROUPNAME)) - if len(cmds) == 0: - print "::: no command found in registry" - return 1 - print "::: found [%i] command%s" % (len(cmds), - "s" if len(cmds)>1 else "") - cmds.sort(cmp=lambda x,y: cmp(x.name, y.name)) - cmds = [cmd for cmd in cmds if cmd.name != 'list-commands'] - for i, cmd in enumerate(cmds): - if args.detailed: - print "="*80 - print " - %s" % (' '.join(cmd.name.split('.')),) - if args.detailed: - try: - cmd.load().parser.print_help() - except Exception,err: - print "** could not inspect command [%s]:\n%s" % ( - cmd.name, - err) - print "="*80 - print "" - return 0 -#acmdlib.register('list-commands', 'PyUtils.acmdlib:list_commands') - -# an argument to force the loading of all available commands -ACMD_PARSER.add_argument( - '--load-commands', - action='store_true', - default=False, - help='force the loading of all available commands') -def _load_commands(): - cmds = list(ext_plugins.get(group=ACMD_GROUPNAME)) - for cmd in cmds: - try: - cmd.load() - except Exception,err: - print "** could not load command [%s]:\n%s" % ( - cmd.name, - err) - + return Plugins.register(name, value) diff --git a/Tools/PyUtils/python/scripts/__init__.py b/Tools/PyUtils/python/scripts/__init__.py index fac15a1bbcc..b0c5d373f70 100644 --- a/Tools/PyUtils/python/scripts/__init__.py +++ b/Tools/PyUtils/python/scripts/__init__.py @@ -1,26 +1,23 @@ -# Copyright (C) 2002-2017 CERN for the benefit of the ATLAS collaboration +# Copyright (C) 2002-2019 CERN for the benefit of the ATLAS collaboration # hook for PyUtils.scripts package -# FIXME: waiting for a proper declarative file import PyUtils.acmdlib as acmdlib -acmdlib.register('chk-file', 'PyUtils.scripts.check_file:main') -acmdlib.register('diff-pool', 'PyUtils.scripts.diff_pool_files:main') -acmdlib.register('diff-root', 'PyUtils.scripts.diff_root_files:main') -acmdlib.register('dump-root', 'PyUtils.scripts.dump_root_file:main') -acmdlib.register('chk-sg', 'PyUtils.scripts.check_sg:main') -acmdlib.register('ath-dump', 'PyUtils.scripts.ath_dump:main') -acmdlib.register('chk-rflx', 'PyUtils.scripts.check_reflex:main') -acmdlib.register('gen-klass', 'PyUtils.scripts.gen_klass:main') +acmdlib.register('chk-file', 'PyUtils.scripts.check_file') +acmdlib.register('diff-pool', 'PyUtils.scripts.diff_pool_files') +acmdlib.register('diff-root', 'PyUtils.scripts.diff_root_files') +acmdlib.register('dump-root', 'PyUtils.scripts.dump_root_file') +acmdlib.register('chk-sg', 'PyUtils.scripts.check_sg') +acmdlib.register('ath-dump', 'PyUtils.scripts.ath_dump') +acmdlib.register('chk-rflx', 'PyUtils.scripts.check_reflex') +acmdlib.register('gen-klass', 'PyUtils.scripts.gen_klass') -acmdlib.register('merge-files', 'PyUtils.scripts.merge_files:main') -acmdlib.register('filter-files', 'PyUtils.scripts.filter_files:main') +acmdlib.register('merge-files', 'PyUtils.scripts.merge_files') +acmdlib.register('filter-files', 'PyUtils.scripts.filter_files') -acmdlib.register('cmake.new-skeleton', 'PyUtils.scripts.cmake_newskeleton:main') -acmdlib.register('cmake.new-pkg', 'PyUtils.scripts.cmake_newpkg:main') -acmdlib.register('cmake.new-analysisalg', 'PyUtils.scripts.cmake_newanalysisalg:main') +acmdlib.register('cmake.new-skeleton', 'PyUtils.scripts.cmake_newskeleton') +acmdlib.register('cmake.new-pkg', 'PyUtils.scripts.cmake_newpkg') +acmdlib.register('cmake.new-analysisalg', 'PyUtils.scripts.cmake_newanalysisalg') -acmdlib.register('jira.issues', 'PyUtils.scripts.jira_issues:main') -# acmdlib.register('jira.issue', 'PyUtils.scripts.jira_issue:main') +acmdlib.register('jira.issues', 'PyUtils.scripts.jira_issues') ## - -- GitLab