From 099d3857a7092c2a0c3eca092522c944cae5f2f5 Mon Sep 17 00:00:00 2001 From: Rechi Date: Mon, 19 Nov 2018 09:14:26 +0100 Subject: [PATCH] add reverse dependencies check --- README.md | 2 ++ kodi_addon_checker/addons/Addon.py | 9 ++++++ kodi_addon_checker/addons/Repository.py | 7 +++++ kodi_addon_checker/check_addon.py | 2 ++ kodi_addon_checker/check_dependencies.py | 35 ++++++++++++++++++++++++ 5 files changed, 55 insertions(+) diff --git a/README.md b/README.md index 08c6908b..58258bf3 100644 --- a/README.md +++ b/README.md @@ -43,6 +43,8 @@ It can also be used locally for detecting problems in your addons. - Check if files in addon are marked as executable or not. +- Check for unused script.module addons + All of the validation and checks are done according to the kodi [addon rules](https://kodi.wiki/view/Add-on_rules) ## Installation diff --git a/kodi_addon_checker/addons/Addon.py b/kodi_addon_checker/addons/Addon.py index e8c8c890..dfe64455 100644 --- a/kodi_addon_checker/addons/Addon.py +++ b/kodi_addon_checker/addons/Addon.py @@ -19,3 +19,12 @@ def __init__(self, addon_xml: ET.Element): self.dependencies = [] for dependency in addon_xml.findall('./requires/import'): self.dependencies.append(AddonDependency(dependency)) + + def __eq__(self, other): + return self.id == other.id and self.version == other.version + + def dependsOn(self, addonId): + for dependency in self.dependencies: + if dependency.id == addonId: + return True + return False diff --git a/kodi_addon_checker/addons/Repository.py b/kodi_addon_checker/addons/Repository.py index 67d3591f..766d2e9d 100644 --- a/kodi_addon_checker/addons/Repository.py +++ b/kodi_addon_checker/addons/Repository.py @@ -38,3 +38,10 @@ def find(self, addonId): if addon.id == addonId: return addon return None + + def rdepends(self, addonId): + rdepends = [] + for addon in self.addons: + if addon.dependsOn(addonId): + rdepends.append(addon) + return rdepends diff --git a/kodi_addon_checker/check_addon.py b/kodi_addon_checker/check_addon.py index 2419a1fa..5a5f72af 100644 --- a/kodi_addon_checker/check_addon.py +++ b/kodi_addon_checker/check_addon.py @@ -53,6 +53,8 @@ def start(addon_path, branch_name, all_repo_addons, pr, config=None): check_dependencies.check_addon_dependencies(addon_report, repo_addons, parsed_xml, branch_name) + check_dependencies.check_reverse_dependencies(addon_report, addon_id, branch_name, all_repo_addons) + check_files.check_file_permission(addon_report, file_index) check_files.check_for_invalid_xml_files(addon_report, file_index) diff --git a/kodi_addon_checker/check_dependencies.py b/kodi_addon_checker/check_dependencies.py index 0f8c12ac..1af7d108 100644 --- a/kodi_addon_checker/check_dependencies.py +++ b/kodi_addon_checker/check_dependencies.py @@ -75,6 +75,41 @@ def check_addon_dependencies(report: Report, repo_addons: dict, parsed_xml, bran LOGGER.warn("Misconfiguration in VERSION_ATTRB of check_dependencies") +def check_reverse_dependencies(report: Report, addon: str, branch_name: str, all_repo_addons: dict): + addonInRepo = None + rdepends = [] + rdependsLowerBranch = [] + branchFound = False + + for branch, repo in sorted(all_repo_addons.items()): + if not branchFound and branch != branch_name: + for rdepend in repo.rdepends(addon): + if rdepend not in rdependsLowerBranch: + rdependsLowerBranch.append(rdepend) + continue + branchFound = True + + addonFind = repo.find(addon) + if addonFind and addonInRepo and addonFind != addonInRepo: + break + + addonInRepo = addonFind + + for rdepend in repo.rdepends(addon): + if rdepend not in rdependsLowerBranch and rdepend not in rdepends: + rdepends.append(rdepend) + if addon.startswith("script.module.") and len(rdepends) + len(rdependsLowerBranch) == 0: + report.add(Record(WARNING, "This module isn't required by any add-on.")) + + if len(rdepends) > 0: + report.add(Record(INFORMATION, "Reverse dependencies: {} ({})" + .format(", ".join(sorted([r.id for r in rdepends])), len(rdepends)))) + + if len(rdependsLowerBranch) > 0: + report.add(Record(INFORMATION, "Reverse dependencies (in lower branches): {} ({})" + .format(", ".join(sorted([r.id for r in rdependsLowerBranch])), len(rdependsLowerBranch)))) + + def _get_ignore_list(branch_name): if branch_name == "leia":