-
Notifications
You must be signed in to change notification settings - Fork 0
Expand file tree
/
Copy path__init__.py
More file actions
104 lines (84 loc) · 2.84 KB
/
__init__.py
File metadata and controls
104 lines (84 loc) · 2.84 KB
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
97
98
99
100
101
102
103
104
import argparse
import inspect
import os
from ._file import File
def action(func):
"""Decorator for buider actions.
Currently does nothing.
TODO: Add auto-logging.
TODO: Cache results.
TODO: Run actions concurrently.
TODO: Apply to classes to make class- and function-based actions
interchangeable.
"""
def wrapped_func(*args, **kargs):
print(func.__name__, ' '.join(map(str, args)),
str(kargs) if len(kargs) else '')
return func(*args, **kargs)
wrapped_func.__func = func
return wrapped_func
def unwrap_function(func):
try:
return func.__func
except AttributeError:
return func
def add_builder_arguments(arg_parser):
arg_parser.add_argument('-v', '--verbose', help='make output more verbose',
action='count')
def add_command_arguments(command, parser, defaults):
args = inspect.getfullargspec(command)
if args.defaults is not None:
no_defaults = len(args.args) - len(args.defaults)
args_defaults = [None] * no_defaults + list(args.defaults)
else:
args_defaults = [None] * len(args.args)
for i in range(len(args.args)):
name = args.args[i]
default = args_defaults[i]
if default is None and name in defaults:
default = defaults[name]
if name in args.annotations:
argtype = args.annotations[name]
else:
argtype = None
if argtype is File:
argtype = str
if default is False and (not argtype or argtype is bool):
parser.add_argument('--' + name, action='store_true')
else:
if default is not None:
arghelp = '[default=' + str(default) + ']'
else:
arghelp = None
# TODO: Generate arguments help from the docstring
parser.add_argument('--' + name, type=argtype, default=default,
help=arghelp)
def run_build(func, arguments):
kwargs = {}
fargs = inspect.getfullargspec(func)
for name in fargs.args:
if name in fargs.annotations and fargs.annotations[name] is File:
kwargs[name] = File(arguments[name])
else:
kwargs[name] = arguments[name]
func(**kwargs)
def run(*cmds):
parser = argparse.ArgumentParser()
add_builder_arguments(parser)
defaults = {}
build_script = unwrap_function(cmds[0]).__globals__['__file__']
defaults['source_dir'] = os.path.dirname(build_script) or '.'
defaults['base_build_path'] = os.path.join(defaults['source_dir'], 'build')
if len(cmds) == 1:
func = unwrap_function(cmds[0])
parser.set_defaults(func=func)
add_command_arguments(func, parser, defaults)
else:
subparsers = parser.add_subparsers()
for func in cmds:
func = unwrap_function(func)
subparser = subparsers.add_parser(func.__name__, help=func.__doc__)
subparser.set_defaults(func=func)
add_command_arguments(func, subparser, defaults)
args = parser.parse_args()
run_build(args.func, vars(args))