From 81025eabd2659edb266f8d3f5b6a420e31d12fef Mon Sep 17 00:00:00 2001 From: Campbell Barton Date: Sat, 19 Oct 2024 17:53:17 +1100 Subject: [PATCH] Refactor: various changes to "make license" - Avoid manipulating a dictionary arguments, use return values & iterators to return results. - Move logic out of the file reading context once the file was read (reducing right-shift). - Move intermediate license data from a dictionary to a named-tuple for better clarity & type safety. - Remove use of `dataclass` as a container for constants, as it quite clear to define the constants directly in the global namespace. - Group imports at the beginning of the file (no need to quiet pylint). - Add headings for code sections. - Use double quotes. - Use the term "dir" instead of both dir/folder. - Note the limitations parsing CMake files directly, with a possible alternative. --- tools/utils_maintenance/make_license.py | 479 +++++++++++++----------- 1 file changed, 256 insertions(+), 223 deletions(-) diff --git a/tools/utils_maintenance/make_license.py b/tools/utils_maintenance/make_license.py index 3c8cfc4f1cf..a7389fabaeb 100644 --- a/tools/utils_maintenance/make_license.py +++ b/tools/utils_maintenance/make_license.py @@ -1,25 +1,36 @@ # SPDX-FileCopyrightText: 2024 Blender Authors # # SPDX-License-Identifier: GPL-2.0-or-later -# pylint: disable=wrong-import-position, missing-function-docstring, missing-module-docstring, missing-class-docstring +# pylint: disable=missing-function-docstring, missing-module-docstring, missing-class-docstring -from dataclasses import dataclass -from pathlib import Path +import itertools +import json import os +import re +import sys + +from pathlib import Path + +from typing import ( + Iterator, + NamedTuple, +) + +# ----------------------------------------------------------------------------- +# Path Constants + +ROOT_DIR = Path(os.path.abspath(Path(os.path.dirname(__file__)) / "../../")) + +DIRPATH_LICENSES: Path = ROOT_DIR / "release/license/" +DIRPATH_EXTERN_LIBRARIES: Path = ROOT_DIR / "extern" + +FILEPATH_VERSIONS_CMAKE: Path = ROOT_DIR / "build_files/build_environment/cmake/versions.cmake" +FILEPATH_LICENSES_INDEX: Path = DIRPATH_LICENSES / "licenses.json" # List of licenses and definitions. +FILEPATH_LICENSE_GENERATED: Path = DIRPATH_LICENSES / "license.md" # Generated licenses file. -CURRENT_DIR = Path(os.path.dirname(__file__)) -ROOT = Path(os.path.abspath(CURRENT_DIR / "../../")) - - -@dataclass -class Filepaths: - licenses_folder: Path = ROOT / "release/license/" - versions_cmake: Path = ROOT / "build_files/build_environment/cmake/versions.cmake" - extern_libraries: Path = ROOT / "extern" - licenses_index: Path = licenses_folder / "licenses.json" # List of licenses and definitions. - license_generated: Path = licenses_folder / "license.md" # Generated licenses file. - +# ----------------------------------------------------------------------------- +# Constants INTRODUCTION = r"""). - text = re.sub(r'', '', text, flags=re.DOTALL) + text = re.sub(r"", "", text, flags=re.DOTALL) # Find all licenses in < >. - license_pattern = r'<([^<|>]+?)>' + license_pattern = r"<([^<|>]+?)>" # Find all matches. matches = re.findall(license_pattern, text) @@ -517,27 +553,27 @@ def get_introduction(licenses: dict[str, License]) -> str: for license_lookup in license_lookups: if license_lookup not in licenses: - print(f'Error: {license_lookup} license not found in: "{Filepaths.licenses_index}"') + print(f"Error: {license_lookup} license not found in: \"{FILEPATH_LICENSES_INDEX}\"") continue license_item = licenses[license_lookup] introduction = introduction.replace( - f'<{license_lookup}>', + f"<{license_lookup}>", license_item.dump() ) introduction = introduction.replace( - f'<{license_lookup}|link>', - f'[{license_item.name}]({license_item.url})' + f"<{license_lookup}|link>", + f"[{license_item.name}]({license_item.url})" ) return introduction def generate_license_file(licenses: dict[str, License]) -> None: - filepath = Filepaths.license_generated + filepath = FILEPATH_LICENSE_GENERATED - with open(filepath, 'w', encoding='utf8') as fh: + with open(filepath, "w", encoding="utf8") as fh: fh.write(get_introduction(licenses)) for license_item in sorted(licenses.values()): @@ -545,12 +581,12 @@ def generate_license_file(licenses: dict[str, License]) -> None: continue if license_item.url: - fh.write(f'\n\n## [{license_item.name}]({license_item.url})\n\n') + fh.write(f"\n\n## [{license_item.name}]({license_item.url})\n\n") else: - fh.write(f'\n\n## {license_item.name}\n\n') + fh.write(f"\n\n## {license_item.name}\n\n") if license_item.copyright_exemption: - fh.write(f'{license_item.copyright_exemption}\n\n') + fh.write(f"{license_item.copyright_exemption}\n\n") fh.write("| Library | Version |\n") fh.write("| ------- | ------- |\n") else: @@ -565,25 +601,22 @@ def generate_license_file(licenses: dict[str, License]) -> None: exception_license = licenses.get(exception) if exception_license is None: - print( - f'Error: {exception} extension license not found in: ' - f'{Filepaths.licenses_index}"' - ) + print(f"Error: {exception} extension license not found in: \"{FILEPATH_LICENSES_INDEX}\"") continue fh.write(exception_license.dump(i + 1)) fh.write("\n") - fh.write("\n") - - print(f'\nLicense file successfully generated: "{filepath}"') + print(f"\nLicense file successfully generated: \"{filepath}\"") print("Remember to commit the file to the Blender repository.\n") -def main() -> None: - licenses = initialize_licenses() +# ----------------------------------------------------------------------------- +# Main Function - fetch_libraries_licenses(licenses) + +def main() -> None: + licenses = fetch_libraries_licenses() generate_license_file(licenses)