summaryrefslogtreecommitdiffstats
path: root/build/scripts/docs_manifest.py
blob: 8945ceff928feb3292315092a9be21d09c1008c2 (plain) (blame)
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
105
106
107
108
109
110
111
112
113
import argparse
import json
import os
import sys


def parse_args(argv):
    parser = argparse.ArgumentParser()
    parser.add_argument("--output", type=str, required=True)
    parser.add_argument("--type", type=str, choices=["yfm"], default="yfm")
    parser.add_argument("--version", type=str, default="1.0")
    parser.add_argument("items", nargs='*', default=[])
    return parser.parse_args(argv)


def generate_manifest(args):
    if not args.output or os.path.isdir(args.output):
        raise Exception(f"Output path '{args.output}' is a directory")
    output_dir = os.path.dirname(args.output)
    if output_dir:
        os.makedirs(output_dir, exist_ok=True)

    kvs = {}
    for item in args.items:
        try:
            key, value = item.split("=", 1)
        except Exception:
            raise Exception(f"Invalid data format [{item}], expected `key=value`")
        if not key or not value:
            raise Exception(f"Invalid data format [{item}], both `key` and `value` must be non-empty")
        if key not in ("html", "preprocessed"):
            raise Exception(f"Unexpected `key`: [{item}]")
        if key in kvs:
            raise Exception(f"Duplicate `key` [{key}]")

        kvs[key] = value

    return json.dumps({"version": args.version, "type": args.type, "map": kvs})


def main():
    args = parse_args(sys.argv[1:])
    try:
        content = generate_manifest(args)
    except Exception as e:
        print(f"Error: {e}", file=sys.stderr, flush=True)
        sys.exit(1)
    with open(args.output, "w") as f:
        f.write(content)


def test_manifest():
    args = parse_args(['--output', 'docs.manifest', 'html=html.tar.gz', 'preprocessed=preprocessed.tar.gz'])
    content = generate_manifest(args)
    assert json.loads(content) == json.loads(
        '{"type": "yfm", "map": {"preprocessed": "preprocessed.tar.gz", "html": "html.tar.gz"}, "version": "1.0"}'
    )


def test_invald_input():
    # invalid output
    args = parse_args(['--output', '', 'html=html.tar.gz', 'preprocessed=preprocessed.tar.gz'])
    try:
        generate_manifest(args)
        assert False
    except Exception:
        pass

    # invalid output
    args = parse_args(['--output', 'oops/', 'html=html.tar.gz', 'preprocessed=preprocessed.tar.gz'])
    try:
        generate_manifest(args)
        assert False
    except Exception:
        pass

    # invalid format
    args = parse_args(['--output', 'docs.manifest', 'html=', 'preprocessed=preprocessed.tar.gz'])
    try:
        generate_manifest(args)
        assert False
    except Exception:
        pass

    # invalid format
    args = parse_args(['--output', 'docs.manifest', 'html=html-docs.tar.gz', 'preprocessed:preprocessed.tar.gz'])
    try:
        generate_manifest(args)
        assert False
    except Exception:
        pass

    # duplicate keys
    args = parse_args(
        ['--output', 'docs.manifest', 'html=html-docs.tar.gz', 'preprocessed=preprocessed.tar.gz', 'html=html.tar.gz']
    )
    try:
        generate_manifest(args)
        assert False
    except Exception:
        pass

    # unexpected key
    args = parse_args(['--output', 'docs.manifest', 'html=html-docs.tar.gz', '_preprocessed=preprocessed.tar.gz'])
    try:
        generate_manifest(args)
        assert False
    except Exception:
        pass


if __name__ == '__main__':
    main()