Gradle プロジェクトを再帰的に clean する

blog1.mammb.com


Gradle プロジェクトは ./gradlew clean でクリーンできるが、依存の解決が必要であったり、java のバージョン違いでエラーになったり、build.gradle.kts のエラーで実行できなかったりする。

ディスク容量削減のために clean したいだけなのに、それぞれのプロジェクトでエラーを解消する必要がありとても厄介。


以下で gradle に頼らず、指定ディレクトリを再帰的に clean することができる。

find . -name "gradlew" -exec sh -c 'for g; do r=$(dirname "$g"); find "$r" -type d \( -name "build" -o -name ".gradle" -o -name "out" -o -name ".idea" \) -exec sh -c "for p; do [ -e \"\$p\" ] && echo \"Deleting: \$p\" && rm -rf \"\$p\"; done" _ {} +; done' _ {} +
  • find . -name "gradlew" カレントディレクトリ配下から gradlew を検索

  • exec sh -c '...' _ {} + 検索した gradlew のパスを後続のシェルスクリプトに渡す

    • _ はプレースホルダー $0 に相当
    • {} には見つかったファイルの名前が順番に入り、+ をつけると、見つかったファイルを1つずつ処理するのではなく、一度にまとめてコマンドに渡して実行する
  • for g; do r=$(dirname "$g"); ... done 渡された gradlew のパスを1つずつループ処理

    • dirname で親ディレクトリを変数 r(プロジェクトルート)に格納
  • find "$r" -type d \( -name "build" -o -name ".gradle" -o -name "out" -o -name ".idea" \) 特定したルート $r 配下のディレクトリ(-type d)を対象に、削除対象ディレクトリを検索

  • -exec sh -c "for p; do ... done" _ {} + 検索した削除対象のフォルダを一括で引数として受け取り、ループ処理に渡す

  • [ -e "\$p" ] && echo "Deleting: \$p" && rm -rf "\$p" 引数として受け取ったパス \$p が存在する場合、エコー出力して rm -rf で物理削除