thailint 0.15.8__py3-none-any.whl → 0.16.0__py3-none-any.whl

This diff represents the content of publicly available package versions that have been released to one of the supported registries. The information contained in this diff is provided for informational purposes only and reflects changes between package versions as they appear in their respective public registries.
src/cli/config.py CHANGED
@@ -21,22 +21,18 @@ Implementation: Uses Click decorators for command definition, supports multiple
21
21
  validates configuration changes before saving, uses template file for init-config generation
22
22
  """
23
23
 
24
- import logging
25
24
  import sys
26
25
  from pathlib import Path
27
26
 
28
27
  import click
29
28
  import yaml
29
+ from loguru import logger
30
30
 
31
31
  from src.config import ConfigError, save_config, validate_config
32
32
 
33
33
  from .config_merge import perform_merge
34
34
  from .main import cli
35
35
 
36
- # Configure module logger
37
- logger = logging.getLogger(__name__)
38
-
39
-
40
36
  # =============================================================================
41
37
  # Config Command Group
42
38
  # =============================================================================
@@ -177,8 +173,7 @@ def _save_and_report_success(
177
173
  """Save configuration and report success."""
178
174
  save_config(cfg, config_path)
179
175
  click.echo(f"Set {key} = {value}")
180
- if verbose:
181
- logger.info(f"Configuration updated: {key}={value}")
176
+ logger.debug(f"Configuration updated: {key}={value}")
182
177
 
183
178
 
184
179
  @config.command("set")
@@ -256,8 +251,7 @@ def config_reset(ctx: click.Context, yes: bool) -> None:
256
251
  save_config(DEFAULT_CONFIG.copy(), config_path)
257
252
  click.echo("Configuration reset to defaults")
258
253
 
259
- if ctx.obj.get("verbose"):
260
- logger.info("Configuration reset to defaults")
254
+ logger.debug("Configuration reset to defaults")
261
255
  except ConfigError as e:
262
256
  click.echo(f"Error resetting configuration: {e}", err=True)
263
257
  sys.exit(1)
@@ -462,7 +456,6 @@ def hello(ctx: click.Context, name: str, uppercase: bool) -> None:
462
456
  thai-lint hello --name Bob --uppercase
463
457
  """
464
458
  config = ctx.obj["config"]
465
- verbose = ctx.obj.get("verbose", False)
466
459
 
467
460
  # Get greeting from config or use default
468
461
  greeting_template = config.get("greeting", "Hello")
@@ -476,5 +469,4 @@ def hello(ctx: click.Context, name: str, uppercase: bool) -> None:
476
469
  # Output greeting
477
470
  click.echo(message)
478
471
 
479
- if verbose:
480
- logger.info(f"Greeted {name} with template '{greeting_template}'")
472
+ logger.debug(f"Greeted {name} with template '{greeting_template}'")
@@ -6,8 +6,9 @@ Scope: Export and registration of all linter CLI commands (nesting, srp, dry, ma
6
6
  Overview: Package initialization that imports all linter command modules to trigger their registration
7
7
  with the main CLI group via Click decorators. Each submodule defines commands using @cli.command()
8
8
  decorators that automatically register with the CLI when imported. Organized by logical grouping:
9
- structure_quality (nesting, srp), code_smells (dry, magic-numbers), code_patterns (print-statements,
9
+ structure_quality (nesting, srp), code_smells (dry, magic-numbers), code_patterns (improper-logging,
10
10
  method-property, stateless-class), structure (file-placement, pipeline), documentation (file-header).
11
+ Note: print-statements is a deprecated alias for improper-logging.
11
12
 
12
13
  Dependencies: Click for CLI framework, src.cli.main for CLI group, individual linter modules
13
14
 
@@ -34,6 +35,7 @@ from src.cli.linters import ( # noqa: F401
34
35
 
35
36
  # Re-export command functions for testing and reference
36
37
  from src.cli.linters.code_patterns import (
38
+ improper_logging,
37
39
  method_property,
38
40
  print_statements,
39
41
  stateless_class,
@@ -52,7 +54,8 @@ __all__ = [
52
54
  "dry",
53
55
  "magic_numbers",
54
56
  # Code pattern commands
55
- "print_statements",
57
+ "improper_logging",
58
+ "print_statements", # deprecated alias for improper_logging
56
59
  "method_property",
57
60
  "stateless_class",
58
61
  # Structure commands
@@ -1,29 +1,31 @@
1
1
  """
2
- Purpose: CLI commands for code pattern linters (print-statements, method-property, stateless-class, lazy-ignores, lbyl)
2
+ Purpose: CLI commands for code pattern linters (improper-logging, method-property, stateless-class, lazy-ignores, lbyl)
3
3
 
4
4
  Scope: Commands that detect code patterns and anti-patterns in Python code
5
5
 
6
- Overview: Provides CLI commands for code pattern linting: print-statements detects print() and
7
- console.log calls that should use proper logging, method-property finds methods that should be
8
- @property decorators, stateless-class detects classes without state that should be module
9
- functions, lazy-ignores detects unjustified linting suppressions, and lbyl detects Look Before
10
- You Leap anti-patterns. Each command supports standard options (config, format, recursive) and
11
- integrates with the orchestrator for execution.
6
+ Overview: Provides CLI commands for code pattern linting: improper-logging detects print() and
7
+ console.log calls that should use proper logging as well as conditional verbose patterns,
8
+ method-property finds methods that should be @property decorators, stateless-class detects
9
+ classes without state that should be module functions, lazy-ignores detects unjustified linting
10
+ suppressions, and lbyl detects Look Before You Leap anti-patterns. Each command supports
11
+ standard options (config, format, recursive) and integrates with the orchestrator for execution.
12
+ Note: print-statements is a deprecated alias for improper-logging.
12
13
 
13
14
  Dependencies: click for CLI framework, src.cli.main for CLI group, src.cli.utils for shared utilities
14
15
 
15
- Exports: print_statements, method_property, stateless_class, lazy_ignores, lbyl commands
16
+ Exports: improper_logging, print_statements (alias), method_property, stateless_class, lazy_ignores, lbyl commands
16
17
 
17
18
  Interfaces: Click CLI commands registered to main CLI group
18
19
 
19
20
  Implementation: Click decorators for command definition, orchestrator-based linting execution
20
21
  """
21
22
 
22
- import logging
23
23
  import sys
24
24
  from pathlib import Path
25
25
  from typing import TYPE_CHECKING, NoReturn
26
26
 
27
+ from loguru import logger
28
+
27
29
  from src.cli.linters.shared import ExecuteParams, create_linter_command
28
30
  from src.cli.utils import execute_linting_on_paths, setup_base_orchestrator, validate_paths_exist
29
31
  from src.core.cli_utils import format_violations
@@ -32,53 +34,59 @@ from src.core.types import Violation
32
34
  if TYPE_CHECKING:
33
35
  from src.orchestrator.core import Orchestrator
34
36
 
35
- # Configure module logger
36
- logger = logging.getLogger(__name__)
37
-
38
37
 
39
38
  # =============================================================================
40
- # Print Statements Command
39
+ # Improper Logging Command (formerly print-statements)
41
40
  # =============================================================================
42
41
 
43
42
 
44
- def _setup_print_statements_orchestrator(
43
+ def _setup_improper_logging_orchestrator(
45
44
  path_objs: list[Path], config_file: str | None, verbose: bool, project_root: Path | None = None
46
45
  ) -> "Orchestrator":
47
- """Set up orchestrator for print-statements command."""
46
+ """Set up orchestrator for improper-logging command."""
48
47
  return setup_base_orchestrator(path_objs, config_file, verbose, project_root)
49
48
 
50
49
 
51
- def _run_print_statements_lint(
50
+ def _run_improper_logging_lint(
52
51
  orchestrator: "Orchestrator", path_objs: list[Path], recursive: bool, parallel: bool = False
53
52
  ) -> list[Violation]:
54
- """Execute print-statements lint on files or directories."""
53
+ """Execute improper-logging lint on files or directories."""
55
54
  all_violations = execute_linting_on_paths(orchestrator, path_objs, recursive, parallel)
56
- return [v for v in all_violations if "print-statement" in v.rule_id]
55
+ return [v for v in all_violations if v.rule_id.startswith("improper-logging.")]
57
56
 
58
57
 
59
- def _execute_print_statements_lint(params: ExecuteParams) -> NoReturn:
60
- """Execute print-statements lint."""
58
+ def _execute_improper_logging_lint(params: ExecuteParams) -> NoReturn:
59
+ """Execute improper-logging lint."""
61
60
  validate_paths_exist(params.path_objs)
62
- orchestrator = _setup_print_statements_orchestrator(
61
+ orchestrator = _setup_improper_logging_orchestrator(
63
62
  params.path_objs, params.config_file, params.verbose, params.project_root
64
63
  )
65
- print_statements_violations = _run_print_statements_lint(
64
+ improper_logging_violations = _run_improper_logging_lint(
66
65
  orchestrator, params.path_objs, params.recursive, params.parallel
67
66
  )
68
67
 
69
- if params.verbose:
70
- logger.info(f"Found {len(print_statements_violations)} print statement violation(s)")
68
+ logger.debug(f"Found {len(improper_logging_violations)} improper logging violation(s)")
71
69
 
72
- format_violations(print_statements_violations, params.format)
73
- sys.exit(1 if print_statements_violations else 0)
70
+ format_violations(improper_logging_violations, params.format)
71
+ sys.exit(1 if improper_logging_violations else 0)
74
72
 
75
73
 
74
+ # Primary command
75
+ improper_logging = create_linter_command(
76
+ "improper-logging",
77
+ _execute_improper_logging_lint,
78
+ "Check for improper logging patterns in code.",
79
+ "Detects print()/console statements and conditional verbose patterns that should\n"
80
+ " be replaced with proper logging configuration.",
81
+ )
82
+
83
+ # Backward-compatible alias (deprecated)
76
84
  print_statements = create_linter_command(
77
85
  "print-statements",
78
- _execute_print_statements_lint,
79
- "Check for print/console statements in code.",
80
- "Detects print() calls in Python and console.log/warn/error/debug/info calls\n"
81
- " in TypeScript/JavaScript that should be replaced with proper logging.",
86
+ _execute_improper_logging_lint, # Same executor as improper-logging
87
+ "Alias for improper-logging (deprecated).",
88
+ "DEPRECATED: Use 'improper-logging' instead. Detects print() calls in Python and\n"
89
+ " console.log/warn/error/debug/info calls in TypeScript/JavaScript.",
82
90
  )
83
91
 
84
92
 
@@ -112,8 +120,7 @@ def _execute_method_property_lint(params: ExecuteParams) -> NoReturn:
112
120
  orchestrator, params.path_objs, params.recursive, params.parallel
113
121
  )
114
122
 
115
- if params.verbose:
116
- logger.info(f"Found {len(method_property_violations)} method-property violation(s)")
123
+ logger.debug(f"Found {len(method_property_violations)} method-property violation(s)")
117
124
 
118
125
  format_violations(method_property_violations, params.format)
119
126
  sys.exit(1 if method_property_violations else 0)
@@ -159,8 +166,7 @@ def _execute_stateless_class_lint(params: ExecuteParams) -> NoReturn:
159
166
  orchestrator, params.path_objs, params.recursive, params.parallel
160
167
  )
161
168
 
162
- if params.verbose:
163
- logger.info(f"Found {len(stateless_class_violations)} stateless-class violation(s)")
169
+ logger.debug(f"Found {len(stateless_class_violations)} stateless-class violation(s)")
164
170
 
165
171
  format_violations(stateless_class_violations, params.format)
166
172
  sys.exit(1 if stateless_class_violations else 0)
@@ -206,8 +212,7 @@ def _execute_lazy_ignores_lint(params: ExecuteParams) -> NoReturn:
206
212
  orchestrator, params.path_objs, params.recursive, params.parallel
207
213
  )
208
214
 
209
- if params.verbose:
210
- logger.info(f"Found {len(lazy_ignores_violations)} lazy-ignores violation(s)")
215
+ logger.debug(f"Found {len(lazy_ignores_violations)} lazy-ignores violation(s)")
211
216
 
212
217
  format_violations(lazy_ignores_violations, params.format)
213
218
  sys.exit(1 if lazy_ignores_violations else 0)
@@ -253,8 +258,7 @@ def _execute_lbyl_lint(params: ExecuteParams) -> NoReturn:
253
258
  orchestrator, params.path_objs, params.recursive, params.parallel
254
259
  )
255
260
 
256
- if params.verbose:
257
- logger.info(f"Found {len(lbyl_violations)} LBYL violation(s)")
261
+ logger.debug(f"Found {len(lbyl_violations)} LBYL violation(s)")
258
262
 
259
263
  format_violations(lbyl_violations, params.format)
260
264
  sys.exit(1 if lbyl_violations else 0)
@@ -23,13 +23,13 @@ Suppressions:
23
23
  many parameters by framework design (dry command has 8 params for extra options)
24
24
  """
25
25
 
26
- import logging
27
26
  import sys
28
27
  from pathlib import Path
29
28
  from typing import TYPE_CHECKING, Any, NoReturn
30
29
 
31
30
  import click
32
31
  import yaml
32
+ from loguru import logger
33
33
 
34
34
  from src.cli.linters.shared import (
35
35
  ExecuteParams,
@@ -53,10 +53,6 @@ from src.core.types import Violation
53
53
  if TYPE_CHECKING:
54
54
  from src.orchestrator.core import Orchestrator
55
55
 
56
- # Configure module logger
57
- logger = logging.getLogger(__name__)
58
-
59
-
60
56
  # =============================================================================
61
57
  # DRY Command (custom options - cannot use create_linter_command)
62
58
  # =============================================================================
@@ -87,8 +83,7 @@ def _load_dry_config_file(orchestrator: "Orchestrator", config_file: str, verbos
87
83
  except KeyError:
88
84
  return # No DRY config in file
89
85
  orchestrator.config.update({"dry": dry_config})
90
- if verbose:
91
- logger.info(f"Loaded DRY config from {config_file}")
86
+ logger.debug(f"Loaded DRY config from {config_file}")
92
87
 
93
88
 
94
89
  def _apply_dry_config_override(
@@ -108,10 +103,9 @@ def _clear_dry_cache(orchestrator: "Orchestrator", verbose: bool) -> None:
108
103
 
109
104
  if cache_path.exists():
110
105
  cache_path.unlink()
111
- if verbose:
112
- logger.info(f"Cleared cache: {cache_path}")
113
- elif verbose:
114
- logger.info("Cache file does not exist, nothing to clear")
106
+ logger.debug(f"Cleared cache: {cache_path}")
107
+ else:
108
+ logger.debug("Cache file does not exist, nothing to clear")
115
109
 
116
110
 
117
111
  def _run_dry_lint(
@@ -242,8 +236,7 @@ def _execute_dry_lint( # pylint: disable=too-many-arguments,too-many-positional
242
236
 
243
237
  dry_violations = _run_dry_lint(orchestrator, path_objs, recursive, parallel)
244
238
 
245
- if verbose:
246
- logger.info(f"Found {len(dry_violations)} DRY violation(s)")
239
+ logger.debug(f"Found {len(dry_violations)} DRY violation(s)")
247
240
 
248
241
  format_violations(dry_violations, format)
249
242
  sys.exit(1 if dry_violations else 0)
@@ -279,8 +272,7 @@ def _execute_magic_numbers_lint(params: ExecuteParams) -> NoReturn:
279
272
  orchestrator, params.path_objs, params.recursive, params.parallel
280
273
  )
281
274
 
282
- if params.verbose:
283
- logger.info(f"Found {len(magic_numbers_violations)} magic number violation(s)")
275
+ logger.debug(f"Found {len(magic_numbers_violations)} magic number violation(s)")
284
276
 
285
277
  format_violations(magic_numbers_violations, params.format)
286
278
  sys.exit(1 if magic_numbers_violations else 0)
@@ -325,8 +317,7 @@ def _execute_stringly_typed_lint(params: ExecuteParams) -> NoReturn:
325
317
  orchestrator, params.path_objs, params.recursive, params.parallel
326
318
  )
327
319
 
328
- if params.verbose:
329
- logger.info(f"Found {len(stringly_violations)} stringly-typed violation(s)")
320
+ logger.debug(f"Found {len(stringly_violations)} stringly-typed violation(s)")
330
321
 
331
322
  format_violations(stringly_violations, params.format)
332
323
  sys.exit(1 if stringly_violations else 0)
@@ -18,11 +18,12 @@ Interfaces: Click CLI commands registered to main CLI group
18
18
  Implementation: Click decorators for command definition, orchestrator-based linting execution
19
19
  """
20
20
 
21
- import logging
22
21
  import sys
23
22
  from pathlib import Path
24
23
  from typing import TYPE_CHECKING, NoReturn
25
24
 
25
+ from loguru import logger
26
+
26
27
  from src.cli.linters.shared import ExecuteParams, create_linter_command
27
28
  from src.cli.utils import execute_linting_on_paths, setup_base_orchestrator, validate_paths_exist
28
29
  from src.core.cli_utils import format_violations
@@ -31,9 +32,6 @@ from src.core.types import Violation
31
32
  if TYPE_CHECKING:
32
33
  from src.orchestrator.core import Orchestrator
33
34
 
34
- # Configure module logger
35
- logger = logging.getLogger(__name__)
36
-
37
35
 
38
36
  # =============================================================================
39
37
  # File Header Command
@@ -65,8 +63,7 @@ def _execute_file_header_lint(params: ExecuteParams) -> NoReturn:
65
63
  orchestrator, params.path_objs, params.recursive, params.parallel
66
64
  )
67
65
 
68
- if params.verbose:
69
- logger.info(f"Found {len(file_header_violations)} file header violation(s)")
66
+ logger.debug(f"Found {len(file_header_violations)} file header violation(s)")
70
67
 
71
68
  format_violations(file_header_violations, params.format)
72
69
  sys.exit(1 if file_header_violations else 0)
@@ -24,12 +24,12 @@ Suppressions:
24
24
  --rule option for 6 total parameters - framework design requirement for CLI extensibility.
25
25
  """
26
26
 
27
- import logging
28
27
  import sys
29
28
  from pathlib import Path
30
29
  from typing import TYPE_CHECKING, NoReturn
31
30
 
32
31
  import click
32
+ from loguru import logger
33
33
 
34
34
  from src.cli.linters.shared import (
35
35
  ExecuteParams,
@@ -46,9 +46,6 @@ from src.core.types import Violation
46
46
  if TYPE_CHECKING:
47
47
  from src.orchestrator.core import Orchestrator
48
48
 
49
- # Configure module logger
50
- logger = logging.getLogger(__name__)
51
-
52
49
 
53
50
  # =============================================================================
54
51
  # String Concat Loop Command
@@ -88,8 +85,7 @@ def _execute_string_concat_lint(params: ExecuteParams) -> NoReturn:
88
85
  orchestrator, params.path_objs, params.recursive, params.parallel
89
86
  )
90
87
 
91
- if params.verbose:
92
- logger.info(f"Found {len(violations)} string-concat-loop violation(s)")
88
+ logger.debug(f"Found {len(violations)} string-concat-loop violation(s)")
93
89
 
94
90
  format_violations(violations, params.format)
95
91
  sys.exit(1 if violations else 0)
@@ -124,8 +120,7 @@ def _execute_regex_in_loop_lint(params: ExecuteParams) -> NoReturn:
124
120
  orchestrator, params.path_objs, params.recursive, params.parallel
125
121
  )
126
122
 
127
- if params.verbose:
128
- logger.info(f"Found {len(violations)} regex-in-loop violation(s)")
123
+ logger.debug(f"Found {len(violations)} regex-in-loop violation(s)")
129
124
 
130
125
  format_violations(violations, params.format)
131
126
  sys.exit(1 if violations else 0)
@@ -207,8 +202,7 @@ def _execute_perf_lint(params: ExecuteParams, rule: str | None) -> NoReturn:
207
202
  orchestrator, params.path_objs, params.recursive, rule, params.parallel
208
203
  )
209
204
 
210
- if params.verbose:
211
- logger.info(f"Found {len(violations)} performance violation(s)")
205
+ logger.debug(f"Found {len(violations)} performance violation(s)")
212
206
 
213
207
  format_violations(violations, params.format)
214
208
  sys.exit(1 if violations else 0)
src/cli/linters/shared.py CHANGED
@@ -27,12 +27,12 @@ Suppressions:
27
27
  by Click framework design (ctx, paths, config_file, format, recursive, parallel = 6 params)
28
28
  """
29
29
 
30
- import logging
31
30
  from dataclasses import dataclass
32
31
  from pathlib import Path
33
32
  from typing import TYPE_CHECKING, Any
34
33
 
35
34
  import click
35
+ from loguru import logger
36
36
 
37
37
  from src.cli.utils import (
38
38
  format_option,
@@ -185,10 +185,6 @@ def run_linter_command(
185
185
  handle_linting_error(e, params.verbose)
186
186
 
187
187
 
188
- # Configure module logger
189
- logger = logging.getLogger(__name__)
190
-
191
-
192
188
  def ensure_config_section(orchestrator: "Orchestrator", section: str) -> dict[str, Any]:
193
189
  """Ensure a config section exists and return it.
194
190
 
@@ -219,8 +215,7 @@ def set_config_value(config: dict[str, Any], key: str, value: Any, verbose: bool
219
215
  if value is None:
220
216
  return
221
217
  config[key] = value
222
- if verbose:
223
- logger.debug(f"Overriding {key} to {value}")
218
+ logger.debug(f"Overriding {key} to {value}")
224
219
 
225
220
 
226
221
  def filter_violations_by_prefix(violations: list[Violation], prefix: str) -> list[Violation]:
@@ -25,12 +25,12 @@ Suppressions:
25
25
  """
26
26
 
27
27
  import json
28
- import logging
29
28
  import sys
30
29
  from pathlib import Path
31
30
  from typing import TYPE_CHECKING, Any, NoReturn
32
31
 
33
32
  import click
33
+ from loguru import logger
34
34
 
35
35
  from src.cli.linters.shared import (
36
36
  ensure_config_section,
@@ -54,10 +54,6 @@ from src.core.types import Violation
54
54
  if TYPE_CHECKING:
55
55
  from src.orchestrator.core import Orchestrator
56
56
 
57
- # Configure module logger
58
- logger = logging.getLogger(__name__)
59
-
60
-
61
57
  # =============================================================================
62
58
  # File Placement Command
63
59
  # =============================================================================
@@ -93,8 +89,7 @@ def _apply_inline_rules(orchestrator: "Orchestrator", rules: str, verbose: bool)
93
89
  """Parse and apply inline JSON rules."""
94
90
  rules_config = _parse_json_rules(rules)
95
91
  orchestrator.config.update(rules_config)
96
- if verbose:
97
- logger.debug(f"Applied inline rules: {rules_config}")
92
+ logger.debug(f"Applied inline rules: {rules_config}")
98
93
 
99
94
 
100
95
  def _parse_json_rules(rules: str) -> dict[str, Any]:
@@ -195,8 +190,7 @@ def _execute_file_placement_lint( # pylint: disable=too-many-arguments,too-many
195
190
  # Filter to only file-placement violations
196
191
  violations = [v for v in all_violations if v.rule_id.startswith("file-placement")]
197
192
 
198
- if verbose:
199
- logger.info(f"Found {len(violations)} violation(s)")
193
+ logger.debug(f"Found {len(violations)} violation(s)")
200
194
 
201
195
  format_violations(violations, format)
202
196
  sys.exit(1 if violations else 0)
@@ -320,8 +314,7 @@ def _execute_pipeline_lint( # pylint: disable=too-many-arguments,too-many-posit
320
314
  _apply_pipeline_config_override(orchestrator, min_continues, verbose)
321
315
  pipeline_violations = _run_pipeline_lint(orchestrator, path_objs, recursive, parallel)
322
316
 
323
- if verbose:
324
- logger.info(f"Found {len(pipeline_violations)} collection-pipeline violation(s)")
317
+ logger.debug(f"Found {len(pipeline_violations)} collection-pipeline violation(s)")
325
318
 
326
319
  format_violations(pipeline_violations, format)
327
320
  sys.exit(1 if pipeline_violations else 0)
@@ -24,13 +24,13 @@ Suppressions:
24
24
  - too-many-arguments,too-many-positional-arguments: Click commands require many parameters by framework design
25
25
  """
26
26
 
27
- import logging
28
27
  import sys
29
28
  from contextlib import suppress
30
29
  from pathlib import Path
31
30
  from typing import TYPE_CHECKING, NoReturn
32
31
 
33
32
  import click
33
+ from loguru import logger
34
34
 
35
35
  from src.cli.linters.shared import (
36
36
  ensure_config_section,
@@ -52,10 +52,6 @@ from src.core.types import Violation
52
52
  if TYPE_CHECKING:
53
53
  from src.orchestrator.core import Orchestrator
54
54
 
55
- # Configure module logger
56
- logger = logging.getLogger(__name__)
57
-
58
-
59
55
  # =============================================================================
60
56
  # Nesting Command
61
57
  # =============================================================================
@@ -79,8 +75,7 @@ def _apply_nesting_config_override(
79
75
  nesting_config["max_nesting_depth"] = max_depth
80
76
  _apply_nesting_to_languages(nesting_config, max_depth)
81
77
 
82
- if verbose:
83
- logger.debug(f"Overriding max_nesting_depth to {max_depth}")
78
+ logger.debug(f"Overriding max_nesting_depth to {max_depth}")
84
79
 
85
80
 
86
81
  def _apply_nesting_to_languages(nesting_config: dict, max_depth: int) -> None:
@@ -189,8 +184,7 @@ def _execute_nesting_lint( # pylint: disable=too-many-arguments,too-many-positi
189
184
  _apply_nesting_config_override(orchestrator, max_depth, verbose)
190
185
  nesting_violations = _run_nesting_lint(orchestrator, path_objs, recursive, parallel)
191
186
 
192
- if verbose:
193
- logger.info(f"Found {len(nesting_violations)} nesting violation(s)")
187
+ logger.debug(f"Found {len(nesting_violations)} nesting violation(s)")
194
188
 
195
189
  format_violations(nesting_violations, format)
196
190
  sys.exit(1 if nesting_violations else 0)
@@ -321,8 +315,7 @@ def _execute_srp_lint( # pylint: disable=too-many-arguments,too-many-positional
321
315
  _apply_srp_config_override(orchestrator, max_methods, max_loc, verbose)
322
316
  srp_violations = _run_srp_lint(orchestrator, path_objs, recursive, parallel)
323
317
 
324
- if verbose:
325
- logger.info(f"Found {len(srp_violations)} SRP violation(s)")
318
+ logger.debug(f"Found {len(srp_violations)} SRP violation(s)")
326
319
 
327
320
  format_violations(srp_violations, format)
328
321
  sys.exit(1 if srp_violations else 0)
src/cli/main.py CHANGED
@@ -21,32 +21,29 @@ Implementation: Uses Click decorators for group definition, stores parsed option
21
21
  in test environments.
22
22
  """
23
23
 
24
- import logging
25
24
  import sys
26
25
  from pathlib import Path
27
26
 
28
27
  import click
28
+ from loguru import logger
29
29
 
30
30
  from src import __version__
31
31
  from src.config import ConfigError, load_config
32
32
 
33
- # Configure module logger
34
- logger = logging.getLogger(__name__)
35
-
36
33
 
37
34
  def setup_logging(verbose: bool = False) -> None:
38
- """Configure logging for the CLI application.
35
+ """Configure loguru for the CLI application.
39
36
 
40
37
  Args:
41
- verbose: Enable DEBUG level logging if True, INFO otherwise.
38
+ verbose: Enable DEBUG level logging if True, WARNING otherwise.
42
39
  """
43
- level = logging.DEBUG if verbose else logging.INFO
44
-
45
- logging.basicConfig(
40
+ logger.remove() # Remove default handler
41
+ level = "DEBUG" if verbose else "WARNING"
42
+ logger.add(
43
+ sys.stderr,
46
44
  level=level,
47
- format="%(asctime)s | %(levelname)-8s | %(message)s",
48
- datefmt="%Y-%m-%d %H:%M:%S",
49
- stream=sys.stdout,
45
+ format="<green>{time:YYYY-MM-DD HH:mm:ss}</green> | <level>{level:<8}</level> | <level>{message}</level>",
46
+ colorize=True,
50
47
  )
51
48
 
52
49