From 8e288a9060545989533505699c19d9997e6a8aff Mon Sep 17 00:00:00 2001 From: aqua Date: Thu, 1 Sep 2022 19:32:26 +0300 Subject: Add scripts/qrc_lint.py --- .pylintrc | 2 +- INSTALL.md | 1 + bitbucket-pipelines.yml | 4 +- scripts/qrc_lint.py | 97 +++++++++++++++++++++++++++++++++++++ src/application.cpp | 2 +- src/rekonq.kcfg | 3 ++ src/settings/test/test_settings.cpp | 8 +-- src/settings/test/test_settings.qrc | 10 ++-- third-party/resources.qrc | 20 +++++--- third-party/tabler-icons.theme | 5 ++ 10 files changed, 134 insertions(+), 18 deletions(-) create mode 100755 scripts/qrc_lint.py diff --git a/.pylintrc b/.pylintrc index 9d817307..518f0fc3 100644 --- a/.pylintrc +++ b/.pylintrc @@ -27,7 +27,7 @@ extension-pkg-allow-list= # be loaded. Extensions are loading into the active Python interpreter and may # run arbitrary code. (This is an alternative name to extension-pkg-allow-list # for backward compatibility.) -extension-pkg-whitelist= +extension-pkg-whitelist=lxml # Return non-zero exit code if any of these messages/categories are detected, # even if score is above --fail-under value. Syntax same as enable. Messages diff --git a/INSTALL.md b/INSTALL.md index b4a62152..ca401f44 100644 --- a/INSTALL.md +++ b/INSTALL.md @@ -16,6 +16,7 @@ To build, rekonq needs at least: - gtest and gmock - gcov, lcov - clang-tidy +- python-lxml for some of the scripts ## Building rekonq diff --git a/bitbucket-pipelines.yml b/bitbucket-pipelines.yml index 539eee04..1c2cf424 100644 --- a/bitbucket-pipelines.yml +++ b/bitbucket-pipelines.yml @@ -10,8 +10,9 @@ pipelines: - python --version - pylint scripts/check_license.py - pylint scripts/rekonf.py + - pylint scripts/qrc_lint.py - step: - name: license headers check + name: Static checks runs-on: - 'self.hosted' - 'linux.shell' @@ -19,6 +20,7 @@ pipelines: - git submodule update --init - cmake --preset debug -GNinja - ninja -C cmake-build-debug rekonq_check_license + - git ls-files | grep '\.qrc$' | xargs -n1 ./scripts/qrc_lint.py - step: name: Debug Build Test runs-on: diff --git a/scripts/qrc_lint.py b/scripts/qrc_lint.py new file mode 100755 index 00000000..9520f22a --- /dev/null +++ b/scripts/qrc_lint.py @@ -0,0 +1,97 @@ +#!/usr/bin/env python3 +# ============================================================ +# The rekonq project +# ============================================================ +# SPDX-License-Identifier: GPL-3.0-only +# Copyright (C) 2022 aqua +# ============================================================ +""" 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 != '': + 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('') + 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() diff --git a/src/application.cpp b/src/application.cpp index 228b3d38..aba1fc69 100644 --- a/src/application.cpp +++ b/src/application.cpp @@ -51,7 +51,7 @@ Application::Application(int &argc, char *argv[]) : SingleApplication(argc, argv } // setWindowIcon(KIcon("rekonq")); - if (const auto iconTheme = m_settings->value("IconTheme"); iconTheme.isValid()) { + if (const auto iconTheme = m_settings->value("Appearance/IconTheme"); iconTheme.isValid()) { spdlog::info("Set icon theme {}", qUtf8Printable(iconTheme.toString())); QIcon::setThemeName(iconTheme.toString()); } diff --git a/src/rekonq.kcfg b/src/rekonq.kcfg index 0de9cd44..0b23782e 100644 --- a/src/rekonq.kcfg +++ b/src/rekonq.kcfg @@ -49,6 +49,9 @@ + + tabler + getFont(QFont::AnyStyle) diff --git a/src/settings/test/test_settings.cpp b/src/settings/test/test_settings.cpp index babbcdb6..24bbf349 100644 --- a/src/settings/test/test_settings.cpp +++ b/src/settings/test/test_settings.cpp @@ -76,14 +76,16 @@ TEST(settings, Settings) TEST(settings, SettingsDialog) { + constexpr unsigned n_settings = 36; // there are 36 settings in total MockSettings mockSettings; // There are 4 groups in total, but General should not be calling beginGroup/endGroup // beginGroup/endGroup are called twice: during the ctor and when accepted EXPECT_CALL(mockSettings, beginGroup).Times(3 * 4); EXPECT_CALL(mockSettings, endGroup).Times(3 * 4); - // There are 35 settings in total, one of which is hidden and won't be set by the dialog - EXPECT_CALL(mockSettings, value).Times(35 * 2).WillRepeatedly(ReturnArg<1>()); - EXPECT_CALL(mockSettings, setValue(_, _)).Times(33 + 34); + EXPECT_CALL(mockSettings, value).Times(n_settings * 2).WillRepeatedly(ReturnArg<1>()); + // 1 setting is hidden and won't be set by the dialog + // save and reset will both call setValue on all non-hidden settings + EXPECT_CALL(mockSettings, setValue(_, _)).Times(n_settings * 2 - 3); EXPECT_CALL(mockSettings, setValue(QStringEq("homepage"), QVariantEq("about:blank"))); // change setting diff --git a/src/settings/test/test_settings.qrc b/src/settings/test/test_settings.qrc index deaf088f..16e74fef 100644 --- a/src/settings/test/test_settings.qrc +++ b/src/settings/test/test_settings.qrc @@ -1,5 +1,7 @@ - - - rekonqrc - + + + + + rekonqrc + diff --git a/third-party/resources.qrc b/third-party/resources.qrc index f692daee..49496028 100644 --- a/third-party/resources.qrc +++ b/third-party/resources.qrc @@ -5,27 +5,31 @@ tabler-icons.theme - tabler-icons/icons/backspace.svg + tabler-icons/icons/chevron-right.svg + tabler-icons/icons/star.svg tabler-icons/icons/browser-plus.svg - tabler-icons/icons/chevron-left.svg - tabler-icons/icons/chevron-right.svg - tabler-icons/icons/chevrons-right.svg + tabler-icons/icons/backspace.svg + tabler-icons/icons/trash.svg tabler-icons/icons/folder-plus.svg tabler-icons/icons/home.svg + tabler-icons/icons/arrow-right.svg + tabler-icons/icons/arrow-right.svg + tabler-icons/icons/arrow-left.svg tabler-icons/icons/refresh.svg - tabler-icons/icons/star.svg - tabler-icons/icons/trash.svg tabler-icons/icons/x.svg + + tabler-icons/icons/file-code.svg + tabler-icons/icons/bookmark.svg tabler-icons/icons/bookmarks.svg tabler-icons/icons/browser.svg tabler-icons/icons/download.svg tabler-icons/icons/folder.svg - tabler-icons/icons/keyboard.svg + tabler-icons/icons/tool.svg tabler-icons/icons/puzzle.svg tabler-icons/icons/settings.svg - tabler-icons/icons/tool.svg + tabler-icons/icons/keyboard.svg diff --git a/third-party/tabler-icons.theme b/third-party/tabler-icons.theme index 88941053..8d754e3d 100644 --- a/third-party/tabler-icons.theme +++ b/third-party/tabler-icons.theme @@ -7,6 +7,11 @@ Size=24 Context=Actions Type=Scalable +[mimetypes/scalable] +Size=24 +Context=Mimetypes +Type=Scalable + [places/scalable] Size=24 Context=Places -- cgit v1.2.1