Passed
Push — master ( 42467a...9d011f )
by Matěj
03:19 queued 11s
created

utils.gen_tables.Output.__init__()   A

Complexity

Conditions 4

Size

Total Lines 21
Code Lines 18

Duplication

Lines 0
Ratio 0 %

Code Coverage

Tests 0
CRAP Score 20

Importance

Changes 0
Metric Value
cc 4
eloc 18
nop 3
dl 0
loc 21
ccs 0
cts 16
cp 0
crap 20
rs 9.5
c 0
b 0
f 0
1
from glob import glob
2
import collections
3
import os
4
5
import argparse
6
7
import ssg.build_yaml
8
9
10
class References:
11
    def __init__(self):
12
        self.ref_by_family = collections.defaultdict(lambda: collections.defaultdict(set))
13
14
    def handle_rule_ref_family(self, rule_name, family, rule_content):
15
        ids = rule_content.split(",")
16
        for id in ids:
17
            self.ref_by_family[family][id].add(rule_name)
18
19
    def handle_rule(self, rule_entry):
20
        for family, content in rule_entry.references.items():
21
            self.handle_rule_ref_family(rule_entry.id_, family, content)
22
23
    def sorted(self):
24
        refs_by_family = collections.OrderedDict()
25
        families = sorted(self.ref_by_family.keys())
26
        for f in families:
27
            refs_by_family[f] = collections.OrderedDict()
28
            sorted_refs = sorted(self.ref_by_family[f].keys())
29
            for ref in sorted_refs:
30
                refs_by_family[f][ref] = sorted(self.ref_by_family[f][ref])
31
        return refs_by_family
32
33
34
class Output(object):
35
    def __init__(self, product, build_dir):
36
        path = "{build_dir}/{product}/rules".format(build_dir=build_dir, product=product)
37
        rule_files = glob("{path}/*".format(path=path))
38
        if not rule_files:
39
            msg = (
40
                "No files found in '{path}', please make sure that you select the build dir "
41
                "correctly and that the appropriate product is built.".format(path=path)
42
            )
43
            raise ValueError(msg)
44
        rules_dict = dict()
45
        for r_file in rule_files:
46
            rule = ssg.build_yaml.Rule.from_yaml(r_file)
47
            rules_dict[rule.id_] = rule
48
49
        references = References()
50
        for rule in rules_dict.values():
51
            references.handle_rule(rule)
52
53
        self.product = product
54
        self.sorted_refs = references.sorted()
55
        self.rules_dict = rules_dict
56
57
    def get_result(self):
58
        raise NotImplementedError()
59
60
61
class HtmlOutput(Output):
62
    def get_result(self):
63
        import ssg.jinja
64
        subst_dict = dict(all_refs=self.sorted_refs, rules=self.rules_dict, product=self.product)
65
        html_jinja_template = os.path.join(os.path.dirname(__file__), "references-template.html")
66
        return ssg.jinja.process_file(html_jinja_template, subst_dict)
67
68
69
class JsonOutput(Output):
70
    def get_result(self):
71
        import json
72
        return json.dumps(self.sorted_refs, indent=2, sort_keys=True)
73
74
75
def parse_args():
76
    parser = argparse.ArgumentParser(description="Generate reference-rule mapping.")
77
    parser.add_argument("product", help="What product to consider")
78
    parser.add_argument("--build-dir", default="build", help="Path to the build directory")
79
    parser.add_argument("--output-type", choices=("html", "json"), default="html")
80
    parser.add_argument("--output", help="The filename to generate")
81
    parser.add_argument("--family", help="Which family of references to output (output all by default)")
82
    return parser.parse_args()
83
84
85
if __name__ == "__main__":
86
    output_class_map = dict(
87
            html=HtmlOutput,
88
            json=JsonOutput,
89
    )
90
    args = parse_args()
91
    result = output_class_map[args.output_type](args.product, args.build_dir).get_result()
92
    if not args.output:
93
        print(result)
94
    else:
95
        with open(args.output, "w") as outfile:
96
            outfile.write(result)
97