-
-
Notifications
You must be signed in to change notification settings - Fork 5
Expand file tree
/
Copy pathutil.py
More file actions
88 lines (70 loc) · 2.79 KB
/
util.py
File metadata and controls
88 lines (70 loc) · 2.79 KB
1
2
3
4
5
6
7
8
9
10
11
12
13
14
15
16
17
18
19
20
21
22
23
24
25
26
27
28
29
30
31
32
33
34
35
36
37
38
39
40
41
42
43
44
45
46
47
48
49
50
51
52
53
54
55
56
57
58
59
60
61
62
63
64
65
66
67
68
69
70
71
72
73
74
75
76
77
78
79
80
81
82
83
84
85
86
87
88
import sys
import shutil
import subprocess
from pathlib import Path
import logging
from typing import Optional, List
try:
import tomllib
except ModuleNotFoundError:
import tomli as tomllib
from cpp_linter_hooks.versions import CLANG_FORMAT_VERSIONS, CLANG_TIDY_VERSIONS
LOG = logging.getLogger(__name__)
def get_version_from_dependency(tool: str) -> Optional[str]:
"""Get the version of a tool from the pyproject.toml dependencies."""
pyproject_path = Path(__file__).parent.parent / "pyproject.toml"
if not pyproject_path.exists():
return None
with open(pyproject_path, "rb") as f:
data = tomllib.load(f)
# Check [project].dependencies
dependencies = data.get("project", {}).get("dependencies", [])
for dep in dependencies:
if dep.startswith(f"{tool}=="):
return dep.split("==")[1]
return None
DEFAULT_CLANG_FORMAT_VERSION = get_version_from_dependency("clang-format")
DEFAULT_CLANG_TIDY_VERSION = get_version_from_dependency("clang-tidy")
def _resolve_version(versions: List[str], user_input: Optional[str]) -> Optional[str]:
"""Resolve the latest matching version based on user input and available versions."""
if user_input is None:
return None
if user_input in versions:
return user_input
try:
# filter versions that start with the user input
matched_versions = [v for v in versions if v.startswith(user_input)]
if not matched_versions:
raise ValueError
# define a function to parse version strings into tuples for comparison
def parse_version(v: str):
return tuple(map(int, v.split(".")))
# return the latest version
return max(matched_versions, key=parse_version)
except ValueError:
LOG.warning("Version %s not found in available versions", user_input)
return None
def _install_tool(tool: str, version: str) -> Optional[Path]:
"""Install a tool using pip, suppressing output."""
try:
subprocess.check_call(
[sys.executable, "-m", "pip", "install", f"{tool}=={version}"],
stdout=subprocess.DEVNULL,
stderr=subprocess.DEVNULL,
)
return shutil.which(tool)
except subprocess.CalledProcessError:
return None
def _resolve_install(tool: str, version: Optional[str]) -> Optional[Path]:
"""Resolve the installation of a tool, checking for version and installing if necessary."""
user_version = _resolve_version(
CLANG_FORMAT_VERSIONS if tool == "clang-format" else CLANG_TIDY_VERSIONS,
version,
)
if user_version is None:
user_version = (
DEFAULT_CLANG_FORMAT_VERSION
if tool == "clang-format"
else DEFAULT_CLANG_TIDY_VERSION
)
return _install_tool(tool, user_version)