Mercurial > repos > shellac > sam_consensus_v3
comparison env/lib/python3.9/site-packages/planemo/cli.py @ 0:4f3585e2f14b draft default tip
"planemo upload commit 60cee0fc7c0cda8592644e1aad72851dec82c959"
| author | shellac |
|---|---|
| date | Mon, 22 Mar 2021 18:12:50 +0000 |
| parents | |
| children |
comparison
equal
deleted
inserted
replaced
| -1:000000000000 | 0:4f3585e2f14b |
|---|---|
| 1 """The module describes a CLI framework extending ``click``.""" | |
| 2 import functools | |
| 3 import os | |
| 4 import sys | |
| 5 | |
| 6 import click | |
| 7 | |
| 8 from planemo import __version__ | |
| 9 from planemo.context import configure_standard_planemo_logging, PlanemoContext | |
| 10 from planemo.exit_codes import ExitCodeException | |
| 11 from planemo.galaxy import profiles | |
| 12 from .config import OptionSource | |
| 13 from .io import error | |
| 14 | |
| 15 | |
| 16 CONTEXT_SETTINGS = dict(auto_envvar_prefix='PLANEMO') | |
| 17 COMMAND_ALIASES = { | |
| 18 "l": "lint", | |
| 19 "o": "open", | |
| 20 "t": "test", | |
| 21 "s": "serve", | |
| 22 } | |
| 23 | |
| 24 | |
| 25 class PlanemoCliContext(PlanemoContext): | |
| 26 """Describe context of Planemo CLI computation. | |
| 27 | |
| 28 Extend PlanemoContext with operations for CLI concerns (exit code) and | |
| 29 for interacting with the click library. | |
| 30 """ | |
| 31 | |
| 32 def _log_message(self, message): | |
| 33 click.echo(message, file=sys.stderr) | |
| 34 | |
| 35 def exit(self, exit_code): | |
| 36 """Exit planemo with the supplied exit code.""" | |
| 37 self.vlog("Exiting planemo with exit code [%d]" % exit_code) | |
| 38 raise ExitCodeException(exit_code) | |
| 39 | |
| 40 | |
| 41 pass_context = click.make_pass_decorator(PlanemoCliContext, ensure=True) | |
| 42 cmd_folder = os.path.abspath(os.path.join(os.path.dirname(__file__), | |
| 43 'commands')) | |
| 44 | |
| 45 | |
| 46 def list_cmds(): | |
| 47 """List planemo commands from commands folder.""" | |
| 48 rv = [] | |
| 49 for filename in os.listdir(cmd_folder): | |
| 50 if filename.endswith('.py') and \ | |
| 51 filename.startswith('cmd_'): | |
| 52 rv.append(filename[len("cmd_"):-len(".py")]) | |
| 53 rv.sort() | |
| 54 return rv | |
| 55 | |
| 56 | |
| 57 def name_to_command(name): | |
| 58 """Convert a subcommand name to the cli function for that command. | |
| 59 | |
| 60 Command <X> is defined by the method 'planemo.commands.cmd_<x>:cli', | |
| 61 this method uses `__import__` to load and return that method. | |
| 62 """ | |
| 63 try: | |
| 64 if sys.version_info[0] == 2: | |
| 65 name = name.encode('ascii', 'replace') | |
| 66 mod_name = 'planemo.commands.cmd_' + name | |
| 67 mod = __import__(mod_name, None, None, ['cli']) | |
| 68 except ImportError as e: | |
| 69 error("Problem loading command %s, exception %s" % (name, e)) | |
| 70 return | |
| 71 return mod.cli | |
| 72 | |
| 73 | |
| 74 class PlanemoCLI(click.MultiCommand): | |
| 75 | |
| 76 def list_commands(self, ctx): | |
| 77 return list_cmds() | |
| 78 | |
| 79 def get_command(self, ctx, name): | |
| 80 if name in COMMAND_ALIASES: | |
| 81 name = COMMAND_ALIASES[name] | |
| 82 return name_to_command(name) | |
| 83 | |
| 84 | |
| 85 def command_function(f): | |
| 86 """Extension point for processing kwds after click callbacks.""" | |
| 87 @functools.wraps(f) | |
| 88 def handle_blended_options(*args, **kwds): | |
| 89 profile = kwds.get("profile", None) | |
| 90 if profile: | |
| 91 ctx = args[0] | |
| 92 profile_defaults = profiles.ensure_profile( | |
| 93 ctx, profile, **kwds | |
| 94 ) | |
| 95 _setup_profile_options(ctx, profile_defaults, kwds) | |
| 96 | |
| 97 try: | |
| 98 return f(*args, **kwds) | |
| 99 except ExitCodeException as e: | |
| 100 sys.exit(e.exit_code) | |
| 101 | |
| 102 return pass_context(handle_blended_options) | |
| 103 | |
| 104 | |
| 105 def _setup_profile_options(ctx, profile_defaults, kwds): | |
| 106 for key, value in profile_defaults.items(): | |
| 107 option_present = key in kwds | |
| 108 option_cli_specified = option_present and (ctx.get_option_source(key) == OptionSource.cli) | |
| 109 use_profile_option = not option_present or not option_cli_specified | |
| 110 if use_profile_option: | |
| 111 kwds[key] = value | |
| 112 ctx.set_option_source( | |
| 113 key, OptionSource.profile, force=True | |
| 114 ) | |
| 115 | |
| 116 | |
| 117 @click.command(cls=PlanemoCLI, context_settings=CONTEXT_SETTINGS) | |
| 118 @click.version_option(__version__) | |
| 119 @click.option('-v', '--verbose', is_flag=True, | |
| 120 help='Enables verbose mode.') | |
| 121 @click.option('--config', | |
| 122 default="~/.planemo.yml", | |
| 123 envvar="PLANEMO_GLOBAL_CONFIG_PATH", | |
| 124 help="Planemo configuration YAML file.") | |
| 125 @click.option('--directory', | |
| 126 default="~/.planemo", | |
| 127 envvar="PLANEMO_GLOBAL_WORKSPACE", | |
| 128 help="Workspace for planemo.") | |
| 129 @pass_context | |
| 130 def planemo(ctx, config, directory, verbose, configure_logging=True): | |
| 131 """A command-line toolkit for building tools and workflows for Galaxy. | |
| 132 | |
| 133 Check out the full documentation for Planemo online | |
| 134 http://planemo.readthedocs.org or open with ``planemo docs``. | |
| 135 | |
| 136 All the individual planemo commands support the ``--help`` option, for | |
| 137 example use ``planemo lint --help`` for more details on checking tools. | |
| 138 """ | |
| 139 ctx.verbose = verbose | |
| 140 if configure_logging: | |
| 141 configure_standard_planemo_logging(verbose) | |
| 142 ctx.planemo_config = os.path.expanduser(config) | |
| 143 ctx.planemo_directory = os.path.expanduser(directory) | |
| 144 | |
| 145 | |
| 146 __all__ = ( | |
| 147 "command_function", | |
| 148 "list_cmds", | |
| 149 "name_to_command", | |
| 150 "planemo", | |
| 151 "PlanemoCliContext", | |
| 152 ) |
