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
« prev ^ index » next coverage.py v7.8.0, created at 2025-04-04 07:16 +0000
1import subprocess
2import shutil
4from ..config import ClangFormatOptions
5from ..exceptions import SfgException
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.
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
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.
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
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}"]
37 if sort_includes is not None:
38 args += ["--sort-includes", sort_includes]
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
49 result = subprocess.run(args, input=code, capture_output=True, text=True)
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
57 return result.stdout