Skip to content

Commit c06e787

Browse files
committed
add in-place patching and patch read from stdin. enables use of
jsonpatch in a shell script like so: cat <<EOT | jsonpatch -i a.json [{"path": "/foo", "value": "baz", "op": "replace"}] EOT which will edit a.json in-place and leave a backup in a.json.orig.
1 parent 48f9adb commit c06e787

File tree

1 file changed

+17
-4
lines changed

1 file changed

+17
-4
lines changed

bin/jsonpatch

Lines changed: 17 additions & 4 deletions
Original file line numberDiff line numberDiff line change
@@ -1,12 +1,11 @@
11
#!/usr/bin/env python
22
# -*- coding: utf-8 -*-
33

4-
from __future__ import print_function
5-
64
import sys
75
import os.path
86
import json
97
import jsonpatch
8+
import tempfile
109
import argparse
1110

1211

@@ -15,9 +14,12 @@ parser = argparse.ArgumentParser(
1514
parser.add_argument('ORIGINAL', type=argparse.FileType('r'),
1615
help='Original file')
1716
parser.add_argument('PATCH', type=argparse.FileType('r'),
18-
help='Patch file')
17+
nargs='?', default=sys.stdin,
18+
help='Patch file (read from stdin if omitted)')
1919
parser.add_argument('--indent', type=int, default=None,
2020
help='Indent output by n spaces')
21+
parser.add_argument('-i', '--in-place', action='store_true',
22+
help='Modify ORIGINAL in-place instead of to stdout')
2123
parser.add_argument('-v', '--version', action='version',
2224
version='%(prog)s ' + jsonpatch.__version__)
2325

@@ -35,7 +37,18 @@ def patch_files():
3537
doc = json.load(args.ORIGINAL)
3638
patch = json.load(args.PATCH)
3739
result = jsonpatch.apply_patch(doc, patch)
38-
print(json.dumps(result, indent=args.indent))
40+
if args.in_place:
41+
dirname = os.path.abspath(os.path.dirname(args.ORIGINAL.name))
42+
fd, pathname = tempfile.mkstemp(dir=dirname)
43+
fp = os.fdopen(fd, 'w')
44+
else:
45+
fp = sys.stdout
46+
json.dump(result, fp, indent=args.indent)
47+
if args.in_place:
48+
fp.close()
49+
os.link(args.ORIGINAL.name, args.ORIGINAL.name + '.orig')
50+
os.chmod(pathname, os.stat(args.ORIGINAL.name).st_mode)
51+
os.rename(pathname, args.ORIGINAL.name)
3952

4053

4154
if __name__ == "__main__":

0 commit comments

Comments
 (0)