| |
| |
|
|
| import sys |
| import os.path |
| import json |
| import jsonpatch |
| import tempfile |
| import argparse |
|
|
|
|
| parser = argparse.ArgumentParser( |
| description='Apply a JSON patch on a JSON file') |
| parser.add_argument('ORIGINAL', type=argparse.FileType('r'), |
| help='Original file') |
| parser.add_argument('PATCH', type=argparse.FileType('r'), |
| nargs='?', default=sys.stdin, |
| help='Patch file (read from stdin if omitted)') |
| parser.add_argument('--indent', type=int, default=None, |
| help='Indent output by n spaces') |
| parser.add_argument('-b', '--backup', action='store_true', |
| help='Back up ORIGINAL if modifying in-place') |
| parser.add_argument('-i', '--in-place', action='store_true', |
| help='Modify ORIGINAL in-place instead of to stdout') |
| parser.add_argument('-v', '--version', action='version', |
| version='%(prog)s ' + jsonpatch.__version__) |
| parser.add_argument('-u', '--preserve-unicode', action='store_true', |
| help='Output Unicode character as-is without using Code Point') |
|
|
| def main(): |
| try: |
| patch_files() |
| except KeyboardInterrupt: |
| sys.exit(1) |
|
|
|
|
| def patch_files(): |
| """ Diffs two JSON files and prints a patch """ |
| args = parser.parse_args() |
| doc = json.load(args.ORIGINAL) |
| patch = json.load(args.PATCH) |
| result = jsonpatch.apply_patch(doc, patch) |
|
|
| if args.in_place: |
| dirname = os.path.abspath(os.path.dirname(args.ORIGINAL.name)) |
|
|
| try: |
| |
| |
| |
| |
| |
|
|
| fd, pathname = tempfile.mkstemp(dir=dirname) |
| fp = os.fdopen(fd, 'w') |
| atomic = True |
|
|
| except OSError: |
| |
| |
| |
|
|
| if args.backup: |
| os.rename(args.ORIGINAL.name, args.ORIGINAL.name + '.orig') |
| fp = open(args.ORIGINAL.name, 'w') |
| atomic = False |
|
|
| else: |
| |
| |
|
|
| fp = sys.stdout |
|
|
| |
| |
| |
| json.dump(result, fp, indent=args.indent, ensure_ascii=not(args.preserve_unicode)) |
| fp.write('\n') |
|
|
| if args.in_place: |
| |
| |
|
|
| fp.close() |
|
|
| if atomic: |
| try: |
| |
| |
| |
|
|
| if args.backup: |
| os.link(args.ORIGINAL.name, args.ORIGINAL.name + '.orig') |
| os.chmod(pathname, os.stat(args.ORIGINAL.name).st_mode) |
| os.rename(pathname, args.ORIGINAL.name) |
|
|
| except OSError: |
| |
| |
| |
| |
| os.unlink(args.ORIGINAL.name) |
| os.rename(pathname, args.ORIGINAL.name) |
|
|
|
|
| if __name__ == "__main__": |
| main() |
|
|