From ce58f326d1bb389ff4b73c918354462e3452b8bb Mon Sep 17 00:00:00 2001 From: John Andersen Date: Fri, 21 Jun 2024 00:54:05 +0000 Subject: [PATCH] feat: no entrypoint registration required in tree Signed-off-by: John Andersen --- cve_bin_tool/checkers/__init__.py | 21 ++++++++++++ cve_bin_tool/cli.py | 13 ++----- cve_bin_tool/egg_updater.py | 19 ----------- cve_bin_tool/version_scanner.py | 34 ++++++++++++------- .../oot-checker/oot_checker/checker_name.py | 2 +- setup.py | 20 ----------- test/test_checkers.py | 13 ++----- 7 files changed, 49 insertions(+), 73 deletions(-) diff --git a/cve_bin_tool/checkers/__init__.py b/cve_bin_tool/checkers/__init__.py index d9d1d59443..9f4a8a2868 100644 --- a/cve_bin_tool/checkers/__init__.py +++ b/cve_bin_tool/checkers/__init__.py @@ -6,10 +6,20 @@ import collections import re +import sys from cve_bin_tool.error_handler import InvalidCheckerError from cve_bin_tool.util import regex_find +if sys.version_info >= (3, 10): + from importlib import metadata as importlib_metadata +else: + import importlib_metadata +if sys.version_info >= (3, 9): + import importlib.resources as resources +else: + import importlib_resources as resources + __all__ = [ "Checker", "VendorProductPair", @@ -439,3 +449,14 @@ def get_version(self, lines, filename): ) return version_info + + +BUILTIN_CHECKERS = { + checker_path.stem: importlib_metadata.EntryPoint( + checker_path.stem, + f'cve_bin_tool.checkers.{checker_path.stem}:{"".join(checker_path.stem.replace("_", " ").title().split())}Checker', + "cve_bin_tool.checkers", + ) + for checker_path in resources.files("cve_bin_tool.checkers").iterdir() + if (checker_path.suffix == ".py" and not checker_path.name.startswith("__")) +} diff --git a/cve_bin_tool/cli.py b/cve_bin_tool/cli.py index ddedd7714b..b292417f1e 100644 --- a/cve_bin_tool/cli.py +++ b/cve_bin_tool/cli.py @@ -75,11 +75,6 @@ from cve_bin_tool.version import VERSION from cve_bin_tool.version_scanner import VersionScanner -if sys.version_info >= (3, 10): - from importlib import metadata as importlib_metadata -else: - import importlib_metadata - sys.excepthook = excepthook # Always install excepthook for entrypoint module. @@ -914,12 +909,10 @@ def main(argv=None): runs = args["runs"] skips = list( map( - lambda checker: checker.name, + lambda checker_name: checker_name, filter( - lambda checker: checker.name not in runs, - importlib_metadata.entry_points().select( - group="cve_bin_tool.checker" - ), + lambda checker_name: checker_name not in runs, + VersionScanner.available_checkers(), ), ) ) diff --git a/cve_bin_tool/egg_updater.py b/cve_bin_tool/egg_updater.py index 3b6421a3db..0e342253f1 100644 --- a/cve_bin_tool/egg_updater.py +++ b/cve_bin_tool/egg_updater.py @@ -75,25 +75,6 @@ def update_egg() -> None: "cve-bin-tool = cve_bin_tool.cli:main", "csv2cve = cve_bin_tool.csv2cve:main", ], - "cve_bin_tool.checker": [ - "{} = cve_bin_tool.checkers.{}:{}".format( - filename.replace(".py", ""), - filename.replace(".py", ""), - "".join( - (filename.replace(".py", "") + " checker") - .replace("_", " ") - .title() - .split() - ), - ) - for filename in os.listdir( - os.path.join( - os.path.abspath(os.path.dirname(__file__)), - "checkers", - ) - ) - if filename.endswith(".py") and "__init__" not in filename - ], }, ) ) diff --git a/cve_bin_tool/version_scanner.py b/cve_bin_tool/version_scanner.py index 3e617ff07d..c70fbc74f9 100644 --- a/cve_bin_tool/version_scanner.py +++ b/cve_bin_tool/version_scanner.py @@ -8,7 +8,7 @@ from pathlib import Path, PurePath from typing import Iterator -from cve_bin_tool.checkers import Checker +from cve_bin_tool.checkers import BUILTIN_CHECKERS, Checker from cve_bin_tool.cvedb import CVEDB from cve_bin_tool.egg_updater import IS_DEVELOP, update_egg from cve_bin_tool.error_handler import ErrorMode @@ -84,22 +84,32 @@ def __init__( @classmethod def load_checkers(cls) -> dict[str, type[Checker]]: """Loads CVE checkers""" - checkers = dict( - map( - lambda checker: (checker.name, checker.load()), - importlib_metadata.entry_points().select(group=cls.CHECKER_ENTRYPOINT), + entrypoint_checkers = { + checker.name: checker.load() + for checker in importlib_metadata.entry_points().select( + group=cls.CHECKER_ENTRYPOINT ) - ) - return checkers + } + builtin_checkers = { + checker.name: checker.load() for checker in BUILTIN_CHECKERS.values() + } + all_checkers = { + **builtin_checkers, + **entrypoint_checkers, + } + return all_checkers @classmethod def available_checkers(cls) -> list[str]: """Discover and list available checker by inspecting the entry points""" - checkers = importlib_metadata.entry_points().select( - group=cls.CHECKER_ENTRYPOINT - ) - checker_list = [item.name for item in checkers] - return checker_list + entrypoint_checker_names = [ + checker.name + for checker in importlib_metadata.entry_points().select( + group=cls.CHECKER_ENTRYPOINT + ) + ] + all_checker_names = list(BUILTIN_CHECKERS.keys()) + entrypoint_checker_names + return all_checker_names def remove_skiplist(self, skips: list[str]) -> None: """Remove specific checkers If a checker is in the skip list, it will be removed from this dictionary. If it's not found or is not a valid checker name, it logs error messages.""" diff --git a/example/oot-checker/oot_checker/checker_name.py b/example/oot-checker/oot_checker/checker_name.py index f88179cd00..823fbfb54a 100644 --- a/example/oot-checker/oot_checker/checker_name.py +++ b/example/oot-checker/oot_checker/checker_name.py @@ -18,4 +18,4 @@ class CurlChecker(Checker): CONTAINS_PATTERNS = [r"curl ([678]+\.[0-9]+\.[0-9]+)"] FILENAME_PATTERNS = [r"curl"] VERSION_PATTERNS = [r"curl ([678]+\.[0-9]+\.[0-9]+)"] - VENDOR_PACKAGE = [("haxx", "curl")] + VENDOR_PRODUCT = [("haxx", "curl")] diff --git a/setup.py b/setup.py index 5f0ba969c6..93c3437410 100644 --- a/setup.py +++ b/setup.py @@ -69,26 +69,6 @@ "cve-bin-tool = cve_bin_tool.cli:main", "csv2cve = cve_bin_tool.csv2cve:main", ], - "cve_bin_tool.checker": [ - "{} = cve_bin_tool.checkers.{}:{}".format( - filename.replace(".py", ""), - filename.replace(".py", ""), - "".join( - (filename.replace(".py", "") + " checker") - .replace("_", " ") - .title() - .split() - ), - ) - for filename in os.listdir( - os.path.join( - os.path.abspath(os.path.dirname(__file__)), - "cve_bin_tool", - "checkers", - ) - ) - if filename.endswith(".py") and "__init__" not in filename - ], }, ) diff --git a/test/test_checkers.py b/test/test_checkers.py index 10ffb136ce..caaa9135eb 100644 --- a/test/test_checkers.py +++ b/test/test_checkers.py @@ -4,19 +4,13 @@ from __future__ import annotations import re -import sys import pytest -from cve_bin_tool.checkers import Checker, VendorProductPair +from cve_bin_tool.checkers import BUILTIN_CHECKERS, Checker, VendorProductPair from cve_bin_tool.egg_updater import IS_DEVELOP, update_egg from cve_bin_tool.log import LOGGER -if sys.version_info >= (3, 10): - from importlib import metadata as importlib_metadata -else: - import importlib_metadata - Pattern = type(re.compile("", 0)) @@ -136,10 +130,7 @@ def setup_class(cls): ) def test_filename_is(self, checker_name, file_name, expected_results): """Test a checker's filename detection""" - checkers = importlib_metadata.entry_points().select( - group="cve_bin_tool.checker" - ) - for checker in checkers: + for checker in BUILTIN_CHECKERS.values(): if checker.name == checker_name: Checker = checker.load() checker = Checker()