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 ) |