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()