Skip to content

Commit 1d285a8

Browse files
committed
add --backup flag and attempt to address various exceptions that may be raised
1 parent c06e787 commit 1d285a8

File tree

1 file changed

+25
-5
lines changed

1 file changed

+25
-5
lines changed

bin/jsonpatch

Lines changed: 25 additions & 5 deletions
Original file line numberDiff line numberDiff line change
@@ -18,6 +18,8 @@ parser.add_argument('PATCH', type=argparse.FileType('r'),
1818
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('-b', '--backup', action='store_true',
22+
help='Back up ORIGINAL if modifying in-place')
2123
parser.add_argument('-i', '--in-place', action='store_true',
2224
help='Modify ORIGINAL in-place instead of to stdout')
2325
parser.add_argument('-v', '--version', action='version',
@@ -37,18 +39,36 @@ def patch_files():
3739
doc = json.load(args.ORIGINAL)
3840
patch = json.load(args.PATCH)
3941
result = jsonpatch.apply_patch(doc, patch)
42+
4043
if args.in_place:
4144
dirname = os.path.abspath(os.path.dirname(args.ORIGINAL.name))
42-
fd, pathname = tempfile.mkstemp(dir=dirname)
43-
fp = os.fdopen(fd, 'w')
45+
try:
46+
fd, pathname = tempfile.mkstemp(dir=dirname)
47+
fp = os.fdopen(fd, 'w')
48+
atomic = True
49+
except OSError:
50+
if args.backup:
51+
os.rename(args.ORIGINAL.name, args.ORIGINAL.name + '.orig')
52+
fp = open(args.ORIGINAL.name, 'w')
53+
atomic = False
54+
4455
else:
4556
fp = sys.stdout
57+
4658
json.dump(result, fp, indent=args.indent)
59+
fp.write('\n')
60+
4761
if args.in_place:
4862
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)
63+
if atomic:
64+
try:
65+
if args.backup:
66+
os.link(args.ORIGINAL.name, args.ORIGINAL.name + '.orig')
67+
os.chmod(pathname, os.stat(args.ORIGINAL.name).st_mode)
68+
os.rename(pathname, args.ORIGINAL.name)
69+
except OSError:
70+
os.unlink(args.ORIGINAL.name)
71+
os.rename(pathname, args.ORIGINAL.name)
5272

5373

5474
if __name__ == "__main__":

0 commit comments

Comments
 (0)