Coverage for lintro / cli_utils / commands / format.py: 96%

56 statements  

« prev     ^ index     » next       coverage.py v7.13.0, created at 2026-04-03 18:53 +0000

1"""Format command implementation using simplified Loguru-based approach.""" 

2 

3import click 

4from click.testing import CliRunner 

5 

6from lintro.utils.tool_executor import run_lint_tools_simple 

7 

8# Constants 

9DEFAULT_PATHS: list[str] = ["."] 

10DEFAULT_EXIT_CODE: int = 0 

11DEFAULT_ACTION: str = "fmt" 

12 

13 

14@click.command() 

15@click.pass_context 

16@click.argument("paths", nargs=-1, type=click.Path(exists=True)) 

17@click.option( 

18 "--tools", 

19 default=None, 

20 help="Comma-separated list of tools to run (e.g., ruff,black) or 'all'.", 

21) 

22@click.option( 

23 "--tool-options", 

24 default=None, 

25 help="Tool-specific options in format tool:option=value,tool2:option=value.", 

26) 

27@click.option( 

28 "--exclude", 

29 default=None, 

30 help="Comma-separated patterns to exclude from formatting.", 

31) 

32@click.option( 

33 "--include-venv", 

34 is_flag=True, 

35 default=False, 

36 help="Include virtual environment directories in formatting.", 

37) 

38@click.option( 

39 "--group-by", 

40 default="auto", 

41 type=click.Choice(["file", "code", "none", "auto"]), 

42 help="How to group issues in output.", 

43) 

44@click.option( 

45 "--output", 

46 type=click.Path(), 

47 help="Output file path for writing results.", 

48) 

49@click.option( 

50 "--output-format", 

51 default="grid", 

52 type=click.Choice(["plain", "grid", "markdown", "html", "json", "csv", "github"]), 

53 help="Output format for displaying results.", 

54) 

55@click.option( 

56 "--verbose", 

57 "-v", 

58 is_flag=True, 

59 default=False, 

60 help="Enable verbose output with debug information.", 

61) 

62@click.option( 

63 "--no-log", 

64 is_flag=True, 

65 default=False, 

66 help="Disable logging to file.", 

67) 

68@click.option( 

69 "--raw-output", 

70 is_flag=True, 

71 default=False, 

72 help="Show raw tool output instead of formatted output.", 

73) 

74@click.option( 

75 "--stream/--no-stream", 

76 default=False, 

77 help="Stream tool output in real-time (useful for long operations)", 

78) 

79@click.option( 

80 "--debug", 

81 is_flag=True, 

82 help="Enable debug output on console", 

83) 

84@click.option( 

85 "--auto-install", 

86 is_flag=True, 

87 help="Auto-install Node.js dependencies if node_modules is missing", 

88) 

89@click.option( 

90 "--yes", 

91 "-y", 

92 is_flag=True, 

93 help="Skip confirmation prompt and proceed immediately", 

94) 

95def format_command( 

96 ctx: click.Context, 

97 paths: tuple[str, ...], 

98 tools: str | None, 

99 tool_options: str | None, 

100 exclude: str | None, 

101 include_venv: bool, 

102 output: str | None, 

103 group_by: str, 

104 output_format: str, 

105 verbose: bool, 

106 no_log: bool, 

107 raw_output: bool, 

108 stream: bool, 

109 debug: bool, 

110 auto_install: bool, 

111 yes: bool, 

112) -> None: 

113 """Format code using configured formatting tools. 

114 

115 Runs code formatting tools on the specified paths to automatically fix style issues. 

116 Uses simplified Loguru-based logging for clean output and proper file logging. 

117 

118 Args: 

119 ctx: click.Context: Click context object for command execution. 

120 paths: tuple[str, ...]: 

121 Paths to format (defaults to current directory if none provided). 

122 tools: str | None: Specific tools to run, or 'all' for all available tools. 

123 tool_options: str | None: Tool-specific configuration options. 

124 exclude: str | None: Patterns to exclude from formatting. 

125 include_venv: bool: Whether to include virtual environment directories. 

126 output: str | None: Path to output file for results. 

127 group_by: str: How to group issues in the output display. 

128 output_format: str: Format for displaying results. 

129 verbose: bool: Enable detailed debug output. 

130 no_log: bool: Whether to disable logging to file. 

131 raw_output: bool: Show raw tool output instead of formatted output. 

132 stream: bool: Whether to stream tool output in real-time. 

133 debug: bool: Whether to enable debug output on console. 

134 auto_install: bool: Whether to auto-install Node.js deps if missing. 

135 yes: bool: Skip confirmation prompt and proceed immediately. 

136 """ 

137 # Default to current directory if no paths provided 

138 normalized_paths: list[str] = list(paths) if paths else list(DEFAULT_PATHS) 

139 

140 # Run with simplified approach 

141 exit_code: int = run_lint_tools_simple( 

142 action=DEFAULT_ACTION, 

143 paths=normalized_paths, 

144 tools=tools, 

145 tool_options=tool_options, 

146 exclude=exclude, 

147 include_venv=include_venv, 

148 group_by=group_by, 

149 output_format=output_format, 

150 verbose=verbose, 

151 raw_output=raw_output, 

152 output_file=output, 

153 debug=debug, 

154 stream=stream, 

155 no_log=no_log, 

156 auto_install=auto_install, 

157 yes=yes, 

158 ) 

159 

160 # Exit with code from tool execution 

161 # For fmt action, exit_code is 1 only if there were execution errors 

162 # (not if issues were found and fixed - that's success) 

163 ctx.exit(exit_code) 

164 

165 

166def format_code( 

167 paths: list[str] | None = None, 

168 tools: str | None = None, 

169 tool_options: str | None = None, 

170 exclude: str | None = None, 

171 include_venv: bool = False, 

172 group_by: str = "auto", 

173 output_format: str = "grid", 

174 verbose: bool = False, 

175 auto_install: bool = False, 

176 yes: bool = False, 

177) -> None: 

178 """Programmatic format function. 

179 

180 Args: 

181 paths: list[str] | None: List of file/directory paths to format. 

182 tools: str | None: Comma-separated list of tool names to run. 

183 tool_options: str | None: Tool-specific configuration options. 

184 exclude: str | None: Comma-separated patterns of files/dirs to exclude. 

185 include_venv: bool: Whether to include virtual environment directories. 

186 group_by: str: How to group issues in output (tool, file, etc). 

187 output_format: str: Format for displaying results (table, json, etc). 

188 verbose: bool: Whether to show verbose output during execution. 

189 auto_install: bool: Whether to auto-install Node.js deps if missing. 

190 yes: bool: Skip confirmation prompt and proceed immediately. 

191 

192 Returns: 

193 None: This function does not return a value. 

194 

195 Raises: 

196 RuntimeError: If format fails for any reason. 

197 """ 

198 args: list[str] = [] 

199 if paths: 

200 args.extend(paths) 

201 if tools: 

202 args.extend(["--tools", tools]) 

203 if tool_options: 

204 args.extend(["--tool-options", tool_options]) 

205 if exclude: 

206 args.extend(["--exclude", exclude]) 

207 if include_venv: 

208 args.append("--include-venv") 

209 if group_by: 

210 args.extend(["--group-by", group_by]) 

211 if output_format: 

212 args.extend(["--output-format", output_format]) 

213 if verbose: 

214 args.append("--verbose") 

215 if auto_install: 

216 args.append("--auto-install") 

217 if yes: 

218 args.append("--yes") 

219 

220 runner = CliRunner() 

221 result = runner.invoke(format_command, args) 

222 if result.exit_code != DEFAULT_EXIT_CODE: 

223 raise RuntimeError(f"Format failed: {result.output}") 

224 return None 

225 

226 

227# Legacy alias for backward compatibility 

228format_code_legacy = format_code 

229 

230# Export the Click command as the main interface 

231__all__ = ["format_command", "format_code", "format_code_legacy"]