killpy 0.24.0__tar.gz → 0.24.1__tar.gz
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.
- {killpy-0.24.0 → killpy-0.24.1}/PKG-INFO +5 -2
- {killpy-0.24.0 → killpy-0.24.1}/README.md +4 -1
- {killpy-0.24.0 → killpy-0.24.1}/killpy/__main__.py +10 -2
- {killpy-0.24.0 → killpy-0.24.1}/killpy/cli.py +52 -22
- {killpy-0.24.0 → killpy-0.24.1}/killpy/commands/delete.py +10 -2
- {killpy-0.24.0 → killpy-0.24.1}/killpy/intelligence/tracker.py +29 -1
- {killpy-0.24.0 → killpy-0.24.1}/killpy.egg-info/PKG-INFO +5 -2
- {killpy-0.24.0 → killpy-0.24.1}/pyproject.toml +1 -1
- {killpy-0.24.0 → killpy-0.24.1}/killpy/__init__.py +0 -0
- {killpy-0.24.0 → killpy-0.24.1}/killpy/cleaner.py +0 -0
- {killpy-0.24.0 → killpy-0.24.1}/killpy/cleaners/__init__.py +0 -0
- {killpy-0.24.0 → killpy-0.24.1}/killpy/commands/__init__.py +0 -0
- {killpy-0.24.0 → killpy-0.24.1}/killpy/commands/_utils.py +0 -0
- {killpy-0.24.0 → killpy-0.24.1}/killpy/commands/clean.py +0 -0
- {killpy-0.24.0 → killpy-0.24.1}/killpy/commands/doctor.py +0 -0
- {killpy-0.24.0 → killpy-0.24.1}/killpy/commands/find.py +0 -0
- {killpy-0.24.0 → killpy-0.24.1}/killpy/commands/list.py +0 -0
- {killpy-0.24.0 → killpy-0.24.1}/killpy/commands/stats.py +0 -0
- {killpy-0.24.0 → killpy-0.24.1}/killpy/detectors/__init__.py +0 -0
- {killpy-0.24.0 → killpy-0.24.1}/killpy/detectors/artifacts.py +0 -0
- {killpy-0.24.0 → killpy-0.24.1}/killpy/detectors/base.py +0 -0
- {killpy-0.24.0 → killpy-0.24.1}/killpy/detectors/cache.py +0 -0
- {killpy-0.24.0 → killpy-0.24.1}/killpy/detectors/conda.py +0 -0
- {killpy-0.24.0 → killpy-0.24.1}/killpy/detectors/hatch.py +0 -0
- {killpy-0.24.0 → killpy-0.24.1}/killpy/detectors/pipenv.py +0 -0
- {killpy-0.24.0 → killpy-0.24.1}/killpy/detectors/pipx.py +0 -0
- {killpy-0.24.0 → killpy-0.24.1}/killpy/detectors/poetry.py +0 -0
- {killpy-0.24.0 → killpy-0.24.1}/killpy/detectors/pyenv.py +0 -0
- {killpy-0.24.0 → killpy-0.24.1}/killpy/detectors/tox.py +0 -0
- {killpy-0.24.0 → killpy-0.24.1}/killpy/detectors/uv.py +0 -0
- {killpy-0.24.0 → killpy-0.24.1}/killpy/detectors/venv.py +0 -0
- {killpy-0.24.0 → killpy-0.24.1}/killpy/files/__init__.py +0 -0
- {killpy-0.24.0 → killpy-0.24.1}/killpy/intelligence/__init__.py +0 -0
- {killpy-0.24.0 → killpy-0.24.1}/killpy/intelligence/git_analyzer.py +0 -0
- {killpy-0.24.0 → killpy-0.24.1}/killpy/intelligence/scoring.py +0 -0
- {killpy-0.24.0 → killpy-0.24.1}/killpy/intelligence/suggestions.py +0 -0
- {killpy-0.24.0 → killpy-0.24.1}/killpy/models.py +0 -0
- {killpy-0.24.0 → killpy-0.24.1}/killpy/scanner.py +0 -0
- {killpy-0.24.0 → killpy-0.24.1}/killpy.egg-info/SOURCES.txt +0 -0
- {killpy-0.24.0 → killpy-0.24.1}/killpy.egg-info/dependency_links.txt +0 -0
- {killpy-0.24.0 → killpy-0.24.1}/killpy.egg-info/entry_points.txt +0 -0
- {killpy-0.24.0 → killpy-0.24.1}/killpy.egg-info/requires.txt +0 -0
- {killpy-0.24.0 → killpy-0.24.1}/killpy.egg-info/top_level.txt +0 -0
- {killpy-0.24.0 → killpy-0.24.1}/setup.cfg +0 -0
|
@@ -1,6 +1,6 @@
|
|
|
1
1
|
Metadata-Version: 2.4
|
|
2
2
|
Name: killpy
|
|
3
|
-
Version: 0.24.
|
|
3
|
+
Version: 0.24.1
|
|
4
4
|
Summary: List all .venv directories and Conda environments 🐍 on your system and check how much space they are using. You can then choose which ones to delete in order to free up space 🧹.
|
|
5
5
|
Project-URL: Homepage, https://github.com/Tlaloc-Es/killpy
|
|
6
6
|
Project-URL: Documentation, https://tlaloc-es.github.io/killpy/
|
|
@@ -31,6 +31,8 @@ Find and delete old `.venv`, conda, poetry, pipenv, uv and more — safely, in s
|
|
|
31
31
|
uvx killpy --path ~
|
|
32
32
|
```
|
|
33
33
|
|
|
34
|
+
> ⭐ Featured in [awesome-python](https://github.com/vinta/awesome-python) — a curated list of the best Python tools
|
|
35
|
+
|
|
34
36
|
[Documentation](https://tlaloc-es.github.io/killpy/)
|
|
35
37
|
|
|
36
38
|
[](https://pypi.org/project/killpy/)
|
|
@@ -40,6 +42,7 @@ uvx killpy --path ~
|
|
|
40
42
|
[](https://codecov.io/gh/Tlaloc-Es/killpy)
|
|
41
43
|
[](LICENSE)
|
|
42
44
|
[](<https://twitter.com/intent/tweet?text=%F0%9F%90%8D%20KillPy%20helps%20you%20reclaim%20disk%20space%20by%20detecting%20unused%20Python%20environments%20(.venv,%20poetry%20env,%20conda%20env)%20and%20pipx%20packages.%20Clean,%20organize%20and%20free%20up%20space%20effortlessly!%20%F0%9F%9A%80&url=https://github.com/Tlaloc-Es/KillPy>)
|
|
45
|
+
[](https://github.com/vinta/awesome-python)
|
|
43
46
|
|
|
44
47
|

|
|
45
48
|
|
|
@@ -584,7 +587,7 @@ Typical minimal setup (safe for daily use):
|
|
|
584
587
|
|
|
585
588
|
```yaml
|
|
586
589
|
- repo: https://github.com/Tlaloc-Es/KillPy
|
|
587
|
-
rev: 0.24.
|
|
590
|
+
rev: 0.24.1
|
|
588
591
|
hooks:
|
|
589
592
|
- id: killpy
|
|
590
593
|
```
|
|
@@ -10,6 +10,8 @@ Find and delete old `.venv`, conda, poetry, pipenv, uv and more — safely, in s
|
|
|
10
10
|
uvx killpy --path ~
|
|
11
11
|
```
|
|
12
12
|
|
|
13
|
+
> ⭐ Featured in [awesome-python](https://github.com/vinta/awesome-python) — a curated list of the best Python tools
|
|
14
|
+
|
|
13
15
|
[Documentation](https://tlaloc-es.github.io/killpy/)
|
|
14
16
|
|
|
15
17
|
[](https://pypi.org/project/killpy/)
|
|
@@ -19,6 +21,7 @@ uvx killpy --path ~
|
|
|
19
21
|
[](https://codecov.io/gh/Tlaloc-Es/killpy)
|
|
20
22
|
[](LICENSE)
|
|
21
23
|
[](<https://twitter.com/intent/tweet?text=%F0%9F%90%8D%20KillPy%20helps%20you%20reclaim%20disk%20space%20by%20detecting%20unused%20Python%20environments%20(.venv,%20poetry%20env,%20conda%20env)%20and%20pipx%20packages.%20Clean,%20organize%20and%20free%20up%20space%20effortlessly!%20%F0%9F%9A%80&url=https://github.com/Tlaloc-Es/KillPy>)
|
|
24
|
+
[](https://github.com/vinta/awesome-python)
|
|
22
25
|
|
|
23
26
|

|
|
24
27
|
|
|
@@ -563,7 +566,7 @@ Typical minimal setup (safe for daily use):
|
|
|
563
566
|
|
|
564
567
|
```yaml
|
|
565
568
|
- repo: https://github.com/Tlaloc-Es/KillPy
|
|
566
|
-
rev: 0.24.
|
|
569
|
+
rev: 0.24.1
|
|
567
570
|
hooks:
|
|
568
571
|
- id: killpy
|
|
569
572
|
```
|
|
@@ -52,6 +52,14 @@ def _run_delete_all(path: Path, excluded: set[str], yes: bool) -> None:
|
|
|
52
52
|
console.print("Aborted.")
|
|
53
53
|
return
|
|
54
54
|
|
|
55
|
+
# Record this cleanup session up-front so `killpy stats --history` reflects
|
|
56
|
+
# it; record_deletion() below updates the same record with the freed bytes.
|
|
57
|
+
tracker = UsageTracker()
|
|
58
|
+
try:
|
|
59
|
+
tracker.record_scan_result(envs, path)
|
|
60
|
+
except Exception: # noqa: BLE001
|
|
61
|
+
pass
|
|
62
|
+
|
|
55
63
|
deleted = 0
|
|
56
64
|
freed = 0
|
|
57
65
|
for env in envs:
|
|
@@ -67,9 +75,9 @@ def _run_delete_all(path: Path, excluded: set[str], yes: bool) -> None:
|
|
|
67
75
|
f"freed [bold]{format_size(freed)}[/bold]."
|
|
68
76
|
)
|
|
69
77
|
|
|
70
|
-
# Best-effort: record
|
|
78
|
+
# Best-effort: update the history record created above with freed bytes.
|
|
71
79
|
try:
|
|
72
|
-
|
|
80
|
+
tracker.record_deletion(freed)
|
|
73
81
|
except Exception: # noqa: BLE001
|
|
74
82
|
pass
|
|
75
83
|
|
|
@@ -11,6 +11,7 @@ from typing import Any, TypedDict
|
|
|
11
11
|
from rich.text import Text
|
|
12
12
|
from textual.app import App, ComposeResult
|
|
13
13
|
from textual.binding import Binding
|
|
14
|
+
from textual.coordinate import Coordinate
|
|
14
15
|
from textual.widgets import (
|
|
15
16
|
DataTable,
|
|
16
17
|
Footer,
|
|
@@ -25,7 +26,7 @@ from textual.widgets import (
|
|
|
25
26
|
from killpy.cleaner import Cleaner, CleanerError
|
|
26
27
|
from killpy.cleaners import remove_pycache
|
|
27
28
|
from killpy.files import format_size
|
|
28
|
-
from killpy.intelligence import SuggestionEngine, score_all
|
|
29
|
+
from killpy.intelligence import SuggestionEngine, UsageTracker, score_all
|
|
29
30
|
from killpy.models import Environment
|
|
30
31
|
from killpy.scanner import Scanner
|
|
31
32
|
|
|
@@ -142,9 +143,10 @@ class TableApp(App):
|
|
|
142
143
|
self._filter_query: str = ""
|
|
143
144
|
self._venv_display_indices: list[int] = []
|
|
144
145
|
self._multi_select_mode: bool = False
|
|
145
|
-
self.
|
|
146
|
+
self._selected_venv_paths: set[str] = set()
|
|
146
147
|
self._health_by_path: dict[str, str] = {}
|
|
147
148
|
self.cleaner = Cleaner()
|
|
149
|
+
self.tracker = UsageTracker()
|
|
148
150
|
self.scanner = Scanner(
|
|
149
151
|
types={
|
|
150
152
|
"venv",
|
|
@@ -395,7 +397,7 @@ class TableApp(App):
|
|
|
395
397
|
row["size"],
|
|
396
398
|
row["size_human"],
|
|
397
399
|
_health_text(row["health"]),
|
|
398
|
-
self._compute_row_status(
|
|
400
|
+
self._compute_row_status(row),
|
|
399
401
|
)
|
|
400
402
|
|
|
401
403
|
def render_pipx_table(self) -> None:
|
|
@@ -416,18 +418,18 @@ class TableApp(App):
|
|
|
416
418
|
return data_index, self.venv_rows[data_index]
|
|
417
419
|
return None
|
|
418
420
|
|
|
419
|
-
def _compute_row_status(self,
|
|
421
|
+
def _compute_row_status(self, row: VenvRow) -> str:
|
|
420
422
|
"""Return the status string to display, taking multi-select into account."""
|
|
421
423
|
if row["status"] == EnvStatus.DELETED.value:
|
|
422
424
|
return EnvStatus.DELETED.value
|
|
423
|
-
if self._multi_select_mode and
|
|
425
|
+
if self._multi_select_mode and row["path"] in self._selected_venv_paths:
|
|
424
426
|
return "\u25cf SELECTED"
|
|
425
427
|
return row["status"]
|
|
426
428
|
|
|
427
429
|
def _update_multi_select_label(self) -> None:
|
|
428
430
|
label = self.query_one("#multi-select-label", Label)
|
|
429
431
|
if self._multi_select_mode:
|
|
430
|
-
n = len(self.
|
|
432
|
+
n = len(self._selected_venv_paths)
|
|
431
433
|
label.add_class("visible")
|
|
432
434
|
label.update(
|
|
433
435
|
f"[bold yellow]Multi-select[/bold yellow] — "
|
|
@@ -572,8 +574,27 @@ class TableApp(App):
|
|
|
572
574
|
status_label.update(
|
|
573
575
|
f"Found {venv_count} virtual environments and {pipx_count} pipx packages"
|
|
574
576
|
)
|
|
577
|
+
self._record_scan()
|
|
575
578
|
await self._compute_health_scores()
|
|
576
579
|
|
|
580
|
+
def _record_scan(self) -> None:
|
|
581
|
+
"""Persist this scan session so ``killpy stats --history`` reflects it."""
|
|
582
|
+
try:
|
|
583
|
+
envs = [row["environment"] for row in self.venv_rows]
|
|
584
|
+
envs += [row["environment"] for row in self.pipx_rows]
|
|
585
|
+
self.tracker.record_scan_result(envs, self.root_dir)
|
|
586
|
+
except Exception: # noqa: BLE001
|
|
587
|
+
pass
|
|
588
|
+
|
|
589
|
+
def _record_deletion(self, freed: int) -> None:
|
|
590
|
+
"""Best-effort: add *freed* bytes to the current history record."""
|
|
591
|
+
if freed <= 0:
|
|
592
|
+
return
|
|
593
|
+
try:
|
|
594
|
+
self.tracker.record_deletion(freed)
|
|
595
|
+
except Exception: # noqa: BLE001
|
|
596
|
+
pass
|
|
597
|
+
|
|
577
598
|
async def _compute_health_scores(self) -> None:
|
|
578
599
|
"""Score venv environments and populate the Health column."""
|
|
579
600
|
if not self.venv_rows:
|
|
@@ -614,25 +635,32 @@ class TableApp(App):
|
|
|
614
635
|
|
|
615
636
|
@is_venv_tab
|
|
616
637
|
def action_confirm_delete(self):
|
|
617
|
-
|
|
618
|
-
|
|
619
|
-
|
|
620
|
-
|
|
638
|
+
freed_now = 0
|
|
639
|
+
if self._multi_select_mode and self._selected_venv_paths:
|
|
640
|
+
# Multi-select mode: delete all selected rows. Selection is
|
|
641
|
+
# tracked by path (not by list position) so it stays valid even
|
|
642
|
+
# after the rows have been re-sorted.
|
|
643
|
+
for row in self.venv_rows:
|
|
644
|
+
if row["path"] not in self._selected_venv_paths:
|
|
645
|
+
continue
|
|
621
646
|
if row["status"] == EnvStatus.DELETED.value:
|
|
622
647
|
continue
|
|
623
648
|
if self.delete_environment(row["environment"]):
|
|
649
|
+
freed_now += int(row["size"])
|
|
624
650
|
self.bytes_release += int(row["size"])
|
|
625
651
|
row["status"] = EnvStatus.DELETED.value
|
|
626
|
-
self.
|
|
652
|
+
self._selected_venv_paths.clear()
|
|
627
653
|
else:
|
|
628
654
|
# Normal mode: delete all rows marked for deletion
|
|
629
655
|
for row in self.venv_rows:
|
|
630
656
|
if row["status"] != EnvStatus.MARKED_TO_DELETE.value:
|
|
631
657
|
continue
|
|
632
658
|
if self.delete_environment(row["environment"]):
|
|
659
|
+
freed_now += int(row["size"])
|
|
633
660
|
self.bytes_release += int(row["size"])
|
|
634
661
|
row["status"] = EnvStatus.DELETED.value
|
|
635
662
|
|
|
663
|
+
self._record_deletion(freed_now)
|
|
636
664
|
self.render_venv_table()
|
|
637
665
|
self.query_one("#status-label", Label).update(
|
|
638
666
|
f"{format_size(self.bytes_release)} deleted"
|
|
@@ -675,6 +703,7 @@ class TableApp(App):
|
|
|
675
703
|
return
|
|
676
704
|
if self.delete_environment(row["environment"]):
|
|
677
705
|
self.bytes_release += int(row["size"])
|
|
706
|
+
self._record_deletion(int(row["size"]))
|
|
678
707
|
row["status"] = EnvStatus.DELETED.value
|
|
679
708
|
table.update_cell_at(
|
|
680
709
|
(cursor_cell.row, self.VENV_COL_STATUS),
|
|
@@ -706,6 +735,7 @@ class TableApp(App):
|
|
|
706
735
|
row["status"] = EnvStatus.DELETED.value
|
|
707
736
|
table.update_cell_at((cursor_cell.row, 3), EnvStatus.DELETED.value)
|
|
708
737
|
self.bytes_release += int(row["size"])
|
|
738
|
+
self._record_deletion(int(row["size"]))
|
|
709
739
|
self.query_one("#status-label", Label).update(
|
|
710
740
|
f"{format_size(self.bytes_release)} deleted"
|
|
711
741
|
)
|
|
@@ -794,7 +824,7 @@ class TableApp(App):
|
|
|
794
824
|
"""Toggle multi-select mode on/off (T key)."""
|
|
795
825
|
self._multi_select_mode = not self._multi_select_mode
|
|
796
826
|
if not self._multi_select_mode:
|
|
797
|
-
self.
|
|
827
|
+
self._selected_venv_paths.clear()
|
|
798
828
|
self._update_multi_select_label()
|
|
799
829
|
self.render_venv_table()
|
|
800
830
|
|
|
@@ -810,17 +840,17 @@ class TableApp(App):
|
|
|
810
840
|
resolved = self._resolve_venv_row(cursor_cell.row)
|
|
811
841
|
if not resolved:
|
|
812
842
|
return
|
|
813
|
-
|
|
843
|
+
_, row = resolved
|
|
814
844
|
if row["status"] == EnvStatus.DELETED.value:
|
|
815
845
|
return
|
|
816
|
-
if
|
|
817
|
-
self.
|
|
846
|
+
if row["path"] in self._selected_venv_paths:
|
|
847
|
+
self._selected_venv_paths.discard(row["path"])
|
|
818
848
|
else:
|
|
819
|
-
self.
|
|
849
|
+
self._selected_venv_paths.add(row["path"])
|
|
820
850
|
self._update_multi_select_label()
|
|
821
851
|
table.update_cell_at(
|
|
822
|
-
(cursor_cell.row, self.VENV_COL_STATUS),
|
|
823
|
-
self._compute_row_status(
|
|
852
|
+
Coordinate(cursor_cell.row, self.VENV_COL_STATUS),
|
|
853
|
+
self._compute_row_status(row),
|
|
824
854
|
)
|
|
825
855
|
|
|
826
856
|
@is_venv_tab
|
|
@@ -829,13 +859,13 @@ class TableApp(App):
|
|
|
829
859
|
if not self._multi_select_mode:
|
|
830
860
|
return
|
|
831
861
|
non_deleted = {
|
|
832
|
-
i
|
|
862
|
+
self.venv_rows[i]["path"]
|
|
833
863
|
for i in self._venv_display_indices
|
|
834
864
|
if self.venv_rows[i]["status"] != EnvStatus.DELETED.value
|
|
835
865
|
}
|
|
836
|
-
if non_deleted == self.
|
|
837
|
-
self.
|
|
866
|
+
if non_deleted == self._selected_venv_paths:
|
|
867
|
+
self._selected_venv_paths.clear()
|
|
838
868
|
else:
|
|
839
|
-
self.
|
|
869
|
+
self._selected_venv_paths = non_deleted
|
|
840
870
|
self._update_multi_select_label()
|
|
841
871
|
self.render_venv_table()
|
|
@@ -96,6 +96,14 @@ def delete_cmd(
|
|
|
96
96
|
abort=True,
|
|
97
97
|
)
|
|
98
98
|
|
|
99
|
+
# Record this cleanup session up-front so `killpy stats --history` reflects
|
|
100
|
+
# it; record_deletion() below updates the same record with the freed bytes.
|
|
101
|
+
tracker = UsageTracker()
|
|
102
|
+
try:
|
|
103
|
+
tracker.record_scan_result(envs, path)
|
|
104
|
+
except Exception: # noqa: BLE001
|
|
105
|
+
pass
|
|
106
|
+
|
|
99
107
|
cleaner = Cleaner(dry_run=False)
|
|
100
108
|
freed = 0
|
|
101
109
|
errors = 0
|
|
@@ -114,9 +122,9 @@ def delete_cmd(
|
|
|
114
122
|
+ (f" — [red]{errors} error(s)[/red]" if errors else "")
|
|
115
123
|
)
|
|
116
124
|
|
|
117
|
-
# Best-effort: record
|
|
125
|
+
# Best-effort: update the history record created above with freed bytes.
|
|
118
126
|
try:
|
|
119
|
-
|
|
127
|
+
tracker.record_deletion(freed)
|
|
120
128
|
except Exception: # noqa: BLE001
|
|
121
129
|
pass
|
|
122
130
|
|
|
@@ -6,9 +6,11 @@ import json
|
|
|
6
6
|
import logging
|
|
7
7
|
import os
|
|
8
8
|
import tempfile
|
|
9
|
+
from collections.abc import Iterable
|
|
10
|
+
from datetime import datetime, timezone
|
|
9
11
|
from pathlib import Path
|
|
10
12
|
|
|
11
|
-
from killpy.models import ScanRecord, ScoredEnvironment
|
|
13
|
+
from killpy.models import Environment, ScanRecord, ScoredEnvironment
|
|
12
14
|
|
|
13
15
|
logger = logging.getLogger(__name__)
|
|
14
16
|
|
|
@@ -35,6 +37,32 @@ class UsageTracker:
|
|
|
35
37
|
history.append(record.to_dict())
|
|
36
38
|
self._save(history)
|
|
37
39
|
|
|
40
|
+
def record_scan_result(
|
|
41
|
+
self,
|
|
42
|
+
environments: Iterable[Environment],
|
|
43
|
+
scan_path: Path | str,
|
|
44
|
+
*,
|
|
45
|
+
deleted_bytes: int = 0,
|
|
46
|
+
) -> None:
|
|
47
|
+
"""Persist a :class:`~killpy.models.ScanRecord` built from a scan result.
|
|
48
|
+
|
|
49
|
+
Convenience wrapper around :meth:`record_scan` so callers don't have to
|
|
50
|
+
assemble a :class:`ScanRecord` by hand. Records the number of
|
|
51
|
+
environments found and their total size; ``deleted_bytes`` can be set
|
|
52
|
+
when the freed amount is already known, otherwise use
|
|
53
|
+
:meth:`record_deletion` afterwards to update the same record.
|
|
54
|
+
"""
|
|
55
|
+
envs = list(environments)
|
|
56
|
+
self.record_scan(
|
|
57
|
+
ScanRecord(
|
|
58
|
+
timestamp=datetime.now(tz=timezone.utc),
|
|
59
|
+
total_space_found=sum(e.size_bytes for e in envs),
|
|
60
|
+
total_space_deleted=deleted_bytes,
|
|
61
|
+
environments_count=len(envs),
|
|
62
|
+
scan_path=str(scan_path),
|
|
63
|
+
)
|
|
64
|
+
)
|
|
65
|
+
|
|
38
66
|
def record_deletion(self, size_bytes: int) -> None:
|
|
39
67
|
"""Increment the ``total_space_deleted`` counter of the last scan record."""
|
|
40
68
|
history = self._load()
|
|
@@ -1,6 +1,6 @@
|
|
|
1
1
|
Metadata-Version: 2.4
|
|
2
2
|
Name: killpy
|
|
3
|
-
Version: 0.24.
|
|
3
|
+
Version: 0.24.1
|
|
4
4
|
Summary: List all .venv directories and Conda environments 🐍 on your system and check how much space they are using. You can then choose which ones to delete in order to free up space 🧹.
|
|
5
5
|
Project-URL: Homepage, https://github.com/Tlaloc-Es/killpy
|
|
6
6
|
Project-URL: Documentation, https://tlaloc-es.github.io/killpy/
|
|
@@ -31,6 +31,8 @@ Find and delete old `.venv`, conda, poetry, pipenv, uv and more — safely, in s
|
|
|
31
31
|
uvx killpy --path ~
|
|
32
32
|
```
|
|
33
33
|
|
|
34
|
+
> ⭐ Featured in [awesome-python](https://github.com/vinta/awesome-python) — a curated list of the best Python tools
|
|
35
|
+
|
|
34
36
|
[Documentation](https://tlaloc-es.github.io/killpy/)
|
|
35
37
|
|
|
36
38
|
[](https://pypi.org/project/killpy/)
|
|
@@ -40,6 +42,7 @@ uvx killpy --path ~
|
|
|
40
42
|
[](https://codecov.io/gh/Tlaloc-Es/killpy)
|
|
41
43
|
[](LICENSE)
|
|
42
44
|
[](<https://twitter.com/intent/tweet?text=%F0%9F%90%8D%20KillPy%20helps%20you%20reclaim%20disk%20space%20by%20detecting%20unused%20Python%20environments%20(.venv,%20poetry%20env,%20conda%20env)%20and%20pipx%20packages.%20Clean,%20organize%20and%20free%20up%20space%20effortlessly!%20%F0%9F%9A%80&url=https://github.com/Tlaloc-Es/KillPy>)
|
|
45
|
+
[](https://github.com/vinta/awesome-python)
|
|
43
46
|
|
|
44
47
|

|
|
45
48
|
|
|
@@ -584,7 +587,7 @@ Typical minimal setup (safe for daily use):
|
|
|
584
587
|
|
|
585
588
|
```yaml
|
|
586
589
|
- repo: https://github.com/Tlaloc-Es/KillPy
|
|
587
|
-
rev: 0.24.
|
|
590
|
+
rev: 0.24.1
|
|
588
591
|
hooks:
|
|
589
592
|
- id: killpy
|
|
590
593
|
```
|
|
@@ -1,6 +1,6 @@
|
|
|
1
1
|
[project]
|
|
2
2
|
name = "killpy"
|
|
3
|
-
version = "0.24.
|
|
3
|
+
version = "0.24.1"
|
|
4
4
|
description = "List all .venv directories and Conda environments 🐍 on your system and check how much space they are using. You can then choose which ones to delete in order to free up space 🧹."
|
|
5
5
|
readme = "README.md"
|
|
6
6
|
classifiers = [
|
|
File without changes
|
|
File without changes
|
|
File without changes
|
|
File without changes
|
|
File without changes
|
|
File without changes
|
|
File without changes
|
|
File without changes
|
|
File without changes
|
|
File without changes
|
|
File without changes
|
|
File without changes
|
|
File without changes
|
|
File without changes
|
|
File without changes
|
|
File without changes
|
|
File without changes
|
|
File without changes
|
|
File without changes
|
|
File without changes
|
|
File without changes
|
|
File without changes
|
|
File without changes
|
|
File without changes
|
|
File without changes
|
|
File without changes
|
|
File without changes
|
|
File without changes
|
|
File without changes
|
|
File without changes
|
|
File without changes
|
|
File without changes
|
|
File without changes
|
|
File without changes
|
|
File without changes
|
|
File without changes
|