Skip to content

Commit 4dd3689

Browse files
committed
pass only major version around
1 parent cdcbda9 commit 4dd3689

File tree

5 files changed

+41
-53
lines changed

5 files changed

+41
-53
lines changed

clang_tools/install.py

Lines changed: 24 additions & 32 deletions
Original file line numberDiff line numberDiff line change
@@ -4,6 +4,7 @@
44
55
The module that performs the installation of clang-tools.
66
"""
7+
78
import os
89
from pathlib import Path, PurePath
910
import re
@@ -13,30 +14,23 @@
1314
from typing import Optional, cast
1415

1516
from . import release_tag, install_os, RESET_COLOR, suffix, YELLOW
16-
from .util import (
17-
download_file,
18-
verify_sha512,
19-
get_sha_checksum,
20-
parse_version,
21-
VERSION_TUPLE,
22-
)
17+
from .util import download_file, verify_sha512, get_sha_checksum, parse_version
2318

2419

2520
#: This pattern is designed to match only the major version number.
2621
RE_PARSE_VERSION = re.compile(rb"version\s([\d\.]+)", re.MULTILINE)
2722

2823

29-
def is_installed(tool_name: str, version: VERSION_TUPLE) -> Optional[Path]:
24+
def is_installed(tool_name: str, version: int) -> Optional[Path]:
3025
"""Detect if the specified tool is installed.
3126
3227
:param tool_name: The name of the specified tool.
33-
:param version: The specific version to expect.
28+
:param version: The specific major version to expect.
3429
3530
:returns: The path to the detected tool (if found), otherwise `None`.
3631
"""
37-
ver_major = version[0]
3832
exe_name = (
39-
f"{tool_name}" + (f"-{ver_major}" if install_os != "windows" else "") + suffix
33+
f"{tool_name}" + (f"-{version}" if install_os != "windows" else "") + suffix
4034
)
4135
try:
4236
result = subprocess.run(
@@ -62,18 +56,16 @@ def is_installed(tool_name: str, version: VERSION_TUPLE) -> Optional[Path]:
6256
path = Path(exe_path).resolve()
6357
print("at", str(path))
6458
ver_tuple = ver_match.split(".")
65-
if ver_tuple is None or ver_tuple[0] != str(ver_major):
59+
if ver_tuple is None or ver_tuple[0] != str(version):
6660
return None # version is unknown or not the desired major release
6761
return path
6862

6963

70-
def clang_tools_binary_url(
71-
tool: str, version: VERSION_TUPLE, tag: str = release_tag
72-
) -> str:
64+
def clang_tools_binary_url(tool: str, version: int, tag: str = release_tag) -> str:
7365
"""Assemble the URL to the binary.
7466
7567
:param tool: The name of the tool to download.
76-
:param version: The version of the tool to download.
68+
:param version: The major version of the tool to download.
7769
:param tag: The release tag used in the base URL.
7870
7971
:returns: The URL used to download the specified tool.
@@ -82,38 +74,38 @@ def clang_tools_binary_url(
8274
"https://github.com/cpp-linter/clang-tools-static-binaries/releases/download/"
8375
+ tag
8476
)
85-
download_url = f"{base_url}/{tool}-{version[0]}_{install_os}-amd64{suffix}"
77+
download_url = f"{base_url}/{tool}-{version}_{install_os}-amd64{suffix}"
8678
return download_url.replace(" ", "")
8779

8880

8981
def install_tool(
90-
tool_name: str, version: VERSION_TUPLE, directory: str, no_progress_bar: bool
82+
tool_name: str, version: int, directory: str, no_progress_bar: bool
9183
) -> bool:
9284
"""An abstract function that can install either clang-tidy or clang-format.
9385
9486
:param tool_name: The name of the clang-tool to install.
95-
:param version: The version of the tools to install.
87+
:param version: The major version of the tools to install.
9688
:param directory: The installation directory.
9789
:param no_progress_bar: A flag used to disable the downloads' progress bar.
9890
9991
:returns: `True` if the binary had to be downloaded and installed.
10092
`False` if the binary was not downloaded but is installed in ``directory``.
10193
"""
102-
destination = Path(directory, f"{tool_name}-{version[0]}{suffix}")
94+
destination = Path(directory, f"{tool_name}-{version}{suffix}")
10395
bin_url = clang_tools_binary_url(tool_name, version)
10496
if destination.exists():
105-
print(f"{tool_name}-{version[0]}", "already installed...")
97+
print(f"{tool_name}-{version}", "already installed...")
10698
print(" checking SHA512...", end=" ")
10799
if verify_sha512(get_sha_checksum(bin_url), destination.read_bytes()):
108100
print("valid")
109101
return False
110102
print("invalid")
111103
uninstall_tool(tool_name, version, directory)
112-
print("Downloading", tool_name, f"(version {version[0]})")
104+
print("Downloading", tool_name, f"(version {version})")
113105
bin_name = str(PurePath(bin_url).stem)
114106
if download_file(bin_url, bin_name, no_progress_bar) is None:
115107
raise OSError(f"Failed to download {bin_name} from {bin_url}")
116-
move_and_chmod_bin(bin_name, f"{tool_name}-{version[0]}{suffix}", directory)
108+
move_and_chmod_bin(bin_name, f"{tool_name}-{version}{suffix}", directory)
117109
if not verify_sha512(get_sha_checksum(bin_url), destination.read_bytes()):
118110
raise ValueError(
119111
f"File was corrupted during download from {bin_url}"
@@ -162,7 +154,7 @@ def move_and_chmod_bin(old_bin_name: str, new_bin_name: str, install_dir: str) -
162154

163155
def create_sym_link(
164156
tool_name: str,
165-
version: VERSION_TUPLE,
157+
version: int,
166158
install_dir: str,
167159
overwrite: bool = False,
168160
target: Optional[Path] = None,
@@ -171,7 +163,7 @@ def create_sym_link(
171163
doesn't have the version number appended.
172164
173165
:param tool_name: The name of the clang-tool to symlink.
174-
:param version: The version of the clang-tool to symlink.
166+
:param version: The major version of the clang-tool to symlink.
175167
:param install_dir: The installation directory to create the symlink in.
176168
:param overwrite: A flag to indicate if an existing symlink should be overwritten.
177169
:param target: The target executable's path and name for which to create a symlink
@@ -186,7 +178,7 @@ def create_sym_link(
186178
link_root_path.mkdir(parents=True)
187179
link = link_root_path / (tool_name + suffix)
188180
if target is None:
189-
target = link_root_path / f"{tool_name}-{version[0]}{suffix}"
181+
target = link_root_path / f"{tool_name}-{version}{suffix}"
190182
if link.exists():
191183
if not link.is_symlink():
192184
print(
@@ -220,15 +212,15 @@ def create_sym_link(
220212
return False
221213

222214

223-
def uninstall_tool(tool_name: str, version: VERSION_TUPLE, directory: str):
215+
def uninstall_tool(tool_name: str, version: int, directory: str):
224216
"""Remove a specified tool of a given version.
225217
226218
:param tool_name: The name of the clang tool to uninstall.
227-
:param version: The version of the clang-tools to remove.
219+
:param version: The major version of the clang-tools to remove.
228220
:param directory: The directory from which to remove the
229221
installed clang-tools.
230222
"""
231-
tool_path = Path(directory, f"{tool_name}-{version[0]}{suffix}")
223+
tool_path = Path(directory, f"{tool_name}-{version}{suffix}")
232224
if tool_path.exists():
233225
print("Removing", tool_path.name, "from", str(tool_path.parent))
234226
tool_path.unlink()
@@ -251,19 +243,19 @@ def uninstall_clang_tools(version: str, directory: str):
251243
print(f"Uninstalling version {version} from {str(install_dir)}")
252244
version_tuple = parse_version(version)
253245
for tool in ("clang-format", "clang-tidy"):
254-
uninstall_tool(tool, version_tuple, install_dir)
246+
uninstall_tool(tool, version_tuple[0], install_dir)
255247

256248

257249
def install_clang_tools(
258-
version: VERSION_TUPLE,
250+
version: int,
259251
tools: str,
260252
directory: str,
261253
overwrite: bool,
262254
no_progress_bar: bool,
263255
) -> None:
264256
"""Wraps functions used to individually install tools.
265257
266-
:param version: The version of the tools to install.
258+
:param version: The major version of the tools to install.
267259
:param tools: The specify tool(s) to install.
268260
:param directory: The installation directory.
269261
:param overwrite: A flag to indicate if the creation of a symlink has

clang_tools/main.py

Lines changed: 1 addition & 1 deletion
Original file line numberDiff line numberDiff line change
@@ -71,7 +71,7 @@ def main():
7171
version = parse_version(args.install)
7272
if version != (0, 0, 0):
7373
install_clang_tools(
74-
version,
74+
version[0],
7575
args.tool,
7676
args.directory,
7777
args.overwrite,

clang_tools/util.py

Lines changed: 2 additions & 3 deletions
Original file line numberDiff line numberDiff line change
@@ -4,6 +4,7 @@
44
55
A module containing utility functions.
66
"""
7+
78
import platform
89
import hashlib
910
from pathlib import Path
@@ -12,8 +13,6 @@
1213
from urllib.error import HTTPError
1314
from http.client import HTTPResponse
1415

15-
VERSION_TUPLE = Tuple[int, int, int]
16-
1716

1817
def check_install_os() -> str:
1918
"""Identify this Operating System.
@@ -102,7 +101,7 @@ def verify_sha512(checksum: str, exe: bytes) -> bool:
102101
return checksum == hashlib.sha512(exe).hexdigest()
103102

104103

105-
def parse_version(version: str) -> VERSION_TUPLE:
104+
def parse_version(version: str) -> Tuple[int, int, int]:
106105
"""Parse the given version string into a semantic specification.
107106
108107
:param version: The version specification as a string.

tests/test_install.py

Lines changed: 12 additions & 15 deletions
Original file line numberDiff line numberDiff line change
@@ -12,18 +12,17 @@
1212
is_installed,
1313
uninstall_clang_tools,
1414
)
15-
from clang_tools.util import VERSION_TUPLE
1615

1716

18-
@pytest.mark.parametrize("version", [(v, 0, 0) for v in range(7, 17)] + [(12, 0, 1)])
17+
@pytest.mark.parametrize("version", list(range(7, 17)))
1918
@pytest.mark.parametrize(
2019
"tool_name",
2120
["clang-format", "clang-tidy", "clang-query", "clang-apply-replacements"],
2221
)
23-
def test_clang_tools_binary_url(tool_name: str, version: VERSION_TUPLE):
22+
def test_clang_tools_binary_url(tool_name: str, version: int):
2423
"""Test `clang_tools_binary_url()`"""
2524
url = clang_tools_binary_url(tool_name, version)
26-
assert f"{tool_name}-{version[0]}_{install_os}-amd64" in url
25+
assert f"{tool_name}-{version}_{install_os}-amd64" in url
2726

2827

2928
@pytest.mark.parametrize("directory", ["", "."])
@@ -36,10 +35,10 @@ def test_dir_name(monkeypatch: pytest.MonkeyPatch, directory: str):
3635

3736
def test_create_symlink(monkeypatch: pytest.MonkeyPatch, tmp_path: Path):
3837
"""Test creation of symlink."""
39-
tool_name, version = ("clang-tool", (1, 0, 0))
38+
tool_name, version = ("clang-tool", 1)
4039
monkeypatch.chdir(str(tmp_path))
4140
# use a test tar file and rename it to "clang-tool-1" (+ OS suffix)
42-
test_target = tmp_path / f"{tool_name}-{version[0]}{suffix}"
41+
test_target = tmp_path / f"{tool_name}-{version}{suffix}"
4342
test_target.write_bytes(b"some binary data")
4443

4544
# create the symlink
@@ -49,16 +48,14 @@ def test_create_symlink(monkeypatch: pytest.MonkeyPatch, tmp_path: Path):
4948
# intentionally overwrite symlink
5049
assert create_sym_link(tool_name, version, str(tmp_path), True)
5150

52-
# test safegaurd that doesn't overwrite a file that isn't a symlink
51+
# test safeguard that doesn't overwrite a file that isn't a symlink
5352
os.remove(str(tmp_path / f"{tool_name}{suffix}"))
5453
Path(tmp_path / f"{tool_name}{suffix}").write_bytes(b"som data")
5554
assert not create_sym_link(tool_name, version, str(tmp_path), True)
5655

5756

58-
@pytest.mark.parametrize("version", [(12, 0, 0)])
59-
def test_install_tools(
60-
monkeypatch: pytest.MonkeyPatch, tmp_path: Path, version: VERSION_TUPLE
61-
):
57+
@pytest.mark.parametrize("version", [12])
58+
def test_install_tools(monkeypatch: pytest.MonkeyPatch, tmp_path: Path, version: int):
6259
"""Test install tools to a temp directory."""
6360
monkeypatch.chdir(tmp_path)
6461
tool_name = "clang-format"
@@ -67,14 +64,14 @@ def test_install_tools(
6764
# invoking again should return False
6865
assert not install_tool(tool_name, version, str(tmp_path), False)
6966
# uninstall the tool deliberately
70-
uninstall_clang_tools(".".join([str(x) for x in version]), str(tmp_path))
67+
uninstall_clang_tools(f"{version}.0.0", str(tmp_path))
7168
assert f"{tool_name}-{version}{suffix}" not in [
7269
fd.name for fd in tmp_path.iterdir()
7370
]
7471

7572

76-
@pytest.mark.parametrize("version", [(0, 0, 0)])
77-
def test_is_installed(version: VERSION_TUPLE):
73+
@pytest.mark.parametrize("version", [0])
74+
def test_is_installed(version: int):
7875
"""Test if installed version matches specified ``version``"""
7976
tool_path = is_installed("clang-format", version=version)
8077
assert tool_path is None
@@ -87,7 +84,7 @@ def test_path_warning(capsys: pytest.CaptureFixture):
8784
2. indicates a failure to download a tool
8885
"""
8986
try:
90-
install_clang_tools((0, 0, 0), "x", ".", False, False)
87+
install_clang_tools(0, "x", ".", False, False)
9188
except OSError as exc:
9289
if install_dir_name(".") not in os.environ.get("PATH", ""): # pragma: no cover
9390
# this warning does not happen in an activated venv

tests/test_util.py

Lines changed: 2 additions & 2 deletions
Original file line numberDiff line numberDiff line change
@@ -25,7 +25,7 @@ def test_check_install_os():
2525
def test_download_file(monkeypatch: pytest.MonkeyPatch, tmp_path: Path, tag: str):
2626
"""Test that deliberately fails to download a file."""
2727
monkeypatch.chdir(str(tmp_path))
28-
url = clang_tools_binary_url("clang-format", (12, 0, 0), tag=tag)
28+
url = clang_tools_binary_url("clang-format", 12, tag=tag)
2929
file_name = download_file(url, "file.tar.gz", True)
3030
assert file_name is not None
3131

@@ -37,7 +37,7 @@ def test_get_sha(monkeypatch: pytest.MonkeyPatch):
3737
expected = Path(f"clang-format-12_{install_os}-amd64.sha512sum").read_text(
3838
encoding="utf-8"
3939
)
40-
url = clang_tools_binary_url("clang-format", (12, 0, 0), tag=release_tag)
40+
url = clang_tools_binary_url("clang-format", 12, tag=release_tag)
4141
assert get_sha_checksum(url) == expected
4242

4343

0 commit comments

Comments
 (0)