Skip to content

Commit c4eb3b8

Browse files
Copilotstefankoegl
andcommitted
Fix command line argument parsing
Co-authored-by: stefankoegl <[email protected]>
1 parent 9962830 commit c4eb3b8

File tree

2 files changed

+72
-46
lines changed

2 files changed

+72
-46
lines changed

bin/jsonpointer

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

4-
54
import argparse
65
import json
6+
import os
77
import sys
88

99
import jsonpointer
1010

11-
parser = argparse.ArgumentParser(
12-
description='Resolve a JSON pointer on JSON files')
13-
14-
# Accept pointer as argument or as file
15-
ptr_group = parser.add_mutually_exclusive_group(required=True)
16-
17-
ptr_group.add_argument('-f', '--pointer-file', type=argparse.FileType('r'),
18-
nargs='?',
19-
help='File containing a JSON pointer expression')
20-
21-
ptr_group.add_argument('POINTER', type=str, nargs='?',
22-
help='A JSON pointer expression')
23-
24-
parser.add_argument('FILE', type=argparse.FileType('r'), nargs='+',
25-
help='Files for which the pointer should be resolved')
26-
parser.add_argument('--indent', type=int, default=None,
27-
help='Indent output by n spaces')
28-
parser.add_argument('-v', '--version', action='version',
29-
version='%(prog)s ' + jsonpointer.__version__)
30-
31-
3211
def main():
12+
# First handle backward compatibility for v1 command line syntax:
13+
# jsonpointer ptr.json file.json
14+
if len(sys.argv) >= 3 and not sys.argv[1].startswith('-'):
15+
# Check if the first argument is a file path
16+
if os.path.isfile(sys.argv[1]):
17+
# Insert -f option before the first argument
18+
sys.argv.insert(1, '-f')
19+
20+
parser = argparse.ArgumentParser(
21+
description='Resolve a JSON pointer on JSON files')
22+
23+
# Use mutually exclusive group for pointer specification
24+
pointer_group = parser.add_mutually_exclusive_group(required=True)
25+
pointer_group.add_argument('-e', '--expression',
26+
help='A JSON pointer expression (e.g. "/foo/bar")')
27+
pointer_group.add_argument('-f', '--pointer-file', metavar='POINTER_FILE',
28+
help='File containing a JSON pointer expression')
29+
30+
parser.add_argument('FILE', type=argparse.FileType('r'), nargs='+',
31+
help='Files for which the pointer should be resolved')
32+
parser.add_argument('--indent', type=int, default=None,
33+
help='Indent output by n spaces')
34+
parser.add_argument('-v', '--version', action='version',
35+
version='%(prog)s ' + jsonpointer.__version__)
36+
37+
args = parser.parse_args()
38+
3339
try:
34-
resolve_files()
40+
resolve_files(args)
3541
except KeyboardInterrupt:
3642
sys.exit(1)
3743

3844

39-
def parse_pointer(args):
40-
if args.POINTER:
41-
ptr = args.POINTER
45+
def resolve_files(args):
46+
"""Resolve a JSON pointer on JSON files"""
47+
# Get pointer from expression or file
48+
if args.expression:
49+
ptr = args.expression
4250
elif args.pointer_file:
43-
ptr = args.pointer_file.read().strip()
51+
with open(args.pointer_file) as f:
52+
content = f.read().strip()
53+
# Handle JSON-encoded strings
54+
if content.startswith('"') and content.endswith('"'):
55+
try:
56+
ptr = json.loads(content)
57+
except json.JSONDecodeError:
58+
ptr = content
59+
else:
60+
ptr = content
4461
else:
45-
parser.print_usage()
46-
sys.exit(1)
47-
48-
return ptr
49-
50-
51-
def resolve_files():
52-
""" Resolve a JSON pointer on JSON files """
53-
args = parser.parse_args()
54-
55-
ptr = parse_pointer(args)
62+
sys.exit(1) # This should never happen because the group is required
5663

64+
# Process each file
5765
for f in args.FILE:
5866
doc = json.load(f)
5967
try:

doc/commandline.rst

Lines changed: 26 additions & 8 deletions
Original file line numberDiff line numberDiff line change
@@ -6,18 +6,26 @@ that can be used to resolve a JSON pointers on JSON files.
66

77
The program has the following usage ::
88

9-
usage: jsonpointer [-h] [--indent INDENT] [-v] POINTER FILE [FILE ...]
9+
usage: jsonpointer [-h] (-e EXPRESSION | -f POINTER_FILE) [--indent INDENT]
10+
[-v]
11+
FILE [FILE ...]
1012

1113
Resolve a JSON pointer on JSON files
1214

1315
positional arguments:
14-
POINTER File containing a JSON pointer expression
15-
FILE Files for which the pointer should be resolved
16+
FILE Files for which the pointer should be resolved
1617

17-
optional arguments:
18-
-h, --help show this help message and exit
19-
--indent INDENT Indent output by n spaces
20-
-v, --version show program's version number and exit
18+
options:
19+
-h, --help show this help message and exit
20+
-e EXPRESSION, --expression EXPRESSION
21+
A JSON pointer expression (e.g. "/foo/bar")
22+
-f POINTER_FILE, --pointer-file POINTER_FILE
23+
File containing a JSON pointer expression
24+
--indent INDENT Indent output by n spaces
25+
-v, --version show program's version number and exit
26+
27+
For backward compatibility, if the first argument is a file path, it is treated as
28+
if `-f` was specified, allowing the command to be used as in previous versions.
2129

2230

2331
Example
@@ -36,7 +44,17 @@ Example
3644
$ cat ptr.json
3745
"/a"
3846
39-
# resolve JSON pointer
47+
# resolve JSON pointer (version 1 compatible syntax)
4048
$ jsonpointer ptr.json a.json b.json
4149
[1, 2, 3]
4250
{"b": [1, 3, 4]}
51+
52+
# resolve with -f option
53+
$ jsonpointer -f ptr.json a.json b.json
54+
[1, 2, 3]
55+
{"b": [1, 3, 4]}
56+
57+
# resolve with -e option for direct expression
58+
$ jsonpointer -e "/a" a.json b.json
59+
[1, 2, 3]
60+
{"b": [1, 3, 4]}

0 commit comments

Comments
 (0)