Skip to content

Instantly share code, notes, and snippets.

@radityagumay
Created April 13, 2026 00:34
Show Gist options
  • Select an option

  • Save radityagumay/8cda5c0785d5750cc1dedf7b55e78704 to your computer and use it in GitHub Desktop.

Select an option

Save radityagumay/8cda5c0785d5750cc1dedf7b55e78704 to your computer and use it in GitHub Desktop.
A scripts to delete android build directories
#!/bin/bash
# ╔══════════════════════════════════════════════════════════════════╗
# ║ clean_android_builds.sh — README ║
# ╠══════════════════════════════════════════════════════════════════╣
# ║ ║
# ║ DESCRIPTION ║
# ║ Recursively removes all `build/` directories across every ║
# ║ module in every Android project under a given root directory. ║
# ║ Gradle build outputs can balloon to several GBs over time; ║
# ║ this script reclaims that space safely and quickly. ║
# ║ ║
# ║ USAGE ║
# ║ ./clean_android_builds.sh [OPTIONS] [root_dir] ║
# ║ ║
# ║ OPTIONS ║
# ║ --dry-run Preview deletions without removing anything. ║
# ║ Always run this first to sanity-check the list. ║
# ║ --help Show usage information and exit. ║
# ║ ║
# ║ ARGUMENTS ║
# ║ root_dir Path to the folder containing your Android ║
# ║ projects. Flags and path can be in any order. ║
# ║ Default: /Users/raditya.gumay/Documents/ ║
# ║ AndroidProjects ║
# ║ ║
# ║ EXAMPLES ║
# ║ # Preview what would be deleted (safe, no changes) ║
# ║ ./clean_android_builds.sh --dry-run ║
# ║ ║
# ║ # Delete all build dirs under the default root ║
# ║ ./clean_android_builds.sh ║
# ║ ║
# ║ # Delete build dirs under a custom path ║
# ║ ./clean_android_builds.sh ~/Projects/MyAndroidApps ║
# ║ ║
# ║ # Dry run against a custom path ║
# ║ ./clean_android_builds.sh --dry-run ~/Projects/MyAndroidApps ║
# ║ ║
# ║ WHAT IT CLEANS ║
# ║ Every directory named `build/` found recursively under ║
# ║ root_dir. This covers: ║
# ║ • Top-level project build/ ║
# ║ • Per-module build/ (app, core, feature-*, etc.) ║
# ║ It does NOT delete: ║
# ║ • build/ dirs nested inside another build/ (deduped) ║
# ║ • Anything inside .git/ directories ║
# ║ ║
# ║ SETUP ║
# ║ chmod +x clean_android_builds.sh ║
# ║ ║
# ║ REQUIREMENTS ║
# ║ bash, find, du, bc (all available by default on macOS) ║
# ║ ║
# ║ AUTHOR ║
# ║ Raditya Gumay — GoTo Maps & Navigation Platform ║
# ║ ║
# ╚══════════════════════════════════════════════════════════════════╝
ROOT_DIR="/Users/raditya.gumay/Documents/AndroidProjects"
DRY_RUN=false
TOTAL_FREED=0
CLEANED_COUNT=0
SKIPPED_COUNT=0
# ── Parse flags ──────────────────────────────────────────────
for arg in "$@"; do
case $arg in
--dry-run) DRY_RUN=true ;;
--help)
echo "Usage: $0 [--dry-run] [root_dir]"
echo ""
echo " root_dir Root directory containing your Android projects."
echo " Default: /Users/raditya.gumay/Documents/AndroidProjects"
echo " --dry-run Preview what would be deleted without removing anything."
exit 0
;;
--*) echo "Unknown flag: $arg"; exit 1 ;;
*) ROOT_DIR="$arg" ;;
esac
done
# ── Colors ───────────────────────────────────────────────────
RED='\033[0;31m'
GREEN='\033[0;32m'
YELLOW='\033[1;33m'
CYAN='\033[0;36m'
BOLD='\033[1m'
RESET='\033[0m'
# ── Helpers ──────────────────────────────────────────────────
human_readable_size() {
local size=$1
if [ "$size" -ge 1073741824 ]; then
echo "$(echo "scale=2; $size/1073741824" | bc) GB"
elif [ "$size" -ge 1048576 ]; then
echo "$(echo "scale=2; $size/1048576" | bc) MB"
elif [ "$size" -ge 1024 ]; then
echo "$(echo "scale=2; $size/1024" | bc) KB"
else
echo "${size} B"
fi
}
dir_size_bytes() {
du -sk "$1" 2>/dev/null | awk '{print $1 * 1024}'
}
# ── Validate root dir ────────────────────────────────────────
if [ ! -d "$ROOT_DIR" ]; then
echo -e "${RED}Error: Directory '$ROOT_DIR' does not exist.${RESET}"
exit 1
fi
echo ""
echo -e "${BOLD}╔══════════════════════════════════════════════════╗${RESET}"
echo -e "${BOLD}║ Android Build Directory Cleaner ║${RESET}"
echo -e "${BOLD}╚══════════════════════════════════════════════════╝${RESET}"
echo ""
echo -e " 📁 Root : ${CYAN}$ROOT_DIR${RESET}"
if $DRY_RUN; then
echo -e " 🔍 Mode : ${YELLOW}DRY RUN (nothing will be deleted)${RESET}"
else
echo -e " 🗑️ Mode : ${RED}LIVE (build dirs will be deleted)${RESET}"
fi
echo ""
# ── Ask for confirmation unless dry-run ──────────────────────
if ! $DRY_RUN; then
read -r -p " Continue? [y/N] " confirm
case "$confirm" in
[yY][eE][sS]|[yY]) echo "" ;;
*)
echo -e "\n ${YELLOW}Aborted.${RESET}\n"
exit 0
;;
esac
fi
# ── Find and process all build/ directories ──────────────────
# Exclude any build/ dir that is itself inside another build/ dir
# to avoid double-counting nested hits.
while IFS= read -r build_dir; do
size_bytes=$(dir_size_bytes "$build_dir")
size_human=$(human_readable_size "$size_bytes")
if $DRY_RUN; then
echo -e " ${YELLOW}[DRY RUN]${RESET} Would remove: ${CYAN}$build_dir${RESET} (${size_human})"
TOTAL_FREED=$((TOTAL_FREED + size_bytes))
CLEANED_COUNT=$((CLEANED_COUNT + 1))
else
echo -ne " 🗑️ Removing: ${CYAN}$build_dir${RESET} (${size_human}) ... "
if rm -rf "$build_dir" 2>/dev/null; then
echo -e "${GREEN}done${RESET}"
TOTAL_FREED=$((TOTAL_FREED + size_bytes))
CLEANED_COUNT=$((CLEANED_COUNT + 1))
else
echo -e "${RED}failed${RESET}"
SKIPPED_COUNT=$((SKIPPED_COUNT + 1))
fi
fi
done < <(find "$ROOT_DIR" -type d -name "build" \
! -path "*/build/*/build" \
! -path "*/.git/*" \
2>/dev/null | sort)
# ── Summary ──────────────────────────────────────────────────
echo ""
echo -e "${BOLD}─────────────────────────────────────────────────────${RESET}"
if $DRY_RUN; then
echo -e " ${YELLOW}[DRY RUN] Summary${RESET}"
echo -e " Directories that would be removed : ${BOLD}$CLEANED_COUNT${RESET}"
echo -e " Estimated space to be freed : ${BOLD}$(human_readable_size $TOTAL_FREED)${RESET}"
else
echo -e " ${GREEN}✅ Clean complete!${RESET}"
echo -e " Directories removed : ${BOLD}$CLEANED_COUNT${RESET}"
echo -e " Failed / skipped : ${BOLD}$SKIPPED_COUNT${RESET}"
echo -e " Space freed : ${BOLD}$(human_readable_size $TOTAL_FREED)${RESET}"
fi
echo -e "${BOLD}─────────────────────────────────────────────────────${RESET}"
echo ""
@radityagumay

Copy link
Copy Markdown
Author

Examples!

Screenshot 2026-04-13 at 7 35 13 AM Screenshot 2026-04-13 at 7 35 31 AM Screenshot 2026-04-13 at 7 35 24 AM

Sign up for free to join this conversation on GitHub. Already have an account? Sign in to comment