44
55The module that performs the installation of clang-tools.
66"""
7+
78import os
89from pathlib import Path , PurePath
910import re
1011import shutil
1112import subprocess
1213import sys
13- from typing import Optional
14- from . import release_tag
14+ from typing import Optional , cast
1515
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
1818
1919
2020#: This pattern is designed to match only the major version number.
2121RE_PARSE_VERSION = re .compile (rb"version\s([\d\.]+)" , re .MULTILINE )
2222
2323
24- def is_installed (tool_name : str , version : str ) -> Optional [Path ]:
24+ def is_installed (tool_name : str , version : Version ) -> Optional [Path ]:
2525 """Detect if the specified tool is installed.
2626
2727 :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.
2929
3030 :returns: The path to the detected tool (if found), otherwise `None`.
3131 """
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 ))
3732 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
3936 )
4037 try :
4138 result = subprocess .run (
@@ -47,19 +44,21 @@ def is_installed(tool_name: str, version: str) -> Optional[Path]:
4744 except (FileNotFoundError , subprocess .CalledProcessError ):
4845 return None # tool is not installed
4946 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" )
5049 print (
5150 f"Found a installed version of { tool_name } :" ,
52- ver_num . groups ( 0 )[ 0 ]. decode ( encoding = "utf-8" ) ,
51+ ver_match ,
5352 end = " " ,
5453 )
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 :
5756 print () # print end-of-line
5857 return None # failed to locate the binary
59- path = Path (path ).resolve ()
58+ path = Path (exe_path ).resolve ()
6059 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 ]) :
6362 return None # version is unknown or not the desired major release
6463 return path
6564
@@ -160,7 +159,7 @@ def create_sym_link(
160159 version : str ,
161160 install_dir : str ,
162161 overwrite : bool = False ,
163- target : Path = None ,
162+ target : Optional [ Path ] = None ,
164163) -> bool :
165164 """Create a symlink to the installed binary that
166165 doesn't have the version number appended.
@@ -249,7 +248,7 @@ def uninstall_clang_tools(version: str, directory: str):
249248
250249
251250def 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
253252) -> None :
254253 """Wraps functions used to individually install tools.
255254
@@ -261,7 +260,7 @@ def install_clang_tools(
261260 :param no_progress_bar: A flag used to disable the downloads' progress bar.
262261 """
263262 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" , "" ):
265264 print (
266265 f"{ YELLOW } { install_dir } " ,
267266 f"directory is not in your environment variable PATH.{ RESET_COLOR } " ,
@@ -270,7 +269,7 @@ def install_clang_tools(
270269 native_bin = is_installed (tool_name , version )
271270 if native_bin is None : # (not already installed)
272271 # `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 )
274273 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
276275 )
0 commit comments