summaryrefslogtreecommitdiff
path: root/scripts/qrc_lint.py
blob: 9520f22a0c2fadab62691efd9e3cc4dad7955b93 (plain)
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
#!/usr/bin/env python3
# ============================================================
#     The rekonq project
# ============================================================
# SPDX-License-Identifier: GPL-3.0-only
# Copyright (C) 2022 aqua <aqua@iserlohn-fortress.net>
# ============================================================
""" Lint qrc files """

import argparse
import sys
from os.path import (dirname, exists, join)
from lxml import etree


def lint(dir_name: str, tree: etree._ElementTree) -> bool:
    """ Lint an etree and return if errors were found """
    has_check_errors = False
    root = tree.getroot()

    # check doctype
    if tree.docinfo.doctype != '<!DOCTYPE RCC>':
        print(f'unknown doctype { tree.docinfo.doctype }')
        has_check_errors = True

    qresources = root.findall('qresource')
    # check if qresource's have prefix
    for qres in qresources:
        if qres.get('prefix') is None:
            print('qresource without prefix')
            has_check_errors = True

    # check if qresource's are sorted by prefix
    sortedqres = sorted(qresources, key=lambda x: x.get('prefix'))
    if qresources != sortedqres:
        print('qresources are not sorted')
        has_check_errors = True

    for qres in sortedqres:
        files = qres.findall('file')

        # check if files are sorted
        if files != sorted(files, key=lambda x: x.get('alias')):
            print(f'qresources prefix={ qres.get("prefix") }:\tfiles are not sorted')
            has_check_errors = True

        # check for missing files and missing alias
        for file in files:
            if file.get('alias') is None:
                print(f'file path={ file.text }:\tmissing file alias')
                has_check_errors = True
            path = join(dir_name, file.text)
            if not exists(path):
                print(f'file path={ path }:\tfile does not exist')
                has_check_errors = True

    return has_check_errors


def regen(root: etree.Element, outfile: str):
    """ Regenerate an etree """
    out_root = etree.Element('RCC', {'version': '1.0'})
    for qresource in sorted(root.findall('qresource'), key=lambda x: x.get('prefix')):
        out_qres = etree.SubElement(out_root, 'qresource', {'prefix': qresource.get('prefix')})

        for file in sorted(qresource.findall('file'), key=lambda x: x.get('alias')):
            out_file = etree.SubElement(out_qres, 'file', {'alias': file.get('alias')})
            out_file.text = file.text

    with etree.xmlfile(outfile, encoding='utf-8', close=True) as xml_file:
        xml_file.write_declaration(standalone=True)
        xml_file.write_doctype('<!DOCTYPE RCC>')
        xml_file.write(out_root, pretty_print=True)


def main():
    """ Main function """
    parser = argparse.ArgumentParser(description='Lint qrc file')
    parser.add_argument('file', type=str, help='qrc file')
    parser.add_argument('--regen', action='store_true', help='Regenerate qrc file')
    args = parser.parse_args()

    if not exists(args.file):
        sys.exit('input file "{args.file}" doesn\'t exist')
    else:
        print(args.file)

    tree = etree.parse(args.file)

    if args.regen:
        regen(tree.getroot(), args.file)
    elif lint(dirname(args.file), tree):
        sys.exit('Errors during lint')


if __name__ == '__main__':
    main()