diff --git a/src/codacy/reporter.py b/src/codacy/reporter.py index d7bf64d..1beff32 100755 --- a/src/codacy/reporter.py +++ b/src/codacy/reporter.py @@ -76,6 +76,30 @@ def strip_prefix(line, prefix): return filename +def merge_reports(report_list): + """Merges together several report structures from parse_report_file""" + final_report = { + 'language': "python", + 'fileReports': [] + } + + for report in report_list: + # First, merge together detailed report structures + # This assumes no overlap + # TODO: What should we do if there is a file listed multiple times? + final_report['fileReports'] += report['fileReports'] + + # Gather all per-file coverage + total_coverages = [] + for fileentry in final_report['fileReports']: + total_coverages += [fileentry['total']] + + # And average + final_report['total'] = sum(total_coverages)/len(total_coverages) + + return final_report + + def parse_report_file(report_file, git_directory): """Parse XML file and POST it to the Codacy API :param report_file: @@ -140,7 +164,9 @@ def upload_report(report, token, commit): def run(): parser = argparse.ArgumentParser(description='Codacy coverage reporter for Python.') - parser.add_argument("-r", "--report", type=str, help="coverage report file", default=DEFAULT_REPORT_FILE) + parser.add_argument("-r", "--report", help="coverage report file", + default=[DEFAULT_REPORT_FILE], type=str, + action='append') parser.add_argument("-c", "--commit", type=str, help="git commit hash") parser.add_argument("-d", "--directory", type=str, help="git top level directory") parser.add_argument("-v", "--verbose", help="show debug information", action="store_true") @@ -157,12 +183,18 @@ def run(): if not args.commit: args.commit = get_git_revision_hash() - if not os.path.isfile(args.report): - logging.error("Coverage report " + args.report + " not found.") - exit(1) + # Explictly check ALL files before parsing any + for rfile in args.report: + if not os.path.isfile(rfile): + logging.error("Coverage report " + args.report + " not found.") + exit(1) + + reports = [] + for rfile in args.report: + logging.info("Parsing report file %s...", rfile) + reports.append(parse_report_file(rfile, args.directory)) - logging.info("Parsing report file...") - report = parse_report_file(args.report, args.directory) + report = merge_reports(reports) logging.info("Uploading report...") upload_report(report, CODACY_PROJECT_TOKEN, args.commit) diff --git a/tests/coverage-merge/cobertura.3.xml b/tests/coverage-merge/cobertura.3.xml new file mode 100644 index 0000000..015adc2 --- /dev/null +++ b/tests/coverage-merge/cobertura.3.xml @@ -0,0 +1,31 @@ + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + diff --git a/tests/coverage-merge/cobertura.4.xml b/tests/coverage-merge/cobertura.4.xml new file mode 100644 index 0000000..0e71e5d --- /dev/null +++ b/tests/coverage-merge/cobertura.4.xml @@ -0,0 +1,86 @@ + + + + + + /Users/rafaelcortes/Documents/qamine/python-codacycov + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + diff --git a/tests/coverage-merge/coverage-merge.json b/tests/coverage-merge/coverage-merge.json new file mode 100644 index 0000000..633f759 --- /dev/null +++ b/tests/coverage-merge/coverage-merge.json @@ -0,0 +1,75 @@ +{ + "total": 75, + "fileReports": [ + { + "total": 87, + "coverage": { + "5": 1, + "4": 1, + "6": 2 + }, + "filename": "src/test/resources/TestSourceFile.scala" + }, + { + "total": 87, + "coverage": { + "9": 1, + "10": 1 + }, + "filename": "src/test/resources/TestSourceFile.scala" + }, + { + "total": 87, + "coverage": { + "1": 1, + "3": 1, + "2": 1 + }, + "filename": "src/test/resources/TestSourceFile2.scala" + }, + { + "total": 66, + "coverage": { + "1": 1, + "4": 1 + }, + "filename": "src/codacy/__init__.py" + }, + { + "total": 49, + "coverage": { + "50": 1, + "60": 1, + "80": 1, + "52": 1, + "26": 1, + "20": 1, + "49": 1, + "44": 1, + "42": 1, + "43": 1, + "3": 1, + "5": 1, + "4": 1, + "7": 1, + "6": 1, + "9": 1, + "11": 1, + "15": 1, + "14": 1, + "17": 1, + "16": 1, + "55": 1, + "54": 1, + "31": 1, + "30": 1, + "51": 1, + "36": 1, + "34": 1, + "57": 1 + }, + "filename": "src/codacy/reporter.py" + } + ], + "language": "python" +} diff --git a/tests/tests.py b/tests/tests.py index 86eca4a..ba813b8 100644 --- a/tests/tests.py +++ b/tests/tests.py @@ -15,13 +15,11 @@ def _file_location(*args): class ReporterTests(unittest.TestCase): - def compare_parse_result(self, generated_filename, expected_filename): + def compare_parse_result(self, generated, expected_filename): def file_get_contents(filename): with open(filename) as f: return f.read() - generated = codacy.reporter.parse_report_file(generated_filename, '') - json_content = file_get_contents(expected_filename) expected = json.loads(json_content) @@ -30,21 +28,42 @@ def file_get_contents(filename): def test_parser_coverage3(self): self.maxDiff = None - self.compare_parse_result(_file_location('coverage3', 'cobertura.xml'), + generated = codacy.reporter.parse_report_file( + _file_location('coverage3', 'cobertura.xml'), '') + self.compare_parse_result(generated, _file_location('coverage3', 'coverage.json')) def test_parser_coverage4(self): self.maxDiff = None - self.compare_parse_result(_file_location('coverage4', 'cobertura.xml'), + generated = codacy.reporter.parse_report_file( + _file_location('coverage4', 'cobertura.xml'), '') + self.compare_parse_result(generated, _file_location('coverage4', 'coverage.json')) def test_parser_git_filepath(self): self.maxDiff = None - self.compare_parse_result(_file_location('filepath', 'cobertura.xml.tpl'), + generated = codacy.reporter.parse_report_file( + _file_location('filepath', 'cobertura.xml.tpl'), '') + + self.compare_parse_result(generated, _file_location('filepath', 'coverage.json')) + def test_merge(self): + self.maxDiff = None + + generated3 = codacy.reporter.parse_report_file( + _file_location('coverage-merge', 'cobertura.3.xml'), '') + generated4 = codacy.reporter.parse_report_file( + _file_location('coverage-merge', 'cobertura.4.xml'), '') + + result = codacy.reporter.merge_reports([generated3, generated4]) + + self.compare_parse_result(result, _file_location('coverage-merge', 'coverage-merge.json')) + + + if __name__ == '__main__': unittest.main()