devklean 1.0.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.
- devklean-1.0.0/.gitignore +22 -0
- devklean-1.0.0/CHANGELOG.md +85 -0
- devklean-1.0.0/LICENSE +21 -0
- devklean-1.0.0/PKG-INFO +257 -0
- devklean-1.0.0/README.md +221 -0
- devklean-1.0.0/pyproject.toml +108 -0
- devklean-1.0.0/src/devklean/__init__.py +6 -0
- devklean-1.0.0/src/devklean/__main__.py +4 -0
- devklean-1.0.0/src/devklean/_version.py +8 -0
- devklean-1.0.0/src/devklean/cli/__init__.py +3 -0
- devklean-1.0.0/src/devklean/cli/commands/__init__.py +4 -0
- devklean-1.0.0/src/devklean/cli/commands/clean.py +106 -0
- devklean-1.0.0/src/devklean/cli/commands/common.py +38 -0
- devklean-1.0.0/src/devklean/cli/commands/doctor.py +43 -0
- devklean-1.0.0/src/devklean/cli/commands/history.py +14 -0
- devklean-1.0.0/src/devklean/cli/commands/restore.py +20 -0
- devklean-1.0.0/src/devklean/cli/commands/scan.py +16 -0
- devklean-1.0.0/src/devklean/cli/confirmation.py +51 -0
- devklean-1.0.0/src/devklean/cli/dispatcher.py +45 -0
- devklean-1.0.0/src/devklean/cli/main.py +61 -0
- devklean-1.0.0/src/devklean/cli/parser.py +164 -0
- devklean-1.0.0/src/devklean/config/__init__.py +15 -0
- devklean-1.0.0/src/devklean/config/defaults.py +14 -0
- devklean-1.0.0/src/devklean/config/manager.py +226 -0
- devklean-1.0.0/src/devklean/config/models.py +48 -0
- devklean-1.0.0/src/devklean/config/paths.py +24 -0
- devklean-1.0.0/src/devklean/config/targets.py +23 -0
- devklean-1.0.0/src/devklean/deletion/__init__.py +17 -0
- devklean-1.0.0/src/devklean/deletion/history.py +66 -0
- devklean-1.0.0/src/devklean/deletion/integrity.py +39 -0
- devklean-1.0.0/src/devklean/deletion/metadata.py +198 -0
- devklean-1.0.0/src/devklean/deletion/paths.py +24 -0
- devklean-1.0.0/src/devklean/deletion/safety.py +176 -0
- devklean-1.0.0/src/devklean/deletion/trash.py +89 -0
- devklean-1.0.0/src/devklean/formatting.py +31 -0
- devklean-1.0.0/src/devklean/logging_setup.py +74 -0
- devklean-1.0.0/src/devklean/models.py +34 -0
- devklean-1.0.0/src/devklean/output/__init__.py +5 -0
- devklean-1.0.0/src/devklean/output/base.py +38 -0
- devklean-1.0.0/src/devklean/output/console.py +94 -0
- devklean-1.0.0/src/devklean/output/history_payload.py +34 -0
- devklean-1.0.0/src/devklean/output/json.py +75 -0
- devklean-1.0.0/src/devklean/output/scan_payload.py +51 -0
- devklean-1.0.0/src/devklean/output/sorting.py +12 -0
- devklean-1.0.0/src/devklean/output/text.py +183 -0
- devklean-1.0.0/src/devklean/output/theme.py +46 -0
- devklean-1.0.0/src/devklean/scanner/__init__.py +17 -0
- devklean-1.0.0/src/devklean/scanner/filters.py +32 -0
- devklean-1.0.0/src/devklean/scanner/scanner.py +170 -0
- devklean-1.0.0/src/devklean/tui.py +126 -0
- devklean-1.0.0/tests/benchmark_scanner.py +47 -0
- devklean-1.0.0/tests/conftest.py +89 -0
- devklean-1.0.0/tests/test_clean_flow.py +137 -0
- devklean-1.0.0/tests/test_cli_parser.py +57 -0
- devklean-1.0.0/tests/test_config.py +203 -0
- devklean-1.0.0/tests/test_config_precedence.py +111 -0
- devklean-1.0.0/tests/test_confirmation.py +88 -0
- devklean-1.0.0/tests/test_console.py +101 -0
- devklean-1.0.0/tests/test_deletion.py +242 -0
- devklean-1.0.0/tests/test_doctor.py +150 -0
- devklean-1.0.0/tests/test_dry_run.py +56 -0
- devklean-1.0.0/tests/test_formatting.py +50 -0
- devklean-1.0.0/tests/test_history.py +252 -0
- devklean-1.0.0/tests/test_integration.py +107 -0
- devklean-1.0.0/tests/test_integrity.py +118 -0
- devklean-1.0.0/tests/test_json_output.py +106 -0
- devklean-1.0.0/tests/test_logging.py +97 -0
- devklean-1.0.0/tests/test_models.py +47 -0
- devklean-1.0.0/tests/test_output_sorting.py +19 -0
- devklean-1.0.0/tests/test_packaging.py +56 -0
- devklean-1.0.0/tests/test_perf_scan.py +71 -0
- devklean-1.0.0/tests/test_restore.py +48 -0
- devklean-1.0.0/tests/test_safety.py +241 -0
- devklean-1.0.0/tests/test_scan_json_cli.py +39 -0
- devklean-1.0.0/tests/test_scan_permissions.py +52 -0
- devklean-1.0.0/tests/test_scan_settings.py +35 -0
- devklean-1.0.0/tests/test_scanner.py +51 -0
- devklean-1.0.0/tests/test_text_renderer.py +62 -0
- devklean-1.0.0/tests/test_windows_guard.py +78 -0
|
@@ -0,0 +1,22 @@
|
|
|
1
|
+
# Virtual environments
|
|
2
|
+
.venv/
|
|
3
|
+
venv/
|
|
4
|
+
env/
|
|
5
|
+
|
|
6
|
+
# Python
|
|
7
|
+
__pycache__/
|
|
8
|
+
*.py[cod]
|
|
9
|
+
*$py.class
|
|
10
|
+
*.egg-info/
|
|
11
|
+
.eggs/
|
|
12
|
+
dist/
|
|
13
|
+
build/
|
|
14
|
+
|
|
15
|
+
# Testing / tooling
|
|
16
|
+
.pytest_cache/
|
|
17
|
+
.mypy_cache/
|
|
18
|
+
.ruff_cache/
|
|
19
|
+
.coverage
|
|
20
|
+
htmlcov/
|
|
21
|
+
|
|
22
|
+
AUDIT.md
|
|
@@ -0,0 +1,85 @@
|
|
|
1
|
+
# Changelog
|
|
2
|
+
|
|
3
|
+
All notable changes to this project are documented here.
|
|
4
|
+
|
|
5
|
+
The format is based on [Keep a Changelog](https://keepachangelog.com/en/1.1.0/),
|
|
6
|
+
and this project adheres to [Semantic Versioning](https://semver.org/spec/v2.0.0.html).
|
|
7
|
+
|
|
8
|
+
## [Unreleased]
|
|
9
|
+
|
|
10
|
+
## [1.0.0] - 2026-06-30
|
|
11
|
+
|
|
12
|
+
First stable release. No breaking changes to the CLI since `0.1.0`; this
|
|
13
|
+
release marks the API and behavior as stable.
|
|
14
|
+
|
|
15
|
+
### Added
|
|
16
|
+
|
|
17
|
+
- A default-command shorthand: running `devklean <path>` (or `devklean` with no
|
|
18
|
+
arguments) is treated as a `scan`, so the most common operation needs no
|
|
19
|
+
subcommand.
|
|
20
|
+
- Permission errors encountered while scanning are now tracked and surfaced in
|
|
21
|
+
`--json` output.
|
|
22
|
+
|
|
23
|
+
### Changed
|
|
24
|
+
|
|
25
|
+
- Path resolution now honors `XDG_*` environment variables consistently across
|
|
26
|
+
log, config, and deletion-metadata paths on all platforms.
|
|
27
|
+
- Note: if you previously had `XDG_*` variables set, devklean may now resolve
|
|
28
|
+
these paths to different locations than before; existing logs, config, and
|
|
29
|
+
metadata in the old locations will not be migrated automatically.
|
|
30
|
+
- Console output is forced to UTF-8 on Windows to render the `✓`/`✗`/`⚠`
|
|
31
|
+
symbols without raising `UnicodeEncodeError`.
|
|
32
|
+
|
|
33
|
+
### Fixed
|
|
34
|
+
|
|
35
|
+
- Non-interactive commands no longer crash on Windows. The `curses` import (a
|
|
36
|
+
Unix-only module) is now loaded lazily, so `scan`, `clean`, `history`,
|
|
37
|
+
`doctor`, and `restore` import and run on Windows.
|
|
38
|
+
|
|
39
|
+
### Known limitations
|
|
40
|
+
|
|
41
|
+
- Interactive mode (`-i` / `--interactive`) is **Linux/macOS only** because it
|
|
42
|
+
depends on `curses`, which is unavailable on Windows. On Windows, `devklean
|
|
43
|
+
clean -i` now prints a clear message and exits cleanly instead of raising an
|
|
44
|
+
`ImportError`. All other commands work on Windows.
|
|
45
|
+
|
|
46
|
+
## [0.1.0] - 2026-06-28
|
|
47
|
+
|
|
48
|
+
First public pre-release.
|
|
49
|
+
|
|
50
|
+
### Added
|
|
51
|
+
|
|
52
|
+
- **Scanning** — discover cleanable directories (`node_modules`, `.venv`,
|
|
53
|
+
`__pycache__`, `dist`, caches, and more) with size reporting; `scan` command
|
|
54
|
+
with `--json` output.
|
|
55
|
+
- **Cleaning** — `clean` command moves items to the native operating-system
|
|
56
|
+
trash (Recycle Bin on Windows, Trash on macOS, freedesktop trash on Linux) via
|
|
57
|
+
`send2trash`, with a size summary and confirmation. Supports `--dry-run`,
|
|
58
|
+
interactive selection (`-i`), `--allow-symlinks`, and `-y/--yes`.
|
|
59
|
+
- **History & recovery** — `history` lists past cleanup operations (timestamp,
|
|
60
|
+
reclaimed size, strategy, item count) in text or `--json`. Recovery is done
|
|
61
|
+
through the OS trash UI (the OS owns the trash); `restore` explains how.
|
|
62
|
+
- **Safety layer** — a centralized `SafetyValidator` blocks deletion of the
|
|
63
|
+
filesystem root, home directory, mounted drive roots, protected system
|
|
64
|
+
directories, and symlinks (opt in with `--allow-symlinks`); protected
|
|
65
|
+
locations reached via a symlink (e.g. macOS `/etc`) are classified as
|
|
66
|
+
protected and cannot be bypassed with `--allow-symlinks`. Large deletions
|
|
67
|
+
(≥ 1 GiB by default) require typing `DELETE`.
|
|
68
|
+
- **Integrity** — `doctor` command detects corrupt metadata and removes only
|
|
69
|
+
confirmed-corrupt records after confirmation; reads degrade gracefully and
|
|
70
|
+
surface warnings.
|
|
71
|
+
- **Configuration** — TOML config with precedence project (`.devklean.toml`) >
|
|
72
|
+
global (`~/.config/devklean/config.toml`) > built-in defaults; keys for
|
|
73
|
+
`exclude`, `default_yes`, `theme`, `confirm_threshold`, targets, and ignores;
|
|
74
|
+
validation warns on unknown keys / malformed TOML without crashing.
|
|
75
|
+
- **Logging** — structured, rotating file logs at
|
|
76
|
+
`~/.cache/devklean/logs/latest.log`, separate from terminal output.
|
|
77
|
+
- **UX** — consistent `✓`/`✗`/`⚠` messaging, color that respects `NO_COLOR`,
|
|
78
|
+
non-tty output, and a `theme` setting; polished interactive mode.
|
|
79
|
+
- **Performance** — `os.scandir`-based size computation and concurrent
|
|
80
|
+
per-target sizing.
|
|
81
|
+
- **Packaging** — distributable via `pip`/`pipx`; MIT licensed.
|
|
82
|
+
|
|
83
|
+
[Unreleased]: https://github.com/smurftyy/devklean/compare/v1.0.0...HEAD
|
|
84
|
+
[1.0.0]: https://github.com/smurftyy/devklean/compare/v0.1.0...v1.0.0
|
|
85
|
+
[0.1.0]: https://github.com/smurftyy/devklean/releases/tag/v0.1.0
|
devklean-1.0.0/LICENSE
ADDED
|
@@ -0,0 +1,21 @@
|
|
|
1
|
+
MIT License
|
|
2
|
+
|
|
3
|
+
Copyright (c) 2026 smurftyy
|
|
4
|
+
|
|
5
|
+
Permission is hereby granted, free of charge, to any person obtaining a copy
|
|
6
|
+
of this software and associated documentation files (the "Software"), to deal
|
|
7
|
+
in the Software without restriction, including without limitation the rights
|
|
8
|
+
to use, copy, modify, merge, publish, distribute, sublicense, and/or sell
|
|
9
|
+
copies of the Software, and to permit persons to whom the Software is
|
|
10
|
+
furnished to do so, subject to the following conditions:
|
|
11
|
+
|
|
12
|
+
The above copyright notice and this permission notice shall be included in all
|
|
13
|
+
copies or substantial portions of the Software.
|
|
14
|
+
|
|
15
|
+
THE SOFTWARE IS PROVIDED "AS IS", WITHOUT WARRANTY OF ANY KIND, EXPRESS OR
|
|
16
|
+
IMPLIED, INCLUDING BUT NOT LIMITED TO THE WARRANTIES OF MERCHANTABILITY,
|
|
17
|
+
FITNESS FOR A PARTICULAR PURPOSE AND NONINFRINGEMENT. IN NO EVENT SHALL THE
|
|
18
|
+
AUTHORS OR COPYRIGHT HOLDERS BE LIABLE FOR ANY CLAIM, DAMAGES OR OTHER
|
|
19
|
+
LIABILITY, WHETHER IN AN ACTION OF CONTRACT, TORT OR OTHERWISE, ARISING FROM,
|
|
20
|
+
OUT OF OR IN CONNECTION WITH THE SOFTWARE OR THE USE OR OTHER DEALINGS IN THE
|
|
21
|
+
SOFTWARE.
|
devklean-1.0.0/PKG-INFO
ADDED
|
@@ -0,0 +1,257 @@
|
|
|
1
|
+
Metadata-Version: 2.4
|
|
2
|
+
Name: devklean
|
|
3
|
+
Version: 1.0.0
|
|
4
|
+
Summary: Clean up common development artifacts (node_modules, .venv, caches) to reclaim disk space
|
|
5
|
+
Project-URL: Homepage, https://github.com/smurftyy/devklean
|
|
6
|
+
Project-URL: Repository, https://github.com/smurftyy/devklean
|
|
7
|
+
Project-URL: Issues, https://github.com/smurftyy/devklean/issues
|
|
8
|
+
Project-URL: Changelog, https://github.com/smurftyy/devklean/blob/main/CHANGELOG.md
|
|
9
|
+
Author-email: smurftyy <oladapooloyede185@gmail.com>
|
|
10
|
+
License-Expression: MIT
|
|
11
|
+
License-File: LICENSE
|
|
12
|
+
Keywords: cleanup,cli,development,disk-space,node_modules,venv
|
|
13
|
+
Classifier: Development Status :: 5 - Production/Stable
|
|
14
|
+
Classifier: Environment :: Console
|
|
15
|
+
Classifier: Intended Audience :: Developers
|
|
16
|
+
Classifier: Intended Audience :: End Users/Desktop
|
|
17
|
+
Classifier: Operating System :: OS Independent
|
|
18
|
+
Classifier: Programming Language :: Python :: 3
|
|
19
|
+
Classifier: Programming Language :: Python :: 3.8
|
|
20
|
+
Classifier: Programming Language :: Python :: 3.9
|
|
21
|
+
Classifier: Programming Language :: Python :: 3.10
|
|
22
|
+
Classifier: Programming Language :: Python :: 3.11
|
|
23
|
+
Classifier: Programming Language :: Python :: 3.12
|
|
24
|
+
Classifier: Topic :: System :: Filesystems
|
|
25
|
+
Classifier: Topic :: Utilities
|
|
26
|
+
Requires-Python: >=3.8
|
|
27
|
+
Requires-Dist: send2trash>=1.8.2
|
|
28
|
+
Requires-Dist: tomli>=2.0.0; python_version < '3.11'
|
|
29
|
+
Provides-Extra: dev
|
|
30
|
+
Requires-Dist: build>=1.0; extra == 'dev'
|
|
31
|
+
Requires-Dist: mypy>=1.8; extra == 'dev'
|
|
32
|
+
Requires-Dist: pytest-cov>=4.0; extra == 'dev'
|
|
33
|
+
Requires-Dist: pytest>=7.0; extra == 'dev'
|
|
34
|
+
Requires-Dist: ruff>=0.6; extra == 'dev'
|
|
35
|
+
Description-Content-Type: text/markdown
|
|
36
|
+
|
|
37
|
+
# devklean
|
|
38
|
+
|
|
39
|
+
[](https://github.com/smurftyy/devklean/actions/workflows/ci.yml)
|
|
40
|
+
[](https://pypi.org/project/devklean/)
|
|
41
|
+
[](https://pypi.org/project/devklean/)
|
|
42
|
+
[](https://github.com/smurftyy/devklean/blob/main/LICENSE)
|
|
43
|
+
|
|
44
|
+
**Reclaim disk space by safely cleaning up development artifacts** — `node_modules`, `.venv`, build caches, and other regenerable directories — with a trash-backed safety net so nothing is ever lost to a typo.
|
|
45
|
+
|
|
46
|
+
<!-- TODO: insert terminal recording GIF of `devklean clean` here -->
|
|
47
|
+
|
|
48
|
+
## Why
|
|
49
|
+
|
|
50
|
+
Development trees accumulate gigabytes of regenerable junk. `devklean` finds it, shows you exactly what it found and how big it is, and removes it **to your native system trash** — the Recycle Bin on Windows, Trash on macOS, the freedesktop trash on Linux — not `rm -rf`, so a mistaken delete is recoverable from your trash. It refuses to touch dangerous paths, makes large deletions require an explicit typed confirmation, and keeps a history of what it removed.
|
|
51
|
+
|
|
52
|
+
## Installation
|
|
53
|
+
|
|
54
|
+
```bash
|
|
55
|
+
# Recommended: isolated install as a standalone CLI tool
|
|
56
|
+
pipx install devklean
|
|
57
|
+
|
|
58
|
+
# Or into the current environment
|
|
59
|
+
pip install devklean
|
|
60
|
+
```
|
|
61
|
+
|
|
62
|
+
Requires Python 3.8+. Runtime dependencies are `send2trash` (used for all deletions) and `tomli` (only on Python < 3.11).
|
|
63
|
+
|
|
64
|
+
## Quick start
|
|
65
|
+
|
|
66
|
+
```bash
|
|
67
|
+
# See what could be cleaned under the current directory — no changes made
|
|
68
|
+
devklean scan
|
|
69
|
+
|
|
70
|
+
# Scan and delete (with confirmation), moving items to the trash
|
|
71
|
+
devklean clean
|
|
72
|
+
|
|
73
|
+
# Preview a clean without deleting anything
|
|
74
|
+
devklean clean --dry-run
|
|
75
|
+
```
|
|
76
|
+
|
|
77
|
+
## Commands
|
|
78
|
+
|
|
79
|
+
| Command | What it does |
|
|
80
|
+
| --- | --- |
|
|
81
|
+
| `devklean scan [PATH]` | Find cleanable directories and report sizes. Never deletes. |
|
|
82
|
+
| `devklean clean [PATH]` | Scan, then delete (to trash) after confirmation. |
|
|
83
|
+
| `devklean restore` | Explain how to recover deleted items from your system trash. |
|
|
84
|
+
| `devklean history` | Show previous cleanup operations (timestamp, size, strategy, item count). |
|
|
85
|
+
| `devklean doctor` | Inspect and repair the deletion metadata store. |
|
|
86
|
+
| `devklean --version` | Print the version. |
|
|
87
|
+
|
|
88
|
+
**Default command:** running `devklean` with no subcommand defaults to `clean` — so `devklean` is `devklean clean`, and `devklean ~/code` is `devklean clean ~/code`. As a convenience, a bare `devklean --dry-run` (without `-i`) is treated as a `scan` preview.
|
|
89
|
+
|
|
90
|
+
### `scan`
|
|
91
|
+
|
|
92
|
+
```bash
|
|
93
|
+
devklean scan # scan current directory
|
|
94
|
+
devklean scan ~/projects # scan a specific path
|
|
95
|
+
devklean scan --json # machine-readable output for tooling
|
|
96
|
+
```
|
|
97
|
+
|
|
98
|
+
### `clean`
|
|
99
|
+
|
|
100
|
+
```bash
|
|
101
|
+
devklean clean # scan + delete with a y/N confirmation
|
|
102
|
+
devklean clean ~/projects # clean a specific path
|
|
103
|
+
devklean clean --dry-run # show what *would* be deleted; delete nothing
|
|
104
|
+
devklean clean -i # interactive: pick items in a TUI (Linux/macOS only)
|
|
105
|
+
devklean clean --allow-symlinks # permit deleting symlinked targets (blocked by default)
|
|
106
|
+
devklean clean -y # skip the y/N prompt (large deletions still require typing DELETE)
|
|
107
|
+
```
|
|
108
|
+
|
|
109
|
+
| Flag | Meaning |
|
|
110
|
+
| --- | --- |
|
|
111
|
+
| `--dry-run` | Report what would be deleted; make no changes. Output says "would delete". |
|
|
112
|
+
| `-i`, `--interactive` | Choose items in a terminal UI (SPACE select, A all, D none, ENTER confirm, Q quit). **Linux/macOS only** — see [Platform support](#platform-support). |
|
|
113
|
+
| `--allow-symlinks` | Allow deleting symbolic links. Off by default (symlinks are blocked). |
|
|
114
|
+
| `-y`, `--yes` | Skip the standard confirmation. Deletions over the size threshold still require typing `DELETE`. |
|
|
115
|
+
|
|
116
|
+
### `restore`
|
|
117
|
+
|
|
118
|
+
devklean moves items to your operating system's own trash, which the OS owns —
|
|
119
|
+
so recovery is done through your file manager's trash, not through devklean.
|
|
120
|
+
This command just shows you how:
|
|
121
|
+
|
|
122
|
+
```bash
|
|
123
|
+
devklean restore # explains how to recover from the Recycle Bin / Trash
|
|
124
|
+
```
|
|
125
|
+
|
|
126
|
+
- **Windows** — open the Recycle Bin and restore the item.
|
|
127
|
+
- **macOS** — open Trash in Finder and "Put Back".
|
|
128
|
+
- **Linux** — open Trash in your file manager and restore.
|
|
129
|
+
|
|
130
|
+
Run `devklean history` to see what was removed and when.
|
|
131
|
+
|
|
132
|
+
### `history`
|
|
133
|
+
|
|
134
|
+
```bash
|
|
135
|
+
devklean history # human-readable table of past cleanups
|
|
136
|
+
devklean history --json # machine-readable
|
|
137
|
+
```
|
|
138
|
+
|
|
139
|
+
### `doctor`
|
|
140
|
+
|
|
141
|
+
```bash
|
|
142
|
+
devklean doctor # report corrupt metadata; prompt before removing it
|
|
143
|
+
devklean doctor --yes # remove corrupt records without prompting
|
|
144
|
+
```
|
|
145
|
+
|
|
146
|
+
## Usage example
|
|
147
|
+
|
|
148
|
+
```text
|
|
149
|
+
$ devklean clean ~/code/my-app
|
|
150
|
+
devklean scanning /home/me/code/my-app...
|
|
151
|
+
|
|
152
|
+
TYPE SIZE PATH
|
|
153
|
+
──────────────────────────────────────────────────────────────────────
|
|
154
|
+
Node.js 612.0 MB /home/me/code/my-app/node_modules
|
|
155
|
+
Python venv 188.0 MB /home/me/code/my-app/.venv
|
|
156
|
+
Build output 34.0 MB /home/me/code/my-app/dist
|
|
157
|
+
──────────────────────────────────────────────────────────────────────
|
|
158
|
+
TOTAL 834.0 MB
|
|
159
|
+
|
|
160
|
+
Delete 3 directories (~834.0 MB)? (y/N) y
|
|
161
|
+
|
|
162
|
+
✓ /home/me/code/my-app/node_modules
|
|
163
|
+
✓ /home/me/code/my-app/.venv
|
|
164
|
+
✓ /home/me/code/my-app/dist
|
|
165
|
+
|
|
166
|
+
✓ Cleaned 3 directories, freed ~834.0 MB.
|
|
167
|
+
```
|
|
168
|
+
|
|
169
|
+
<!-- TODO: insert terminal recording GIF of interactive mode (`devklean clean -i`) here -->
|
|
170
|
+
|
|
171
|
+
## Platform support
|
|
172
|
+
|
|
173
|
+
`devklean` runs on **Linux, macOS, and Windows**. All core commands — `scan`,
|
|
174
|
+
`clean`, `history`, `doctor`, and `restore` — work on every platform.
|
|
175
|
+
|
|
176
|
+
**Known limitation:** interactive mode (`-i` / `--interactive`) is **Linux/macOS
|
|
177
|
+
only** for now. It is built on Python's `curses` module, which is not available
|
|
178
|
+
on Windows. Running `devklean clean -i` on Windows prints a clear message and
|
|
179
|
+
exits without making changes, rather than crashing — use `devklean clean`
|
|
180
|
+
(non-interactive) instead. Windows support for interactive mode may come in a
|
|
181
|
+
future release.
|
|
182
|
+
|
|
183
|
+
## Configuration
|
|
184
|
+
|
|
185
|
+
`devklean` reads TOML config with the precedence **project > global > built-in defaults**:
|
|
186
|
+
|
|
187
|
+
1. A project file `.devklean.toml`, discovered by walking up from the current directory.
|
|
188
|
+
2. The global file `~/.config/devklean/config.toml` (or `$XDG_CONFIG_HOME/devklean/config.toml`).
|
|
189
|
+
|
|
190
|
+
```toml
|
|
191
|
+
# ~/.config/devklean/config.toml or ./.devklean.toml
|
|
192
|
+
|
|
193
|
+
# Directory names to never touch (merged into the ignore list)
|
|
194
|
+
exclude = ["node_modules", ".git"]
|
|
195
|
+
|
|
196
|
+
[defaults]
|
|
197
|
+
dry_run = false
|
|
198
|
+
interactive = false
|
|
199
|
+
default_yes = false # skip the y/N prompt (the large-deletion DELETE gate still applies)
|
|
200
|
+
theme = "default" # "default" or "mono"
|
|
201
|
+
confirm_threshold = 1073741824 # bytes; deletions >= this require typing DELETE (default 1 GiB)
|
|
202
|
+
path = "."
|
|
203
|
+
|
|
204
|
+
[targets]
|
|
205
|
+
exclude = ["dist"] # remove built-in target *types*
|
|
206
|
+
[targets.custom]
|
|
207
|
+
".turbo" = "Turborepo cache" # add custom target directory types
|
|
208
|
+
|
|
209
|
+
[ignore]
|
|
210
|
+
paths = ["/keep/this/node_modules"] # absolute paths to skip
|
|
211
|
+
directories = ["vendor"] # directory names to skip
|
|
212
|
+
```
|
|
213
|
+
|
|
214
|
+
Scalar keys from the project file override the global file; list keys (`exclude`, `ignore.*`) are unioned. Unknown keys and malformed TOML produce a warning rather than a crash.
|
|
215
|
+
|
|
216
|
+
Color follows the `theme` setting and is automatically disabled when output is piped or `NO_COLOR` is set.
|
|
217
|
+
|
|
218
|
+
## Logs
|
|
219
|
+
|
|
220
|
+
`devklean` writes detailed structured logs (commands, scanned/deleted paths, sizes, errors) to:
|
|
221
|
+
|
|
222
|
+
```
|
|
223
|
+
~/.cache/devklean/logs/latest.log # or $XDG_CACHE_HOME/devklean/logs/latest.log
|
|
224
|
+
```
|
|
225
|
+
|
|
226
|
+
Logs rotate (5 backups) and are kept entirely separate from terminal output.
|
|
227
|
+
|
|
228
|
+
## FAQ
|
|
229
|
+
|
|
230
|
+
**Why didn't it delete something?**
|
|
231
|
+
`devklean` refuses to delete paths that should never be removed: the filesystem root, your home directory, mounted drive roots, protected system directories (`/etc`, `/usr`, …), and symbolic links. Symlinks can be allowed with `--allow-symlinks`. Each refusal prints the specific reason.
|
|
232
|
+
|
|
233
|
+
**It asked me to type `DELETE` — why?**
|
|
234
|
+
Deletions whose total size meets the `confirm_threshold` (default 1 GiB) require an explicit typed confirmation as an extra guard against large accidental deletes. This gate is intentionally **not** bypassed by `--yes` or `default_yes`; only `--dry-run` skips it.
|
|
235
|
+
|
|
236
|
+
**Where do deleted files go? Can I get them back?**
|
|
237
|
+
Items are moved to your operating system's native trash (Recycle Bin on Windows, Trash on macOS, the freedesktop trash on Linux), not permanently deleted. Recover them through your file manager's trash UI — devklean does not own that trash and can't move items back. Run `devklean history` to see what was removed, or `devklean restore` for recovery instructions.
|
|
238
|
+
|
|
239
|
+
**How do I exclude a folder?**
|
|
240
|
+
Add its name to `exclude` (global or project `.devklean.toml`), or an absolute path to `[ignore].paths`. See [Configuration](#configuration).
|
|
241
|
+
|
|
242
|
+
**Where are the logs?**
|
|
243
|
+
`~/.cache/devklean/logs/latest.log` (see [Logs](#logs)).
|
|
244
|
+
|
|
245
|
+
**How do I turn off colors?**
|
|
246
|
+
Set `NO_COLOR=1`, pipe the output, or set `theme = "mono"` in config.
|
|
247
|
+
|
|
248
|
+
**Something looks wrong with my history data.**
|
|
249
|
+
Run `devklean doctor` to detect and remove corrupt metadata records.
|
|
250
|
+
|
|
251
|
+
## Contributing
|
|
252
|
+
|
|
253
|
+
See [CONTRIBUTING.md](CONTRIBUTING.md). Bug reports and PRs are welcome.
|
|
254
|
+
|
|
255
|
+
## License
|
|
256
|
+
|
|
257
|
+
MIT — see [LICENSE](LICENSE).
|
devklean-1.0.0/README.md
ADDED
|
@@ -0,0 +1,221 @@
|
|
|
1
|
+
# devklean
|
|
2
|
+
|
|
3
|
+
[](https://github.com/smurftyy/devklean/actions/workflows/ci.yml)
|
|
4
|
+
[](https://pypi.org/project/devklean/)
|
|
5
|
+
[](https://pypi.org/project/devklean/)
|
|
6
|
+
[](https://github.com/smurftyy/devklean/blob/main/LICENSE)
|
|
7
|
+
|
|
8
|
+
**Reclaim disk space by safely cleaning up development artifacts** — `node_modules`, `.venv`, build caches, and other regenerable directories — with a trash-backed safety net so nothing is ever lost to a typo.
|
|
9
|
+
|
|
10
|
+
<!-- TODO: insert terminal recording GIF of `devklean clean` here -->
|
|
11
|
+
|
|
12
|
+
## Why
|
|
13
|
+
|
|
14
|
+
Development trees accumulate gigabytes of regenerable junk. `devklean` finds it, shows you exactly what it found and how big it is, and removes it **to your native system trash** — the Recycle Bin on Windows, Trash on macOS, the freedesktop trash on Linux — not `rm -rf`, so a mistaken delete is recoverable from your trash. It refuses to touch dangerous paths, makes large deletions require an explicit typed confirmation, and keeps a history of what it removed.
|
|
15
|
+
|
|
16
|
+
## Installation
|
|
17
|
+
|
|
18
|
+
```bash
|
|
19
|
+
# Recommended: isolated install as a standalone CLI tool
|
|
20
|
+
pipx install devklean
|
|
21
|
+
|
|
22
|
+
# Or into the current environment
|
|
23
|
+
pip install devklean
|
|
24
|
+
```
|
|
25
|
+
|
|
26
|
+
Requires Python 3.8+. Runtime dependencies are `send2trash` (used for all deletions) and `tomli` (only on Python < 3.11).
|
|
27
|
+
|
|
28
|
+
## Quick start
|
|
29
|
+
|
|
30
|
+
```bash
|
|
31
|
+
# See what could be cleaned under the current directory — no changes made
|
|
32
|
+
devklean scan
|
|
33
|
+
|
|
34
|
+
# Scan and delete (with confirmation), moving items to the trash
|
|
35
|
+
devklean clean
|
|
36
|
+
|
|
37
|
+
# Preview a clean without deleting anything
|
|
38
|
+
devklean clean --dry-run
|
|
39
|
+
```
|
|
40
|
+
|
|
41
|
+
## Commands
|
|
42
|
+
|
|
43
|
+
| Command | What it does |
|
|
44
|
+
| --- | --- |
|
|
45
|
+
| `devklean scan [PATH]` | Find cleanable directories and report sizes. Never deletes. |
|
|
46
|
+
| `devklean clean [PATH]` | Scan, then delete (to trash) after confirmation. |
|
|
47
|
+
| `devklean restore` | Explain how to recover deleted items from your system trash. |
|
|
48
|
+
| `devklean history` | Show previous cleanup operations (timestamp, size, strategy, item count). |
|
|
49
|
+
| `devklean doctor` | Inspect and repair the deletion metadata store. |
|
|
50
|
+
| `devklean --version` | Print the version. |
|
|
51
|
+
|
|
52
|
+
**Default command:** running `devklean` with no subcommand defaults to `clean` — so `devklean` is `devklean clean`, and `devklean ~/code` is `devklean clean ~/code`. As a convenience, a bare `devklean --dry-run` (without `-i`) is treated as a `scan` preview.
|
|
53
|
+
|
|
54
|
+
### `scan`
|
|
55
|
+
|
|
56
|
+
```bash
|
|
57
|
+
devklean scan # scan current directory
|
|
58
|
+
devklean scan ~/projects # scan a specific path
|
|
59
|
+
devklean scan --json # machine-readable output for tooling
|
|
60
|
+
```
|
|
61
|
+
|
|
62
|
+
### `clean`
|
|
63
|
+
|
|
64
|
+
```bash
|
|
65
|
+
devklean clean # scan + delete with a y/N confirmation
|
|
66
|
+
devklean clean ~/projects # clean a specific path
|
|
67
|
+
devklean clean --dry-run # show what *would* be deleted; delete nothing
|
|
68
|
+
devklean clean -i # interactive: pick items in a TUI (Linux/macOS only)
|
|
69
|
+
devklean clean --allow-symlinks # permit deleting symlinked targets (blocked by default)
|
|
70
|
+
devklean clean -y # skip the y/N prompt (large deletions still require typing DELETE)
|
|
71
|
+
```
|
|
72
|
+
|
|
73
|
+
| Flag | Meaning |
|
|
74
|
+
| --- | --- |
|
|
75
|
+
| `--dry-run` | Report what would be deleted; make no changes. Output says "would delete". |
|
|
76
|
+
| `-i`, `--interactive` | Choose items in a terminal UI (SPACE select, A all, D none, ENTER confirm, Q quit). **Linux/macOS only** — see [Platform support](#platform-support). |
|
|
77
|
+
| `--allow-symlinks` | Allow deleting symbolic links. Off by default (symlinks are blocked). |
|
|
78
|
+
| `-y`, `--yes` | Skip the standard confirmation. Deletions over the size threshold still require typing `DELETE`. |
|
|
79
|
+
|
|
80
|
+
### `restore`
|
|
81
|
+
|
|
82
|
+
devklean moves items to your operating system's own trash, which the OS owns —
|
|
83
|
+
so recovery is done through your file manager's trash, not through devklean.
|
|
84
|
+
This command just shows you how:
|
|
85
|
+
|
|
86
|
+
```bash
|
|
87
|
+
devklean restore # explains how to recover from the Recycle Bin / Trash
|
|
88
|
+
```
|
|
89
|
+
|
|
90
|
+
- **Windows** — open the Recycle Bin and restore the item.
|
|
91
|
+
- **macOS** — open Trash in Finder and "Put Back".
|
|
92
|
+
- **Linux** — open Trash in your file manager and restore.
|
|
93
|
+
|
|
94
|
+
Run `devklean history` to see what was removed and when.
|
|
95
|
+
|
|
96
|
+
### `history`
|
|
97
|
+
|
|
98
|
+
```bash
|
|
99
|
+
devklean history # human-readable table of past cleanups
|
|
100
|
+
devklean history --json # machine-readable
|
|
101
|
+
```
|
|
102
|
+
|
|
103
|
+
### `doctor`
|
|
104
|
+
|
|
105
|
+
```bash
|
|
106
|
+
devklean doctor # report corrupt metadata; prompt before removing it
|
|
107
|
+
devklean doctor --yes # remove corrupt records without prompting
|
|
108
|
+
```
|
|
109
|
+
|
|
110
|
+
## Usage example
|
|
111
|
+
|
|
112
|
+
```text
|
|
113
|
+
$ devklean clean ~/code/my-app
|
|
114
|
+
devklean scanning /home/me/code/my-app...
|
|
115
|
+
|
|
116
|
+
TYPE SIZE PATH
|
|
117
|
+
──────────────────────────────────────────────────────────────────────
|
|
118
|
+
Node.js 612.0 MB /home/me/code/my-app/node_modules
|
|
119
|
+
Python venv 188.0 MB /home/me/code/my-app/.venv
|
|
120
|
+
Build output 34.0 MB /home/me/code/my-app/dist
|
|
121
|
+
──────────────────────────────────────────────────────────────────────
|
|
122
|
+
TOTAL 834.0 MB
|
|
123
|
+
|
|
124
|
+
Delete 3 directories (~834.0 MB)? (y/N) y
|
|
125
|
+
|
|
126
|
+
✓ /home/me/code/my-app/node_modules
|
|
127
|
+
✓ /home/me/code/my-app/.venv
|
|
128
|
+
✓ /home/me/code/my-app/dist
|
|
129
|
+
|
|
130
|
+
✓ Cleaned 3 directories, freed ~834.0 MB.
|
|
131
|
+
```
|
|
132
|
+
|
|
133
|
+
<!-- TODO: insert terminal recording GIF of interactive mode (`devklean clean -i`) here -->
|
|
134
|
+
|
|
135
|
+
## Platform support
|
|
136
|
+
|
|
137
|
+
`devklean` runs on **Linux, macOS, and Windows**. All core commands — `scan`,
|
|
138
|
+
`clean`, `history`, `doctor`, and `restore` — work on every platform.
|
|
139
|
+
|
|
140
|
+
**Known limitation:** interactive mode (`-i` / `--interactive`) is **Linux/macOS
|
|
141
|
+
only** for now. It is built on Python's `curses` module, which is not available
|
|
142
|
+
on Windows. Running `devklean clean -i` on Windows prints a clear message and
|
|
143
|
+
exits without making changes, rather than crashing — use `devklean clean`
|
|
144
|
+
(non-interactive) instead. Windows support for interactive mode may come in a
|
|
145
|
+
future release.
|
|
146
|
+
|
|
147
|
+
## Configuration
|
|
148
|
+
|
|
149
|
+
`devklean` reads TOML config with the precedence **project > global > built-in defaults**:
|
|
150
|
+
|
|
151
|
+
1. A project file `.devklean.toml`, discovered by walking up from the current directory.
|
|
152
|
+
2. The global file `~/.config/devklean/config.toml` (or `$XDG_CONFIG_HOME/devklean/config.toml`).
|
|
153
|
+
|
|
154
|
+
```toml
|
|
155
|
+
# ~/.config/devklean/config.toml or ./.devklean.toml
|
|
156
|
+
|
|
157
|
+
# Directory names to never touch (merged into the ignore list)
|
|
158
|
+
exclude = ["node_modules", ".git"]
|
|
159
|
+
|
|
160
|
+
[defaults]
|
|
161
|
+
dry_run = false
|
|
162
|
+
interactive = false
|
|
163
|
+
default_yes = false # skip the y/N prompt (the large-deletion DELETE gate still applies)
|
|
164
|
+
theme = "default" # "default" or "mono"
|
|
165
|
+
confirm_threshold = 1073741824 # bytes; deletions >= this require typing DELETE (default 1 GiB)
|
|
166
|
+
path = "."
|
|
167
|
+
|
|
168
|
+
[targets]
|
|
169
|
+
exclude = ["dist"] # remove built-in target *types*
|
|
170
|
+
[targets.custom]
|
|
171
|
+
".turbo" = "Turborepo cache" # add custom target directory types
|
|
172
|
+
|
|
173
|
+
[ignore]
|
|
174
|
+
paths = ["/keep/this/node_modules"] # absolute paths to skip
|
|
175
|
+
directories = ["vendor"] # directory names to skip
|
|
176
|
+
```
|
|
177
|
+
|
|
178
|
+
Scalar keys from the project file override the global file; list keys (`exclude`, `ignore.*`) are unioned. Unknown keys and malformed TOML produce a warning rather than a crash.
|
|
179
|
+
|
|
180
|
+
Color follows the `theme` setting and is automatically disabled when output is piped or `NO_COLOR` is set.
|
|
181
|
+
|
|
182
|
+
## Logs
|
|
183
|
+
|
|
184
|
+
`devklean` writes detailed structured logs (commands, scanned/deleted paths, sizes, errors) to:
|
|
185
|
+
|
|
186
|
+
```
|
|
187
|
+
~/.cache/devklean/logs/latest.log # or $XDG_CACHE_HOME/devklean/logs/latest.log
|
|
188
|
+
```
|
|
189
|
+
|
|
190
|
+
Logs rotate (5 backups) and are kept entirely separate from terminal output.
|
|
191
|
+
|
|
192
|
+
## FAQ
|
|
193
|
+
|
|
194
|
+
**Why didn't it delete something?**
|
|
195
|
+
`devklean` refuses to delete paths that should never be removed: the filesystem root, your home directory, mounted drive roots, protected system directories (`/etc`, `/usr`, …), and symbolic links. Symlinks can be allowed with `--allow-symlinks`. Each refusal prints the specific reason.
|
|
196
|
+
|
|
197
|
+
**It asked me to type `DELETE` — why?**
|
|
198
|
+
Deletions whose total size meets the `confirm_threshold` (default 1 GiB) require an explicit typed confirmation as an extra guard against large accidental deletes. This gate is intentionally **not** bypassed by `--yes` or `default_yes`; only `--dry-run` skips it.
|
|
199
|
+
|
|
200
|
+
**Where do deleted files go? Can I get them back?**
|
|
201
|
+
Items are moved to your operating system's native trash (Recycle Bin on Windows, Trash on macOS, the freedesktop trash on Linux), not permanently deleted. Recover them through your file manager's trash UI — devklean does not own that trash and can't move items back. Run `devklean history` to see what was removed, or `devklean restore` for recovery instructions.
|
|
202
|
+
|
|
203
|
+
**How do I exclude a folder?**
|
|
204
|
+
Add its name to `exclude` (global or project `.devklean.toml`), or an absolute path to `[ignore].paths`. See [Configuration](#configuration).
|
|
205
|
+
|
|
206
|
+
**Where are the logs?**
|
|
207
|
+
`~/.cache/devklean/logs/latest.log` (see [Logs](#logs)).
|
|
208
|
+
|
|
209
|
+
**How do I turn off colors?**
|
|
210
|
+
Set `NO_COLOR=1`, pipe the output, or set `theme = "mono"` in config.
|
|
211
|
+
|
|
212
|
+
**Something looks wrong with my history data.**
|
|
213
|
+
Run `devklean doctor` to detect and remove corrupt metadata records.
|
|
214
|
+
|
|
215
|
+
## Contributing
|
|
216
|
+
|
|
217
|
+
See [CONTRIBUTING.md](CONTRIBUTING.md). Bug reports and PRs are welcome.
|
|
218
|
+
|
|
219
|
+
## License
|
|
220
|
+
|
|
221
|
+
MIT — see [LICENSE](LICENSE).
|