From 65b0db4e1c6d0a4d1e90f4a39ece076e92341baa Mon Sep 17 00:00:00 2001 From: Nour <104147021+MohammedTarigg@users.noreply.github.com> Date: Tue, 10 Mar 2026 11:20:40 +0300 Subject: [PATCH] feat(clean): add opt-in Docker unused data pruning (#554) * feat(clean): add opt-in Docker unused data pruning * fix(clean): make docker prune default --------- Co-authored-by: Tw93 --- lib/clean/dev.sh | 9 +++++++-- tests/clean_dev_caches.bats | 36 +++++++++++++++++++++++++++++++----- 2 files changed, 38 insertions(+), 7 deletions(-) diff --git a/lib/clean/dev.sh b/lib/clean/dev.sh index fb8eefd..97c0905 100644 --- a/lib/clean/dev.sh +++ b/lib/clean/dev.sh @@ -198,13 +198,18 @@ clean_dev_docker() { fi stop_section_spinner if [[ "$docker_running" == "true" ]]; then - clean_tool_cache "Docker build cache" docker builder prune -af + # Remove unused images, stopped containers, unused networks, and + # anonymous volumes in one pass. This maps better to the large + # reclaimable "docker system df" buckets users typically see. + clean_tool_cache "Docker unused data" docker system prune -af --volumes else + echo -e " ${GRAY}${ICON_WARNING}${NC} Docker unused data · skipped (daemon not running)" + note_activity debug_log "Docker daemon not running, skipping Docker cache cleanup" fi else note_activity - echo -e " ${YELLOW}${ICON_DRY_RUN}${NC} Docker build cache · would clean" + echo -e " ${YELLOW}${ICON_DRY_RUN}${NC} Docker unused data · would clean" fi fi safe_clean ~/.docker/buildx/cache/* "Docker BuildX cache" diff --git a/tests/clean_dev_caches.bats b/tests/clean_dev_caches.bats index 9a2137e..dfa12b0 100644 --- a/tests/clean_dev_caches.bats +++ b/tests/clean_dev_caches.bats @@ -160,24 +160,50 @@ EOF } @test "clean_dev_docker skips when daemon not running" { - run env HOME="$HOME" PROJECT_ROOT="$PROJECT_ROOT" MO_DEBUG=1 DRY_RUN=false bash --noprofile --norc <<'EOF' + run env HOME="$HOME" PROJECT_ROOT="$PROJECT_ROOT" DRY_RUN=false bash --noprofile --norc <<'EOF' set -euo pipefail source "$PROJECT_ROOT/lib/core/common.sh" source "$PROJECT_ROOT/lib/clean/dev.sh" start_section_spinner() { :; } stop_section_spinner() { :; } run_with_timeout() { return 1; } -clean_tool_cache() { echo "$1"; } safe_clean() { echo "$2"; } -debug_log() { echo "$*"; } +debug_log() { :; } docker() { return 1; } export -f docker clean_dev_docker EOF [ "$status" -eq 0 ] - [[ "$output" == *"Docker daemon not running"* ]] - [[ "$output" != *"Docker build cache"* ]] + [[ "$output" == *"Docker unused data · skipped (daemon not running)"* ]] + [[ "$output" == *"Docker BuildX cache"* ]] + [[ "$output" != *"Docker unused data|Docker unused data docker system prune -af --volumes"* ]] +} + +@test "clean_dev_docker prunes unused docker data when daemon is running" { + run env HOME="$HOME" PROJECT_ROOT="$PROJECT_ROOT" DRY_RUN=false bash --noprofile --norc <<'EOF' +set -euo pipefail +source "$PROJECT_ROOT/lib/core/common.sh" +source "$PROJECT_ROOT/lib/clean/dev.sh" +start_section_spinner() { :; } +stop_section_spinner() { :; } +run_with_timeout() { shift; "$@"; } +clean_tool_cache() { echo "$1|$*"; } +safe_clean() { :; } +note_activity() { :; } +debug_log() { :; } +docker() { + if [[ "$1" == "info" ]]; then + return 0 + fi + return 0 +} +export -f docker +clean_dev_docker +EOF + + [ "$status" -eq 0 ] + [[ "$output" == *"Docker unused data|Docker unused data docker system prune -af --volumes"* ]] } @test "clean_developer_tools runs key stages" {