-
Notifications
You must be signed in to change notification settings - Fork 0
Expand file tree
/
Copy pathcommand_creator.py
More file actions
99 lines (82 loc) · 2.97 KB
/
command_creator.py
File metadata and controls
99 lines (82 loc) · 2.97 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
import os.path
import click
from glob import glob
import click
import groups as groups_util
import config
from models.config import Config
from appliance_cli.command_generation import generate_commands
from functools import lru_cache
def tools(root_command, **kwargs):
class ConfigCallback():
def __init__(self, callback_func):
self.callback = callback_func
def run(self, ctx, callstack, *a):
configs = glob_configs(callstack)
if not configs:
raise click.ClickException("""
No tools found in '{}'
""".format('/'.join(callstack)).strip())
self.callback(ctx, configs, *a)
kwargs['group']['pass_context'] = True
kwargs['command']['pass_context'] = True
def _tools(config_callback):
config_hash = _hashify_all(subcommand_key = 'commands', **kwargs)
callback = ConfigCallback(config_callback).run
generate_commands(root_command, config_hash, callback)
return _tools
def groups(root_command, **kwargs):
kwargs['command']['pass_context'] = True
def _groups(callback):
groups_hash = _hashify_all_groups(**kwargs)
generate_commands(root_command, groups_hash, callback)
return _groups
# The commands are hashed into the following structure
# NOTES: `command` and `group` both supports callable objects as a means
# to customize the hashes. They are called with:
# - command: The config object
# - group: The current name
# {
# command1: **<command>,
# namespace1: {
# **<group>,
# <subcommand_key>: {
# command2: **<command>
# ...
# }
# }
# }
def _hashify_all(group = {}, command = {}, subcommand_key = ''):
def build_group_hashes():
cur_hash = combined_hash
names = config.names()
for idx, name in enumerate(config.names()):
cur_names = names[0:idx]
_copy_values(group, cur_hash, cur_names)
cur_hash = cur_hash.setdefault(subcommand_key, {})\
.setdefault(name, {})
return cur_hash
combined_hash = {}
for config in glob_configs():
_copy_values(command, build_group_hashes(), config)
return combined_hash.setdefault(subcommand_key, {})
@lru_cache()
def _glob_paths(*parts):
path = os.path.join(config.TOOL_DIR, *parts, '**/config.yaml')
return glob(path, recursive=True)
def glob_configs(parts = []):
return list(map(lambda p: Config.cache(p), _glob_paths(*parts)))
# Generates a similar hash to Config hasify func - for node groups
# {
# groupX: **<node>,
# ...
# }
def _hashify_all_groups(command = {}):
combined_hash = {}
for group in groups_util.list_():
group_hash = combined_hash.setdefault(group, {})
_copy_values(command, group_hash, group)
return combined_hash
def _copy_values(source, target, args):
for k, v in source.items():
target[k] = (v(args) if callable(v) else v)