|
1
|
|
|
"""Run docopt in GOATOOLS.""" |
|
2
|
|
|
|
|
3
|
|
|
from __future__ import print_function |
|
4
|
|
|
|
|
5
|
|
|
__copyright__ = "Copyright (C) 2016-2018, DV Klopfenstein, H Tang, All rights reserved." |
|
6
|
|
|
__author__ = "DV Klopfenstein" |
|
7
|
|
|
|
|
8
|
|
|
import sys |
|
9
|
|
|
import re |
|
10
|
|
|
from docopt import docopt |
|
11
|
|
|
from goatools.gosubdag.utils import get_kwargs |
|
12
|
|
|
|
|
13
|
|
|
|
|
14
|
|
|
class DocOptParse(object): |
|
15
|
|
|
"""Run docopt in GOATOOLS.""" |
|
16
|
|
|
|
|
17
|
|
|
def __init__(self, doc, exp_keys, exp_elems): |
|
18
|
|
|
self.doc = doc |
|
19
|
|
|
self.exp_keys = exp_keys if exp_keys else set() # Expected dictionary keys |
|
20
|
|
|
self.exp_elems = exp_elems if exp_elems else set() # Expected set elements (True/False) |
|
21
|
|
|
|
|
22
|
|
|
def get_docargs(self, args=None, prt=None, **kws): |
|
23
|
|
|
"""Pare down docopt. Return a minimal dictionary and a set containing runtime arg values.""" |
|
24
|
|
|
args_user = sys.argv[1:] if args is None else args |
|
25
|
|
|
arg_kws = self._get_docargs(args_user, prt) |
|
26
|
|
|
if 'intvals' in kws: |
|
27
|
|
|
self._set_intvals(arg_kws, kws['intvals']) |
|
28
|
|
|
return arg_kws |
|
29
|
|
|
|
|
30
|
|
|
def _get_docargs(self, args_user, prt): |
|
31
|
|
|
"""Pare down docopt. Return a minimal dictionary and a set containing runtime arg values.""" |
|
32
|
|
|
if prt is not None: |
|
33
|
|
|
print("DocOptParse BEFORE docopt: {}".format(args_user)) |
|
34
|
|
|
docargs = docopt(self.doc, args_user) |
|
35
|
|
|
if prt is not None: |
|
36
|
|
|
print("DocOptParse AFTER docopt: {}".format(docargs)) |
|
37
|
|
|
kwargs_doc = {re.sub(r'^-{1,2}', '', k):v for k, v in docargs.items()} |
|
38
|
|
|
self._chk_docopt_kws(kwargs_doc, args_user) |
|
39
|
|
|
kwargs_usr = get_kwargs(kwargs_doc, self.exp_keys, self.exp_elems) |
|
40
|
|
|
if prt is not None: |
|
41
|
|
|
print("DocOptParse AFTER pared: {}".format(kwargs_usr)) |
|
42
|
|
|
for key in ['taxid']: |
|
43
|
|
|
if key in kwargs_usr: |
|
44
|
|
|
kwargs_usr[key] = int(kwargs_usr[key]) |
|
45
|
|
|
if prt is not None: |
|
46
|
|
|
print("DocOptParse AFTER edited/checked: {}".format(kwargs_usr)) |
|
47
|
|
|
return kwargs_usr |
|
48
|
|
|
|
|
49
|
|
|
@staticmethod |
|
50
|
|
|
def _set_intvals(kws, keys): |
|
51
|
|
|
"""Convert keyword values to int.""" |
|
52
|
|
|
for key in keys: |
|
53
|
|
|
if key in kws: |
|
54
|
|
|
kws[key] = int(kws[key]) |
|
55
|
|
|
|
|
56
|
|
|
def _chk_docopt_exit(self, args, exp_letters): |
|
57
|
|
|
"""Check if docopt exit was for an unknown argument.""" |
|
58
|
|
|
if args is None: |
|
59
|
|
|
args = sys.argv[1:] |
|
60
|
|
|
keys_all = self.exp_keys.union(self.exp_elems) |
|
61
|
|
|
if exp_letters: |
|
62
|
|
|
keys_all |= exp_letters |
|
63
|
|
|
unknown_args = self._chk_docunknown(args, keys_all) |
|
64
|
|
|
if unknown_args: |
|
65
|
|
|
raise RuntimeError("{USAGE}\n **FATAL: UNKNOWN ARGS: {UNK}".format( |
|
66
|
|
|
USAGE=self.doc, UNK=" ".join(unknown_args))) |
|
67
|
|
|
|
|
68
|
|
|
def _chk_docopt_kws(self, docdict, exp): |
|
69
|
|
|
"""Check for common user errors when running from the command-line.""" |
|
70
|
|
|
for key, val in docdict.items(): |
|
71
|
|
|
if isinstance(val, str): |
|
72
|
|
|
assert '=' not in val, self._err("'=' FOUND IN VALUE", key, val, exp) |
|
73
|
|
|
elif key != 'help' and key not in self.exp_keys and key not in self.exp_elems: |
|
74
|
|
|
raise RuntimeError(self._err("UNKNOWN KEY", key, val, exp)) |
|
75
|
|
|
|
|
76
|
|
|
def _err(self, msg, key, val, exp): |
|
77
|
|
|
return "{DOC}\n{MSG}: KEY({K}) VAL({V}): {EXP}".format( |
|
78
|
|
|
DOC=self.doc, MSG=msg, K=key, V=val, EXP=" ".join(exp)) |
|
79
|
|
|
|
|
80
|
|
|
@staticmethod |
|
81
|
|
|
def _chk_docunknown(args, exp): |
|
82
|
|
|
"""Return any unknown args.""" |
|
83
|
|
|
unknown = [] |
|
84
|
|
|
for arg in args: |
|
85
|
|
|
if arg[:2] == '--': |
|
86
|
|
|
val = arg[2:] |
|
87
|
|
|
if val not in exp: |
|
88
|
|
|
unknown.append(arg) |
|
89
|
|
|
elif arg[:1] == '-': |
|
90
|
|
|
val = arg[1:] |
|
91
|
|
|
if val not in exp: |
|
92
|
|
|
unknown.append(arg) |
|
93
|
|
|
if '-h' in unknown or '--help' in unknown: |
|
94
|
|
|
return [] |
|
95
|
|
|
return unknown |
|
96
|
|
|
|
|
97
|
|
|
|
|
98
|
|
|
# Copyright (C) 2016-2018, DV Klopfenstein, H Tang, All rights reserved. |
|
99
|
|
|
|