1- # fuzz/ command_util.py
1+ # command_util.py
22
33import subprocess
4- import time
54import logging
5+ import time
66from pathlib import Path
7- from typing import Optional , cast
7+ from typing import Optional , Tuple , List
88from returns .maybe import Maybe
99from errors import CommandError
1010
1111def _run_subprocess (
1212 cmd : str ,
13- cwd : Optional [Path ] = None ,
13+ cwd : Optional [Path ] = None , # 修复:添加 Optional 类型
1414 capture_output : bool = False ,
15- timeout : Optional [int ] = None ,
16- logger : Optional [logging .Logger ] = None ,
17- ) -> tuple [int , list [str ]]:
15+ timeout : Optional [int ] = None , # 修复:添加 Optional 类型
16+ logger : Optional [logging .Logger ] = None , # 修复:添加 Optional 类型
17+ ) -> Tuple [int , List [str ]]: # 建议使用 Tuple 替代 tuple
1818 """
1919 低层执行子进程命令
2020 - capture_output=True:捕获 stdout,返回输出列表
21- - timeout 秒超时(无超时则None )
21+ - timeout 秒超时(无超时则 None )
2222 - logger 用于实时打印输出
2323 返回:(退出码, 输出行列表)
2424 """
@@ -33,28 +33,29 @@ def _run_subprocess(
3333 errors = "replace" ,
3434 )
3535
36- output_lines = []
36+ output_lines : List [ str ] = []
3737 start_time = time .time ()
3838
3939 try :
4040 if capture_output :
41- # 类型断言确保 stdout 不为 None
42- stdout = cast (Optional [subprocess .PIPE ], process .stdout )
43- if stdout is None :
44- raise RuntimeError ("Stdout should not be None when capture_output is True" )
41+ # 确保 stdout 不是 None
42+ if process .stdout is None :
43+ raise RuntimeError ("stdout is unexpectedly None in capture mode" )
4544
4645 while True :
47- line = stdout .readline ()
46+ line = process . stdout .readline ()
4847 if line :
49- output_lines .append (line .rstrip ())
48+ line_stripped = line .rstrip ()
49+ output_lines .append (line_stripped )
5050 if logger :
51- logger .debug (line . rstrip () )
51+ logger .debug (line_stripped )
5252 elif process .poll () is not None :
5353 break
5454
55- if timeout is not None and (time .time () - start_time ) > timeout :
55+ # 处理超时逻辑
56+ if timeout and (time .time () - start_time ) > timeout :
5657 if logger :
57- logger .error (f"⌛ Command timed out after { timeout } seconds " )
58+ logger .error (f"⌛ 命令超时,耗时 { timeout } 秒 " )
5859 process .terminate ()
5960 try :
6061 process .wait (timeout = 5 )
@@ -68,9 +69,9 @@ def _run_subprocess(
6869
6970 except Exception as e :
7071 if logger :
71- logger .exception (f"Error during command execution: { e } " )
72+ logger .exception (f"执行命令时出错: { e } " )
7273 process .kill ()
73- raise e
74+ raise CommandError ( f"Command failed: { str ( e ) } " ) from e
7475
7576 return process .returncode , output_lines
7677
@@ -79,15 +80,15 @@ def run_command_build_fuzz(
7980 cmd : str ,
8081 oss_fuzz_dir : Path ,
8182 project : str = "" ,
82- allowed_exit_codes : Maybe [list [int ]] = Maybe .empty () ,
83+ allowed_exit_codes : Maybe [List [int ]] = Maybe .empty ,
8384 skip_yes : bool = False
8485) -> int :
8586 """build_fuzz.py 中使用的 run_command,简化版,抛异常"""
8687 allowed_codes = allowed_exit_codes .value_or ([0 ])
8788 cmd_str = f"yes | { cmd } " if not skip_yes else cmd
8889 exit_code , _ = _run_subprocess (cmd_str , cwd = oss_fuzz_dir )
8990 if exit_code not in allowed_codes :
90- error_msg = f"Command failed (exit code: { exit_code } ) "
91+ error_msg = f"命令失败(退出码: { exit_code } ) "
9192 if project :
9293 error_msg += f" for project: { project } "
9394 raise CommandError (error_msg , project = project , exit_code = exit_code )
@@ -98,16 +99,22 @@ def run_command_fuzz_all_targets(
9899 cmd : str ,
99100 log_msg : str ,
100101 logger : logging .Logger ,
101- allowed_exit_codes : Maybe [list [int ]] = Maybe .empty () ,
102+ allowed_exit_codes : Maybe [List [int ]] = Maybe .empty ,
102103 timeout : int = 3600 ,
103104) -> bool :
104- """run_fuzz_all_targets_print1.py 中使用,带实时日志与超时,返回bool """
105+ """run_fuzz_all_targets_print1.py 中使用,带实时日志与超时,返回 bool """
105106 logger .info (f"▶️ { log_msg } ..." )
106107 logger .debug (f" $ { cmd } " )
107108
108109 allowed_codes = allowed_exit_codes .value_or ([])
109- exit_code , _ = _run_subprocess (cmd , capture_output = True , timeout = timeout , logger = logger )
110+ exit_code , _ = _run_subprocess (
111+ cmd ,
112+ capture_output = True ,
113+ timeout = timeout ,
114+ logger = logger
115+ )
116+
110117 if exit_code not in [0 , * allowed_codes ]:
111- logger .error (f"❌ Command execution failed, exit code: { exit_code } " )
118+ logger .error (f"❌ 命令执行失败,退出码: { exit_code } " )
112119 return False
113120 return True
0 commit comments