|
1 | | -import argparse |
2 | | -import logging |
3 | | -import sys |
4 | | -from typing import Dict, List |
5 | | - |
6 | | -import logmuse |
7 | 1 | import typer |
8 | | -from ubiquerg import VersionInHelpParser |
9 | 2 |
|
10 | 3 | from ._version import __version__ |
11 | 4 | from .const import PKG_NAME |
12 | | -from .eido.argparser import build_subparser as eido_subparser |
13 | | -from .eido.const import CONVERT_CMD, INSPECT_CMD, VALIDATE_CMD |
14 | | -from .eido.conversion import ( |
15 | | - convert_project, |
16 | | - get_available_pep_filters, |
17 | | - pep_conversion_plugins, |
18 | | -) |
19 | | -from .eido.exceptions import EidoFilterError, EidoValidationError |
20 | | -from .eido.inspection import inspect_project |
21 | | -from .eido.validation import validate_config, validate_project, validate_sample |
| 5 | +from .eido.cli import app as eido_app |
22 | 6 | from .pephubclient.cli import app as phc_app |
23 | | -from .project import Project |
24 | | - |
25 | | - |
26 | | -def _get_subparser(parser, *names): |
27 | | - """ |
28 | | - Access nested subparsers by name. |
29 | | - Example: _get_subparser(main_parser, "cmdA", "subA1") |
30 | | - """ |
31 | | - current = parser |
32 | | - for name in names: |
33 | | - # find subparsers action |
34 | | - subactions = [ |
35 | | - a for a in current._actions if isinstance(a, argparse._SubParsersAction) |
36 | | - ] |
37 | | - if not subactions: |
38 | | - raise ValueError(f"{current} has no subparsers") |
39 | 7 |
|
40 | | - action = subactions[0] |
41 | | - if name not in action.choices: |
42 | | - raise ValueError(f"Subparser '{name}' not found") |
43 | 8 |
|
44 | | - current = action.choices[name] |
| 9 | +def version_callback(value: bool): |
| 10 | + if value: |
| 11 | + typer.echo(f"{PKG_NAME} version: {__version__}") |
| 12 | + raise typer.Exit() |
45 | 13 |
|
46 | | - return current |
47 | 14 |
|
48 | | - |
49 | | -def _parse_filter_args_str(input): |
50 | | - """ |
51 | | - Parse user input specification. |
52 | | -
|
53 | | - :param Iterable[Iterable[str]] input: user command line input, |
54 | | - formatted as follows: [[arg=txt, arg1=txt]] |
55 | | - :return dict: mapping of keys, which are input names and values |
56 | | - """ |
57 | | - lst = [] |
58 | | - for i in input or []: |
59 | | - lst.extend(i) |
60 | | - return ( |
61 | | - {x.split("=")[0]: x.split("=")[1] for x in lst if "=" in x} |
62 | | - if lst is not None |
63 | | - else lst |
64 | | - ) |
| 15 | +app = typer.Typer(help=f"{PKG_NAME} - Portable Encapsulated Projects toolkit") |
65 | 16 |
|
66 | 17 |
|
67 | | -def print_error_summary( |
68 | | - errors_by_type: Dict[str, List[Dict[str, str]]], _LOGGER: logging.Logger |
| 18 | +@app.callback() |
| 19 | +def common( |
| 20 | + ctx: typer.Context, |
| 21 | + version: bool = typer.Option( |
| 22 | + None, "--version", "-v", callback=version_callback, help="package version" |
| 23 | + ), |
69 | 24 | ): |
70 | | - """Print a summary of errors, organized by error type""" |
71 | | - n_error_types = len(errors_by_type) |
72 | | - _LOGGER.error(f"Found {n_error_types} types of error:") |
73 | | - for err_type, items in errors_by_type.items(): |
74 | | - n = len(items) |
75 | | - msg = f" - {err_type}: ({n} samples) " |
76 | | - if n < 50: |
77 | | - msg += ", ".join(x["sample_name"] for x in items) |
78 | | - _LOGGER.error(msg) |
| 25 | + pass |
79 | 26 |
|
80 | | - if len(errors_by_type) > 1: |
81 | | - final_msg = f"Validation unsuccessful. {len(errors_by_type)} error types found." |
82 | | - else: |
83 | | - final_msg = f"Validation unsuccessful. {len(errors_by_type)} error type found." |
84 | | - |
85 | | - _LOGGER.error(final_msg) |
86 | | - |
87 | | - |
88 | | -app = typer.Typer(help=f"{PKG_NAME} - Portable Encapsulated Projects toolkit") |
89 | 27 |
|
90 | 28 | app.add_typer(phc_app, name="phc", help="Client for the PEPhub server") |
91 | | - |
92 | | - |
93 | | -# def build_argparser(): |
94 | | -# """ |
95 | | -# Builds argument parser. |
96 | | -# |
97 | | -# :return argparse.ArgumentParser: Argument parser |
98 | | -# """ |
99 | | -# |
100 | | -# banner = "%(prog)s - Portable Encapsulated Projects toolkit" |
101 | | -# # additional_description = "\nhttps://geniml.databio.org" |
102 | | -# |
103 | | -# parser = VersionInHelpParser( |
104 | | -# prog=PKG_NAME, |
105 | | -# version=f"{__version__}", |
106 | | -# description=banner, |
107 | | -# ) |
108 | | -# |
109 | | -# # Individual subcommands |
110 | | -# msg_by_cmd = { |
111 | | -# "eido": "PEP validation, conversion, and inspection", |
112 | | -# "phc": "Client for the PEPhub server", |
113 | | -# # "pephubclient": "Client for the PEPhub server", |
114 | | -# } |
115 | | -# |
116 | | -# sp = parser.add_subparsers(dest="command") |
117 | | -# subparsers: Dict[str, VersionInHelpParser] = {} |
118 | | -# for k, v in msg_by_cmd.items(): |
119 | | -# subparsers[k] = sp.add_parser(k, description=v, help=v) |
120 | | -# |
121 | | -# # build up subparsers for modules |
122 | | -# subparsers["eido"] = eido_subparser(subparsers["eido"]) |
123 | | -# |
124 | | -# return parser |
125 | | -# |
126 | | -# |
127 | | -# def main(test_args=None): |
128 | | -# """Primary workflow""" |
129 | | -# if len(sys.argv) > 1 and sys.argv[1] == "phc": |
130 | | -# from .pephubclient.cli import app |
131 | | -# |
132 | | -# sub_args = sys.argv[2:] |
133 | | -# app( |
134 | | -# args=sub_args, |
135 | | -# prog_name=f"{PKG_NAME} phc", |
136 | | -# ) |
137 | | -# parser = logmuse.add_logging_options(build_argparser()) |
138 | | -# args, remaining = parser.parse_known_args() |
139 | | -# |
140 | | -# if test_args: |
141 | | -# args.__dict__.update(test_args) |
142 | | -# |
143 | | -# global _LOGGER |
144 | | -# _LOGGER = logmuse.logger_via_cli(args, make_root=True) |
145 | | -# |
146 | | -# if args.command is None: |
147 | | -# parser.print_help(sys.stderr) |
148 | | -# sys.exit(1) |
149 | | -# |
150 | | -# if args.command == "eido": |
151 | | -# if args.subcommand == CONVERT_CMD: |
152 | | -# convert_sp = _get_subparser(parser, "eido", CONVERT_CMD) |
153 | | -# filters = get_available_pep_filters() |
154 | | -# if args.list: |
155 | | -# _LOGGER.info("Available filters:") |
156 | | -# if len(filters) < 1: |
157 | | -# _LOGGER.info("No available filters") |
158 | | -# for filter_name in filters: |
159 | | -# _LOGGER.info(f" - {filter_name}") |
160 | | -# sys.exit(0) |
161 | | -# if not "format" in args: |
162 | | -# _LOGGER.error("The following arguments are required: --format") |
163 | | -# convert_sp.print_help(sys.stderr) |
164 | | -# sys.exit(1) |
165 | | -# if args.describe: |
166 | | -# if args.format not in filters: |
167 | | -# raise EidoFilterError( |
168 | | -# f"'{args.format}' filter not found. Available filters: {', '.join(filters)}" |
169 | | -# ) |
170 | | -# filter_functions_by_name = pep_conversion_plugins() |
171 | | -# print(filter_functions_by_name[args.format].__doc__) |
172 | | -# sys.exit(0) |
173 | | -# if args.pep is None: |
174 | | -# # parser.print_help(sys.stderr) |
175 | | -# # sp[CONVERT_CMD].print_help(sys.stderr) |
176 | | -# convert_sp.print_help(sys.stderr) |
177 | | -# _LOGGER.info("The following arguments are required: PEP") |
178 | | -# sys.exit(1) |
179 | | -# if args.paths: |
180 | | -# paths = {y[0]: y[1] for y in [x.split("=") for x in args.paths]} |
181 | | -# else: |
182 | | -# paths = None |
183 | | -# |
184 | | -# p = Project( |
185 | | -# args.pep, |
186 | | -# sample_table_index=args.st_index, |
187 | | -# subsample_table_index=args.sst_index, |
188 | | -# amendments=args.amendments, |
189 | | -# ) |
190 | | -# plugin_kwargs = _parse_filter_args_str(args.args) |
191 | | -# |
192 | | -# # append paths |
193 | | -# plugin_kwargs["paths"] = paths |
194 | | -# |
195 | | -# convert_project(p, args.format, plugin_kwargs) |
196 | | -# _LOGGER.info("Conversion successful") |
197 | | -# sys.exit(0) |
198 | | -# |
199 | | -# _LOGGER.debug(f"Creating a Project object from: {args.pep}") |
200 | | -# if args.subcommand == VALIDATE_CMD: |
201 | | -# p = Project( |
202 | | -# args.pep, |
203 | | -# sample_table_index=args.st_index, |
204 | | -# subsample_table_index=args.sst_index, |
205 | | -# amendments=args.amendments, |
206 | | -# ) |
207 | | -# if args.sample_name: |
208 | | -# try: |
209 | | -# args.sample_name = int(args.sample_name) |
210 | | -# except ValueError: |
211 | | -# # If sample_name is not an integer, leave it as a string. |
212 | | -# pass |
213 | | -# _LOGGER.debug( |
214 | | -# f"Comparing Sample ('{args.pep}') in Project ('{args.pep}') " |
215 | | -# f"against a schema: {args.schema}" |
216 | | -# ) |
217 | | -# validator = validate_sample |
218 | | -# arguments = [p, args.sample_name, args.schema] |
219 | | -# elif args.just_config: |
220 | | -# _LOGGER.debug( |
221 | | -# f"Comparing Project ('{args.pep}') against a schema: {args.schema}" |
222 | | -# ) |
223 | | -# validator = validate_config |
224 | | -# arguments = [p, args.schema] |
225 | | -# else: |
226 | | -# _LOGGER.debug( |
227 | | -# f"Comparing Project ('{args.pep}') against a schema: {args.schema}" |
228 | | -# ) |
229 | | -# validator = validate_project |
230 | | -# arguments = [p, args.schema] |
231 | | -# try: |
232 | | -# validator(*arguments) |
233 | | -# except EidoValidationError as e: |
234 | | -# print_error_summary(e.errors_by_type, _LOGGER) |
235 | | -# sys.exit(1) |
236 | | -# _LOGGER.info("Validation successful") |
237 | | -# sys.exit(0) |
238 | | -# |
239 | | -# if args.subcommand == INSPECT_CMD: |
240 | | -# p = Project( |
241 | | -# args.pep, |
242 | | -# sample_table_index=args.st_index, |
243 | | -# subsample_table_index=args.sst_index, |
244 | | -# amendments=args.amendments, |
245 | | -# ) |
246 | | -# inspect_project(p, args.sample_name, args.attr_limit) |
247 | | -# sys.exit(0) |
| 29 | +app.add_typer(eido_app, name="eido", help="PEP validation, conversion, and inspection") |
248 | 30 |
|
249 | 31 |
|
250 | 32 | def main(): |
251 | | - """Primary workflow""" |
252 | | - app() |
| 33 | + app(prog_name=PKG_NAME) |
0 commit comments