From 4c759ca6a4d0c0b6577a0a8e23ad80f948447865 Mon Sep 17 00:00:00 2001 From: =?UTF-8?q?Emilio=20L=C3=B3pez?= Date: Wed, 4 Jan 2023 17:29:24 -0300 Subject: [PATCH] slither-doctor: add new PATH checks This ensures PATH is correctly configured, and hints the user about what they might need to do to configure it correctly. --- slither/tools/doctor/checks/__init__.py | 2 + slither/tools/doctor/checks/paths.py | 56 +++++++++++++++++++++++++ 2 files changed, 58 insertions(+) create mode 100644 slither/tools/doctor/checks/paths.py diff --git a/slither/tools/doctor/checks/__init__.py b/slither/tools/doctor/checks/__init__.py index 762c60b5d..8a0741940 100644 --- a/slither/tools/doctor/checks/__init__.py +++ b/slither/tools/doctor/checks/__init__.py @@ -1,6 +1,7 @@ from typing import Callable, List from dataclasses import dataclass +from slither.tools.doctor.checks.paths import check_slither_path from slither.tools.doctor.checks.platform import compile_project, detect_platform from slither.tools.doctor.checks.versions import show_versions @@ -12,6 +13,7 @@ class Check: ALL_CHECKS: List[Check] = [ + Check("PATH configuration", check_slither_path), Check("Software versions", show_versions), Check("Project platform", detect_platform), Check("Project compilation", compile_project), diff --git a/slither/tools/doctor/checks/paths.py b/slither/tools/doctor/checks/paths.py new file mode 100644 index 000000000..53fae78ad --- /dev/null +++ b/slither/tools/doctor/checks/paths.py @@ -0,0 +1,56 @@ +from pathlib import Path +from typing import List, Optional, Tuple +import shutil +import sysconfig + +from slither.utils.colors import yellow, green, red + + +def check_path_config(name: str) -> Tuple[bool, Optional[Path], List[Path]]: + binary_path = shutil.which(name) + possible_paths = [] + + for scheme in sysconfig.get_scheme_names(): + script_path = Path(sysconfig.get_path("scripts", scheme)) + purelib_path = Path(sysconfig.get_path("purelib", scheme)) + script_binary_path = shutil.which(name, path=script_path) + if script_binary_path is not None: + possible_paths.append((script_path, purelib_path)) + + binary_here = False + if binary_path is not None: + binary_path = Path(binary_path) + this_code = Path(__file__) + this_binary = list(filter(lambda x: this_code.is_relative_to(x[1]), possible_paths)) + binary_here = len(this_binary) > 0 and all( + binary_path.is_relative_to(script) for script, _ in this_binary + ) + + return binary_here, binary_path, list(set(script for script, _ in possible_paths)) + + +def check_slither_path(**_kwargs) -> None: + binary_here, binary_path, possible_paths = check_path_config("slither") + show_paths = False + + if binary_path: + print(green(f"`slither` found in PATH at `{binary_path}`.")) + if binary_here: + print(green("Its location matches this slither-doctor installation.")) + else: + print( + yellow( + f"This path does not correspond to this slither-doctor installation.\n" + + "Double-check the order of directories in PATH if you have several slither installations." + ) + ) + show_paths = True + else: + print(red("`slither` was not found in PATH.")) + show_paths = True + + if show_paths: + print() + print("Consider adding one of the following directories to PATH:") + for path in possible_paths: + print(f" * {path}")