44import shlex
55import subprocess
66from typing import TYPE_CHECKING , Optional
7-
87import isort
98
109from codeflash .cli_cmds .console import console , logger
1110
1211if TYPE_CHECKING :
1312 from pathlib import Path
1413
15- def get_diff_lines_output_by_black (filepath : str ) -> Optional [str ]:
14+ def get_nth_line (text : str , n : int ) -> str | None :
15+ for i , line in enumerate (text .splitlines (), start = 1 ):
16+ if i == n :
17+ return line
18+ return None
19+
20+ def get_diff_output (cmd : list [str ]) -> Optional [str ]:
1621 try :
17- subprocess .run (['black' , '--version' ], check = True ,
18- stdout = subprocess .DEVNULL , stderr = subprocess .DEVNULL )
19- result = subprocess .run (
20- ['black' , '--diff' , filepath ],
21- capture_output = True ,
22- text = True
23- )
24- return result .stdout .strip () if result .stdout else None
25- except (FileNotFoundError ):
22+ result = subprocess .run (cmd , capture_output = True , text = True , check = True )
23+ return result .stdout .strip () or None
24+ except (FileNotFoundError , subprocess .CalledProcessError ) as e :
25+ if isinstance (e , subprocess .CalledProcessError ):
26+ # ruff returns 1 when the file needs formatting, and 0 when it is already formatted
27+ is_ruff = cmd [0 ] == "ruff"
28+ if e .returncode == 0 and is_ruff :
29+ return ""
30+ elif e .returncode == 1 and is_ruff :
31+ return e .stdout .strip () or None
2632 return None
2733
2834
35+ def get_diff_lines_output_by_black (filepath : str ) -> Optional [str ]:
36+ try :
37+ import black # type: ignore
38+ return get_diff_output (['black' , '--diff' , filepath ])
39+ except ImportError :
40+ return None
41+
2942def get_diff_lines_output_by_ruff (filepath : str ) -> Optional [str ]:
3043 try :
31- subprocess .run (['ruff' , '--version' ], check = True ,
32- stdout = subprocess .DEVNULL , stderr = subprocess .DEVNULL )
33- result = subprocess .run (
34- ['ruff' , "format" , '--diff' , filepath ],
35- capture_output = True ,
36- text = True
37- )
38- return result .stdout .strip () if result .stdout else None
39- except (FileNotFoundError ):
44+ import ruff # type: ignore
45+ return get_diff_output (['ruff' , 'format' , '--diff' , filepath ])
46+ except ImportError :
47+ print ("can't import ruff" )
4048 return None
4149
4250
4351def get_diff_lines_count (diff_output : str ) -> int :
44- diff_lines = [line for line in diff_output .split ('\n ' )
45- if line .startswith (('+' , '-' )) and not line .startswith (('+++' , '---' ))]
52+ lines = diff_output .split ('\n ' )
53+ def is_diff_line (line : str ) -> bool :
54+ return line .startswith (('+' , '-' )) and not line .startswith (('+++' , '---' ))
55+ diff_lines = [line for line in lines if is_diff_line (line )]
4656 return len (diff_lines )
4757
4858def is_safe_to_format (filepath : str , max_diff_lines : int = 100 ) -> bool :
@@ -54,9 +64,8 @@ def is_safe_to_format(filepath: str, max_diff_lines: int = 100) -> bool:
5464 logger .warning (f"black formatter not found, trying ruff instead..." )
5565 diff_changes_stdout = get_diff_lines_output_by_ruff (filepath )
5666 if diff_changes_stdout is None :
57- msg = f"Both ruff, black formatters not found, skipping formatting diff check."
58- logger .warning (msg )
59- raise FileNotFoundError (msg )
67+ logger .warning (f"Both ruff, black formatters not found, skipping formatting diff check." )
68+ return False
6069
6170 diff_lines_count = get_diff_lines_count (diff_changes_stdout )
6271
@@ -73,7 +82,7 @@ def format_code(formatter_cmds: list[str], path: Path, print_status: bool = True
7382 if not path .exists ():
7483 msg = f"File { path } does not exist. Cannot format the file."
7584 raise FileNotFoundError (msg )
76- if formatter_name == "disabled" or not is_safe_to_format (path ): # few -> False, large -> True
85+ if formatter_name == "disabled" or not is_safe_to_format (str ( path )):
7786 return path .read_text (encoding = "utf8" )
7887
7988 file_token = "$file" # noqa: S105
0 commit comments