killpy 0.8.0__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.8.0/PKG-INFO +97 -0
- killpy-0.8.0/README.md +86 -0
- killpy-0.8.0/killpy/__init__.py +0 -0
- killpy-0.8.0/killpy/__main__.py +165 -0
- killpy-0.8.0/killpy/envs_handler.py +110 -0
- killpy-0.8.0/killpy.egg-info/PKG-INFO +97 -0
- killpy-0.8.0/killpy.egg-info/SOURCES.txt +11 -0
- killpy-0.8.0/killpy.egg-info/dependency_links.txt +1 -0
- killpy-0.8.0/killpy.egg-info/entry_points.txt +2 -0
- killpy-0.8.0/killpy.egg-info/requires.txt +2 -0
- killpy-0.8.0/killpy.egg-info/top_level.txt +1 -0
- killpy-0.8.0/pyproject.toml +43 -0
- killpy-0.8.0/setup.cfg +4 -0
killpy-0.8.0/PKG-INFO
ADDED
|
@@ -0,0 +1,97 @@
|
|
|
1
|
+
Metadata-Version: 2.1
|
|
2
|
+
Name: killpy
|
|
3
|
+
Version: 0.8.0
|
|
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
|
+
Classifier: Environment :: Console
|
|
6
|
+
Classifier: License :: OSI Approved :: MIT License
|
|
7
|
+
Classifier: Programming Language :: Python :: 3.12
|
|
8
|
+
Description-Content-Type: text/markdown
|
|
9
|
+
Requires-Dist: rich>=13.9.4
|
|
10
|
+
Requires-Dist: textual>=1.0.0
|
|
11
|
+
|
|
12
|
+
<div align="center">
|
|
13
|
+
|
|
14
|
+
</div>
|
|
15
|
+
|
|
16
|
+
```plaintext
|
|
17
|
+
โ โ โ โ โ โโโโ โ โ ____
|
|
18
|
+
โโโ โ โ โ โ โ โ โ .'`_ o `;__,
|
|
19
|
+
โ โโ โ โ โ โโโโโ โโโโ . .'.'` '---' '
|
|
20
|
+
โ โ โ โ โ โ โ โ .`-...-'.'
|
|
21
|
+
โ โโโ `-...-' A tool to delete .venv directories and Conda envs
|
|
22
|
+
```
|
|
23
|
+
|
|
24
|
+
[](https://pypi.org/project/killpy/)
|
|
25
|
+
[](https://pepy.tech/project/killpy)
|
|
26
|
+
[](https://github.com/Tlaloc-Es/killpy/stargazers)
|
|
27
|
+
|
|
28
|
+
<div align="center">
|
|
29
|
+
|
|
30
|
+

|
|
31
|
+
|
|
32
|
+
</div>
|
|
33
|
+
|
|
34
|
+
# Delete .venv Directories
|
|
35
|
+
|
|
36
|
+
`killpy` is a simple tool designed to locate and delete `.venv` directories from your projects (and Conda envs too). It can help you quickly clean up unnecessary virtual environments and save disk space.
|
|
37
|
+
|
|
38
|
+
## Features
|
|
39
|
+
|
|
40
|
+
- **Automatic search:** Finds all .venv directories and any folders containing a pyvenv.cfg file recursively from the current working directory, as they are considered virtual environment folders.
|
|
41
|
+
- **Support for Conda**: Lists all available Conda environments.
|
|
42
|
+
- **Safe deletion:** Lists the directories to be deleted and asks for confirmation.
|
|
43
|
+
- **Fast and lightweight:** Minimal dependencies for quick execution.
|
|
44
|
+
|
|
45
|
+
## Installation
|
|
46
|
+
|
|
47
|
+
To install `killpy`, use pip:
|
|
48
|
+
|
|
49
|
+
```bash
|
|
50
|
+
pip install killpy
|
|
51
|
+
```
|
|
52
|
+
|
|
53
|
+
## Usage
|
|
54
|
+
|
|
55
|
+
Run the following command to search for .venv directories and any folders containing a pyvenv.cfg file, as well as to list all Conda environments from the current directory and all its subdirectories recursively:
|
|
56
|
+
|
|
57
|
+
```bash
|
|
58
|
+
killpy
|
|
59
|
+
```
|
|
60
|
+
|
|
61
|
+
Or
|
|
62
|
+
|
|
63
|
+
```bash
|
|
64
|
+
pipx run --spec killpy killpy
|
|
65
|
+
```
|
|
66
|
+
|
|
67
|
+
- To **close the application**, press `Ctrl+Q`.
|
|
68
|
+
- To **mark a virtual environment for deletion**, press `D`.
|
|
69
|
+
- To **confirm deletion of marked virtual environments**, press `Ctrl+D`.
|
|
70
|
+
- To **delete a virtual environment immediately**, press `Shift+Delete`.
|
|
71
|
+
|
|
72
|
+
## Roadmap
|
|
73
|
+
|
|
74
|
+
- [ ] Delete `__pycache__` Files
|
|
75
|
+
- [ ] Remove `dist` Folders and Build Artifacts
|
|
76
|
+
- [ ] Clean Up Installed Package Cache
|
|
77
|
+
- [ ] Delete `.egg-info` and `.dist-info` Files
|
|
78
|
+
- [ ] Analyze and Remove Unused Dependencies
|
|
79
|
+
- [ ] Optimize Disk Space in Python Projects
|
|
80
|
+
|
|
81
|
+
## Contributing
|
|
82
|
+
|
|
83
|
+
Contributions are welcome! If you'd like to improve this tool, feel free to fork the repository and submit a pull request.
|
|
84
|
+
|
|
85
|
+
1. Fork the repository
|
|
86
|
+
1. Create a new branch for your feature: `git checkout -b my-feature`
|
|
87
|
+
1. Commit your changes: `git commit -m 'Add my feature'`
|
|
88
|
+
1. Push to the branch: `git push origin my-feature`
|
|
89
|
+
1. Submit a pull request
|
|
90
|
+
|
|
91
|
+
## License
|
|
92
|
+
|
|
93
|
+
This project is licensed under the MIT License. See the [LICENSE](LICENSE) file for details.
|
|
94
|
+
|
|
95
|
+
______________________________________________________________________
|
|
96
|
+
|
|
97
|
+
Thank you for using `killpy`! If you find it useful, please star the repository on GitHub!
|
killpy-0.8.0/README.md
ADDED
|
@@ -0,0 +1,86 @@
|
|
|
1
|
+
<div align="center">
|
|
2
|
+
|
|
3
|
+
</div>
|
|
4
|
+
|
|
5
|
+
```plaintext
|
|
6
|
+
โ โ โ โ โ โโโโ โ โ ____
|
|
7
|
+
โโโ โ โ โ โ โ โ โ .'`_ o `;__,
|
|
8
|
+
โ โโ โ โ โ โโโโโ โโโโ . .'.'` '---' '
|
|
9
|
+
โ โ โ โ โ โ โ โ .`-...-'.'
|
|
10
|
+
โ โโโ `-...-' A tool to delete .venv directories and Conda envs
|
|
11
|
+
```
|
|
12
|
+
|
|
13
|
+
[](https://pypi.org/project/killpy/)
|
|
14
|
+
[](https://pepy.tech/project/killpy)
|
|
15
|
+
[](https://github.com/Tlaloc-Es/killpy/stargazers)
|
|
16
|
+
|
|
17
|
+
<div align="center">
|
|
18
|
+
|
|
19
|
+

|
|
20
|
+
|
|
21
|
+
</div>
|
|
22
|
+
|
|
23
|
+
# Delete .venv Directories
|
|
24
|
+
|
|
25
|
+
`killpy` is a simple tool designed to locate and delete `.venv` directories from your projects (and Conda envs too). It can help you quickly clean up unnecessary virtual environments and save disk space.
|
|
26
|
+
|
|
27
|
+
## Features
|
|
28
|
+
|
|
29
|
+
- **Automatic search:** Finds all .venv directories and any folders containing a pyvenv.cfg file recursively from the current working directory, as they are considered virtual environment folders.
|
|
30
|
+
- **Support for Conda**: Lists all available Conda environments.
|
|
31
|
+
- **Safe deletion:** Lists the directories to be deleted and asks for confirmation.
|
|
32
|
+
- **Fast and lightweight:** Minimal dependencies for quick execution.
|
|
33
|
+
|
|
34
|
+
## Installation
|
|
35
|
+
|
|
36
|
+
To install `killpy`, use pip:
|
|
37
|
+
|
|
38
|
+
```bash
|
|
39
|
+
pip install killpy
|
|
40
|
+
```
|
|
41
|
+
|
|
42
|
+
## Usage
|
|
43
|
+
|
|
44
|
+
Run the following command to search for .venv directories and any folders containing a pyvenv.cfg file, as well as to list all Conda environments from the current directory and all its subdirectories recursively:
|
|
45
|
+
|
|
46
|
+
```bash
|
|
47
|
+
killpy
|
|
48
|
+
```
|
|
49
|
+
|
|
50
|
+
Or
|
|
51
|
+
|
|
52
|
+
```bash
|
|
53
|
+
pipx run --spec killpy killpy
|
|
54
|
+
```
|
|
55
|
+
|
|
56
|
+
- To **close the application**, press `Ctrl+Q`.
|
|
57
|
+
- To **mark a virtual environment for deletion**, press `D`.
|
|
58
|
+
- To **confirm deletion of marked virtual environments**, press `Ctrl+D`.
|
|
59
|
+
- To **delete a virtual environment immediately**, press `Shift+Delete`.
|
|
60
|
+
|
|
61
|
+
## Roadmap
|
|
62
|
+
|
|
63
|
+
- [ ] Delete `__pycache__` Files
|
|
64
|
+
- [ ] Remove `dist` Folders and Build Artifacts
|
|
65
|
+
- [ ] Clean Up Installed Package Cache
|
|
66
|
+
- [ ] Delete `.egg-info` and `.dist-info` Files
|
|
67
|
+
- [ ] Analyze and Remove Unused Dependencies
|
|
68
|
+
- [ ] Optimize Disk Space in Python Projects
|
|
69
|
+
|
|
70
|
+
## Contributing
|
|
71
|
+
|
|
72
|
+
Contributions are welcome! If you'd like to improve this tool, feel free to fork the repository and submit a pull request.
|
|
73
|
+
|
|
74
|
+
1. Fork the repository
|
|
75
|
+
1. Create a new branch for your feature: `git checkout -b my-feature`
|
|
76
|
+
1. Commit your changes: `git commit -m 'Add my feature'`
|
|
77
|
+
1. Push to the branch: `git push origin my-feature`
|
|
78
|
+
1. Submit a pull request
|
|
79
|
+
|
|
80
|
+
## License
|
|
81
|
+
|
|
82
|
+
This project is licensed under the MIT License. See the [LICENSE](LICENSE) file for details.
|
|
83
|
+
|
|
84
|
+
______________________________________________________________________
|
|
85
|
+
|
|
86
|
+
Thank you for using `killpy`! If you find it useful, please star the repository on GitHub!
|
|
File without changes
|
|
@@ -0,0 +1,165 @@
|
|
|
1
|
+
import asyncio
|
|
2
|
+
import shutil
|
|
3
|
+
from enum import Enum
|
|
4
|
+
from pathlib import Path
|
|
5
|
+
|
|
6
|
+
from envs_handler import (
|
|
7
|
+
find_venvs,
|
|
8
|
+
find_venvs_with_pyvenv,
|
|
9
|
+
format_size,
|
|
10
|
+
list_conda_environments,
|
|
11
|
+
remove_conda_env,
|
|
12
|
+
remove_duplicates,
|
|
13
|
+
)
|
|
14
|
+
from textual.app import App, ComposeResult
|
|
15
|
+
from textual.binding import Binding
|
|
16
|
+
from textual.coordinate import Coordinate
|
|
17
|
+
from textual.widgets import DataTable, Footer, Header, Label, Static
|
|
18
|
+
|
|
19
|
+
|
|
20
|
+
class EnvStatus(Enum):
|
|
21
|
+
DELETED = "DELETED"
|
|
22
|
+
MARKED_TO_DELETE = "MARKED TO DELETE"
|
|
23
|
+
|
|
24
|
+
|
|
25
|
+
class TableApp(App):
|
|
26
|
+
deleted_cells: Coordinate = []
|
|
27
|
+
bytes_release: int = 0
|
|
28
|
+
|
|
29
|
+
BINDINGS = [
|
|
30
|
+
Binding(key="ctrl+q", action="quit", description="Quit the app"),
|
|
31
|
+
Binding(
|
|
32
|
+
key="d",
|
|
33
|
+
action="mark_for_delete",
|
|
34
|
+
description="Mark .venv for deletion",
|
|
35
|
+
show=True,
|
|
36
|
+
),
|
|
37
|
+
Binding(
|
|
38
|
+
key="ctrl+d",
|
|
39
|
+
action="confirm_delete",
|
|
40
|
+
description="Confirm deletion of marked .venv",
|
|
41
|
+
show=True,
|
|
42
|
+
),
|
|
43
|
+
Binding(
|
|
44
|
+
key="shift+delete",
|
|
45
|
+
action="delete_now",
|
|
46
|
+
description="Delete the selected .venv immediately",
|
|
47
|
+
show=True,
|
|
48
|
+
),
|
|
49
|
+
]
|
|
50
|
+
|
|
51
|
+
CSS = """
|
|
52
|
+
#banner {
|
|
53
|
+
color: white;
|
|
54
|
+
border: heavy green;
|
|
55
|
+
}
|
|
56
|
+
"""
|
|
57
|
+
|
|
58
|
+
def compose(self) -> ComposeResult:
|
|
59
|
+
yield Header()
|
|
60
|
+
banner = Static(
|
|
61
|
+
"""
|
|
62
|
+
โ โ โ โ โ โโโโ โ โ ____
|
|
63
|
+
โโโ โ โ โ โ โ โ โ .'`_ o `;__,
|
|
64
|
+
โ โโ โ โ โ โโโโโ โโโโ . .'.'` '---' '
|
|
65
|
+
โ โ โ โ โ โ โ โ .`-...-'.'
|
|
66
|
+
โ โโโ `-...-' A tool to delete .venv directories and Conda envs
|
|
67
|
+
""",
|
|
68
|
+
id="banner",
|
|
69
|
+
)
|
|
70
|
+
yield banner
|
|
71
|
+
yield Label("Searching for virtual environments...")
|
|
72
|
+
yield DataTable()
|
|
73
|
+
yield Footer()
|
|
74
|
+
|
|
75
|
+
async def on_mount(self) -> None:
|
|
76
|
+
self.title = """killpy"""
|
|
77
|
+
await self.find_venvs()
|
|
78
|
+
|
|
79
|
+
async def find_venvs(self):
|
|
80
|
+
current_directory = Path.cwd()
|
|
81
|
+
|
|
82
|
+
venvs = await asyncio.gather(
|
|
83
|
+
asyncio.to_thread(find_venvs, current_directory),
|
|
84
|
+
asyncio.to_thread(list_conda_environments),
|
|
85
|
+
asyncio.to_thread(find_venvs_with_pyvenv, current_directory),
|
|
86
|
+
)
|
|
87
|
+
venvs = [env for sublist in venvs for env in sublist]
|
|
88
|
+
venvs = remove_duplicates(venvs)
|
|
89
|
+
|
|
90
|
+
table = self.query_one(DataTable)
|
|
91
|
+
table.focus()
|
|
92
|
+
table.add_columns(
|
|
93
|
+
"Path", "Type", "Last Modified", "Size", "Size (Human Readable)", "Status"
|
|
94
|
+
)
|
|
95
|
+
|
|
96
|
+
for venv in venvs:
|
|
97
|
+
table.add_row(*venv)
|
|
98
|
+
|
|
99
|
+
table.cursor_type = "row"
|
|
100
|
+
table.zebra_stripes = True
|
|
101
|
+
|
|
102
|
+
self.query_one(Label).update(f"Found {len(venvs)} .venv directories")
|
|
103
|
+
|
|
104
|
+
def action_confirm_delete(self):
|
|
105
|
+
table = self.query_one(DataTable)
|
|
106
|
+
for row_index in range(table.row_count):
|
|
107
|
+
row_data = table.get_row_at(row_index)
|
|
108
|
+
current_status = row_data[5]
|
|
109
|
+
if current_status == EnvStatus.MARKED_TO_DELETE.value:
|
|
110
|
+
cursor_cell = Coordinate(row_index, 0)
|
|
111
|
+
if cursor_cell not in self.deleted_cells:
|
|
112
|
+
path = row_data[0]
|
|
113
|
+
self.bytes_release += row_data[3]
|
|
114
|
+
env_type = row_data[1]
|
|
115
|
+
self.delete_environment(path, env_type)
|
|
116
|
+
table.update_cell_at((row_index, 5), EnvStatus.DELETED.value)
|
|
117
|
+
self.deleted_cells.append(cursor_cell)
|
|
118
|
+
self.query_one(Label).update(f"{format_size(self.bytes_release)} deleted")
|
|
119
|
+
self.bell()
|
|
120
|
+
|
|
121
|
+
def action_mark_for_delete(self):
|
|
122
|
+
table = self.query_one(DataTable)
|
|
123
|
+
cursor_cell = table.cursor_coordinate
|
|
124
|
+
if cursor_cell:
|
|
125
|
+
row_data = table.get_row_at(cursor_cell.row)
|
|
126
|
+
current_status = row_data[5]
|
|
127
|
+
if current_status == EnvStatus.DELETED.value:
|
|
128
|
+
return
|
|
129
|
+
elif current_status == EnvStatus.MARKED_TO_DELETE.value:
|
|
130
|
+
table.update_cell_at((cursor_cell.row, 5), "")
|
|
131
|
+
else:
|
|
132
|
+
table.update_cell_at(
|
|
133
|
+
(cursor_cell.row, 5), EnvStatus.MARKED_TO_DELETE.value
|
|
134
|
+
)
|
|
135
|
+
|
|
136
|
+
def action_delete_now(self):
|
|
137
|
+
table = self.query_one(DataTable)
|
|
138
|
+
cursor_cell = table.cursor_coordinate
|
|
139
|
+
if cursor_cell:
|
|
140
|
+
if cursor_cell in self.deleted_cells:
|
|
141
|
+
return
|
|
142
|
+
row_data = table.get_row_at(cursor_cell.row)
|
|
143
|
+
path = row_data[0]
|
|
144
|
+
self.bytes_release += row_data[3]
|
|
145
|
+
env_type = row_data[1]
|
|
146
|
+
self.delete_environment(path, env_type)
|
|
147
|
+
table.update_cell_at((cursor_cell.row, 5), EnvStatus.DELETED.value)
|
|
148
|
+
self.query_one(Label).update(f"{format_size(self.bytes_release)} deleted")
|
|
149
|
+
self.deleted_cells.append(cursor_cell)
|
|
150
|
+
self.bell()
|
|
151
|
+
|
|
152
|
+
def delete_environment(self, path, env_type):
|
|
153
|
+
if env_type in {".venv", "pyvenv.cfg"}:
|
|
154
|
+
shutil.rmtree(path)
|
|
155
|
+
else:
|
|
156
|
+
remove_conda_env(path)
|
|
157
|
+
|
|
158
|
+
|
|
159
|
+
def main():
|
|
160
|
+
app = TableApp()
|
|
161
|
+
app.run()
|
|
162
|
+
|
|
163
|
+
|
|
164
|
+
if __name__ == "__main__":
|
|
165
|
+
main()
|
|
@@ -0,0 +1,110 @@
|
|
|
1
|
+
import subprocess
|
|
2
|
+
from datetime import datetime
|
|
3
|
+
from pathlib import Path
|
|
4
|
+
|
|
5
|
+
|
|
6
|
+
def remove_duplicates(venvs):
|
|
7
|
+
seen_paths = set()
|
|
8
|
+
unique_venvs = []
|
|
9
|
+
|
|
10
|
+
for venv in venvs:
|
|
11
|
+
venv_path = venv[0]
|
|
12
|
+
if venv_path not in seen_paths:
|
|
13
|
+
unique_venvs.append(venv)
|
|
14
|
+
seen_paths.add(venv_path)
|
|
15
|
+
|
|
16
|
+
return unique_venvs
|
|
17
|
+
|
|
18
|
+
|
|
19
|
+
def get_total_size(path: Path) -> int:
|
|
20
|
+
total_size = sum(f.stat().st_size for f in path.rglob("*") if f.is_file())
|
|
21
|
+
return total_size
|
|
22
|
+
|
|
23
|
+
|
|
24
|
+
def format_size(size_in_bytes: int):
|
|
25
|
+
if size_in_bytes >= 1 << 30:
|
|
26
|
+
return f"{size_in_bytes / (1 << 30):.2f} GB"
|
|
27
|
+
elif size_in_bytes >= 1 << 20:
|
|
28
|
+
return f"{size_in_bytes / (1 << 20):.2f} MB"
|
|
29
|
+
elif size_in_bytes >= 1 << 10:
|
|
30
|
+
return f"{size_in_bytes / (1 << 10):.2f} KB"
|
|
31
|
+
else:
|
|
32
|
+
return f"{size_in_bytes} bytes"
|
|
33
|
+
|
|
34
|
+
|
|
35
|
+
def find_venvs(base_directory: Path):
|
|
36
|
+
venvs = []
|
|
37
|
+
for dir_path in base_directory.rglob(".venv"):
|
|
38
|
+
last_modified_timestamp = dir_path.stat().st_mtime
|
|
39
|
+
last_modified = datetime.fromtimestamp(last_modified_timestamp).strftime(
|
|
40
|
+
"%d/%m/%Y"
|
|
41
|
+
)
|
|
42
|
+
size = get_total_size(dir_path)
|
|
43
|
+
size_to_show = format_size(size)
|
|
44
|
+
venvs.append((dir_path, ".venv", last_modified, size, size_to_show))
|
|
45
|
+
venvs.sort(key=lambda x: x[2], reverse=True)
|
|
46
|
+
|
|
47
|
+
return venvs
|
|
48
|
+
|
|
49
|
+
|
|
50
|
+
def find_venvs_with_pyvenv(base_directory: Path):
|
|
51
|
+
venvs = []
|
|
52
|
+
for dir_path in base_directory.rglob("pyvenv.cfg"):
|
|
53
|
+
venv_dir = dir_path.parent
|
|
54
|
+
last_modified_timestamp = dir_path.stat().st_mtime
|
|
55
|
+
last_modified = datetime.fromtimestamp(last_modified_timestamp).strftime(
|
|
56
|
+
"%d/%m/%Y"
|
|
57
|
+
)
|
|
58
|
+
size = get_total_size(venv_dir)
|
|
59
|
+
size_to_show = format_size(size)
|
|
60
|
+
venvs.append((venv_dir, "pyvenv.cfg", last_modified, size, size_to_show))
|
|
61
|
+
|
|
62
|
+
venvs.sort(key=lambda x: x[2], reverse=True)
|
|
63
|
+
return venvs
|
|
64
|
+
|
|
65
|
+
|
|
66
|
+
def remove_conda_env(env_name):
|
|
67
|
+
try:
|
|
68
|
+
subprocess.run(
|
|
69
|
+
["conda", "env", "remove", "-n", env_name],
|
|
70
|
+
check=True,
|
|
71
|
+
)
|
|
72
|
+
except subprocess.CalledProcessError as e:
|
|
73
|
+
print(f"Error: {e}")
|
|
74
|
+
|
|
75
|
+
|
|
76
|
+
def list_conda_environments():
|
|
77
|
+
try:
|
|
78
|
+
result = subprocess.run(
|
|
79
|
+
["conda", "env", "list"],
|
|
80
|
+
capture_output=True,
|
|
81
|
+
text=True,
|
|
82
|
+
check=True,
|
|
83
|
+
)
|
|
84
|
+
|
|
85
|
+
venvs = []
|
|
86
|
+
for line in result.stdout.splitlines():
|
|
87
|
+
if line.strip() and not line.startswith("#"):
|
|
88
|
+
env_info = line.strip().split()
|
|
89
|
+
env_name = env_info[0]
|
|
90
|
+
|
|
91
|
+
if "*" in env_info:
|
|
92
|
+
continue
|
|
93
|
+
|
|
94
|
+
dir_path = Path(env_info[1])
|
|
95
|
+
last_modified_timestamp = dir_path.stat().st_mtime
|
|
96
|
+
last_modified = datetime.fromtimestamp(
|
|
97
|
+
last_modified_timestamp
|
|
98
|
+
).strftime("%d/%m/%Y")
|
|
99
|
+
|
|
100
|
+
size = get_total_size(dir_path)
|
|
101
|
+
size_to_show = format_size(size)
|
|
102
|
+
venvs.append((env_name, "Conda", last_modified, size, size_to_show))
|
|
103
|
+
|
|
104
|
+
venvs.sort(key=lambda x: x[3], reverse=True)
|
|
105
|
+
return venvs
|
|
106
|
+
|
|
107
|
+
except subprocess.CalledProcessError:
|
|
108
|
+
return []
|
|
109
|
+
except Exception:
|
|
110
|
+
return []
|
|
@@ -0,0 +1,97 @@
|
|
|
1
|
+
Metadata-Version: 2.1
|
|
2
|
+
Name: killpy
|
|
3
|
+
Version: 0.8.0
|
|
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
|
+
Classifier: Environment :: Console
|
|
6
|
+
Classifier: License :: OSI Approved :: MIT License
|
|
7
|
+
Classifier: Programming Language :: Python :: 3.12
|
|
8
|
+
Description-Content-Type: text/markdown
|
|
9
|
+
Requires-Dist: rich>=13.9.4
|
|
10
|
+
Requires-Dist: textual>=1.0.0
|
|
11
|
+
|
|
12
|
+
<div align="center">
|
|
13
|
+
|
|
14
|
+
</div>
|
|
15
|
+
|
|
16
|
+
```plaintext
|
|
17
|
+
โ โ โ โ โ โโโโ โ โ ____
|
|
18
|
+
โโโ โ โ โ โ โ โ โ .'`_ o `;__,
|
|
19
|
+
โ โโ โ โ โ โโโโโ โโโโ . .'.'` '---' '
|
|
20
|
+
โ โ โ โ โ โ โ โ .`-...-'.'
|
|
21
|
+
โ โโโ `-...-' A tool to delete .venv directories and Conda envs
|
|
22
|
+
```
|
|
23
|
+
|
|
24
|
+
[](https://pypi.org/project/killpy/)
|
|
25
|
+
[](https://pepy.tech/project/killpy)
|
|
26
|
+
[](https://github.com/Tlaloc-Es/killpy/stargazers)
|
|
27
|
+
|
|
28
|
+
<div align="center">
|
|
29
|
+
|
|
30
|
+

|
|
31
|
+
|
|
32
|
+
</div>
|
|
33
|
+
|
|
34
|
+
# Delete .venv Directories
|
|
35
|
+
|
|
36
|
+
`killpy` is a simple tool designed to locate and delete `.venv` directories from your projects (and Conda envs too). It can help you quickly clean up unnecessary virtual environments and save disk space.
|
|
37
|
+
|
|
38
|
+
## Features
|
|
39
|
+
|
|
40
|
+
- **Automatic search:** Finds all .venv directories and any folders containing a pyvenv.cfg file recursively from the current working directory, as they are considered virtual environment folders.
|
|
41
|
+
- **Support for Conda**: Lists all available Conda environments.
|
|
42
|
+
- **Safe deletion:** Lists the directories to be deleted and asks for confirmation.
|
|
43
|
+
- **Fast and lightweight:** Minimal dependencies for quick execution.
|
|
44
|
+
|
|
45
|
+
## Installation
|
|
46
|
+
|
|
47
|
+
To install `killpy`, use pip:
|
|
48
|
+
|
|
49
|
+
```bash
|
|
50
|
+
pip install killpy
|
|
51
|
+
```
|
|
52
|
+
|
|
53
|
+
## Usage
|
|
54
|
+
|
|
55
|
+
Run the following command to search for .venv directories and any folders containing a pyvenv.cfg file, as well as to list all Conda environments from the current directory and all its subdirectories recursively:
|
|
56
|
+
|
|
57
|
+
```bash
|
|
58
|
+
killpy
|
|
59
|
+
```
|
|
60
|
+
|
|
61
|
+
Or
|
|
62
|
+
|
|
63
|
+
```bash
|
|
64
|
+
pipx run --spec killpy killpy
|
|
65
|
+
```
|
|
66
|
+
|
|
67
|
+
- To **close the application**, press `Ctrl+Q`.
|
|
68
|
+
- To **mark a virtual environment for deletion**, press `D`.
|
|
69
|
+
- To **confirm deletion of marked virtual environments**, press `Ctrl+D`.
|
|
70
|
+
- To **delete a virtual environment immediately**, press `Shift+Delete`.
|
|
71
|
+
|
|
72
|
+
## Roadmap
|
|
73
|
+
|
|
74
|
+
- [ ] Delete `__pycache__` Files
|
|
75
|
+
- [ ] Remove `dist` Folders and Build Artifacts
|
|
76
|
+
- [ ] Clean Up Installed Package Cache
|
|
77
|
+
- [ ] Delete `.egg-info` and `.dist-info` Files
|
|
78
|
+
- [ ] Analyze and Remove Unused Dependencies
|
|
79
|
+
- [ ] Optimize Disk Space in Python Projects
|
|
80
|
+
|
|
81
|
+
## Contributing
|
|
82
|
+
|
|
83
|
+
Contributions are welcome! If you'd like to improve this tool, feel free to fork the repository and submit a pull request.
|
|
84
|
+
|
|
85
|
+
1. Fork the repository
|
|
86
|
+
1. Create a new branch for your feature: `git checkout -b my-feature`
|
|
87
|
+
1. Commit your changes: `git commit -m 'Add my feature'`
|
|
88
|
+
1. Push to the branch: `git push origin my-feature`
|
|
89
|
+
1. Submit a pull request
|
|
90
|
+
|
|
91
|
+
## License
|
|
92
|
+
|
|
93
|
+
This project is licensed under the MIT License. See the [LICENSE](LICENSE) file for details.
|
|
94
|
+
|
|
95
|
+
______________________________________________________________________
|
|
96
|
+
|
|
97
|
+
Thank you for using `killpy`! If you find it useful, please star the repository on GitHub!
|
|
@@ -0,0 +1,11 @@
|
|
|
1
|
+
README.md
|
|
2
|
+
pyproject.toml
|
|
3
|
+
killpy/__init__.py
|
|
4
|
+
killpy/__main__.py
|
|
5
|
+
killpy/envs_handler.py
|
|
6
|
+
killpy.egg-info/PKG-INFO
|
|
7
|
+
killpy.egg-info/SOURCES.txt
|
|
8
|
+
killpy.egg-info/dependency_links.txt
|
|
9
|
+
killpy.egg-info/entry_points.txt
|
|
10
|
+
killpy.egg-info/requires.txt
|
|
11
|
+
killpy.egg-info/top_level.txt
|
|
@@ -0,0 +1 @@
|
|
|
1
|
+
|
|
@@ -0,0 +1 @@
|
|
|
1
|
+
killpy
|
|
@@ -0,0 +1,43 @@
|
|
|
1
|
+
[project]
|
|
2
|
+
name = "killpy"
|
|
3
|
+
version = "0.8.0"
|
|
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
|
+
readme = "README.md"
|
|
6
|
+
classifiers = [
|
|
7
|
+
"Environment :: Console",
|
|
8
|
+
"License :: OSI Approved :: MIT License",
|
|
9
|
+
"Programming Language :: Python :: 3.12"
|
|
10
|
+
]
|
|
11
|
+
dependencies = [
|
|
12
|
+
"rich>=13.9.4",
|
|
13
|
+
"textual>=1.0.0",
|
|
14
|
+
]
|
|
15
|
+
|
|
16
|
+
[tool.setuptools]
|
|
17
|
+
license-files = []
|
|
18
|
+
|
|
19
|
+
[dependency-groups]
|
|
20
|
+
dev = [
|
|
21
|
+
"commitizen>=4.1.0",
|
|
22
|
+
"coverage>=7.6.10",
|
|
23
|
+
"mypy>=1.14.0",
|
|
24
|
+
"pre-commit>=4.0.1",
|
|
25
|
+
"pytest>=8.3.4",
|
|
26
|
+
"pytest-cov>=6.0.0",
|
|
27
|
+
"ruff>=0.8.4",
|
|
28
|
+
]
|
|
29
|
+
|
|
30
|
+
|
|
31
|
+
[tool.uv.workspace]
|
|
32
|
+
members = ["q"]
|
|
33
|
+
|
|
34
|
+
[tool.commitizen]
|
|
35
|
+
name = "cz_conventional_commits"
|
|
36
|
+
version = "0.8.0"
|
|
37
|
+
version_files = [
|
|
38
|
+
"src/__version__.py",
|
|
39
|
+
"pyproject.toml:version"
|
|
40
|
+
]
|
|
41
|
+
|
|
42
|
+
[project.scripts]
|
|
43
|
+
killpy = "killpy.__main__:main"
|
killpy-0.8.0/setup.cfg
ADDED