create_jcoverage_report.py 3.5 KB

123456789101112131415161718192021222324252627282930313233343536373839404142434445464748495051525354555657585960616263646566676869707172737475767778798081828384858687888990919293949596979899100101102103104105106107108109110111112113114115116117118119120121122123124125126127128129130131132
  1. import argparse
  2. import tarfile
  3. import zipfile
  4. import os
  5. import sys
  6. import time
  7. import subprocess
  8. def mkdir_p(path):
  9. try:
  10. os.makedirs(path)
  11. except OSError:
  12. pass
  13. class Timer(object):
  14. def __init__(self):
  15. self.start = time.time()
  16. def step(self, msg):
  17. sys.stderr.write("{} ({}s)\n".format(msg, int(time.time() - self.start)))
  18. self.start = time.time()
  19. def main(
  20. source,
  21. output,
  22. java,
  23. prefix_filter,
  24. exclude_filter,
  25. jars_list,
  26. output_format,
  27. tar_output,
  28. agent_disposition,
  29. runners_paths,
  30. ):
  31. timer = Timer()
  32. reports_dir = 'jacoco_reports_dir'
  33. mkdir_p(reports_dir)
  34. with tarfile.open(source) as tf:
  35. tf.extractall(reports_dir)
  36. timer.step("Coverage data extracted")
  37. reports = [os.path.join(reports_dir, fname) for fname in os.listdir(reports_dir)]
  38. with open(jars_list) as f:
  39. jars = f.read().strip().split()
  40. if jars and runners_paths:
  41. for r in runners_paths:
  42. try:
  43. jars.remove(r)
  44. except ValueError:
  45. pass
  46. src_dir = 'sources_dir'
  47. cls_dir = 'classes_dir'
  48. mkdir_p(src_dir)
  49. mkdir_p(cls_dir)
  50. for jar in jars:
  51. if jar.endswith('devtools-jacoco-agent.jar'):
  52. agent_disposition = jar
  53. # Skip java contrib - it's irrelevant coverage
  54. if jar.startswith('contrib/java'):
  55. continue
  56. with zipfile.ZipFile(jar) as jf:
  57. for entry in jf.infolist():
  58. if entry.filename.endswith('.java'):
  59. dest = src_dir
  60. elif entry.filename.endswith('.class'):
  61. dest = cls_dir
  62. else:
  63. continue
  64. entry.filename = entry.filename.encode('utf-8')
  65. jf.extract(entry, dest)
  66. timer.step("Jar files extracted")
  67. if not agent_disposition:
  68. print >> sys.stderr, 'Can\'t find jacoco agent. Will not generate html report for java coverage.'
  69. if tar_output:
  70. report_dir = 'java.report.temp'
  71. else:
  72. report_dir = output
  73. mkdir_p(report_dir)
  74. if agent_disposition:
  75. agent_cmd = [
  76. java,
  77. '-jar',
  78. agent_disposition,
  79. src_dir,
  80. cls_dir,
  81. prefix_filter or '.',
  82. exclude_filter or '__no_exclude__',
  83. report_dir,
  84. output_format,
  85. ]
  86. agent_cmd += reports
  87. subprocess.check_call(agent_cmd)
  88. timer.step("Jacoco finished")
  89. if tar_output:
  90. with tarfile.open(output, 'w') as outf:
  91. outf.add(report_dir, arcname='.')
  92. if __name__ == '__main__':
  93. if 'LC_ALL' in os.environ:
  94. if os.environ['LC_ALL'] == 'C':
  95. os.environ['LC_ALL'] = 'en_GB.UTF-8'
  96. parser = argparse.ArgumentParser()
  97. parser.add_argument('--source', action='store')
  98. parser.add_argument('--output', action='store')
  99. parser.add_argument('--java', action='store')
  100. parser.add_argument('--prefix-filter', action='store')
  101. parser.add_argument('--exclude-filter', action='store')
  102. parser.add_argument('--jars-list', action='store')
  103. parser.add_argument('--output-format', action='store', default="html")
  104. parser.add_argument('--raw-output', dest='tar_output', action='store_false', default=True)
  105. parser.add_argument('--agent-disposition', action='store')
  106. parser.add_argument('--runner-path', dest='runners_paths', action='append', default=[])
  107. args = parser.parse_args()
  108. main(**vars(args))