33This script reads values, including nested values, from structured data files (JSON, YAML, TOML, INI).
44
55Usage:
6- dotcat <file> <dot_separated_key >
6+ dotcat <file> <dotted-path >
77
88Example:
99 dotcat config.json python.editor.tabSize
@@ -75,14 +75,27 @@ def red(text: str) -> str:
7575
7676USAGE = f"""
7777{ bold ('dotcat' )}
78+ Read values from structured data files (JSON, YAML, TOML, INI)
79+
80+ Usage: dotcat <file> <dotted-path>
81+
82+ <file> The input file (JSON, YAML, TOML, INI).
83+ <dotted-path> The dotted path to the desired data (e.g., project.authors).
84+
85+ See `dotcat --help` for more information.
86+ """
87+
88+ HELP = f"""
89+ { bold ('dotcat' )}
7890Read values, including nested values, from structured data files (JSON, YAML, TOML, INI)
7991
8092{ bold ('USAGE:' )}
81- dotcat <file> <dot_separated_key >
93+ dotcat <file> <dotted-path >
8294
83- { bold ('EXAMPLE:' )}
84- dotcat config.json python.editor.tabSize
85- dotcat somefile.toml a.b.c
95+ { bold ('EXAMPLES:' )}
96+ dotcat config.json python.editor.tabSize
97+ dotcat somefile.toml a.b.c
98+ dotcat package.json dependencies.react
8699"""
87100
88101######################################################################
@@ -299,8 +312,8 @@ def from_attr_chain(data: Dict[str, Any], lookup_chain: str) -> Any:
299312 Accesses a nested dictionary value with an attribute chain encoded by a dot-separated string.
300313
301314 Args:
302- adict : The dictionary to access.
303- lookup_path : The dot-separated string representing the nested keys.
315+ data : The dictionary to access.
316+ lookup_chain : The dotted-path string representing the nested keys.
304317
305318 Returns:
306319 The value at the specified nested key, or None if the key doesn't exist.
@@ -329,26 +342,31 @@ def from_attr_chain(data: Dict[str, Any], lookup_chain: str) -> Any:
329342
330343def parse_args (args : List [str ]) -> Tuple [str , str , str , bool ]:
331344 """
332- Returns the filename, lookup chain , output format, and check_install flag.
345+ Returns the filename, dotted-path , output format, and check_install flag.
333346
334347 Args:
335348 args: The list of command-line arguments.
336349
337350 Returns:
338- The filename, lookup chain , output format, and check_install flag.
351+ The filename, dotted-path , output format, and check_install flag.
339352 """
340353 # Handle help commands
341- if args is None or len (args ) == 0 or args == ["help" ] or args == ["--help" ]:
342- print (USAGE )
354+ if args is None or len (args ) == 0 :
355+ print (HELP ) # Show help for no arguments
356+ sys .exit (0 )
357+
358+ # Handle explicit help requests
359+ if "help" in args or "-h" in args or "--help" in args :
360+ print (HELP ) # Show help for help requests
343361 sys .exit (0 )
344362
345363 parser = argparse .ArgumentParser (add_help = False )
346364 parser .add_argument ("file" , type = str , nargs = "?" , help = "The file to read from" )
347365 parser .add_argument (
348- "dot_separated_key " ,
366+ "dotted_path " ,
349367 type = str ,
350368 nargs = "?" ,
351- help = "The dot-separated key to look up" ,
369+ help = "The dotted-path to look up" ,
352370 )
353371 parser .add_argument (
354372 "--output" ,
@@ -365,15 +383,15 @@ def parse_args(args: List[str]) -> Tuple[str, str, str, bool]:
365383 parsed_args = parser .parse_args (args )
366384 return (
367385 parsed_args .file ,
368- parsed_args .dot_separated_key ,
386+ parsed_args .dotted_path ,
369387 parsed_args .output ,
370388 parsed_args .check_install ,
371389 )
372390
373391
374392def is_likely_dot_path (arg : str ) -> bool :
375393 """
376- Determines if an argument is likely a dot path rather than a file path.
394+ Determines if an argument is likely a dotted- path rather than a file path.
377395
378396 Args:
379397 arg: The argument to check.
@@ -402,8 +420,8 @@ def run(args: List[str] = None) -> None:
402420 check_install ()
403421 return
404422
405- # Special case: If we have only one argument and it looks like a dot path,
406- # treat it as the dot path rather than the file
423+ # Special case: If we have only one argument and it looks like a dotted- path,
424+ # treat it as the dotted- path rather than the file
407425 if filename is not None and lookup_chain is None and len (args ) == 1 :
408426 if is_likely_dot_path (filename ):
409427 # Swap the arguments
@@ -414,33 +432,33 @@ def run(args: List[str] = None) -> None:
414432 # Handle cases where one of the required arguments is missing
415433 if lookup_chain is None or filename is None :
416434 if filename is not None and lookup_chain is None :
417- # Case 1: File is provided but dot pattern is missing
435+ # Case 1: File is provided but dotted-path is missing
418436 try :
419437 if os .path .exists (filename ):
420- # File exists, but dot pattern is missing
438+ # File exists, but dotted-path is missing
421439 print (
422- f"{ red ( 'Dot' ) } path required. { red ( ' Which' ) } value do you want me to look up in { filename } ?"
440+ f"Dotted- path required. Which value do you want me to look up in { filename } ?"
423441 )
424- print (f"\n $dotcat { filename } { red ('<pattern >' )} " )
442+ print (f"\n $dotcat { filename } { red ('<dotted-path >' )} " )
425443 sys .exit (2 ) # Invalid usage
426444 except Exception :
427445 # If there's any error checking the file, fall back to general usage message
428446 pass
429447 elif filename is None and lookup_chain is not None :
430- # Case 2: Dot pattern is provided but file is missing
431- # Check if the argument looks like a dot path (contains dots)
448+ # Case 2: Dotted-path is provided but file is missing
449+ # Check if the argument looks like a dotted- path (contains dots)
432450 if "." in lookup_chain :
433- # It looks like a dot path, so assume the file is missing
451+ # It looks like a dotted- path, so assume the file is missing
434452 print (
435- f"{ red ( ' File' ) } path required. { red ( ' Which' ) } file contains the value at { lookup_chain } ?"
453+ f"File path required. Which file contains the value at { lookup_chain } ?"
436454 )
437455 print (f"\n $dotcat { red ('<file>' )} { lookup_chain } " )
438456 sys .exit (2 ) # Invalid usage
439457 # Otherwise, it might be a file without an extension or something else,
440458 # so fall back to the general usage message
441459
442460 # General usage message for other cases
443- print (USAGE )
461+ print (USAGE ) # Display usage for invalid arguments
444462 sys .exit (2 ) # Invalid usage
445463
446464 # gets the parsed data
0 commit comments