Coverage for src/pystencilssfg/emission/clang_format.py: 70%

23 statements  

« prev     ^ index     » next       coverage.py v7.8.0, created at 2025-04-04 07:16 +0000

1import subprocess 

2import shutil 

3 

4from ..config import ClangFormatOptions 

5from ..exceptions import SfgException 

6 

7 

8def invoke_clang_format( 

9 code: str, options: ClangFormatOptions, sort_includes: str | None = None 

10) -> str: 

11 """Call the `clang-format` command-line tool to format the given code string 

12 according to the given style arguments. 

13 

14 Args: 

15 code: Code string to format 

16 options: Options controlling the clang-format invocation 

17 sort_includes: Option to be passed on to clang-format's ``--sort-includes`` argument 

18 

19 Returns: 

20 The formatted code, if `clang-format` was run sucessfully. 

21 Otherwise, the original unformatted code, unless `codestyle.force_clang_format` 

22 was set to true. In the latter case, an exception is thrown. 

23 

24 Forced Formatting: 

25 If `codestyle.force_clang_format` was set to true but the formatter could not 

26 be executed (binary not found, or error during exection), the function will 

27 throw an exception. 

28 """ 

29 if options.get_option("skip"): 

30 return code 

31 

32 binary = options.get_option("binary") 

33 force = options.get_option("force") 

34 style = options.get_option("code_style") 

35 args = [binary, f"--style={style}"] 

36 

37 if sort_includes is not None: 

38 args += ["--sort-includes", sort_includes] 

39 

40 if not shutil.which(binary): 

41 if force: 

42 raise SfgException( 

43 "`force_clang_format` was set to true in code style, " 

44 "but clang-format binary could not be found." 

45 ) 

46 else: 

47 return code 

48 

49 result = subprocess.run(args, input=code, capture_output=True, text=True) 

50 

51 if result.returncode != 0: 

52 if force: 

53 raise SfgException(f"Call to clang-format failed: \n{result.stderr}") 

54 else: 

55 return code 

56 

57 return result.stdout