Skip to content

Commit 9939b4a

Browse files
authored
feat: verbose argument (#251)
added verbose argv to print all folders that will be deleted on dry run
1 parent c1a9af4 commit 9939b4a

File tree

6 files changed

+61
-25
lines changed

6 files changed

+61
-25
lines changed

README.md

Lines changed: 1 addition & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -122,6 +122,7 @@ options:
122122
-c, --configure Open module configuration screen
123123
-p, --custom-path Specify path for custom modules
124124
-f, --force Accept all warnings
125+
-v, --verbose Print folders to be deleted
125126
126127
```
127128

mac_cleanup/core.py

Lines changed: 9 additions & 8 deletions
Original file line numberDiff line numberDiff line change
@@ -4,7 +4,7 @@
44
from itertools import chain
55
from pathlib import Path as Path_
66
from types import TracebackType
7-
from typing import Any, Final, Optional, Type, TypeGuard, TypeVar, final
7+
from typing import Any, Final, Generator, Optional, Type, TypeGuard, TypeVar, final
88

99
import attr
1010
from beartype import beartype # pyright: ignore [reportUnknownVariableType]
@@ -192,8 +192,8 @@ def __filter_modules(module_: BaseModule, filter_type: Type[T]) -> TypeGuard[T]:
192192

193193
return isinstance(module_, filter_type)
194194

195-
def _count_dry(self) -> float:
196-
"""Counts free space for dry run :return: Approx amount of bytes to be removed."""
195+
def _extract_paths(self) -> Generator[tuple[Path_, float], None, None]:
196+
"""Extracts all paths from the collector :return: Yields paths with size."""
197197

198198
from concurrent.futures import ThreadPoolExecutor, as_completed
199199

@@ -208,28 +208,29 @@ def _count_dry(self) -> float:
208208
# Extracts paths from path_modules list
209209
path_list: list[Path_] = [path.get_path for path in path_modules]
210210

211-
# Set counter for estimated size
212-
estimate_size: float = 0
213-
214211
# Get thread executor
215212
executor = ThreadPoolExecutor()
216213

217214
try:
218215
# Add tasks to executor
219216
tasks = [executor.submit(self._get_size, path) for path in path_list]
220217

218+
# Store paths and their corresponding futures
219+
path_future_zip = list(zip(path_list, tasks, strict=True))
220+
221221
# Wait for task completion and add ProgressBar
222222
for future in ProgressBar.wrap_iter(
223223
as_completed(tasks), description="Collecting dry run", total=len(path_list)
224224
):
225-
estimate_size += future.result(timeout=10)
225+
path = next(p for p, f in path_future_zip if f == future)
226+
size = future.result(timeout=10)
227+
yield path, size
226228
except KeyboardInterrupt:
227229
# Shutdown executor without waiting for tasks
228230
executor.shutdown(wait=False)
229231
else:
230232
# Cleanup executor
231233
executor.shutdown(wait=True)
232-
return estimate_size
233234

234235

235236
class ProxyCollector:

mac_cleanup/main.py

Lines changed: 8 additions & 1 deletion
Original file line numberDiff line numberDiff line change
@@ -71,7 +71,14 @@ def start(self) -> None:
7171
if args.dry_run:
7272
from rich.prompt import Confirm
7373

74-
freed_space = bytes_to_human(self.base_collector._count_dry()) # noqa
74+
estimate_size: float = 0
75+
76+
for path, size in self.base_collector._extract_paths():
77+
if args.verbose and size:
78+
console.print(bytes_to_human(size), path, no_wrap=True)
79+
estimate_size += size
80+
81+
freed_space = bytes_to_human(estimate_size) # noqa
7582

7683
print_panel(text=f"Approx [success]{freed_space}[/success] will be cleaned", title="[info]Dry run results")
7784

mac_cleanup/parser.py

Lines changed: 4 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -16,6 +16,7 @@ class Args:
1616
configure: bool = attr.ib(default=False)
1717
custom_path: bool = attr.ib(default=False)
1818
force: bool = attr.ib(default=False)
19+
verbose: bool = attr.ib(default=False)
1920

2021

2122
parser = ArgumentParser(
@@ -37,10 +38,13 @@ class Args:
3738

3839
parser.add_argument("-f", "--force", help="Accept all warnings", action="store_true")
3940

41+
parser.add_argument("-v", "--verbose", help="Print folders to be deleted", action="store_true")
42+
4043
args = Args()
4144
parser.parse_args(namespace=args)
4245

4346
# args.dry_run = True # debug
4447
# args.configure = True # debug
4548
# args.custom_path = True # debug
4649
# args.force = True # debug
50+
# args.verbose = True # debug

tests/test_core.py

Lines changed: 15 additions & 6 deletions
Original file line numberDiff line numberDiff line change
@@ -194,8 +194,8 @@ def dummy_path_stat(console_self: Pathlib, follow_symlinks: bool) -> None: # no
194194
base_collector._get_size(Pathlib("/"))
195195

196196
@pytest.mark.parametrize("size_multiplier", [0, 1, 1024])
197-
def test_count_dry(self, size_multiplier: int, base_collector: _Collector, monkeypatch: MonkeyPatch):
198-
"""Test :meth:`mac_cleanup.core._Collector._count_dry`"""
197+
def test_extract_paths(self, size_multiplier: int, base_collector: _Collector, monkeypatch: MonkeyPatch):
198+
"""Test :meth:`mac_cleanup.core._Collector._extract_paths`"""
199199

200200
# Get size in bytes
201201
size = 1024 * size_multiplier
@@ -209,11 +209,16 @@ def test_count_dry(self, size_multiplier: int, base_collector: _Collector, monke
209209
# Simulate stuff in execute_list
210210
monkeypatch.setattr(base_collector, "_execute_list", [Unit(message="test", modules=[Path("~/test")])])
211211

212+
# Call _extract_paths
213+
paths = list(base_collector._extract_paths())
214+
212215
# Check results
213-
assert base_collector._count_dry() == size
216+
assert len(paths) == 1
217+
assert paths[0][0] == Path("~/test").get_path
218+
assert paths[0][1] == size
214219

215-
def test_count_dry_error(self, base_collector: _Collector, monkeypatch: MonkeyPatch):
216-
"""Test errors in :meth:`mac_cleanup.core._Collector._count_dry`"""
220+
def test_extract_paths_error(self, base_collector: _Collector, monkeypatch: MonkeyPatch):
221+
"""Test errors in :meth:`mac_cleanup.core._Collector._extract_paths`"""
217222

218223
# Dummy get size raising KeyboardInterrupt
219224
def dummy_get_size(clc_self: _Collector, path: Pathlib) -> float: # noqa # noqa
@@ -226,4 +231,8 @@ def dummy_get_size(clc_self: _Collector, path: Pathlib) -> float: # noqa # noq
226231
monkeypatch.setattr(base_collector, "_execute_list", [Unit(message="test", modules=[Path("~/test")])])
227232

228233
# Check prematurely exit return 0
229-
assert base_collector._count_dry() == 0
234+
# Call _extract_paths
235+
paths = list(base_collector._extract_paths())
236+
237+
# Check results
238+
assert len(paths) == 0

tests/test_main.py

Lines changed: 24 additions & 10 deletions
Original file line numberDiff line numberDiff line change
@@ -105,11 +105,14 @@ def dummy_count_free_space(entry_self: EntryPoint) -> float: # noqa
105105
assert f"Removed - {size_multiplier / 2} GB" in captured_stdout
106106

107107
@pytest.mark.parametrize("cleanup_prompted", [True, False])
108-
def test_dry_run_prompt(self, cleanup_prompted: bool, capsys: CaptureFixture[str], monkeypatch: MonkeyPatch):
109-
"""Test dry_run with optional cleanup in :class:`mac_cleanup.main.EntryPoint`"""
108+
@pytest.mark.parametrize("verbose", [True, False])
109+
def test_dry_run_prompt(
110+
self, cleanup_prompted: bool, verbose: bool, capsys: CaptureFixture[str], monkeypatch: MonkeyPatch
111+
):
112+
"""Test dry_run with verbose and optional cleanup in :class:`mac_cleanup.main.EntryPoint`"""
110113

111-
# Dummy count_dry returning 1 GB
112-
dummy_count_dry: Callable[..., float] = lambda: float(1024**3)
114+
# Dummy _extract_paths returning [Pathlib("test") and 1 GB]
115+
dummy_extract_paths: Callable[..., list[tuple[Pathlib, float]]] = lambda: [(Pathlib("test"), float(1024**3))]
113116

114117
# Dummy Config with empty init
115118
def dummy_config_init(cfg_self: Config, config_path_: Pathlib) -> None: # noqa # noqa
@@ -136,15 +139,18 @@ def dummy_config_call(config_path_: Pathlib, configuration_prompted: bool) -> No
136139
mock_entry_point = EntryPoint()
137140
monkeypatch.setattr(EntryPoint, "__new__", lambda: mock_entry_point)
138141

139-
# Simulate count_dry with predefined result
140-
monkeypatch.setattr(mock_entry_point.base_collector, "_count_dry", dummy_count_dry)
142+
# Simulate _extract_paths with predefined result
143+
monkeypatch.setattr(mock_entry_point.base_collector, "_extract_paths", dummy_extract_paths)
141144

142145
# Simulate empty cleanup
143146
monkeypatch.setattr(EntryPoint, "cleanup", dummy_cleanup)
144147

145148
# Simulate dry run was prompted
146149
monkeypatch.setattr("mac_cleanup.parser.Args.dry_run", True)
147150

151+
# Simulate verbose was set
152+
monkeypatch.setattr("mac_cleanup.parser.Args.verbose", verbose)
153+
148154
# Call entrypoint
149155
main()
150156

@@ -155,15 +161,23 @@ def dummy_config_call(config_path_: Pathlib, configuration_prompted: bool) -> No
155161
assert "Dry run results" in captured_stdout
156162
assert "Approx 1.0 GB will be cleaned" in captured_stdout
157163

164+
# Check verbose message
165+
if verbose:
166+
assert "1.0 GB test" in captured_stdout
167+
168+
# Check no verbose message
169+
if not verbose:
170+
assert "1.0 GB test" not in captured_stdout
171+
158172
# Check exit message
159173
if not cleanup_prompted:
160174
assert "Exiting..." in captured_stdout
161175

162176
def test_dry_run_prompt_error(self, capsys: CaptureFixture[str], monkeypatch: MonkeyPatch):
163177
"""Test errors in dry_run in :class:`mac_cleanup.main.EntryPoint`"""
164178

165-
# Dummy count_dry returning 1 GB
166-
dummy_count_dry: Callable[..., float] = lambda: float(1024**3)
179+
# Dummy _extract_paths returning [Pathlib("test") and 1 GB]
180+
dummy_extract_paths: Callable[..., list[tuple[Pathlib, float]]] = lambda: [(Pathlib("test"), float(1024**3))]
167181

168182
# Dummy Config with no init and empty call
169183
# Dummy Config with empty init
@@ -189,8 +203,8 @@ def dummy_input(*args: Any, **kwargs: Any) -> None: # noqa
189203
mock_entry_point = EntryPoint()
190204
monkeypatch.setattr(EntryPoint, "__new__", lambda: mock_entry_point)
191205

192-
# Simulate count_dry with predefined result
193-
monkeypatch.setattr(mock_entry_point.base_collector, "_count_dry", dummy_count_dry)
206+
# Simulate _extract_paths with predefined result
207+
monkeypatch.setattr(mock_entry_point.base_collector, "_extract_paths", dummy_extract_paths)
194208

195209
# Simulate dry run was prompted
196210
monkeypatch.setattr("mac_cleanup.parser.Args.dry_run", True)

0 commit comments

Comments
 (0)