Skip to content
Merged
Show file tree
Hide file tree
Changes from all commits
Commits
File filter

Filter by extension

Filter by extension

Conversations
Failed to load comments.
Loading
Jump to
Jump to file
Failed to load files.
Loading
Diff view
Diff view
8 changes: 4 additions & 4 deletions src/sifty/cli/app.py
Original file line number Diff line number Diff line change
Expand Up @@ -335,7 +335,7 @@ def checkup_cmd() -> None:
console.print(table)
issues = sum(1 for f in findings if f.severity != "ok")
if issues:
console.print(f"[bold]{issues}[/bold] item(s) worth a look - checkup never changes anything itself.")
console.print(f"[bold]{issues:,}[/bold] item(s) worth a look - checkup never changes anything itself.")
else:
success("All clear - nothing needs attention.")

Expand Down Expand Up @@ -444,16 +444,16 @@ def undo_cmd(
console.print("Nothing to undo - no restorable items in history.")
return
if not confirm(
f"Restore {run.restorable} item(s) from the {run.action} clean at {run.ts}?",
f"Restore {run.restorable:,} item(s) from the {run.action} clean at {run.ts}?",
assume_yes=yes,
):
warn("Cancelled.")
return
with console.status("Restoring from the Recycle Bin…"):
restored, failed = undo.undo(run.id)
success(f"Restored {restored} item(s).")
success(f"Restored {restored:,} item(s).")
if failed:
warn(f"{failed} item(s) could not be restored (see `sifty logs`).")
warn(f"{failed:,} item(s) could not be restored (see `sifty logs`).")


def entrypoint() -> None:
Expand Down
16 changes: 8 additions & 8 deletions src/sifty/cli/commands/apps.py
Original file line number Diff line number Diff line change
Expand Up @@ -37,7 +37,7 @@ def list_cmd(
])
return

table = Table(title=f"Installed apps ({len(items)})")
table = Table(title=f"Installed apps ({len(items):,})")
table.add_column("Name")
table.add_column("Version", style="dim")
table.add_column("Publisher", style="dim")
Expand All @@ -57,7 +57,7 @@ def startup_cmd() -> None:
for e in entries
])
return
table = Table(title=f"Startup programs ({len(entries)})")
table = Table(title=f"Startup programs ({len(entries):,})")
table.add_column("Name")
table.add_column("Origin", style="dim")
table.add_column("Command")
Expand Down Expand Up @@ -86,15 +86,15 @@ def orphans_cmd() -> None:
success("No orphaned uninstall entries found.")
return

table = Table(title=f"Orphaned uninstall entries ({len(entries)})")
table = Table(title=f"Orphaned uninstall entries ({len(entries):,})")
table.add_column("Application")
table.add_column("Reason", style="dim")
table.add_column("Key (hive)", style="dim")
for e in entries:
table.add_row(e.display_name, e.reason, e.hive)
console.print(table)
console.print(
f"\n[dim]{len(entries)} entry/entries with broken uninstallers. "
f"\n[dim]{len(entries):,} entry/entries with broken uninstallers. "
"These can be removed manually via regedit or a registry cleaner.[/dim]"
)

Expand Down Expand Up @@ -139,7 +139,7 @@ def _report_leftovers(name: str) -> None:
if not items:
return
total = sum(i.size_bytes for i in items)
warn(f"{len(items)} leftover item(s) found ({human_size(total)}).")
warn(f"{len(items):,} leftover item(s) found ({human_size(total)}).")
console.print(f'[dim]Review and remove them with: [cyan]sifty apps leftovers "{name}"[/cyan][/dim]')


Expand Down Expand Up @@ -180,11 +180,11 @@ def leftovers_cmd(
if not apply:
console.print("[dim]Dry-run - re-run with --apply to move them to the Recycle Bin.[/dim]")
return
if not confirm(f"Move {len(items)} item(s) ({human_size(total)}) to the Recycle Bin?", assume_yes=yes):
if not confirm(f"Move {len(items):,} item(s) ({human_size(total)}) to the Recycle Bin?", assume_yes=yes):
warn("Cancelled.")
return
result = clean_leftovers(items, dry_run=False)
history.record_clean("leftovers", name, result.bytes_freed, result.items, result.trashed)
success(f"Sent {result.items} item(s) ({human_size(result.bytes_freed)}) to the Recycle Bin.")
success(f"Sent {result.items:,} item(s) ({human_size(result.bytes_freed)}) to the Recycle Bin.")
if result.skipped:
warn(f"{len(result.skipped)} item(s) skipped (in use or protected).")
warn(f"{len(result.skipped):,} item(s) skipped (in use or protected).")
16 changes: 8 additions & 8 deletions src/sifty/cli/commands/cleanup.py
Original file line number Diff line number Diff line change
Expand Up @@ -45,18 +45,18 @@ def duplicates_cmd(
success("No duplicates to remove.")
return
console.print(
f"{len(groups)} duplicate group(s) · [bold]{preview.items}[/bold] redundant copies · "
f"{len(groups):,} duplicate group(s) · [bold]{preview.items:,}[/bold] redundant copies · "
f"[bold]{human_size(preview.bytes_freed)}[/bold] reclaimable."
)
if not apply:
console.print("[dim]Dry-run - re-run with --apply to remove the extra copies.[/dim]")
return
if not confirm(f"Move {preview.items} redundant copies ({human_size(preview.bytes_freed)}) to the Recycle Bin?", assume_yes=yes):
if not confirm(f"Move {preview.items:,} redundant copies ({human_size(preview.bytes_freed)}) to the Recycle Bin?", assume_yes=yes):
warn("Cancelled.")
return
result = cleanup.trash_paths(to_delete, dry_run=False, extra_protected=extra)
history.record_clean("cleanup-duplicates", str(path), result.bytes_freed, result.items, result.trashed)
success(f"Sent {result.items} copies ({human_size(result.bytes_freed)}) to the Recycle Bin.")
success(f"Sent {result.items:,} copies ({human_size(result.bytes_freed)}) to the Recycle Bin.")


@app.command("large")
Expand Down Expand Up @@ -114,17 +114,17 @@ def stale_cmd(
for p, s, m in items:
table.add_row(human_size(s), datetime.fromtimestamp(m).strftime("%Y-%m-%d"), p.name)
console.print(table)
console.print(f"\n[bold]{len(items)} items · {human_size(total)}[/bold]")
console.print(f"\n[bold]{len(items):,} items · {human_size(total)}[/bold]")
if not apply:
console.print("[dim]Dry-run - re-run with --apply to remove them.[/dim]")
return
if not confirm(f"Move {len(items)} stale items ({human_size(total)}) to the Recycle Bin?", assume_yes=yes):
if not confirm(f"Move {len(items):,} stale items ({human_size(total)}) to the Recycle Bin?", assume_yes=yes):
warn("Cancelled.")
return
extra = list(exclude) if exclude else None
result = cleanup.trash_paths([p for p, _s, _m in items], dry_run=False, extra_protected=extra)
history.record_clean("cleanup-stale", f"Downloads >{days}d", result.bytes_freed, result.items, result.trashed)
success(f"Sent {result.items} items ({human_size(result.bytes_freed)}) to the Recycle Bin.")
success(f"Sent {result.items:,} items ({human_size(result.bytes_freed)}) to the Recycle Bin.")


@app.command("worktrees")
Expand Down Expand Up @@ -163,12 +163,12 @@ def worktrees_cmd(
if not apply:
console.print("[dim]Dry-run - re-run with --apply to prune and trash them.[/dim]")
return
if not confirm(f"Prune {len(orphans)} orphaned worktree(s)?", assume_yes=yes):
if not confirm(f"Prune {len(orphans):,} orphaned worktree(s)?", assume_yes=yes):
warn("Cancelled.")
return
result = prune_worktrees(path, dry_run=False)
history.record_clean("cleanup-worktrees", str(path), result.bytes_freed, result.items, result.trashed)
success(f"Pruned {result.items} worktree(s) ({human_size(result.bytes_freed)}).")
success(f"Pruned {result.items:,} worktree(s) ({human_size(result.bytes_freed)}).")


class _null:
Expand Down
2 changes: 1 addition & 1 deletion src/sifty/cli/commands/disk.py
Original file line number Diff line number Diff line change
Expand Up @@ -119,6 +119,6 @@ def duplicates_cmd(
each = disk._entry_size(paths[0])
wasted = each * (len(paths) - 1)
reclaimable += wasted
table.add_row(str(len(paths)), human_size(each), human_size(wasted), str(paths[0]))
table.add_row(f"{len(paths):,}", human_size(each), human_size(wasted), str(paths[0]))
console.print(table)
console.print(f"\n[bold]Reclaimable by de-duplicating: {human_size(reclaimable)}[/bold]")
2 changes: 1 addition & 1 deletion src/sifty/cli/commands/junk.py
Original file line number Diff line number Diff line change
Expand Up @@ -84,4 +84,4 @@ def clean_cmd(
)
success(f"Sent {result.items:,} items ({human_size(result.bytes_freed)}) to the Recycle Bin.")
if result.skipped:
warn(f"{len(result.skipped)} item(s) skipped (in use or protected).")
warn(f"{len(result.skipped):,} item(s) skipped (in use or protected).")
6 changes: 3 additions & 3 deletions src/sifty/cli/commands/optimize.py
Original file line number Diff line number Diff line change
Expand Up @@ -69,12 +69,12 @@ def run_cmd(
for op in runnable:
console.print(f" [cyan]{op.key}[/cyan] {op.description}")
if skipped_admin:
console.print(f"\n[dim]{len(skipped_admin)} admin-only operation(s) skipped "
console.print(f"\n[dim]{len(skipped_admin):,} admin-only operation(s) skipped "
f"(relaunch with --admin to include them).[/dim]")
console.print("\n[dim]Dry-run - re-run with --apply to execute.[/dim]")
return

if not confirm(f"Run {len(runnable)} optimization operation(s)?", assume_yes=yes):
if not confirm(f"Run {len(runnable):,} optimization operation(s)?", assume_yes=yes):
warn("Cancelled.")
return

Expand All @@ -87,6 +87,6 @@ def run_cmd(
console.print(f"[red]failed: {msg}[/red]")

if skipped_admin:
warn(f"{len(skipped_admin)} admin-only operation(s) skipped "
warn(f"{len(skipped_admin):,} admin-only operation(s) skipped "
f"(relaunch with --admin to include them).")
success("Optimization complete.")
14 changes: 7 additions & 7 deletions src/sifty/cli/commands/organize.py
Original file line number Diff line number Diff line change
Expand Up @@ -46,25 +46,25 @@ def _run(path: Path, scheme: str, *, apply: bool, yes: bool) -> None:
success("Nothing to organize - all files are already sorted.")
return

table = Table(title=f"Organize '{path}' by {scheme} ({len(moves)} files)")
table = Table(title=f"Organize '{path}' by {scheme} ({len(moves):,} files)")
table.add_column("File")
table.add_column("→ Folder", style="cyan")
for m in moves[:50]:
table.add_row(m.src.name, m.dest.parent.name)
console.print(table)
if len(moves) > 50:
console.print(f"[dim]…and {len(moves) - 50} more.[/dim]")
console.print(f"[dim]…and {len(moves) - 50:,} more.[/dim]")

if not apply:
console.print("[dim]Dry-run - nothing moved. Re-run with 'organize apply' to perform.[/dim]")
return

if not confirm(f"Move {len(moves)} files into subfolders?", assume_yes=yes):
if not confirm(f"Move {len(moves):,} files into subfolders?", assume_yes=yes):
warn("Cancelled.")
return

done = organize.apply_moves(moves)
success(f"Organized {done} files. Undo with [cyan]sifty organize undo[/cyan].")
success(f"Organized {done:,} files. Undo with [cyan]sifty organize undo[/cyan].")


@app.command("undo")
Expand All @@ -76,10 +76,10 @@ def undo_cmd(
if not pairs:
warn("Nothing to undo - no organize session recorded.")
return
if not confirm(f"Move {len(pairs)} file(s) back to their original locations?", assume_yes=yes):
if not confirm(f"Move {len(pairs):,} file(s) back to their original locations?", assume_yes=yes):
warn("Cancelled.")
return
restored, failed = organize.undo_last()
success(f"Restored {restored} file(s).")
success(f"Restored {restored:,} file(s).")
if failed:
warn(f"{failed} file(s) could not be restored (moved or replaced since).")
warn(f"{failed:,} file(s) could not be restored (moved or replaced since).")
2 changes: 1 addition & 1 deletion src/sifty/cli/commands/profile.py
Original file line number Diff line number Diff line change
Expand Up @@ -45,7 +45,7 @@ def add_cmd(
error(f"Unknown categories: {', '.join(unknown)}. Valid: {', '.join(sorted(valid))}")
raise typer.Exit(1)
profiles.save(Profile(name, category))
success(f"Saved profile '{name}' ({len(category)} categories).")
success(f"Saved profile '{name}' ({len(category):,} categories).")


@app.command("remove")
Expand Down
10 changes: 5 additions & 5 deletions src/sifty/cli/commands/purge.py
Original file line number Diff line number Diff line change
Expand Up @@ -45,7 +45,7 @@ def scan_cmd(
table.add_row(a.pattern, human_size(a.size_bytes), str(a.path))
total += a.size_bytes
table.add_section()
table.add_row("", f"[bold]{human_size(total)}[/bold]", f"[dim]{len(artifacts)} directories[/dim]")
table.add_row("", f"[bold]{human_size(total)}[/bold]", f"[dim]{len(artifacts):,} directories[/dim]")
console.print(table)
console.print("\nRun [cyan]sifty purge clean PATH --apply[/cyan] to remove them.")

Expand All @@ -71,25 +71,25 @@ def clean_cmd(

total = sum(a.size_bytes for a in artifacts)
console.print(
f"Found [bold]{len(artifacts)}[/bold] artifact directories "
f"Found [bold]{len(artifacts):,}[/bold] artifact directories "
f"totalling [bold]{human_size(total)}[/bold]."
)
if not apply:
console.print("[dim]Dry-run - re-run with --apply to remove.[/dim]")
return

if not confirm(
f"Move {len(artifacts)} artifact directories ({human_size(total)}) to the Recycle Bin?",
f"Move {len(artifacts):,} artifact directories ({human_size(total)}) to the Recycle Bin?",
assume_yes=yes,
):
warn("Cancelled.")
return

result = purge.purge_artifacts([a.path for a in artifacts], dry_run=False)
history.record_clean("purge", str(path), result.bytes_freed, result.items, result.trashed)
success(f"Sent {result.items} directories ({human_size(result.bytes_freed)}) to the Recycle Bin.")
success(f"Sent {result.items:,} directories ({human_size(result.bytes_freed)}) to the Recycle Bin.")
if result.skipped:
warn(f"{len(result.skipped)} skipped (in use or protected).")
warn(f"{len(result.skipped):,} skipped (in use or protected).")


class _null:
Expand Down
2 changes: 1 addition & 1 deletion src/sifty/cli/commands/startup.py
Original file line number Diff line number Diff line change
Expand Up @@ -22,7 +22,7 @@ def list_cmd() -> None:
for e in entries
])
return
table = Table(title=f"Startup programs ({len(entries)})")
table = Table(title=f"Startup programs ({len(entries):,})")
table.add_column("Name")
table.add_column("State")
table.add_column("Origin", style="dim")
Expand Down
2 changes: 1 addition & 1 deletion src/sifty/cli/commands/updates.py
Original file line number Diff line number Diff line change
Expand Up @@ -38,7 +38,7 @@ def check_cmd() -> None:
success("Everything is up to date.")
return

table = Table(title=f"Available updates ({len(upgrades)})")
table = Table(title=f"Available updates ({len(upgrades):,})")
table.add_column("Name")
table.add_column("Id", style="dim")
table.add_column("Current", justify="right")
Expand Down
Loading