mirror of
https://github.com/tw93/Mole.git
synced 2026-02-04 15:04:42 +00:00
feat: add --dry-run preview mode for cleanup and interactive d shortcut
This commit is contained in:
32
README.md
32
README.md
@@ -23,6 +23,7 @@ curl -fsSL https://raw.githubusercontent.com/tw93/mole/main/install.sh | bash
|
|||||||
```bash
|
```bash
|
||||||
mole # Interactive main menu
|
mole # Interactive main menu
|
||||||
mole clean # Deep system cleanup
|
mole clean # Deep system cleanup
|
||||||
|
mole clean --dry-run # Preview cleanup (no deletions)
|
||||||
mole uninstall # Interactive app uninstaller
|
mole uninstall # Interactive app uninstaller
|
||||||
mole analyze [path]# Analyze disk space (default: home directory)
|
mole analyze [path]# Analyze disk space (default: home directory)
|
||||||
mole --help # Show help
|
mole --help # Show help
|
||||||
@@ -117,6 +118,37 @@ $ mole analyze ~/Downloads
|
|||||||
|
|
||||||
Items (sorted by size):
|
Items (sorted by size):
|
||||||
|
|
||||||
|
### Dry Run Preview
|
||||||
|
|
||||||
|
Before actually deleting, you can preview what would be removed:
|
||||||
|
|
||||||
|
```bash
|
||||||
|
mole clean --dry-run
|
||||||
|
```
|
||||||
|
|
||||||
|
In interactive menu: select Clean System and press `d` instead of Enter.
|
||||||
|
|
||||||
|
Sample output:
|
||||||
|
```bash
|
||||||
|
$ mole clean --dry-run
|
||||||
|
|
||||||
|
🧪 Dry Run mode: showing what would be removed (no deletions).
|
||||||
|
|
||||||
|
▶ System essentials
|
||||||
|
→ User app cache (45.2GB, dry)
|
||||||
|
→ User app logs (2.1GB, dry)
|
||||||
|
→ Trash (12.3GB, dry)
|
||||||
|
|
||||||
|
▶ Browser cleanup
|
||||||
|
→ Chrome cache (8.4GB, dry)
|
||||||
|
→ Safari cache (2.1GB, dry)
|
||||||
|
|
||||||
|
====================================================================
|
||||||
|
🧪 DRY RUN COMPLETE!
|
||||||
|
💾 Potential reclaimable space: 72.00GB (no changes made) | Free space now: 223.5GB
|
||||||
|
====================================================================
|
||||||
|
```
|
||||||
|
|
||||||
TYPE SIZE NAME
|
TYPE SIZE NAME
|
||||||
────────────────────────────────────────────────────────────────────────────────
|
────────────────────────────────────────────────────────────────────────────────
|
||||||
▶ 📁 33.72GB materials ← Use arrow keys to select
|
▶ 📁 33.72GB materials ← Use arrow keys to select
|
||||||
|
|||||||
97
bin/clean.sh
97
bin/clean.sh
@@ -10,6 +10,7 @@ source "$SCRIPT_DIR/../lib/common.sh"
|
|||||||
|
|
||||||
# Configuration
|
# Configuration
|
||||||
SYSTEM_CLEAN=false
|
SYSTEM_CLEAN=false
|
||||||
|
DRY_RUN=false
|
||||||
IS_M_SERIES=$([ "$(uname -m)" = "arm64" ] && echo "true" || echo "false")
|
IS_M_SERIES=$([ "$(uname -m)" = "arm64" ] && echo "true" || echo "false")
|
||||||
total_items=0
|
total_items=0
|
||||||
|
|
||||||
@@ -174,7 +175,9 @@ safe_clean() {
|
|||||||
if [[ -f "$temp_dir/$hash" ]]; then
|
if [[ -f "$temp_dir/$hash" ]]; then
|
||||||
read -r size count < "$temp_dir/$hash"
|
read -r size count < "$temp_dir/$hash"
|
||||||
if [[ "$count" -gt 0 && "$size" -gt 0 ]]; then
|
if [[ "$count" -gt 0 && "$size" -gt 0 ]]; then
|
||||||
rm -rf "$path" 2>/dev/null || true
|
if [[ "$DRY_RUN" != "true" ]]; then
|
||||||
|
rm -rf "$path" 2>/dev/null || true
|
||||||
|
fi
|
||||||
((total_size_bytes += size))
|
((total_size_bytes += size))
|
||||||
((total_count += count))
|
((total_count += count))
|
||||||
removed_any=1
|
removed_any=1
|
||||||
@@ -190,7 +193,9 @@ safe_clean() {
|
|||||||
local count=$(find "$path" -type f 2>/dev/null | wc -l | tr -d ' ')
|
local count=$(find "$path" -type f 2>/dev/null | wc -l | tr -d ' ')
|
||||||
|
|
||||||
if [[ "$count" -gt 0 && "$size_bytes" -gt 0 ]]; then
|
if [[ "$count" -gt 0 && "$size_bytes" -gt 0 ]]; then
|
||||||
rm -rf "$path" 2>/dev/null || true
|
if [[ "$DRY_RUN" != "true" ]]; then
|
||||||
|
rm -rf "$path" 2>/dev/null || true
|
||||||
|
fi
|
||||||
((total_size_bytes += size_bytes))
|
((total_size_bytes += size_bytes))
|
||||||
((total_count += count))
|
((total_count += count))
|
||||||
removed_any=1
|
removed_any=1
|
||||||
@@ -214,7 +219,11 @@ safe_clean() {
|
|||||||
label+=" (${#targets[@]} items)"
|
label+=" (${#targets[@]} items)"
|
||||||
fi
|
fi
|
||||||
|
|
||||||
echo -e " ${GREEN}✓${NC} $label ${GREEN}($size_human)${NC}"
|
if [[ "$DRY_RUN" == "true" ]]; then
|
||||||
|
echo -e " ${YELLOW}→${NC} $label ${YELLOW}($size_human, dry)${NC}"
|
||||||
|
else
|
||||||
|
echo -e " ${GREEN}✓${NC} $label ${GREEN}($size_human)${NC}"
|
||||||
|
fi
|
||||||
((files_cleaned+=total_count))
|
((files_cleaned+=total_count))
|
||||||
((total_size_cleaned+=total_size_bytes))
|
((total_size_cleaned+=total_size_bytes))
|
||||||
((total_items++))
|
((total_items++))
|
||||||
@@ -229,6 +238,14 @@ start_cleanup() {
|
|||||||
echo "Mole will remove app caches, browser data, developer tools, and temporary files."
|
echo "Mole will remove app caches, browser data, developer tools, and temporary files."
|
||||||
echo ""
|
echo ""
|
||||||
|
|
||||||
|
if [[ "$DRY_RUN" == "true" ]]; then
|
||||||
|
echo -e "${YELLOW}🧪 Dry Run mode:${NC} showing what would be removed (no deletions)."
|
||||||
|
echo ""
|
||||||
|
password=""
|
||||||
|
SYSTEM_CLEAN=false
|
||||||
|
return
|
||||||
|
fi
|
||||||
|
|
||||||
# Check if we're in an interactive terminal
|
# Check if we're in an interactive terminal
|
||||||
if [[ -t 0 ]]; then
|
if [[ -t 0 ]]; then
|
||||||
# Interactive mode - ask for password
|
# Interactive mode - ask for password
|
||||||
@@ -783,21 +800,35 @@ perform_cleanup() {
|
|||||||
|
|
||||||
echo ""
|
echo ""
|
||||||
echo "===================================================================="
|
echo "===================================================================="
|
||||||
echo "🎉 CLEANUP COMPLETE!"
|
if [[ "$DRY_RUN" == "true" ]]; then
|
||||||
|
echo "🧪 DRY RUN COMPLETE!"
|
||||||
|
else
|
||||||
|
echo "🎉 CLEANUP COMPLETE!"
|
||||||
|
fi
|
||||||
|
|
||||||
if [[ $total_size_cleaned -gt 0 ]]; then
|
if [[ $total_size_cleaned -gt 0 ]]; then
|
||||||
local freed_gb=$(echo "$total_size_cleaned" | awk '{printf "%.2f", $1/1024/1024}')
|
local freed_gb=$(echo "$total_size_cleaned" | awk '{printf "%.2f", $1/1024/1024}')
|
||||||
echo "💾 Space freed: ${GREEN}${freed_gb}GB${NC} | Free space now: $(get_free_space)"
|
if [[ "$DRY_RUN" == "true" ]]; then
|
||||||
|
echo "💾 Potential reclaimable space: ${GREEN}${freed_gb}GB${NC} (no changes made) | Free space now: $(get_free_space)"
|
||||||
|
else
|
||||||
|
echo "💾 Space freed: ${GREEN}${freed_gb}GB${NC} | Free space now: $(get_free_space)"
|
||||||
|
fi
|
||||||
|
|
||||||
# Add some context to make it more impressive
|
if [[ "$DRY_RUN" != "true" ]]; then
|
||||||
if [[ $(echo "$freed_gb" | awk '{print ($1 >= 1) ? 1 : 0}') -eq 1 ]]; then
|
# Add some context when actually freed
|
||||||
local movies=$(echo "$freed_gb" | awk '{printf "%.0f", $1/4.5}')
|
if [[ $(echo "$freed_gb" | awk '{print ($1 >= 1) ? 1 : 0}') -eq 1 ]]; then
|
||||||
if [[ $movies -gt 0 ]]; then
|
local movies=$(echo "$freed_gb" | awk '{printf "%.0f", $1/4.5}')
|
||||||
echo "🎬 That's like ~$movies 4K movies worth of space!"
|
if [[ $movies -gt 0 ]]; then
|
||||||
|
echo "🎬 That's like ~$movies 4K movies worth of space!"
|
||||||
|
fi
|
||||||
fi
|
fi
|
||||||
fi
|
fi
|
||||||
else
|
else
|
||||||
echo "💾 No significant space was freed (system was already clean) | Free space: $(get_free_space)"
|
if [[ "$DRY_RUN" == "true" ]]; then
|
||||||
|
echo "💾 No significant reclaimable space detected (already clean) | Free space: $(get_free_space)"
|
||||||
|
else
|
||||||
|
echo "💾 No significant space was freed (system was already clean) | Free space: $(get_free_space)"
|
||||||
|
fi
|
||||||
fi
|
fi
|
||||||
|
|
||||||
if [[ $files_cleaned -gt 0 && $total_items -gt 0 ]]; then
|
if [[ $files_cleaned -gt 0 && $total_items -gt 0 ]]; then
|
||||||
@@ -834,25 +865,31 @@ cleanup() {
|
|||||||
trap cleanup EXIT INT TERM
|
trap cleanup EXIT INT TERM
|
||||||
|
|
||||||
main() {
|
main() {
|
||||||
case "${1:-""}" in
|
# Parse args (only dry-run and help for minimal impact)
|
||||||
"--help"|"-h")
|
for arg in "$@"; do
|
||||||
echo "Mole - Deeper system cleanup"
|
case "$arg" in
|
||||||
echo "Usage: clean.sh [options]"
|
"--dry-run"|"-n")
|
||||||
echo ""
|
DRY_RUN=true
|
||||||
echo "Options:"
|
;;
|
||||||
echo " --help, -h Show this help"
|
"--help"|"-h")
|
||||||
echo ""
|
echo "Mole - Deeper system cleanup"
|
||||||
echo "Interactive cleanup with smart password handling"
|
echo "Usage: clean.sh [options]"
|
||||||
echo ""
|
echo ""
|
||||||
exit 0
|
echo "Options:"
|
||||||
;;
|
echo " --help, -h Show this help"
|
||||||
*)
|
echo " --dry-run, -n Preview what would be cleaned without deleting"
|
||||||
hide_cursor
|
echo ""
|
||||||
start_cleanup
|
echo "Interactive cleanup with smart password handling"
|
||||||
perform_cleanup
|
echo ""
|
||||||
show_cursor
|
exit 0
|
||||||
;;
|
;;
|
||||||
esac
|
esac
|
||||||
|
done
|
||||||
|
|
||||||
|
hide_cursor
|
||||||
|
start_cleanup
|
||||||
|
perform_cleanup
|
||||||
|
show_cursor
|
||||||
}
|
}
|
||||||
|
|
||||||
main "$@"
|
main "$@"
|
||||||
|
|||||||
28
mole
28
mole
@@ -267,7 +267,19 @@ interactive_main_menu() {
|
|||||||
printf '\033[u\033[J' # Clear menu
|
printf '\033[u\033[J' # Clear menu
|
||||||
show_cursor
|
show_cursor
|
||||||
case $current_option in
|
case $current_option in
|
||||||
1) exec "$SCRIPT_DIR/bin/clean.sh" ;;
|
1)
|
||||||
|
echo -e "${BLUE}Press 'd' for Dry Run preview, Enter to start cleaning (q to cancel)${NC}"
|
||||||
|
IFS= read -r -s -n1 key2 || true
|
||||||
|
if [[ "$key2" == $'\n' || -z "$key2" ]]; then
|
||||||
|
exec "$SCRIPT_DIR/bin/clean.sh"
|
||||||
|
elif [[ "$key2" == "d" || "$key2" == "D" ]]; then
|
||||||
|
exec "$SCRIPT_DIR/bin/clean.sh" --dry-run
|
||||||
|
elif [[ "$key2" == "q" || "$key2" == "Q" ]]; then
|
||||||
|
:
|
||||||
|
else
|
||||||
|
exec "$SCRIPT_DIR/bin/clean.sh"
|
||||||
|
fi
|
||||||
|
;;
|
||||||
2) exec "$SCRIPT_DIR/bin/uninstall.sh" ;;
|
2) exec "$SCRIPT_DIR/bin/uninstall.sh" ;;
|
||||||
3) clear; show_help; exit 0 ;;
|
3) clear; show_help; exit 0 ;;
|
||||||
4) cleanup_and_exit ;;
|
4) cleanup_and_exit ;;
|
||||||
@@ -278,7 +290,19 @@ interactive_main_menu() {
|
|||||||
printf '\033[u\033[J'
|
printf '\033[u\033[J'
|
||||||
show_cursor
|
show_cursor
|
||||||
case $key in
|
case $key in
|
||||||
1) exec "$SCRIPT_DIR/bin/clean.sh" ;;
|
1)
|
||||||
|
echo -e "${BLUE}Press 'd' for Dry Run preview, Enter to start cleaning (q to cancel)${NC}"
|
||||||
|
IFS= read -r -s -n1 key2 || true
|
||||||
|
if [[ "$key2" == $'\n' || -z "$key2" ]]; then
|
||||||
|
exec "$SCRIPT_DIR/bin/clean.sh"
|
||||||
|
elif [[ "$key2" == "d" || "$key2" == "D" ]]; then
|
||||||
|
exec "$SCRIPT_DIR/bin/clean.sh" --dry-run
|
||||||
|
elif [[ "$key2" == "q" || "$key2" == "Q" ]]; then
|
||||||
|
:
|
||||||
|
else
|
||||||
|
exec "$SCRIPT_DIR/bin/clean.sh"
|
||||||
|
fi
|
||||||
|
;;
|
||||||
2) exec "$SCRIPT_DIR/bin/uninstall.sh" ;;
|
2) exec "$SCRIPT_DIR/bin/uninstall.sh" ;;
|
||||||
3) clear; show_help; exit 0 ;;
|
3) clear; show_help; exit 0 ;;
|
||||||
4) cleanup_and_exit ;;
|
4) cleanup_and_exit ;;
|
||||||
|
|||||||
Reference in New Issue
Block a user