Skip to content

Commit

Permalink
[cmd] Fix check command config file support
Browse files Browse the repository at this point in the history
CodeChecker check didn't recognise options from the config file specified
by the --config option. This patch will solve this problem and add some
extra test cases.
  • Loading branch information
csordasmarton committed Jul 26, 2021
1 parent 53fc3be commit d92f2d1
Show file tree
Hide file tree
Showing 3 changed files with 82 additions and 18 deletions.
18 changes: 16 additions & 2 deletions analyzer/codechecker_analyzer/cmd/check.py
Original file line number Diff line number Diff line change
Expand Up @@ -22,7 +22,7 @@
from codechecker_analyzer.analyzers import analyzer_types
from codechecker_analyzer.arg import OrderedCheckersAction

from codechecker_common import arg, logger
from codechecker_common import arg, cmd_config, logger
from codechecker_common.source_code_comment_handler import REVIEW_STATUS_VALUES

from codechecker_analyzer.cmd.analyze import \
Expand Down Expand Up @@ -706,6 +706,18 @@ def add_arguments_to_parser(parser):
"analyzers which is experimental, take "
"care when relying on it.")

output_opts.add_argument(
'--trim-path-prefix',
type=str,
nargs='*',
dest="trim_path_prefix",
required=False,
default=argparse.SUPPRESS,
help="Removes leading path from files which will be printed. So if "
"you have /a/b/c/x.cpp and /a/b/c/y.cpp then by removing "
"\"/a/b/\" prefix will print files like c/x.cpp and c/y.cpp. "
"If multiple prefix is given, the longest match will be removed.")

parser.add_argument('--review-status',
nargs='*',
dest="review_status",
Expand All @@ -717,7 +729,8 @@ def add_arguments_to_parser(parser):
', '.join(REVIEW_STATUS_VALUES)))

logger.add_verbose_arguments(parser)
parser.set_defaults(func=main)
parser.set_defaults(
func=main, func_process_config_file=cmd_config.process_config_file)


def main(args):
Expand Down Expand Up @@ -838,6 +851,7 @@ def __update_if_key_exists(source, target, key):
input_format='plist'
)
__update_if_key_exists(args, parse_args, 'print_steps')
__update_if_key_exists(args, parse_args, 'trim_path_prefix')
__update_if_key_exists(args, parse_args, 'review_status')
__update_if_key_exists(args, parse_args, 'verbose')
__update_if_key_exists(args, parse_args, 'skipfile')
Expand Down
42 changes: 40 additions & 2 deletions analyzer/tests/functional/config/test_config.py
Original file line number Diff line number Diff line change
Expand Up @@ -52,7 +52,7 @@ def setUp(self):
json.dump(build_log, outfile)

# Test file contents
simple_file_content = "int main() { return 0; }"
simple_file_content = "int main() { return 1/0; }"

# Write content to the test file
with open(self.source_file, 'w',
Expand Down Expand Up @@ -203,4 +203,42 @@ def test_parse_config(self):

out, returncode = self.__run_parse()
print(out)
self.assertEqual(returncode, 0)
self.assertEqual(returncode, 2)

def test_check_config(self):
"""
Run check command with a config file which enables the clangsa
analyzer only and parse the results with a parse command
config.
"""
with open(self.config_file, 'w+',
encoding="utf-8", errors="ignore") as config_f:
json.dump({
'analyzer': ['--analyzers', 'clangsa'],
'parse': ['--trim-path-prefix', '${HOME}']},
config_f)

check_cmd = [self._codechecker_cmd, "check",
"-l", self.build_json,
"-o", self.reports_dir,
"--config", self.config_file]

# Run analyze.
process = subprocess.Popen(
check_cmd,
stdout=subprocess.PIPE,
stderr=subprocess.PIPE,
encoding="utf-8",
errors="ignore")
out, _ = process.communicate()

print(out)
self.assertEqual(process.returncode, 2)
self.assertIn("clangsa analyzed simple.cpp", out)
self.assertNotIn("clang-tidy analyzed simple.cpp", out)

self.assertNotIn(self.source_file, out)

trimmed_file_path = self.source_file.replace(
os.path.expanduser("~") + os.path.sep, "")
self.assertIn(trimmed_file_path, out)
40 changes: 26 additions & 14 deletions codechecker_common/cmd_config.py
Original file line number Diff line number Diff line change
Expand Up @@ -7,12 +7,32 @@
# -------------------------------------------------------------------------
import os

from typing import List

from codechecker_common.util import load_json_or_empty
from codechecker_common import logger

LOG = logger.get_logger('system')


def get_analyze_options(cfg) -> List[str]:
""" Get analyze related options. """
# The config value can be 'analyze' or 'analyzer'
# for backward compatibility.
analyze_cfg = cfg.get("analyze", [])
analyzer_cfg = cfg.get("analyzer", [])
if analyze_cfg:
if analyzer_cfg:
LOG.warning("There is an 'analyze' and an 'analyzer' "
"config configuration option in the config "
"file. Please use the 'analyze' value to be "
"in sync with the subcommands.\n"
"Using the 'analyze' configuration.")
return analyze_cfg

return analyzer_cfg


def process_config_file(args, subcommand_name):
""" Handler to get config file options. """
if 'config_file' not in args:
Expand All @@ -25,20 +45,12 @@ def process_config_file(args, subcommand_name):
# configuration section name is analyzer.
options = None
if subcommand_name == 'analyze':
# The config value can be 'analyze' or 'analyzer'
# for backward compatibility.
analyze_cfg = cfg.get("analyze", [])
analyzer_cfg = cfg.get("analyzer", [])
if analyze_cfg:
if analyzer_cfg:
LOG.warning("There is an 'analyze' and an 'analyzer' "
"config configuration option in the config "
"file. Please use the 'analyze' value to be "
"in sync with the subcommands.\n"
"Using the 'analyze' configuration.")
options = analyze_cfg
elif analyzer_cfg:
options = analyzer_cfg
options = get_analyze_options(cfg)
elif subcommand_name == 'check':
options = [
*get_analyze_options(cfg),
*cfg.get("parse", [])
]
else:
options = cfg.get(subcommand_name, [])

Expand Down

0 comments on commit d92f2d1

Please sign in to comment.