Merge pull request #109 from mattclegg/no-sort-keys

Adding no-sort-keys to pretty_format_json
diff --git a/.travis.yml b/.travis.yml
index 6a0aaa0..a6a39d8 100644
--- a/.travis.yml
+++ b/.travis.yml
@@ -1,12 +1,12 @@
 language: python
 env: # These should match the tox env list
-    - TOXENV=py26
     - TOXENV=py27
     - TOXENV=py33
     - TOXENV=py34
     - TOXENV=pypy
     - TOXENV=pypy3
-install: pip install coveralls tox
+install:
+    - pip install coveralls tox
 script: tox
 # Special snowflake.  Our tests depend on making real commits.
 before_install:
diff --git a/README.md b/README.md
index 773fb81..091a8a4 100644
--- a/README.md
+++ b/README.md
@@ -51,6 +51,8 @@
     - Use `args: ['--django']` to match `test*.py` instead.
 - `pyflakes` - Run pyflakes on your python files.
 - `pretty-format-json` - Checks that all your JSON files are pretty
+    - Use `args: ['--autofix']` to automatically fixing the encountered not-pretty-formatted files and
+    `args: ['--no-sort-keys']` to disable the sort on the keys.
 - `requirements-txt-fixer` - Sorts entries in requirements.txt
 - `trailing-whitespace` - Trims trailing whitespace.
     - Markdown linebreak trailing spaces preserved for `.md` and`.markdown`;
diff --git a/pre_commit_hooks/pretty_format_json.py b/pre_commit_hooks/pretty_format_json.py
index d22dada..6bcc9b0 100644
--- a/pre_commit_hooks/pretty_format_json.py
+++ b/pre_commit_hooks/pretty_format_json.py
@@ -2,14 +2,16 @@
 
 import argparse
 import sys
+from collections import OrderedDict
 
 import simplejson
 
 
-def _get_pretty_format(contents, indent):
+def _get_pretty_format(contents, indent, sort_keys=True):
     return simplejson.dumps(
-        simplejson.loads(contents),
-        sort_keys=True,
+        simplejson.loads(contents,
+                         object_pairs_hook=None if sort_keys else OrderedDict),
+        sort_keys=sort_keys,
         indent=indent
     ) + "\n"  # dumps don't end with a newline
 
@@ -34,6 +36,13 @@
         default=2,
         help='Number of indent spaces used to pretty-format files'
     )
+    parser.add_argument(
+        '--no-sort-keys',
+        action='store_true',
+        dest='no_sort_keys',
+        default=False,
+        help='Keep JSON nodes in the same order'
+    )
 
     parser.add_argument('filenames', nargs='*', help='Filenames to fix')
     args = parser.parse_args(argv)
@@ -46,7 +55,7 @@
             contents = f.read()
             f.close()
 
-            pretty_contents = _get_pretty_format(contents, args.indent)
+            pretty_contents = _get_pretty_format(contents, args.indent, (not args.no_sort_keys))
 
             if contents != pretty_contents:
                 print("File {0} is not pretty-formatted".format(json_file))
diff --git a/testing/resources/not_pretty_formatted_json.json b/testing/resources/not_pretty_formatted_json.json
index 6376d59..58b1d02 100644
--- a/testing/resources/not_pretty_formatted_json.json
+++ b/testing/resources/not_pretty_formatted_json.json
@@ -1,5 +1,6 @@
 {
-    "foo": "bar",
-    "alist": [2, 34, 234],
-    "blah": null
+    "foo":
+    "bar",
+        "alist": [2, 34, 234],
+  "blah": null
 }
diff --git a/testing/resources/unsorted_pretty_formatted_json.json b/testing/resources/unsorted_pretty_formatted_json.json
new file mode 100644
index 0000000..fe8bf5e
--- /dev/null
+++ b/testing/resources/unsorted_pretty_formatted_json.json
@@ -0,0 +1,9 @@
+{
+  "foo": "bar",
+  "alist": [
+    34,
+    2,
+    234
+  ],
+  "blah": null
+}
diff --git a/tests/pretty_format_json_test.py b/tests/pretty_format_json_test.py
index 6165a13..443c20f 100644
--- a/tests/pretty_format_json_test.py
+++ b/tests/pretty_format_json_test.py
@@ -8,6 +8,7 @@
 
 @pytest.mark.parametrize(('filename', 'expected_retval'), (
     ('not_pretty_formatted_json.json', 1),
+    ('unsorted_pretty_formatted_json.json', 1),
     ('pretty_formatted_json.json', 0),
 ))
 def test_pretty_format_json(filename, expected_retval):
@@ -15,6 +16,16 @@
     assert ret == expected_retval
 
 
+@pytest.mark.parametrize(('filename', 'expected_retval'), (
+    ('not_pretty_formatted_json.json', 1),
+    ('unsorted_pretty_formatted_json.json', 0),
+    ('pretty_formatted_json.json', 0),
+))
+def test_unsorted_pretty_format_json(filename, expected_retval):
+    ret = pretty_format_json(['--no-sort-keys', get_resource_path(filename)])
+    assert ret == expected_retval
+
+
 def test_autofix_pretty_format_json(tmpdir):
     srcfile = tmpdir.join('to_be_json_formatted.json')
     with io.open(get_resource_path('not_pretty_formatted_json.json')) as f: