diff options
author | Swapnil Negi <swapnil.negi09@gmail.com> | 2019-01-04 18:29:50 +0100 |
---|---|---|
committer | Andrej Rode <mail@andrejro.de> | 2019-01-04 18:58:02 +0100 |
commit | 055287896c8c97eb0cdda825559e217d8db54a14 (patch) | |
tree | 613262f5ed45ba4eaadf1bd76009aa16ad22806f /gr-utils/python/modtool/cli/base.py | |
parent | 2fcf3b8afe51092003b7f916edb9e5d6372d4842 (diff) |
modtool: gr-modtool overhaul GSoC 2018
This commit contains all the changes done during the 2018 GSoC
"gr-modtool overhaul".
Changes include:
- Rewrite of gr-modtool based on Python Click
- Split of gr-modtool in cli and core
- Adherence to new GNU Radio 3.8 API for OOTs
- Pylint improvements
- Py3k and Py2k compatibility
This feature is merged in a squash-merge due to big refactoring
on the head and base branch and the impossibility to unclutter both.
Diffstat (limited to 'gr-utils/python/modtool/cli/base.py')
-rw-r--r-- | gr-utils/python/modtool/cli/base.py | 171 |
1 files changed, 171 insertions, 0 deletions
diff --git a/gr-utils/python/modtool/cli/base.py b/gr-utils/python/modtool/cli/base.py new file mode 100644 index 0000000000..5fa2b8b7b4 --- /dev/null +++ b/gr-utils/python/modtool/cli/base.py @@ -0,0 +1,171 @@ +# +# Copyright 2018 Free Software Foundation, Inc. +# +# This file is part of GNU Radio +# +# GNU Radio is free software; you can redistribute it and/or modify +# it under the terms of the GNU General Public License as published by +# the Free Software Foundation; either version 3, or (at your option) +# any later version. +# +# GNU Radio is distributed in the hope that it will be useful, +# but WITHOUT ANY WARRANTY; without even the implied warranty of +# MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the +# GNU General Public License for more details. +# +# You should have received a copy of the GNU General Public License +# along with GNU Radio; see the file COPYING. If not, write to +# the Free Software Foundation, Inc., 51 Franklin Street, +# Boston, MA 02110-1301, USA. +# +""" Base CLI module """ + +from __future__ import print_function +from __future__ import absolute_import +from __future__ import unicode_literals + +import os +import sys +import logging +import functools +from importlib import import_module +from pkg_resources import iter_entry_points +from logging import Formatter, StreamHandler + +import click +from click import ClickException +from click_plugins import with_plugins + +from gnuradio import gr + + +class ModToolException(ClickException): + """ Exception class for enhanced CLI interface """ + def show(self, file = None): + """ displays the colored message """ + click.secho('ModToolException: {}'.format(self.format_message()), fg='red') + + +class CommandCLI(click.Group): + """ + This is a derived class of the implemented click class + which overrides some of the functional definitions for external + plug-in support + """ + cmd_folder = os.path.abspath(os.path.dirname(__file__)) + + def list_commands(self, ctx): + """ + Lists all the commands available in the modtool directory + as well as the commands from external plug-ins. + """ + cmds = [] + for filename in os.listdir(self.cmd_folder): + if filename.endswith('.py') and not '_' in filename: + cmds.append(filename[:-3]) + cmds.remove('base') + cmds += self.commands + return sorted(cmds) + + def get_command(self, ctx, cmd_name): + """ + Returns a command object if it exists. The existing in-tree ModTool + command is the priority over the same external plug-in command. + """ + try: + if sys.version_info[0] == 2: + cmd_name = cmd_name.encode('ascii', 'replace') + mod = import_module('gnuradio.modtool.cli.' + cmd_name) + except ImportError: + return self.commands.get(cmd_name) + return mod.cli + + +class ClickHandler(StreamHandler): + """ + This is a derived class of implemented logging class + StreamHandler which overrides some of its functional + definitions to add colors to the stream output + """ + def emit(self, record): + """ Writes message to the stream """ + colormap = { + 'DEBUG': ('white', 'black'), + 'INFO': ('blue', None), + 'WARNING': ('yellow', None), + 'ERROR': ('red', None), + 'CRITICAL': ('white', 'red'), + } + try: + msg = self.format(record) + colors = colormap.get(record.levelname, (None, None)) + fgcolor = colors[0] + bgcolor = colors[1] + click.secho(msg, fg=fgcolor, bg=bgcolor) + self.flush() + except Exception: + self.handleError(record) + + +def setup_cli_logger(logger): + """ Sets up logger for CLI parsing """ + try: + import colorama + stream_handler = ClickHandler() + logger.addHandler(stream_handler) + except ImportError: + stream_handler = logging.StreamHandler() + logger.addHandler(stream_handler) + finally: + logger.setLevel(logging.INFO) + + +def cli_input(msg): + """ Returns enhanced input """ + return input(click.style(msg, fg='cyan')) + + +def common_params(func): + """ Common parameters for various modules""" + @click.option('-d', '--directory', default='.', + help="Base directory of the module. Defaults to the cwd.") + @click.option('--skip-lib', is_flag=True, + help="Don't do anything in the lib/ subdirectory.") + @click.option('--skip-swig', is_flag=True, + help="Don't do anything in the swig/ subdirectory.") + @click.option('--skip-python', is_flag=True, + help="Don't do anything in the python/ subdirectory.") + @click.option('--skip-grc', is_flag=True, + help="Don't do anything in the grc/ subdirectory.") + @click.option('--scm-mode', type=click.Choice(['yes', 'no', 'auto']), + default=gr.prefs().get_string('modtool', 'scm_mode', 'no'), + help="Use source control management [ yes | no | auto ]).") + @click.option('-y', '--yes', is_flag=True, + help="Answer all questions with 'yes'. " + + "This can overwrite and delete your files, so be careful.") + @functools.wraps(func) + def wrapper(*args, **kwargs): + """ Decorator that wraps common options """ + return func(*args, **kwargs) + return wrapper + + +block_name = click.argument('blockname', nargs=1, required=False, metavar="BLOCK_NAME") + + +@with_plugins(iter_entry_points('gnuradio.modtool.cli.plugins')) +@click.command(cls=CommandCLI, + epilog='Manipulate with GNU Radio modules source code tree. ' + + 'Call it without options to run specified command interactively') +def cli(): + """A tool for editing GNU Radio out-of-tree modules.""" + pass + + +def run(module): + """Call the run function of the core modules.""" + try: + module.run() + except ModToolException as err: + click.echo(err, file=sys.stderr) + exit(1) |