Bug 1255179 - Json Rewriter addition. draft
authorGreg Mierzwinski <gmierz2@outlook.com>
Fri, 25 Mar 2016 12:58:02 -0400
changeset 355016 0e83c87d5cd62843947fbf438e30bf7fb1be5428
parent 350969 10f66b3164570b2183333262fa91a16004cbb908
child 355017 4a11bf93515429adcc280fd0fc4a3e7ef0a8d1d6
push id16211
push userbmo:gmierz2@outlook.com
push dateThu, 21 Apr 2016 23:55:54 +0000
bugs1255179
milestone48.0a1
Bug 1255179 - Json Rewriter addition. This contains the json file rewriter which is responsible for mapping URL's found in the "sourceFile" field of code coverage json artifacts to local system paths. MozReview-Commit-ID: BKWwDTm5cHv * * * Bug 1255179 - Use 'json' to rewrite file names. Changed line by line modification to the use of the json module. * * * Bug 1255179 - Fix comments and the rewriter parsing strategy. * * * Bug 1255179 - Remove close on JSON object. * * * Bug 1255179 - Fix record access and path splitting.
python/mozbuild/mozbuild/codecoverage/json_rewriter.py
new file mode 100644
--- /dev/null
+++ b/python/mozbuild/mozbuild/codecoverage/json_rewriter.py
@@ -0,0 +1,77 @@
+# This Source Code Form is subject to the terms of the Mozilla Public
+# License, v. 2.0. If a copy of the MPL was not distributed with this
+# file, You can obtain one at http://mozilla.org/MPL/2.0/.
+
+from argparse import ArgumentParser
+import json
+import os
+import sys
+
+from url_finder import UrlFinder
+from url_finder import UrlFinderError
+from collections import OrderedDict
+
+import buildconfig
+
+class JsonFileRewriter(object):
+    # Class for parsing JSON code coverage files to rewrite source file
+    # urls as local system paths.
+    def __init__(self, appdir, gredir, extra_chrome_manifests):
+        self.topobjdir = buildconfig.topobjdir
+        self.url_finder = UrlFinder(appdir, gredir)
+
+    def rewrite_file(self, in_path, output_suffix):
+        in_path = os.path.abspath(in_path)
+        fileName, filePath = os.path.splitext(in_path)
+        out_path = fileName + output_suffix
+        with open(in_path, 'r') as fh, open(out_path, 'w') as out_fh:
+            data = json.load(fh, object_pairs_hook=OrderedDict)
+            for index, record in enumerate(data):
+                name = record.get('sourceFile')
+                if name:
+                    url = name
+                    try:
+                        res = self.url_finder.rewrite_url(url)
+                        if res is None:
+                            continue
+                    except UrlFinderError as e:
+                        print("Error: %s.\nCouldn't find source info for %s" % (e, url))
+                        continue
+                    src_file, objdir_file, _ = res
+                    assert os.path.isfile(src_file), "Couldn't find mapped source file at %s!" % src_file
+                    record['sourceFile'] = src_file
+            out_fh.write(json.dumps(data, sort_keys=False))
+
+
+def main():
+    parser = ArgumentParser(description="Given a set of json code coverage files produced "
+                            "by mochitests's code coverage, this re-maps file urls "
+                            "back to their source file locations.")
+    parser.add_argument("--app-dir", default="dist/bin/browser/",
+                        help="Prefix of the appdir in use. This is used to map "
+                             "urls starting with resource:///. It may differ by "
+                             "app, but defaults to the valid value for firefox.")
+    parser.add_argument("--gre-dir", default="dist/bin/",
+                        help="Prefix of the gre dir in use. This is used to map "
+                             "urls starting with resource://gre. It may differ by "
+                             "app, but defaults to the valid value for firefox.")
+    parser.add_argument("--output-suffix", default=".out.json",
+                        help="The suffix to append to output files.")
+    parser.add_argument("--extra-chrome-manifests", nargs='+',
+                        help="Paths to files containing extra chrome registration.")
+    parser.add_argument("files", nargs='+',
+                        help="The set of files to process.")
+
+    args = parser.parse_args()
+    if not args.extra_chrome_manifests:
+        extra_path = os.path.join(buildconfig.topobjdir, '_tests',
+                                  'extra.manifest')
+        if os.path.isfile(extra_path):
+            args.extra_chrome_manifests = [extra_path]
+
+    rewriter = JsonFileRewriter(args.app_dir, args.gre_dir, args.extra_chrome_manifests)
+    for f in args.files:
+        rewriter.rewrite_file(f, args.output_suffix)
+
+if __name__ == '__main__':
+    sys.exit(main())
\ No newline at end of file