Skip to content

Commit 9e7ada1

Browse files
style: apply ruff format to src/deadcode/cli.py
1 parent 3b6734d commit 9e7ada1

1 file changed

Lines changed: 85 additions & 24 deletions

File tree

src/deadcode/cli.py

Lines changed: 85 additions & 24 deletions
Original file line numberDiff line numberDiff line change
@@ -18,17 +18,30 @@
1818
err_console = Console(stderr=True)
1919

2020
FORMAT_HELP = "Output format: pretty (default), compact, github, or json"
21-
ALL_CATEGORIES = ["unused_export", "dead_route", "orphaned_css", "unreferenced_component"]
21+
ALL_CATEGORIES = [
22+
"unused_export",
23+
"dead_route",
24+
"orphaned_css",
25+
"unreferenced_component",
26+
]
2227
FORMAT_CHOICES = click.Choice(["pretty", "compact", "github", "json"])
2328

2429

2530
@click.group()
2631
@click.option("--project", "-p", default=".", help="Project directory to scan")
27-
@click.option("--ignore", "-i", multiple=True, help="Additional ignore patterns (gitignore-style)")
28-
@click.option("--include", multiple=True, help="Include only matching files (gitignore-style whitelist)")
32+
@click.option(
33+
"--ignore", "-i", multiple=True, help="Additional ignore patterns (gitignore-style)"
34+
)
35+
@click.option(
36+
"--include",
37+
multiple=True,
38+
help="Include only matching files (gitignore-style whitelist)",
39+
)
2940
@click.version_option(__version__, prog_name="deadcode")
3041
@click.pass_context
31-
def cli(ctx: click.Context, project: str, ignore: tuple[str, ...], include: tuple[str, ...]) -> None:
42+
def cli(
43+
ctx: click.Context, project: str, ignore: tuple[str, ...], include: tuple[str, ...]
44+
) -> None:
3245
"""DeadCode — Find and remove dead code in TS/React/Next.js projects.
3346
3447
Scans for unused exports, dead routes, orphaned CSS classes,
@@ -67,9 +80,17 @@ def _get_fail_threshold(ctx: click.Context) -> int:
6780

6881

6982
@cli.command()
70-
@click.option("--json-output", "-j", is_flag=True, help="Alias for --format=json (deprecated)")
83+
@click.option(
84+
"--json-output", "-j", is_flag=True, help="Alias for --format=json (deprecated)"
85+
)
7186
@click.option("--format", type=FORMAT_CHOICES, default="pretty", help=FORMAT_HELP)
72-
@click.option("--category", "-c", type=click.Choice(ALL_CATEGORIES), default=None, help="Filter by category")
87+
@click.option(
88+
"--category",
89+
"-c",
90+
type=click.Choice(ALL_CATEGORIES),
91+
default=None,
92+
help="Filter by category",
93+
)
7394
@click.option(
7495
"--fail",
7596
"fail_threshold",
@@ -94,7 +115,9 @@ def scan(
94115
sys.exit(1)
95116

96117
include_patterns = ctx.obj.get("include")
97-
scanner = DeadCodeScanner(project, ignore_patterns=ignore, include_patterns=include_patterns)
118+
scanner = DeadCodeScanner(
119+
project, ignore_patterns=ignore, include_patterns=include_patterns
120+
)
98121
result = scanner.scan()
99122

100123
# Filter by category
@@ -149,7 +172,9 @@ def scan(
149172
console.print(f"\n::notice::deadcode: {len(findings)} findings")
150173
else:
151174
# Summary
152-
console.print(f"\n[bold]DeadCode Scan[/bold] — {result.files_scanned} files scanned\n")
175+
console.print(
176+
f"\n[bold]DeadCode Scan[/bold] — {result.files_scanned} files scanned\n"
177+
)
153178

154179
if not findings:
155180
console.print("[green]✓ No dead code found![/green]")
@@ -168,7 +193,9 @@ def scan(
168193

169194
for cat, cat_findings in by_category.items():
170195
label = category_labels.get(cat, cat)
171-
console.print(f"\n[bold yellow]{label}[/bold yellow] ({len(cat_findings)})")
196+
console.print(
197+
f"\n[bold yellow]{label}[/bold yellow] ({len(cat_findings)})"
198+
)
172199

173200
table = Table(show_header=True)
174201
table.add_column("File", style="cyan")
@@ -185,26 +212,42 @@ def scan(
185212

186213
# Total
187214
removable = sum(1 for f in findings if f.removable)
188-
console.print(f"\n[bold]Total:[/bold] {len(findings)} findings ({removable} removable)")
215+
console.print(
216+
f"\n[bold]Total:[/bold] {len(findings)} findings ({removable} removable)"
217+
)
189218

190219
if result.errors:
191-
console.print(f"\n[yellow]{len(result.errors)} scan errors (use --json-output to see)[/yellow]")
220+
console.print(
221+
f"\n[yellow]{len(result.errors)} scan errors (use --json-output to see)[/yellow]"
222+
)
192223

193224
# CI fail threshold
194-
effective_threshold = fail_threshold if fail_threshold is not None else _get_fail_threshold(ctx)
225+
effective_threshold = (
226+
fail_threshold if fail_threshold is not None else _get_fail_threshold(ctx)
227+
)
195228
if effective_threshold >= 0 and len(findings) >= effective_threshold:
196229
if effective_format not in ("json", "github"):
197-
console.print(f"\n[red]FAIL: {len(findings)} findings >= threshold {effective_threshold}[/red]")
230+
console.print(
231+
f"\n[red]FAIL: {len(findings)} findings >= threshold {effective_threshold}[/red]"
232+
)
198233
sys.exit(1)
199234

200235

201236
# ── remove ────────────────────────────────────────────────────────────
202237

203238

204239
@cli.command()
205-
@click.option("--dry-run", is_flag=True, help="Preview what would be removed without making changes")
206240
@click.option(
207-
"--category", "-c", type=click.Choice(ALL_CATEGORIES), default=None, help="Only remove findings in this category"
241+
"--dry-run",
242+
is_flag=True,
243+
help="Preview what would be removed without making changes",
244+
)
245+
@click.option(
246+
"--category",
247+
"-c",
248+
type=click.Choice(ALL_CATEGORIES),
249+
default=None,
250+
help="Only remove findings in this category",
208251
)
209252
@click.pass_context
210253
def remove(ctx: click.Context, dry_run: bool, category: str | None) -> None:
@@ -221,14 +264,18 @@ def remove(ctx: click.Context, dry_run: bool, category: str | None) -> None:
221264
sys.exit(1)
222265

223266
if not dry_run:
224-
console.print("[red]WARNING: This will modify files. Use --dry-run first![/red]")
267+
console.print(
268+
"[red]WARNING: This will modify files. Use --dry-run first![/red]"
269+
)
225270
console.print("[dim]Press Ctrl+C to abort. Running in 3 seconds...[/dim]")
226271
import time
227272

228273
time.sleep(3)
229274

230275
include_patterns = ctx.obj.get("include")
231-
scanner = DeadCodeScanner(project, ignore_patterns=ignore, include_patterns=include_patterns)
276+
scanner = DeadCodeScanner(
277+
project, ignore_patterns=ignore, include_patterns=include_patterns
278+
)
232279
result = scanner.scan()
233280

234281
findings = result.findings
@@ -261,7 +308,9 @@ def remove(ctx: click.Context, dry_run: bool, category: str | None) -> None:
261308
continue
262309

263310
try:
264-
lines = filepath.read_text(encoding="utf-8", errors="replace").splitlines(keepends=True)
311+
lines = filepath.read_text(encoding="utf-8", errors="replace").splitlines(
312+
keepends=True
313+
)
265314
except Exception as e:
266315
console.print(f"[red]Error reading {rel_file}: {e}[/red]")
267316
continue
@@ -272,15 +321,19 @@ def remove(ctx: click.Context, dry_run: bool, category: str | None) -> None:
272321
if dry_run:
273322
for line_num in sorted(lines_to_remove):
274323
content = lines[line_num - 1].rstrip() if line_num <= len(lines) else ""
275-
console.print(f"[yellow]WOULD REMOVE[/yellow] {rel_file}:{line_num}{content.strip()[:80]}")
324+
console.print(
325+
f"[yellow]WOULD REMOVE[/yellow] {rel_file}:{line_num}{content.strip()[:80]}"
326+
)
276327
removed_count += len(lines_to_remove)
277328
else:
278329
for line_num in lines_to_remove:
279330
if 0 < line_num <= len(lines):
280331
lines[line_num - 1] = "" # Blank the line (safer than deleting)
281332
filepath.write_text("".join(lines), encoding="utf-8")
282333
removed_count += len(lines_to_remove)
283-
console.print(f"[green]✓[/green] Cleaned {rel_file} ({len(lines_to_remove)} lines)")
334+
console.print(
335+
f"[green]✓[/green] Cleaned {rel_file} ({len(lines_to_remove)} lines)"
336+
)
284337

285338
action = "Would remove" if dry_run else "Removed"
286339
console.print(f"\n[bold]{action}: {removed_count} dead code entries[/bold]")
@@ -296,14 +349,22 @@ def stats(ctx: click.Context) -> None:
296349
project = ctx.obj["project"]
297350
ignore = _merge_config_ignore(ctx)
298351
include_patterns = ctx.obj.get("include")
299-
scanner = DeadCodeScanner(project, ignore_patterns=ignore, include_patterns=include_patterns)
352+
scanner = DeadCodeScanner(
353+
project, ignore_patterns=ignore, include_patterns=include_patterns
354+
)
300355
result = scanner.scan()
301356

302357
console.print(f"Files scanned: [bold]{result.files_scanned}[/bold]")
303-
console.print(f"Unused exports: [bold yellow]{len(result.unused_exports)}[/bold yellow]")
358+
console.print(
359+
f"Unused exports: [bold yellow]{len(result.unused_exports)}[/bold yellow]"
360+
)
304361
console.print(f"Dead routes: [bold red]{len(result.dead_routes)}[/bold red]")
305-
console.print(f"Orphaned CSS: [bold magenta]{len(result.orphaned_css)}[/bold magenta]")
306-
console.print(f"Unreferenced components: [bold cyan]{len(result.unreferenced_components)}[/bold cyan]")
362+
console.print(
363+
f"Orphaned CSS: [bold magenta]{len(result.orphaned_css)}[/bold magenta]"
364+
)
365+
console.print(
366+
f"Unreferenced components: [bold cyan]{len(result.unreferenced_components)}[/bold cyan]"
367+
)
307368
console.print(f"Total findings: [bold]{len(result.findings)}[/bold]")
308369

309370
if result.errors:

0 commit comments

Comments
 (0)