diff options
Diffstat (limited to 'sources/pyside6/doc/qtattributionsscannertorst.py')
-rw-r--r-- | sources/pyside6/doc/qtattributionsscannertorst.py | 123 |
1 files changed, 123 insertions, 0 deletions
diff --git a/sources/pyside6/doc/qtattributionsscannertorst.py b/sources/pyside6/doc/qtattributionsscannertorst.py new file mode 100644 index 000000000..677371c45 --- /dev/null +++ b/sources/pyside6/doc/qtattributionsscannertorst.py @@ -0,0 +1,123 @@ +# Copyright (C) 2022 The Qt Company Ltd. +# SPDX-License-Identifier: LicenseRef-Qt-Commercial OR LGPL-3.0-only OR GPL-2.0-only OR GPL-3.0-only + +""" +Tool to run qtattributionsscanner and convert its output to rst +""" + +import os +import json +import subprocess +import warnings +from argparse import ArgumentParser, RawTextHelpFormatter +from pathlib import Path + + +USAGE = "Usage: qtattributionsscannertorst [directory] [file]'" + + +libexec_dir = None + + +def indent(lines, indent): + result = '' + for line in lines: + result = f"{result}{indent}{line}\n" + return result + + +rstHeader = """Licenses Used in Qt for Python +****************************** + +Qt for Python contains some code that is not provided under the +GNU Lesser General Public License (LGPL) or the Qt Commercial License, +but rather under specific licenses from the original authors. +The Qt Company gratefully acknowledges these and other contributions +to Qt for Python. We recommend that programs that use Qt for Python +also acknowledge these contributions, and quote these license +statements in an appendix to the documentation. + +Note: You only need to comply with (and acknowledge) the licenses of +the third-party components that you are using with your application. +Click the name of the component to see the licensing details. + +Third-party Licenses +^^^^^^^^^^^^^^^^^^^^ + +The licenses for the third-party sources used by Qt itself are listed +in +`Qt documentation <https://doc.qt.io/qt-5/licenses-used-in-qt.html>`_. +The following table lists parts of Qt for Python that incorporates +code licensed under third-party opensource licenses: + +""" + + +def rstHeadline(title): + return f"{title}\n{'-' * len(title)}\n" + + +def rstUrl(title, url): + return f"`{title} <{url}>`_" + + +def rstLiteralBlock(lines): + return f"::\n\n{indent(lines, ' ')}\n\n" + + +def rstLiteralBlockFromText(text): + return rstLiteralBlock(text.strip().split('\n')) + + +def readFile(fileName): + with open(fileName, 'r') as file: + return file.readlines() + + +def get_libexec_dir(): + libexec_b = subprocess.check_output("qtpaths6 -query QT_INSTALL_LIBEXECS", shell=True) + return libexec_b.decode('utf-8').strip() + + +def runScanner(directory, targetFileName, libexec_dir): + # qtattributionsscanner recursively searches for qt_attribution.json files + # and outputs them in JSON with the paths of the 'LicenseFile' made absolute + scanner = os.path.join(libexec_dir, 'qtattributionsscanner') + command = f'{scanner} --output-format json {directory}' + jsonS = subprocess.check_output(command, shell=True) + if not jsonS: + raise RuntimeError(f'{command} failed to produce output.') + + with open(targetFileName, 'w') as targetFile: + targetFile.write(rstHeader) + for entry in json.loads(jsonS.decode('utf-8')): + content = f"{entry['Name']}\n{entry['Description']}\n{entry['QtUsage']}\n\n" + url = entry['Homepage'] + version = entry['Version'] + if url and version: + content = f"{content}{rstUrl('Project Homepage', url)}, upstream version: {version}\n\n" # noqa E:501 + copyright = entry['Copyright'] + if copyright: + content += rstLiteralBlockFromText(copyright) + content += entry['License'] + '\n\n' + licenseFile = entry['LicenseFile'] + if licenseFile: + if Path(licenseFile).is_file(): + content += rstLiteralBlock(readFile(licenseFile)) + else: + warnings.warn(f'"{licenseFile}" is not a file', RuntimeWarning) + targetFile.write(content) + + +if __name__ == '__main__': + parser = ArgumentParser(description=USAGE, formatter_class=RawTextHelpFormatter) + parser.add_argument("-l", "--libexec", type=str, help="libexec directory of Qt") + parser.add_argument('directory') + parser.add_argument('target') + options = parser.parse_args() + directory = options.directory + targetFileName = options.target + libexec_dir = options.libexec + if not libexec_dir: + libexec_dir = get_libexec_dir() + runScanner(directory, targetFileName, libexec_dir) |