Skip to content

Commit a0ebbb3

Browse files
shenxianpeng2bndy5
andauthored
Fix force overwriting symlink issue (#20) (#22)
* Fix force overwriting issue (#20) * Fix failed test * Updated after review * Use `-f` to update symlink if the tool already exists also make an assertion that the symlinked target exists before creating one * Remove dead code and complete a docstr. * Improve coverage and remove unused import * Simplify logic Co-authored-by: Brendan <2bndy5@gmail.com>
1 parent 4b62769 commit a0ebbb3

File tree

3 files changed

+18
-35
lines changed

3 files changed

+18
-35
lines changed

.gitignore

Lines changed: 1 addition & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -11,3 +11,4 @@ tests/pytestdebug.log
1111
tests/__pycache__/
1212
.eggs
1313
.mypy_cache/
14+
*env

clang_tools/install.py

Lines changed: 14 additions & 26 deletions
Original file line numberDiff line numberDiff line change
@@ -6,7 +6,6 @@
66
"""
77
import os
88
import shutil
9-
import subprocess
109
import sys
1110
from pathlib import Path
1211
from pathlib import PurePath
@@ -17,26 +16,6 @@
1716
from . import YELLOW
1817
from .util import download_file
1918

20-
# pylint: disable=fixme
21-
22-
23-
def is_installed(tool_name: str, version: str) -> bool:
24-
"""An abstract functions to check if a specified clang tool is installed.
25-
26-
:param tool_name: The name of the tool.
27-
:param version: The version of the tool to look for. If provided a blank string,
28-
then only the ``tool_name`` is executed during the check.
29-
:returns: A `bool` describing if the tool was installed and executed properly.
30-
"""
31-
command = [tool_name, "--version"]
32-
if version:
33-
command[0] += f"-{version}"
34-
try:
35-
result = subprocess.run(command, capture_output=True, check=True)
36-
return result.returncode == 0
37-
except FileNotFoundError:
38-
return False
39-
4019

4120
def clang_tools_binary_url(
4221
tool: str, version: str, release_tag: str = "master-208096c1"
@@ -58,9 +37,16 @@ def clang_tools_binary_url(
5837

5938

6039
def install_tool(tool_name: str, version: str, directory: str) -> bool:
61-
"""An abstract function that can install either clang-tidy or clang-format."""
62-
if is_installed(tool_name, version):
63-
# TODO should probably skip this if `directory` is not in the PATH env var.
40+
"""An abstract function that can install either clang-tidy or clang-format.
41+
42+
:param tool_name: The name of the clang-tool to install.
43+
:param version: The version of the tools to install.
44+
:param directory: The installation directory.
45+
46+
:returns: `True` if the binary had to be downloaded and installed.
47+
`False` if the binary was not downloaded but is installed in ``directory``.
48+
"""
49+
if Path(directory, f"{tool_name}-{version}{suffix}").exists():
6450
print(f"{tool_name}-{version}", "already installed")
6551
return False
6652
bin_url = clang_tools_binary_url(tool_name, version)
@@ -142,6 +128,7 @@ def create_sym_link(
142128
return False
143129
os.remove(str(link))
144130
print("overwriting symbolic link", str(link))
131+
assert target.exists()
145132
link.symlink_to(target)
146133
print("symbolic link created", str(link))
147134
return True
@@ -162,5 +149,6 @@ def install_clang_tools(version: str, directory: str, overwrite: bool) -> None:
162149
f"directory is not in your environment variable PATH.{RESET_COLOR}",
163150
)
164151
for tool_name in ("clang-format", "clang-tidy"):
165-
if install_tool(tool_name, version, install_dir):
166-
create_sym_link(tool_name, version, install_dir, overwrite)
152+
install_tool(tool_name, version, install_dir)
153+
# `install_tool()` guarantees that the binary exists now
154+
create_sym_link(tool_name, version, install_dir, overwrite)

tests/test_install.py

Lines changed: 3 additions & 9 deletions
Original file line numberDiff line numberDiff line change
@@ -4,21 +4,13 @@
44
import pytest
55
from clang_tools import install_os, suffix
66
from clang_tools.install import (
7-
is_installed,
87
clang_tools_binary_url,
98
install_dir_name,
109
create_sym_link,
1110
install_tool,
1211
)
1312

1413

15-
@pytest.mark.parametrize("version", ["", pytest.param("1", marks=pytest.mark.xfail)])
16-
@pytest.mark.parametrize("tool_name", ["clang-format", "clang-tidy"])
17-
def test_clang_tools_exist(tool_name: str, version: str):
18-
"""Test `is_installed()`"""
19-
assert is_installed(tool_name, version)
20-
21-
2214
@pytest.mark.parametrize("version", [str(v) for v in range(7, 14)] + ["12.0.1"])
2315
@pytest.mark.parametrize("tool_name", ["clang-format", "clang-tidy"])
2416
def test_clang_tools_binary_url(tool_name: str, version: str):
@@ -61,4 +53,6 @@ def test_install_tools(monkeypatch: pytest.MonkeyPatch, tmp_path: Path, version:
6153
"""Test install tools to a temp directory."""
6254
monkeypatch.chdir(tmp_path)
6355
for tool_name in ("clang-format", "clang-tidy"):
64-
install_tool(tool_name, version, str(tmp_path))
56+
assert install_tool(tool_name, version, str(tmp_path))
57+
# invoking again should return False
58+
assert not install_tool(tool_name, version, str(tmp_path))

0 commit comments

Comments
 (0)