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 )