@@ -37,7 +37,12 @@ class ParseError(Exception):
37
37
pass
38
38
39
39
40
+ class JsonPathError (Exception ):
41
+ pass
42
+
43
+
40
44
def is_clipboard_available () -> bool :
45
+ '''check if the clipboard available'''
41
46
copy_fn , paste_fn = pyperclip .determine_clipboard ()
42
47
return copy_fn .__class__ .__name__ != 'ClipboardUnavailable' \
43
48
and paste_fn .__class__ .__name__ != 'ClipboardUnavailable'
@@ -68,7 +73,7 @@ def parse_to_pyobj(text: str, jpath: Optional[str]) -> tuple[Any, str]:
68
73
# match sub-elements via jsonpath
69
74
subelements = jsonpath (py_obj , jpath )
70
75
if subelements is False :
71
- raise ParseError ( 'wrong jsonpath ' )
76
+ raise JsonPathError ( 'invalid JSONPath or query result is empty ' )
72
77
else :
73
78
return subelements , fmt
74
79
@@ -132,7 +137,8 @@ def clip_value(value: Any):
132
137
133
138
134
139
def format_to_text (py_obj : Any , fmt : str , * ,
135
- compact : bool , escape : bool , indent : int , sort_keys : bool ):
140
+ compact : bool , escape : bool ,
141
+ indent : int , sort_keys : bool ) -> str :
136
142
'''format the py_obj to text'''
137
143
if fmt == 'json' :
138
144
if compact :
@@ -162,7 +168,7 @@ def output(output_fp: IO, text: str, fmt: str, cp2clip: bool):
162
168
pyperclip .copy (text )
163
169
print_inf ('result copied to clipboard.' )
164
170
return
165
- elif stdout .isatty ():
171
+ elif output_fp .isatty ():
166
172
# highlight the text when output to TTY divice
167
173
Lexer = {'json' : JsonLexer , 'toml' : TOMLLexer , 'yaml' : YamlLexer }[fmt ]
168
174
colored_text = highlight (text , Lexer (), TerminalFormatter ())
@@ -179,7 +185,7 @@ def output(output_fp: IO, text: str, fmt: str, cp2clip: bool):
179
185
output_fp .write (text )
180
186
181
187
182
- def process (input_fp : IO , jpath : Optional [str ], to_format : Optional [str ], * ,
188
+ def process (input_fp : IO , jpath : Optional [str ], convert_fmt : Optional [str ], * ,
183
189
compact : bool , cp2clip : bool , escape : bool , indent : int ,
184
190
overview : bool , overwrite : bool , sort_keys : bool ,
185
191
sets : Optional [list ], pops : Optional [list ]):
@@ -188,15 +194,13 @@ def process(input_fp: IO, jpath: Optional[str], to_format: Optional[str], *,
188
194
py_obj , fmt = parse_to_pyobj (input_text , jpath )
189
195
190
196
if sets or pops :
191
- sets = sets or []
192
- pops = pops or []
193
- modify_pyobj (py_obj , sets , pops )
197
+ modify_pyobj (py_obj , sets , pops ) # type: ignore
194
198
195
199
if overview :
196
200
py_obj = get_overview (py_obj )
197
201
198
- to_format = to_format or fmt
199
- formated_text = format_to_text (py_obj , to_format ,
202
+ convert_fmt = convert_fmt or fmt
203
+ formated_text = format_to_text (py_obj , convert_fmt ,
200
204
compact = compact , escape = escape ,
201
205
indent = indent , sort_keys = sort_keys )
202
206
@@ -206,7 +210,7 @@ def process(input_fp: IO, jpath: Optional[str], to_format: Optional[str], *,
206
210
else :
207
211
# truncate file to zero length before overwrite
208
212
output_fp = input_fp
209
- output (output_fp , formated_text , to_format , cp2clip )
213
+ output (output_fp , formated_text , convert_fmt , cp2clip )
210
214
211
215
212
216
def parse_cmdline_args (args : Optional [Sequence [str ]] = None ):
@@ -229,10 +233,10 @@ def parse_cmdline_args(args: Optional[Sequence[str]] = None):
229
233
help = 'output part of the object via jsonpath' )
230
234
parser .add_argument ('-s' , dest = 'sort_keys' , action = 'store_true' ,
231
235
help = 'sort keys of objects on output' )
232
- parser .add_argument ('--set' , nargs = '*' , metavar = "foo.k1=v1 k2[i]=v2" ,
233
- help = 'set the keys to values' )
234
- parser .add_argument ('--pop' , nargs = '*' , metavar = "k1 foo.k2 k3[i]" ,
235
- help = 'pop the specified keys' )
236
+ parser .add_argument ('--set' , metavar = "foo.k1=v1, k2[i]=v2" ,
237
+ help = 'set the keys to values (seperated by `;`) ' )
238
+ parser .add_argument ('--pop' , metavar = "k1, foo.k2, k3[i]" ,
239
+ help = 'pop the specified keys (seperated by `;`) ' )
236
240
parser .add_argument (dest = 'files' , nargs = '*' ,
237
241
help = 'the files that will be processed' )
238
242
parser .add_argument ('-v' , dest = 'version' , action = 'version' ,
@@ -248,6 +252,13 @@ def main():
248
252
if args .cp2clip and not cp2clip :
249
253
print_err ('clipboard unavailable' )
250
254
255
+ # the overwrite will be forced to close when showing overview
256
+ overwrite = False if args .overview else args .overwrite
257
+
258
+ # get sets and pops
259
+ sets = [k .strip () for k in args .set .split (';' )] if args .set else []
260
+ pops = [k .strip () for k in args .pop .split (';' )] if args .pop else []
261
+
251
262
files = args .files or [stdin ]
252
263
253
264
for file in files :
@@ -262,10 +273,10 @@ def main():
262
273
escape = args .escape ,
263
274
indent = args .indent ,
264
275
overview = args .overview ,
265
- overwrite = args . overwrite ,
276
+ overwrite = overwrite ,
266
277
sort_keys = args .sort_keys ,
267
- sets = args . set ,
268
- pops = args . pop )
278
+ sets = sets ,
279
+ pops = pops )
269
280
except ParseError as err :
270
281
print_err (err )
271
282
except FileNotFoundError :
0 commit comments