4
4
5
5
The module that performs the installation of clang-tools.
6
6
"""
7
+
7
8
import os
8
9
from pathlib import Path , PurePath
9
10
import re
10
11
import shutil
11
12
import subprocess
12
13
import sys
13
- from typing import Optional
14
- from . import release_tag
14
+ from typing import Optional , cast
15
15
16
- from . import install_os , RESET_COLOR , suffix , YELLOW
17
- from .util import download_file , verify_sha512 , get_sha_checksum
16
+ from . import release_tag , install_os , RESET_COLOR , suffix , YELLOW
17
+ from .util import download_file , verify_sha512 , get_sha_checksum , Version
18
18
19
19
20
20
#: This pattern is designed to match only the major version number.
21
21
RE_PARSE_VERSION = re .compile (rb"version\s([\d\.]+)" , re .MULTILINE )
22
22
23
23
24
- def is_installed (tool_name : str , version : str ) -> Optional [Path ]:
24
+ def is_installed (tool_name : str , version : Version ) -> Optional [Path ]:
25
25
"""Detect if the specified tool is installed.
26
26
27
27
:param tool_name: The name of the specified tool.
28
- :param version: The specific version to expect.
28
+ :param version: The specific major version to expect.
29
29
30
30
:returns: The path to the detected tool (if found), otherwise `None`.
31
31
"""
32
- version_tuple = version .split ("." )
33
- ver_major = version_tuple [0 ]
34
- if len (version_tuple ) < 3 :
35
- # append minor and patch version numbers if not specified
36
- version_tuple += ("0" ,) * (3 - len (version_tuple ))
37
32
exe_name = (
38
- f"{ tool_name } " + (f"-{ ver_major } " if install_os != "windows" else "" ) + suffix
33
+ f"{ tool_name } "
34
+ + (f"-{ version .info [0 ]} " if install_os != "windows" else "" )
35
+ + suffix
39
36
)
40
37
try :
41
38
result = subprocess .run (
@@ -47,19 +44,21 @@ def is_installed(tool_name: str, version: str) -> Optional[Path]:
47
44
except (FileNotFoundError , subprocess .CalledProcessError ):
48
45
return None # tool is not installed
49
46
ver_num = RE_PARSE_VERSION .search (result .stdout )
47
+ assert ver_num is not None , "Failed to parse version from tool output"
48
+ ver_match = cast (bytes , ver_num .groups (0 )[0 ]).decode (encoding = "utf-8" )
50
49
print (
51
50
f"Found a installed version of { tool_name } :" ,
52
- ver_num . groups ( 0 )[ 0 ]. decode ( encoding = "utf-8" ) ,
51
+ ver_match ,
53
52
end = " " ,
54
53
)
55
- path = shutil .which (exe_name ) # find the installed binary
56
- if path is None :
54
+ exe_path = shutil .which (exe_name ) # find the installed binary
55
+ if exe_path is None :
57
56
print () # print end-of-line
58
57
return None # failed to locate the binary
59
- path = Path (path ).resolve ()
58
+ path = Path (exe_path ).resolve ()
60
59
print ("at" , str (path ))
61
- ver_num = ver_num . groups ( 0 )[ 0 ]. decode ( encoding = "utf-8" ) .split ("." )
62
- if ver_num is None or ver_num [0 ] != ver_major :
60
+ ver_tuple = ver_match .split ("." )
61
+ if ver_tuple is None or ver_tuple [0 ] != str ( version . info [ 0 ]) :
63
62
return None # version is unknown or not the desired major release
64
63
return path
65
64
@@ -160,7 +159,7 @@ def create_sym_link(
160
159
version : str ,
161
160
install_dir : str ,
162
161
overwrite : bool = False ,
163
- target : Path = None ,
162
+ target : Optional [ Path ] = None ,
164
163
) -> bool :
165
164
"""Create a symlink to the installed binary that
166
165
doesn't have the version number appended.
@@ -249,7 +248,7 @@ def uninstall_clang_tools(version: str, directory: str):
249
248
250
249
251
250
def install_clang_tools (
252
- version : str , tools : str , directory : str , overwrite : bool , no_progress_bar : bool
251
+ version : Version , tools : str , directory : str , overwrite : bool , no_progress_bar : bool
253
252
) -> None :
254
253
"""Wraps functions used to individually install tools.
255
254
@@ -261,7 +260,7 @@ def install_clang_tools(
261
260
:param no_progress_bar: A flag used to disable the downloads' progress bar.
262
261
"""
263
262
install_dir = install_dir_name (directory )
264
- if install_dir .rstrip (os .sep ) not in os .environ .get ("PATH" ):
263
+ if install_dir .rstrip (os .sep ) not in os .environ .get ("PATH" , "" ):
265
264
print (
266
265
f"{ YELLOW } { install_dir } " ,
267
266
f"directory is not in your environment variable PATH.{ RESET_COLOR } " ,
@@ -270,7 +269,7 @@ def install_clang_tools(
270
269
native_bin = is_installed (tool_name , version )
271
270
if native_bin is None : # (not already installed)
272
271
# `install_tool()` guarantees that the binary exists now
273
- install_tool (tool_name , version , install_dir , no_progress_bar )
272
+ install_tool (tool_name , version . string , install_dir , no_progress_bar )
274
273
create_sym_link ( # pragma: no cover
275
- tool_name , version , install_dir , overwrite , native_bin
274
+ tool_name , version . string , install_dir , overwrite , native_bin
276
275
)
0 commit comments