Skip to content

Commit

Permalink
[cli] Allow to specify output file name for parse command
Browse files Browse the repository at this point in the history
  • Loading branch information
csordasmarton committed Aug 9, 2021
1 parent 0d100ab commit 8e815cd
Show file tree
Hide file tree
Showing 4 changed files with 62 additions and 17 deletions.
50 changes: 37 additions & 13 deletions analyzer/codechecker_analyzer/cmd/parse.py
Original file line number Diff line number Diff line change
Expand Up @@ -466,7 +466,9 @@ def add_arguments_to_parser(parser):
output_opts.add_argument('-o', '--output',
dest="output_path",
default=argparse.SUPPRESS,
help="Store the output in the given folder.")
help="Store the output in the given file/folder. "
"Note: baseline files must have extension "
"'.baseline'.")

parser.add_argument('--suppress',
type=str,
Expand Down Expand Up @@ -662,7 +664,7 @@ def _generate_json_output(
severity_map: Dict,
input_dirs: List[str],
output_type: str,
output_path: Optional[str],
output_file_path: Optional[str],
trim_path_prefixes: Optional[List[str]],
skip_handler: Callable[[str], bool]
) -> int:
Expand All @@ -682,7 +684,7 @@ def _generate_json_output(
result of analyzing.
output_type : str
Specifies the type of output. It can be gerrit, json, codeclimate.
output_path : Optional[str]
output_file_path : Optional[str]
Path of the output file. If it contains file name then generated output
will be written into.
trim_path_prefixes : Optional[List[str]]
Expand All @@ -699,8 +701,7 @@ def _generate_json_output(
skip_handler)
output_text = json.dumps(reports)

if output_path:
output_file_path = os.path.join(output_path, 'reports.json')
if output_file_path:
with open(output_file_path, mode='w', encoding='utf-8',
errors="ignore") as output_f:
output_f.write(output_text)
Expand Down Expand Up @@ -791,26 +792,49 @@ def main(args):
trim_path_prefixes = args.trim_path_prefix if \
'trim_path_prefix' in args else None

output_path = None
output_dir_path = None
output_file_path = None
if 'output_path' in args:
output_path = os.path.abspath(args.output_path)

if not os.path.exists(output_path):
os.makedirs(output_path)
# It is a file path if it is an existing file or it has an extension.
if os.path.isfile(output_path) or (
not os.path.exists(output_path)
and os.path.splitext(output_path)[1]
):
output_file_path = output_path
output_dir_path = os.path.dirname(output_file_path)
else:
output_dir_path = output_path

if not os.path.exists(output_dir_path):
os.makedirs(output_dir_path)

def get_output_file_path(default_file_name) -> Optional[str]:
""" Return an output file path. """
if output_file_path:
return output_file_path

if not output_dir_path:
return

return os.path.join(output_dir_path, default_file_name)

if export:
if export == 'baseline':
report_hashes, number_of_reports = _parse_convert_reports(
args.input, export, context.severity_map, trim_path_prefixes,
skip_handler)

output_path = get_output_file_path("reports.baseline")
if output_path:
baseline.write(output_path, report_hashes)

sys.exit(2 if number_of_reports else 0)

# The HTML part will be handled separately below.
if export != 'html':
output_path = get_output_file_path("reports.json")
sys.exit(_generate_json_output(
context.severity_map, args.input, export, output_path,
trim_path_prefixes, skip_handler))
Expand Down Expand Up @@ -879,7 +903,7 @@ def skip_html_report_data_handler(report_hash, source_file, report_line,

LOG.info("Generating html output files:")
PlistToHtml.parse(input_path,
output_path,
output_dir_path,
context.path_plist_to_html_dist,
skip_html_report_data_handler,
html_builder,
Expand Down Expand Up @@ -942,14 +966,14 @@ def skip_html_report_data_handler(report_hash, source_file, report_line,

# Create index.html and statistics.html for the generated html files.
if html_builder:
html_builder.create_index_html(output_path)
html_builder.create_statistics_html(output_path)
html_builder.create_index_html(output_dir_path)
html_builder.create_statistics_html(output_dir_path)

print('\nTo view statistics in a browser run:\n> firefox {0}'.format(
os.path.join(output_path, 'statistics.html')))
os.path.join(output_dir_path, 'statistics.html')))

print('\nTo view the results in a browser run:\n> firefox {0}'.format(
os.path.join(args.output_path, 'index.html')))
os.path.join(output_dir_path, 'index.html')))
else:
print("\n----==== Summary ====----")
if file_stats:
Expand Down
Original file line number Diff line number Diff line change
Expand Up @@ -590,3 +590,25 @@ def test_baseline_output(self):
report_hashes, {
'3d15184f38c5fa57e479b744fe3f5035',
'f8fbc46cc5afbb056d92bd3d3d702781'})

def test_custom_baseline_file(self):
""" Test parse baseline custom output file. """
output_path = self.test_workspaces['OUTPUT']
out_file_path = os.path.join(output_path, "cc_reports.baseline")

# Analyze the first project.
test_project_notes = os.path.join(
self.test_workspaces['NORMAL'], "test_files", "notes")

extract_cmd = ['CodeChecker', 'parse',
"-e", "baseline",
"-o", out_file_path,
test_project_notes]

_, _, result = call_command(
extract_cmd, cwd=self.test_dir, env=self.env)
self.assertEqual(result, 2, "Parsing not found any issue.")

report_hashes = baseline.get_report_hashes([out_file_path])
self.assertEqual(
report_hashes, {'3d15184f38c5fa57e479b744fe3f5035'})
4 changes: 1 addition & 3 deletions codechecker_common/output/baseline.py
Original file line number Diff line number Diff line change
Expand Up @@ -8,7 +8,6 @@
""" CodeChecker baseline output helpers. """

from io import TextIOWrapper
import os
from typing import List, Set

from codechecker_common import logger
Expand Down Expand Up @@ -43,12 +42,11 @@ def convert(reports: List[Report]) -> List[str]:
return sorted(set([r.report_hash for r in reports]))


def write(output_dir_path: str, report_hashes: List[str]):
def write(file_path: str, report_hashes: List[str]):
""" Create a new baseline file or extend an existing one with the given
report hashes in the given output directory. It will remove the duplicates
and also sort the report hashes before writing it to a file.
"""
file_path = os.path.join(output_dir_path, 'reports.baseline')
with open(file_path, mode='a+', encoding='utf-8', errors="ignore") as f:
f.seek(0)
old_report_hashes = __get_report_hashes(f)
Expand Down
3 changes: 2 additions & 1 deletion docs/analyzer/user_guide.md
Original file line number Diff line number Diff line change
Expand Up @@ -1655,7 +1655,8 @@ export arguments:
server. For more information see our usage guide.
(default: None)
-o OUTPUT_PATH, --output OUTPUT_PATH
Store the output in the given folder.
Store the output in the given file/folder. Note:
baseline files must have extension '.baseline'.
Environment variables
------------------------------------------------
Expand Down

0 comments on commit 8e815cd

Please sign in to comment.