Patchwork [1,of,5,json-style] get-with-headers: support parsing and pretty printing JSON

login
register
mail settings
Submitter Gregory Szorc
Date March 31, 2015, 9:56 p.m.
Message ID <b2bd63cc9745e161f524.1427838964@gps-mbp.local>
Download mbox | patch
Permalink /patch/8393/
State Accepted
Headers show

Comments

Gregory Szorc - March 31, 2015, 9:56 p.m.
# HG changeset patch
# User Gregory Szorc <gregory.szorc@gmail.com>
# Date 1427774214 25200
#      Mon Mar 30 20:56:54 2015 -0700
# Node ID b2bd63cc9745e161f5249c467aeb871308b20d43
# Parent  888dcab69ca3fe817786a7078bb1f66afa203c8b
get-with-headers: support parsing and pretty printing JSON

Upcoming patches will add support for JSON output from hgweb.

Because JSON output from the templater is hard to read and because it
is easy to introduce malformed JSON, we introduce a JSON processing
mode to get-with-headers.py that will parse and pretty print JSON
from HTTP responses. This will make tests easier to read and write
and it will ensure hgweb is emitting well-formed JSON.

Patch

diff --git a/tests/get-with-headers.py b/tests/get-with-headers.py
--- a/tests/get-with-headers.py
+++ b/tests/get-with-headers.py
@@ -5,8 +5,16 @@  a subset of the headers plus the body of
 
 import httplib, sys
 
 try:
+    import json
+except ImportError:
+    try:
+        import simplejson as json
+    except ImportError:
+        json = None
+
+try:
     import msvcrt, os
     msvcrt.setmode(sys.stdout.fileno(), os.O_BINARY)
     msvcrt.setmode(sys.stderr.fileno(), os.O_BINARY)
 except ImportError:
@@ -19,8 +27,12 @@  if '--twice' in sys.argv:
 headeronly = False
 if '--headeronly' in sys.argv:
     sys.argv.remove('--headeronly')
     headeronly = True
+formatjson = False
+if '--json' in sys.argv:
+    sys.argv.remove('--json')
+    formatjson = True
 
 reasons = {'Not modified': 'Not Modified'} # python 2.4
 
 tag = None
@@ -43,9 +55,25 @@  def request(host, path, show):
             print "%s: %s" % (h, response.getheader(h))
     if not headeronly:
         print
         data = response.read()
-        sys.stdout.write(data)
+
+        # Pretty print JSON. This also has the beneficial side-effect
+        # of verifying emitted JSON is well-formed.
+        if formatjson:
+            if not json:
+                print 'no json module not available'
+                print 'did you forget a #require json?'
+                sys.exit(1)
+
+            # json.dumps() will print trailing newlines. Eliminate them
+            # to make tests easier to write.
+            data = json.loads(data)
+            lines = json.dumps(data, sort_keys=True, indent=2).splitlines()
+            for line in lines:
+                print line.rstrip()
+        else:
+            sys.stdout.write(data)
 
         if twice and response.getheader('ETag', None):
             tag = response.getheader('ETag')