-
Notifications
You must be signed in to change notification settings - Fork 14
/
Copy pathdump-parameter-schema.py
executable file
·96 lines (78 loc) · 2.63 KB
/
dump-parameter-schema.py
1
2
3
4
5
6
7
8
9
10
11
12
13
14
15
16
17
18
19
20
21
22
23
24
25
26
27
28
29
30
31
32
33
34
35
36
37
38
39
40
41
42
43
44
45
46
47
48
49
50
51
52
53
54
55
56
57
58
59
60
61
62
63
64
65
66
67
68
69
70
71
72
73
74
75
76
77
78
79
80
81
82
83
84
85
86
87
88
89
90
91
92
93
94
95
96
#!/usr/bin/env python3
import sys
import argparse
import json
from typing import Union, Literal, Any, cast, Dict
script_path = sys.argv[1]
# Remove the script name from the argument list
sys.argv[1:] = sys.argv[2:]
def _argparse_parse_args(self: argparse.ArgumentParser, args=None, namespace=None):
"""Creates a json string from the argparser instance"""
json_out: Dict[str,Any] = {}
json_out["type"] = "bilingual/monolingual" #TODO "monolingual" or "bilingual" but no idea how to determine this automatically
json_out["description"] = self.description
# non-simple type so it doesn't end up in json
SWITCH = object()
SUBSTITUTE = object()
# We need to skip [0], as this is the prepended `--help`
param_dict: Dict[str,Dict] = {}
for argument in self._actions[1:]:
# Skip --help and --version
if isinstance(argument, (argparse._HelpAction, argparse._VersionAction)):
continue
current_str = {
"help": argument.help,
"required": argument.required
}
if isinstance(argument, argparse._StoreConstAction):
current_str |= {
"type": "bool",
"default": False
}
elif type(argument.type) == type:
current_str |= {
"type": cast(type, argument.type).__name__,
"default": argument.default
}
elif type(argument.type) == argparse.FileType:
current_str |= {
"type": "str",
"default": "-"
}
elif argument.default is not None:
current_str|= {
"type": type(argument.default).__name__,
"default": argument.default
}
else:
print(f"Unknown type for \"{argument.dest}\": skipped\n{argument!r}\n", file=sys.stderr)
continue
# If it is an `--option` type argument
if argument.option_strings:
current_str |= {
SWITCH: argument.option_strings[0], #TODO prefer long names?
SUBSTITUTE: argument.option_strings[0].replace('-','').upper()
}
# or a positional one
else:
current_str |= {
SUBSTITUTE: argument.dest.upper()
}
if argument.choices is not None:
current_str |= {
"allowed_values": argument.choices
}
# Add to the parameter dict
param_dict[current_str[SUBSTITUTE]] = current_str
json_out["parameters"] = param_dict
json_out["command"] = script_path
for _, value in param_dict.items():
if not value["required"]:
json_out["command"] += " ${" + value[SUBSTITUTE] + ":+" + value[SWITCH] + (" $" + value[SUBSTITUTE] if value["type"] != "bool" else "") + "}"
else:
json_out["command"] += (" " + value[SWITCH] if SWITCH in value else "") + " $" + value[SUBSTITUTE]
json.dump(json_out, sys.stdout, indent=4, skipkeys=True)
sys.exit(0)
argparse.ArgumentParser.parse_args = _argparse_parse_args
with open(script_path) as fh:
exec(fh.read())