Coverage for src / jsonclark / __main__.py: 0%

42 statements  

« prev     ^ index     » next       coverage.py v7.13.0, created at 2025-12-16 12:11 +0300

1"""Command-line interface for jsonclark. 

2 

3Usage: 

4 python -m jsonclark [--indent INDENT] [--sort-keys] [--comments] [FILE] 

5 

6Examples: 

7 # Pretty-print JSON from stdin 

8 cat config.jsonc | python -m jsonclark 

9 

10 # Pretty-print with custom indentation 

11 cat config.jsonc | python -m jsonclark --indent 2 

12 

13 # Sort keys in output 

14 cat config.jsonc | python -m jsonclark --sort-keys 

15 

16 # Show extracted comments 

17 cat config.jsonc | python -m jsonclark --comments 

18 

19 # Pretty-print from file 

20 python -m jsonclark config.jsonc 

21 

22 # All options together 

23 python -m jsonclark --indent 4 --sort-keys --comments config.jsonc 

24""" 

25 

26import sys 

27import json 

28import argparse 

29from typing import Any, Optional 

30 

31from jsonclark import loads, loads_comments 

32 

33 

34def format_json( 

35 obj: Any, 

36 indent: Optional[int] = None, 

37 sort_keys: bool = False, 

38 show_comments: bool = False, 

39 comments: Optional[list[str]] = None, 

40) -> str: 

41 """Format a JSON object as a string. 

42 

43 Args: 

44 obj: The object to format 

45 indent: Number of spaces for indentation (None = compact) 

46 sort_keys: Whether to sort dictionary keys 

47 show_comments: Whether to show comments above the JSON 

48 comments: List of comments to display 

49 

50 Returns: 

51 Formatted JSON string 

52 """ 

53 output = "" 

54 

55 # Add comments if requested 

56 if show_comments and comments: 

57 for comment in comments: 

58 output += f"// {comment}\n" 

59 if output: 

60 output += "\n" 

61 

62 # Format the JSON 

63 json_str = json.dumps( 

64 obj, 

65 indent=indent, 

66 sort_keys=sort_keys, 

67 ensure_ascii=False, 

68 ) 

69 output += json_str 

70 

71 return output 

72 

73 

74def main() -> None: 

75 """Main entry point for the CLI tool.""" 

76 parser = argparse.ArgumentParser( 

77 prog="jsonclark", 

78 description="Pretty-print JSON with comment support", 

79 epilog="Examples:\n" 

80 " cat config.jsonc | python -m jsonclark\n" 

81 " python -m jsonclark --indent 2 config.jsonc\n" 

82 " python -m jsonclark --sort-keys --comments config.jsonc", 

83 formatter_class=argparse.RawDescriptionHelpFormatter, 

84 ) 

85 

86 parser.add_argument( 

87 "file", 

88 nargs="?", 

89 help="Input file (default: stdin)", 

90 ) 

91 

92 parser.add_argument( 

93 "--indent", 

94 type=int, 

95 default=2, 

96 help="Number of spaces for indentation (default: 2)", 

97 ) 

98 

99 parser.add_argument( 

100 "--sort-keys", 

101 action="store_true", 

102 help="Sort dictionary keys in output", 

103 ) 

104 

105 parser.add_argument( 

106 "--comments", 

107 action="store_true", 

108 help="Show extracted comments in output", 

109 ) 

110 

111 parser.add_argument( 

112 "--version", 

113 action="version", 

114 version="%(prog)s 0.1.0", 

115 ) 

116 

117 args = parser.parse_args() 

118 

119 try: 

120 # Read input 

121 if args.file: 

122 with open(args.file, "r") as f: 

123 json_text = f.read() 

124 else: 

125 json_text = sys.stdin.read() 

126 

127 # Parse JSON 

128 if args.comments: 

129 obj, comments = loads_comments(json_text) 

130 else: 

131 obj = loads(json_text) 

132 comments = None 

133 

134 # Format output 

135 output = format_json( 

136 obj, 

137 indent=args.indent, 

138 sort_keys=args.sort_keys, 

139 show_comments=args.comments, 

140 comments=comments, 

141 ) 

142 

143 print(output) 

144 

145 except FileNotFoundError as e: 

146 print(f"Error: File not found: {e.filename}", file=sys.stderr) 

147 sys.exit(1) 

148 except Exception as e: 

149 print(f"Error: {e}", file=sys.stderr) 

150 sys.exit(1) 

151 

152 

153if __name__ == "__main__": 

154 main()