Code coverage report supports text format.

coverage.py is hardcoded to generate coverage files in html format. This
makes comparison of the two generated reports harder. While the text
format allows users to use diff.

This cl changes the script so that the user can specify either "html" or
"text" output format via --format arg. The default value is html.

Change-Id: I80da2701e332cb4bcda20bb187b928a307e907bb
Reviewed-on: https://chromium-review.googlesource.com/c/chromium/src/+/2003790
Commit-Queue: Sahel Sharify <[email protected]>
Reviewed-by: Yuke Liao <[email protected]>
Cr-Commit-Position: refs/heads/master@{#732200}
diff --git a/tools/code_coverage/coverage.py b/tools/code_coverage/coverage.py
index 126f48c..8b3b7a4 100755
--- a/tools/code_coverage/coverage.py
+++ b/tools/code_coverage/coverage.py
@@ -190,18 +190,23 @@
   return _GetTargetOS() == 'ios'
 
 
-def _GeneratePerFileLineByLineCoverageInHtml(binary_paths, profdata_file_path,
-                                             filters, ignore_filename_regex):
-  """Generates per file line-by-line coverage in html using 'llvm-cov show'.
+def _GeneratePerFileLineByLineCoverageInFormat(binary_paths, profdata_file_path,
+                                               filters, ignore_filename_regex,
+                                               output_format):
+  """Generates per file line-by-line coverage in html or text using
+  'llvm-cov show'.
 
-  For a file with absolute path /a/b/x.cc, a html report is generated as:
-  OUTPUT_DIR/coverage/a/b/x.cc.html. An index html file is also generated as:
-  OUTPUT_DIR/index.html.
+  For a file with absolute path /a/b/x.cc, a html/txt report is generated as:
+  OUTPUT_DIR/coverage/a/b/x.cc.[html|txt]. For html format, an index html file
+  is also generated as: OUTPUT_DIR/index.html.
 
   Args:
     binary_paths: A list of paths to the instrumented binaries.
     profdata_file_path: A path to the profdata file.
     filters: A list of directories and files to get coverage for.
+    ignore_filename_regex: A regular expression for skipping source code files
+                           with certain file paths.
+    output_format: The output format of generated report files.
   """
   # llvm-cov show [options] -instr-profile PROFILE BIN [-object BIN,...]
   # [[-object BIN]] [SOURCES]
@@ -209,8 +214,9 @@
   # and the rest are specified as keyword argument.
   logging.debug('Generating per file line by line coverage reports using '
                 '"llvm-cov show" command.')
+
   subprocess_cmd = [
-      LLVM_COV_PATH, 'show', '-format=html',
+      LLVM_COV_PATH, 'show', '-format={}'.format(output_format),
       '-output-dir={}'.format(OUTPUT_DIR),
       '-instr-profile={}'.format(profdata_file_path), binary_paths[0]
   ]
@@ -907,6 +913,13 @@
       '\'autoninja -h\' for more details.')
 
   arg_parser.add_argument(
+      '--format',
+      type=str,
+      default='html',
+      help='Output format of the "llvm-cov show" command. The supported '
+      'formats are "text" and "html".')
+
+  arg_parser.add_argument(
       '-v',
       '--verbose',
       action='store_true',
@@ -1009,14 +1022,17 @@
   binary_paths.extend(
       coverage_utils.GetSharedLibraries(binary_paths, BUILD_DIR, otool_path))
 
-  logging.info('Generating code coverage report in html (this can take a while '
-               'depending on size of target!).')
+  assert args.format == 'html' or args.format == 'text', (
+      '%s is not a valid output format for "llvm-cov show". Only "text" and '
+      '"html" formats are supported.' % (args.format))
+  logging.info('Generating code coverage report in %s (this can take a while '
+               'depending on size of target!).' % (args.format))
   per_file_summary_data = _GeneratePerFileCoverageSummary(
       binary_paths, profdata_file_path, absolute_filter_paths,
       args.ignore_filename_regex)
-  _GeneratePerFileLineByLineCoverageInHtml(binary_paths, profdata_file_path,
-                                           absolute_filter_paths,
-                                           args.ignore_filename_regex)
+  _GeneratePerFileLineByLineCoverageInFormat(
+      binary_paths, profdata_file_path, absolute_filter_paths,
+      args.ignore_filename_regex, args.format)
   component_mappings = None
   if not args.no_component_view:
     component_mappings = json.load(urllib2.urlopen(COMPONENT_MAPPING_URL))
@@ -1030,7 +1046,8 @@
       no_file_view=args.no_file_view,
       component_mappings=component_mappings)
 
-  processor.PrepareHtmlReport()
+  if args.format == 'html':
+    processor.PrepareHtmlReport()
 
 
 if __name__ == '__main__':