File: compile_yaml.py

package info (click to toggle)
game-data-packager 85.1
  • links: PTS, VCS
  • area: contrib
  • in suites: trixie
  • size: 33,332 kB
  • sloc: python: 15,320; sh: 713; ansic: 95; makefile: 60
file content (135 lines) | stat: -rwxr-xr-x 5,228 bytes parent folder | download | duplicates (2)
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
114
115
116
117
118
119
120
121
122
123
124
125
126
127
128
129
130
131
132
133
134
135
#!/usr/bin/python3
# encoding=utf-8
#
# Copyright © 2015 Simon McVittie <smcv@debian.org>
# SPDX-License-Identifier: GPL-2.0-or-later

import json
import os
import sys

from game_data_packager.util import load_yaml


def main(f: str, out: str) -> None:
    with open(f, encoding='utf-8') as fd:
        data = load_yaml(fd)
    game = os.path.basename(f)[5:].split('.')[0]

    v = data.pop('files', None)
    offload = os.path.splitext(out)[0] + '.files'
    if v is not None:
        with open(offload + '.tmp', 'w', encoding='utf-8') as fd:
            json.dump(v, fd, sort_keys=True)
        os.rename(offload + '.tmp', offload)
    elif os.path.isfile(offload):
        os.remove(offload)

    groups = data.pop('groups', None)
    offload = os.path.splitext(out)[0] + '.groups'

    if groups is not None:
        with open(offload + '.tmp', 'w', encoding='utf-8') as writer:
            writer.write('# Generated file, do not edit.\n')
            writer.write(
                '# Edit %s.yaml and put it next to vfs.zip instead.\n' %
                os.path.basename(game)
            )

            assert isinstance(groups, dict)
            # The group data starts with a list of groups. This is necessary
            # so we can know whether a group member, encountered later on in
            # the data, is a group or a file.
            for group_name, group_data in sorted(groups.items()):
                if isinstance(group_data, dict):
                    if group_data.get('ignorable'):
                        continue

                writer.write('*%s\n' % group_name)

            for group_name, group_data in sorted(groups.items()):
                if isinstance(group_data, dict):
                    if group_data.get('ignorable'):
                        continue

                    writer.write('[%s]\n' % group_name)
                    attrs = {}
                    members = group_data['group_members']
                    for k, v in group_data.items():
                        if k != 'group_members':
                            attrs[k] = v
                    if attrs:
                        json.dump(attrs, writer, sort_keys=True)
                        writer.write('\n')
                elif isinstance(group_data, (str, list)):
                    writer.write('[%s]\n' % group_name)
                    members = group_data
                else:
                    raise AssertionError('group %r should be dict, str or list'
                                         % group_name)

                has_members = False

                if isinstance(members, str):
                    for line in members.splitlines():
                        assert not line.startswith('[')
                        assert not line.startswith('{')
                        line = line.strip()
                        if (line and
                                not line.startswith('#') and
                                not line.startswith('.')):
                            has_members = True
                            parts = line.split()
                            fpath = line.removeprefix(parts[0]).strip()
                            fpath = fpath.removeprefix(parts[1]).strip()
                            line_to_write = \
                                parts[0] + ' ' + parts[1] + ' ' + fpath
                            writer.write(line_to_write)
                            writer.write('\n')
                elif isinstance(members, list):
                    for m in members:
                        has_members = True
                        writer.write('? ? %s\n' % m)
                else:
                    raise AssertionError(('group %r members should be str'
                                         ' or list')
                                         % group_name)

                # an empty group is no use, and would break the assumption
                # that we can use f.group_members to detect groups
                assert has_members

        os.rename(offload + '.tmp', offload)
    elif os.path.isfile(offload):
        os.remove(offload)

    for k in ('sha1sums', 'sha256sums', 'size_and_md5'):
        v = data.pop(k, None)
        offload = os.path.splitext(out)[0] + '.' + k

        if v is not None:
            with open(offload + '.tmp', 'w', encoding='utf-8') as writer:
                writer.write('# Generated file, do not edit.\n')
                writer.write(
                    '# Edit %s.yaml and put it next to vfs.zip instead.\n' %
                    game)

                for line in v.splitlines():
                    stripped = line.strip()
                    if (stripped == '' or
                            stripped.startswith('#') or
                            stripped.startswith('.')):
                        continue
                    writer.write(line)
                    writer.write('\n')
            os.rename(offload + '.tmp', offload)
        elif os.path.isfile(offload):
            os.remove(offload)

    with open(out + '.tmp', 'w', encoding='utf-8') as fd:
        json.dump(data, fd, sort_keys=True)
    os.rename(out + '.tmp', out)


if __name__ == '__main__':
    main(sys.argv[1], sys.argv[2])