mirror of https://github.com/crytic/slither
parent
5faddb4e7f
commit
16393d51fe
@ -0,0 +1,18 @@ |
||||
from typing import Callable, List |
||||
from dataclasses import dataclass |
||||
|
||||
from slither.tools.doctor.checks.platform import compile_project, detect_platform |
||||
from slither.tools.doctor.checks.versions import show_versions |
||||
|
||||
|
||||
@dataclass |
||||
class Check: |
||||
title: str |
||||
function: Callable[..., None] |
||||
|
||||
|
||||
ALL_CHECKS: List[Check] = [ |
||||
Check("Software versions", show_versions), |
||||
Check("Project platform", detect_platform), |
||||
Check("Project compilation", compile_project), |
||||
] |
@ -0,0 +1,59 @@ |
||||
import logging |
||||
from pathlib import Path |
||||
|
||||
import crytic_compile.crytic_compile as crytic_compile |
||||
|
||||
from slither.tools.doctor.utils import snip_section |
||||
from slither.utils.colors import red, yellow, green |
||||
|
||||
|
||||
def detect_platform(project: str, **kwargs) -> None: |
||||
path = Path(project) |
||||
if path.is_file(): |
||||
print( |
||||
yellow( |
||||
f"{project!r} is a file. Using it as target will manually compile your code with solc and _not_ use a compilation framework. Is that what you meant to do?" |
||||
) |
||||
) |
||||
return |
||||
|
||||
print(f"Trying to detect project type for {project!r}") |
||||
|
||||
supported_platforms = crytic_compile.get_platforms() |
||||
skip_platforms = {"solc", "solc-json", "archive", "standard", "etherscan"} |
||||
detected_platforms = { |
||||
platform.NAME: platform.is_supported(project, **kwargs) |
||||
for platform in supported_platforms |
||||
if platform.NAME.lower() not in skip_platforms |
||||
} |
||||
platform_qty = len([platform for platform, state in detected_platforms.items() if state]) |
||||
|
||||
print("Is this project using...") |
||||
for platform, state in detected_platforms.items(): |
||||
print(f" => {platform + '?':<15}{state and green('Yes') or red('No')}") |
||||
print() |
||||
|
||||
if platform_qty == 0: |
||||
print(red("No platform was detected! This doesn't sound right.")) |
||||
print( |
||||
yellow( |
||||
"Are you trying to analyze a folder with standalone solidity files, without using a compilation framework? If that's the case, then this is okay." |
||||
) |
||||
) |
||||
elif platform_qty > 1: |
||||
print(red("More than one platform was detected! This doesn't sound right.")) |
||||
print( |
||||
red("Please use `--compile-force-framework` in Slither to force the correct framework.") |
||||
) |
||||
else: |
||||
print(green("A single platform was detected."), yellow("Is it the one you expected?")) |
||||
|
||||
|
||||
def compile_project(project: str, **kwargs): |
||||
print("Invoking crytic-compile on the project, please wait...") |
||||
|
||||
try: |
||||
crytic_compile.CryticCompile(project, **kwargs) |
||||
except Exception as e: |
||||
with snip_section("Project compilation failed :( The following error was generated:"): |
||||
logging.exception(e) |
@ -0,0 +1,58 @@ |
||||
from importlib import metadata |
||||
import json |
||||
from typing import Optional |
||||
from packaging.version import parse, LegacyVersion, Version |
||||
import urllib |
||||
|
||||
from slither.utils.colors import yellow, green |
||||
|
||||
|
||||
def get_installed_version(name: str) -> Optional[LegacyVersion | Version]: |
||||
try: |
||||
return parse(metadata.version(name)) |
||||
except metadata.PackageNotFoundError: |
||||
return None |
||||
|
||||
|
||||
def get_github_version(name: str) -> Optional[LegacyVersion | Version]: |
||||
try: |
||||
with urllib.request.urlopen( |
||||
f"https://api.github.com/repos/crytic/{name}/releases/latest" |
||||
) as response: |
||||
text = response.read() |
||||
data = json.loads(text) |
||||
return parse(data["tag_name"]) |
||||
except: |
||||
return None |
||||
|
||||
|
||||
def show_versions(**kwargs) -> None: |
||||
versions = { |
||||
"Slither": (get_installed_version("slither-analyzer"), get_github_version("slither")), |
||||
"crytic-compile": ( |
||||
get_installed_version("crytic-compile"), |
||||
get_github_version("crytic-compile"), |
||||
), |
||||
"solc-select": (get_installed_version("solc-select"), get_github_version("solc-select")), |
||||
} |
||||
|
||||
outdated = { |
||||
name |
||||
for name, (installed, latest) in versions.items() |
||||
if not installed or not latest or latest > installed |
||||
} |
||||
|
||||
for name, (installed, latest) in versions.items(): |
||||
color = yellow if name in outdated else green |
||||
print(f"{name + ':':<16}{color(installed or 'N/A'):<16} (latest is {latest or 'Unknown'})") |
||||
|
||||
if len(outdated) > 0: |
||||
print() |
||||
print( |
||||
yellow( |
||||
f"Please update {', '.join(outdated)} to the latest release before creating a bug report." |
||||
) |
||||
) |
||||
else: |
||||
print() |
||||
print(green("Your tools are up to date.")) |
@ -1,24 +0,0 @@ |
||||
from importlib import metadata |
||||
import json |
||||
from typing import Optional |
||||
from packaging.version import parse, LegacyVersion, Version |
||||
import urllib |
||||
|
||||
|
||||
def get_installed_version(name: str) -> Optional[LegacyVersion | Version]: |
||||
try: |
||||
return parse(metadata.version(name)) |
||||
except metadata.PackageNotFoundError: |
||||
return None |
||||
|
||||
|
||||
def get_github_version(name: str) -> Optional[LegacyVersion | Version]: |
||||
try: |
||||
with urllib.request.urlopen( |
||||
f"https://api.github.com/repos/crytic/{name}/releases/latest" |
||||
) as response: |
||||
text = response.read() |
||||
data = json.loads(text) |
||||
return parse(data["tag_name"]) |
||||
except: |
||||
return None |
Loading…
Reference in new issue