1cef7893435aa41160dd1255c43cb8498279738ccChris Craik#!/usr/bin/env python
2cef7893435aa41160dd1255c43cb8498279738ccChris Craik# Copyright 2015 The Chromium Authors. All rights reserved.
3cef7893435aa41160dd1255c43cb8498279738ccChris Craik# Use of this source code is governed by a BSD-style license that can be
4cef7893435aa41160dd1255c43cb8498279738ccChris Craik# found in the LICENSE file.
5cef7893435aa41160dd1255c43cb8498279738ccChris Craikimport argparse
6cef7893435aa41160dd1255c43cb8498279738ccChris Craikimport json
7cef7893435aa41160dd1255c43cb8498279738ccChris Craikimport os
8cef7893435aa41160dd1255c43cb8498279738ccChris Craikimport sys
9cef7893435aa41160dd1255c43cb8498279738ccChris Craik
10cef7893435aa41160dd1255c43cb8498279738ccChris Craik
11cef7893435aa41160dd1255c43cb8498279738ccChris Craikdef GetFormattedJSONString(file_path):
12cef7893435aa41160dd1255c43cb8498279738ccChris Craik with open(file_path, 'r') as f:
13cef7893435aa41160dd1255c43cb8498279738ccChris Craik    json_obj = json.load(f)
14cef7893435aa41160dd1255c43cb8498279738ccChris Craik    file_content = f.read()
15cef7893435aa41160dd1255c43cb8498279738ccChris Craik return json.dumps(
16cef7893435aa41160dd1255c43cb8498279738ccChris Craik     json_obj, indent=2, sort_keys=True, separators=(',', ': '))
17cef7893435aa41160dd1255c43cb8498279738ccChris Craik
18cef7893435aa41160dd1255c43cb8498279738ccChris Craik
19cef7893435aa41160dd1255c43cb8498279738ccChris Craikdef ValidateJSONFormat(file_path):
20cef7893435aa41160dd1255c43cb8498279738ccChris Craik with open(file_path, 'r') as f:
21cef7893435aa41160dd1255c43cb8498279738ccChris Craik    file_content = f.read()
22cef7893435aa41160dd1255c43cb8498279738ccChris Craik if file_content != GetFormattedJSONString(file_path):
23cef7893435aa41160dd1255c43cb8498279738ccChris Craik   raise Exception(
24cef7893435aa41160dd1255c43cb8498279738ccChris Craik       'Reformat your JSON file by running: %s --format %s' %
25cef7893435aa41160dd1255c43cb8498279738ccChris Craik       (__file__, file_path))
26cef7893435aa41160dd1255c43cb8498279738ccChris Craik print >> sys.stdout, ('%s passes the JSON format validation' % file_path)
27cef7893435aa41160dd1255c43cb8498279738ccChris Craik
28cef7893435aa41160dd1255c43cb8498279738ccChris Craik
29cef7893435aa41160dd1255c43cb8498279738ccChris Craikdef Format(file_path):
30cef7893435aa41160dd1255c43cb8498279738ccChris Craik  formatted_JSON_string = GetFormattedJSONString(file_path)
31cef7893435aa41160dd1255c43cb8498279738ccChris Craik  with open(file_path, 'w') as f:
32cef7893435aa41160dd1255c43cb8498279738ccChris Craik    f.write(formatted_JSON_string)
33cef7893435aa41160dd1255c43cb8498279738ccChris Craik
34cef7893435aa41160dd1255c43cb8498279738ccChris Craik
35cef7893435aa41160dd1255c43cb8498279738ccChris Craikdef Main(args):
36cef7893435aa41160dd1255c43cb8498279738ccChris Craik  description = """A JSON formatting tool.
37cef7893435aa41160dd1255c43cb8498279738ccChris Craik
38cef7893435aa41160dd1255c43cb8498279738ccChris Craik  This is a tool that validate and reformats JSON file so that it complies with
39cef7893435aa41160dd1255c43cb8498279738ccChris Craik  a certain style. The JSON style imposed by this tool is:
40cef7893435aa41160dd1255c43cb8498279738ccChris Craik    * JSON array elements and object members are indented with 2 spaces.
41cef7893435aa41160dd1255c43cb8498279738ccChris Craik    * Dictionaries objects are sorted by key.
42cef7893435aa41160dd1255c43cb8498279738ccChris Craik    * Items are sperated by ', ' and ': '.
43cef7893435aa41160dd1255c43cb8498279738ccChris Craik  """
44cef7893435aa41160dd1255c43cb8498279738ccChris Craik  parser = argparse.ArgumentParser(
45cef7893435aa41160dd1255c43cb8498279738ccChris Craik      description=description, formatter_class=argparse.RawTextHelpFormatter)
46cef7893435aa41160dd1255c43cb8498279738ccChris Craik  parser.add_argument('file_path', type=str, help='The path to JSON file.')
47cef7893435aa41160dd1255c43cb8498279738ccChris Craik  parser.add_argument('--format', action='store_true', default=False,
48cef7893435aa41160dd1255c43cb8498279738ccChris Craik                      help='Format the JSON file.')
49cef7893435aa41160dd1255c43cb8498279738ccChris Craik  options = parser.parse_args(args)
50cef7893435aa41160dd1255c43cb8498279738ccChris Craik  if options.format:
51cef7893435aa41160dd1255c43cb8498279738ccChris Craik    Format(options.file_path)
52cef7893435aa41160dd1255c43cb8498279738ccChris Craik    return 0
53cef7893435aa41160dd1255c43cb8498279738ccChris Craik  ValidateJSONFormat(options.file_path)
54cef7893435aa41160dd1255c43cb8498279738ccChris Craik  return 0
55cef7893435aa41160dd1255c43cb8498279738ccChris Craik
56cef7893435aa41160dd1255c43cb8498279738ccChris Craik
57cef7893435aa41160dd1255c43cb8498279738ccChris Craikif __name__ == '__main__':
58cef7893435aa41160dd1255c43cb8498279738ccChris Craik  sys.exit(Main(sys.argv[1:]))
59