#!/bin/bash set -e days=3 dry_run=false workspace_top=$HOME/workspace while [ $# -gt 0 ]; do case $1 in --days) days="$2"; shift ;; --dry_run) dry_run="$2"; shift ;; --workspace_top) workspace_top="$2"; shift ;; *) echo "ERROR: Wrong option: $1"; exit 1 ;; esac shift done set -x if [ "$days" -lt "0" ]; then echo "ERROR: Refusing to delete workspaces that are $days days old" exit 1 fi echo "Date / size report before (`date`):" ls -ld $workspace_top/* || true df -h $workspace_top || true du -hsc $workspace_top/* || true find_workspaces () { local cur_dir="$1" # If a directory contains no file (ie. only subdirs), consider it # is part of the workspace hierarchy: only directories with at # least one file can be top-level workspaces. if [ x"$(find $cur_dir -maxdepth 1 -type f | wc -l)" != x"0" ]; then echo $cur_dir else # "tail -n +2" is to remove $cur_dir from find output. for dir in $(find $cur_dir -maxdepth 1 -type d | tail -n +2); do find_workspaces "$dir" done fi } # Splitting on newline in case of dirs with whitespace mapfile -t dirs < <(find_workspaces "$workspace_top") rm_dirs=() for dir in "${dirs[@]}"; do if [ x"$(find "$dir" -mtime -$days | wc -l)" = x"0" ]; then if ! $dry_run; then # Move directory out of the way as quickly as possible to minimize # chance of parallel build starting in this directory. # Use a lock to avoid a race condition with a competing # build. flock "$dir" mv "$dir" "$dir.bak" fi rm_dirs=("${rm_dirs[@]}" "$dir.bak") fi done if [ ${#rm_dirs[@]} != 0 ]; then echo "Removing directories:" ls -ld "${rm_dirs[@]}" || true du -hs "${rm_dirs[@]}" || true if ! $dry_run; then # Make sure we can get into all subdirectories. # Glibc tests can leave behind "rw-" directories, the contents of which # can't be cleaned up without "x" permission bit. chmod -R +rwx "${rm_dirs[@]}" rm -rf "${rm_dirs[@]}" else echo "DRY_RUN: NOT REMOVING DIRECTORIES" fi echo "Date / size report after (`date`):" ls -ld $workspace_top/* || true df -h $workspace_top || true du -hsc $workspace_top/* || true fi