Skip to content

Commit 73d81fc

Browse files
furtibSzelethus
andauthored
Add support for config files in per_file rule (#113)
Why: We want to support config files inside the `per_file` rule, too. What: Added the config rule to the `per_file` rule, based on the codechecker_test rule. Addresses: #30 --------- Co-authored-by: Kristóf Umann <[email protected]>
1 parent 5962898 commit 73d81fc

File tree

4 files changed

+38
-26
lines changed

4 files changed

+38
-26
lines changed

src/per_file.bzl

Lines changed: 23 additions & 4 deletions
Original file line numberDiff line numberDiff line change
@@ -20,13 +20,19 @@ for each translation unit.
2020
load("@bazel_tools//tools/build_defs/cc:action_names.bzl", "ACTION_NAMES")
2121
load("@bazel_tools//tools/cpp:toolchain_utils.bzl", "find_cpp_toolchain")
2222
load("@codechecker_bazel//src:tools.bzl", "warning", "source_attr")
23+
load(
24+
"@codechecker_bazel//src:codechecker_config.bzl",
25+
"get_config_file"
26+
)
2327

2428
def _run_code_checker(
2529
ctx,
2630
src,
2731
arguments,
2832
label,
2933
options,
34+
config_file,
35+
env_vars,
3036
compile_commands_json,
3137
compilation_context,
3238
sources_and_headers):
@@ -43,11 +49,11 @@ def _run_code_checker(
4349
codechecker_log = ctx.actions.declare_file(codechecker_log_file_name)
4450

4551
if "--ctu" in options:
46-
inputs = [compile_commands_json] + sources_and_headers
52+
inputs = [compile_commands_json, config_file] + sources_and_headers
4753
else:
4854
# NOTE: we collect only headers, so CTU may not work!
4955
headers = depset([src], transitive = [compilation_context.headers])
50-
inputs = depset([compile_commands_json, src], transitive = [headers])
56+
inputs = depset([compile_commands_json, config_file, src], transitive = [headers])
5157

5258
outputs = [clang_tidy_plist, clangsa_plist, codechecker_log]
5359

@@ -277,7 +283,7 @@ def _collect_all_sources_and_headers(ctx):
277283
sources_and_headers = all_files + headers.to_list()
278284
return sources_and_headers
279285

280-
def _create_wrapper_script(ctx, options, compile_commands_json):
286+
def _create_wrapper_script(ctx, options, compile_commands_json, config_file):
281287
options_str = ""
282288
for item in options:
283289
options_str += item + " "
@@ -289,6 +295,7 @@ def _create_wrapper_script(ctx, options, compile_commands_json):
289295
"{PythonPath}": ctx.attr._python_runtime[PyRuntimeInfo].interpreter_path,
290296
"{compile_commands_json}": compile_commands_json.path,
291297
"{codechecker_args}": options_str,
298+
"{config_file}": config_file.path,
292299
},
293300
)
294301

@@ -297,7 +304,8 @@ def _per_file_impl(ctx):
297304
sources_and_headers = _collect_all_sources_and_headers(ctx)
298305
options = ctx.attr.default_options + ctx.attr.options
299306
all_files = [compile_commands_json]
300-
_create_wrapper_script(ctx, options, compile_commands_json)
307+
config_file, env_vars = get_config_file(ctx)
308+
_create_wrapper_script(ctx, options, compile_commands_json, config_file)
301309
for target in ctx.attr.targets:
302310
if not CcInfo in target:
303311
continue
@@ -314,6 +322,8 @@ def _per_file_impl(ctx):
314322
args,
315323
ctx.attr.name,
316324
options,
325+
config_file,
326+
env_vars,
317327
compile_commands_json,
318328
compilation_context,
319329
sources_and_headers,
@@ -363,13 +373,18 @@ per_file_test = rule(
363373
],
364374
doc = "List of compilable targets which should be checked.",
365375
),
376+
"config": attr.label(
377+
default = None,
378+
doc = "CodeChecker configuration",
379+
),
366380
"_per_file_script_template": attr.label(
367381
default = ":per_file_script.py",
368382
allow_single_file = True,
369383
),
370384
"_python_runtime": attr.label(
371385
default = "@default_python_tools//:py3_runtime",
372386
),
387+
373388
},
374389
outputs = {
375390
"test_script": "%{name}/test_script.sh",
@@ -382,12 +397,16 @@ per_file_test = rule(
382397
def code_checker_test(
383398
name,
384399
targets,
400+
config = None,
385401
options = [],
386402
tags = [],
403+
**kwargs
387404
):
388405
per_file_test(
389406
name = name,
390407
options = options,
391408
targets = targets,
409+
config = config,
392410
tags = tags,
411+
**kwargs
393412
)

src/per_file_script.py

Lines changed: 9 additions & 10 deletions
Original file line numberDiff line numberDiff line change
@@ -32,6 +32,7 @@
3232
COMPILE_COMMANDS_JSON: str = "{compile_commands_json}"
3333
COMPILE_COMMANDS_ABSOLUTE: str = f"{COMPILE_COMMANDS_JSON}.abs"
3434
CODECHECKER_ARGS: str = "{codechecker_args}"
35+
CONFIG_FILE: str = "{config_file}"
3536

3637

3738
def parse_args():
@@ -82,10 +83,15 @@ def _run_codechecker() -> None:
8283
"""
8384
Runs CodeChecker analyze
8485
"""
85-
log(
86-
f"CodeChecker command: CodeChecker analyze {CODECHECKER_ARGS} \
87-
{COMPILE_COMMANDS_ABSOLUTE} --output={DATA_DIR} --file=*/{FILE_PATH}\n"
86+
codechecker_cmd: list[str] = (
87+
["CodeChecker", "analyze"]
88+
+ CODECHECKER_ARGS.split()
89+
+ ["--output=" + DATA_DIR] # type: ignore
90+
+ ["--file=*/" + FILE_PATH] # type: ignore
91+
+ ["--config", CONFIG_FILE]
92+
+ [COMPILE_COMMANDS_ABSOLUTE]
8893
)
94+
log(f"CodeChecker command: {' '.join(codechecker_cmd)}\n")
8995
log("===-----------------------------------------------------===\n")
9096
log(" CodeChecker error log \n")
9197
log("===-----------------------------------------------------===\n")
@@ -99,13 +105,6 @@ def _run_codechecker() -> None:
99105
)
100106
log(result.stdout)
101107

102-
codechecker_cmd: list[str] = (
103-
["CodeChecker", "analyze"]
104-
+ CODECHECKER_ARGS.split()
105-
+ ["--output=" + DATA_DIR] # type: ignore
106-
+ ["--file=*/" + FILE_PATH] # type: ignore
107-
+ [COMPILE_COMMANDS_ABSOLUTE]
108-
)
109108

110109
try:
111110
with open(LOG_FILE, "a") as log_file: # type: ignore

test/unit/config/BUILD

Lines changed: 2 additions & 4 deletions
Original file line numberDiff line numberDiff line change
@@ -90,8 +90,7 @@ codechecker_test(
9090

9191
codechecker_test(
9292
name = "per_file_test_json",
93-
#config = "config_json", #TODO: uncomment
94-
# complains that per_file doesn't have a config attribute
93+
config = "config_json",
9594
targets = [
9695
"test_zero",
9796
],
@@ -101,8 +100,7 @@ codechecker_test(
101100

102101
codechecker_test(
103102
name = "per_file_test_yaml",
104-
#config = "config_yaml", #TODO: uncomment
105-
# complains that per_file doesn't have a config attribute
103+
config = "config_yaml",
106104
targets = [
107105
"test_zero",
108106
],

test/unit/config/test_config.py

Lines changed: 4 additions & 8 deletions
Original file line numberDiff line numberDiff line change
@@ -95,31 +95,27 @@ def test_per_file_test_json(self):
9595
"bazel test //test/unit/config:per_file_test_json"
9696
)
9797
# Should not find the division by zero bug
98-
self.assertEqual(ret, 3) # TODO: Change to 0
99-
# since CodeChecker won't find the division by zero bug
98+
self.assertEqual(ret, 0)
10099
copied_config = os.path.join(
101100
self.BAZEL_BIN_DIR, # type: ignore
102101
"per_file_test_json",
103102
"config.json"
104103
)
105-
self.assertFalse(os.path.exists(copied_config)) # TODO: Set to True
106-
# Before the patch config files aren't supported in per_file
104+
self.assertTrue(os.path.exists(copied_config))
107105

108106
def test_per_file_test_yaml(self):
109107
"""Test: bazel test //test/unit/config:per_file_test_yaml"""
110108
ret, _, _ = self.run_command(
111109
"bazel test //test/unit/config:per_file_test_yaml"
112110
)
113111
# Should not find the division by zero bug
114-
self.assertEqual(ret, 3) # TODO: Change to 0
115-
# since CodeChecker won't find the division by zero bug
112+
self.assertEqual(ret, 0)
116113
copied_config = os.path.join(
117114
self.BAZEL_BIN_DIR, # type: ignore
118115
"per_file_test_yaml",
119116
"config.yaml"
120117
)
121-
self.assertFalse(os.path.exists(copied_config)) # TODO: Set to True
122-
# Before the patch config files aren't supported in per_file
118+
self.assertTrue(os.path.exists(copied_config))
123119

124120

125121
if __name__ == "__main__":

0 commit comments

Comments
 (0)