This Babashka script recursively searches through directories from a given entry
point, identifies files named in the format cleanup-maid-YYYY-MM-DD, and
deletes their parent directories if the date has passed. The script will prompt
the user for confirmation before deleting any directories.
Think of this script like a helper, that keeps your digital household clean. Each directory is like a container of food, and inside each container, thereβs a label (cleanup-maid-YYYY-MM-DD) that tells you when it expires.
If todayβs date is past the expiration date on the label, the script asks you, βHey, this has expiredβshould I throw it out?β If you say yes, it cleans out the whole container (directory), just like youβd toss out spoiled food to keep your fridge fresh.
This way, your system stays clean, just like your fridge stays free of expired leftovers (most of the time)!
- Concept
- Prerequisites
- Installation
- Usage
- Tab Completion
- How It Works
- Git Integration
- Contributing
- License
- Babashka installed on your system
The easiest way to install bb-maid is to use bbin, a script manager for Babashka:
bbin install io.github.simonneutert/bb-maidThis will make the bb-maid command available globally on your system.
Requirements:
- bbin installed
- Java/JDK installed (required by bbin for dependency resolution)
~/.local/binin your PATH (add to your~/.zshrcor~/.bashrcif needed):export PATH="$HOME/.local/bin:$PATH"
After installation, verify it works:
bb-maid
# Should display usage informationNote: If you don't have Java or prefer not to install it, use the manual installation methods below.
To update bb-maid to the latest version when installed via bbin:
bbin install io.github.simonneutert/bb-maid --forceImportant for tab completion users: When updating via bbin, old cached versions may remain in ~/.gitlibs/. To prevent completion path pollution:
Clean update (recommended):
# 1. Uninstall current version
bbin uninstall bb-maid
# 2. Remove old cached versions
rm -rf ~/.gitlibs/libs/io.github.simonneutert/bb-maid/
# 3. Install latest version
bbin install io.github.simonneutert/bb-maid
# 4. For Fish users: Clean up completion paths
fish -c 'set -gx fish_complete_path (string match -v "*bb-maid*" $fish_complete_path)'
# 5. Restart your shellNote: The tab completion setup instructions in this README include duplicate prevention checks (if not contains for Fish, glob patterns with (N) for Zsh/Bash) that help mitigate this issue in future updates.
For development setup, testing, and contributing, see the Development Guide.
For bbin installation:
bb-maid
# Should display: Usage informationFor local repository:
bb tasks
# Should display: Available tasks (clean, clean-in)Note: If you installed via bbin, use the
bb-maidcommand directly. If you cloned the repository, usebbwith the task names (bb clean,bb clean-in).
With bbin installation:
bb-maid clean [path] [options]With local repository:
bb clean [path] [options]The script will recursively search all subdirectories for files named cleanup-maid-YYYY-MM-DD, check if the date has passed, and prompt you before deleting each expired directory.
If no path is provided, it defaults to the current directory.
--max-depth <n>- Limit how deep to recurse into subdirectories (default: unlimited)--follow-links- Follow symbolic links (default: disabled for safety)--yesor-y- Skip confirmation prompts (useful for automation)--dry-runor-n- Show what would be deleted without actually deleting--list- List all cleanup files sorted by date without deleting anything
# Clean current directory (dry run)
bb-maid clean --dry-run
# Clean specific directory
bb-maid clean ~/projects --dry-run
# Only search 2 levels deep in current directory
bb-maid clean --max-depth 2
# Auto-confirm all deletions in a specific directory (be careful!)
bb-maid clean ~/temp-files --yes
# Combine options
bb-maid clean ~/projects --max-depth 3 --dry-run
# List all cleanup files to see what's scheduled
bb-maid clean --list
# List cleanup files in a specific directory
bb-maid clean ~/projects --listNote: Symbolic links are NOT followed by default for safety reasons.
Want to see what directories are scheduled for cleanup without deleting anything? Use the --list option:
# List all cleanup files in current directory
bb-maid clean --list
# List with color-coded expiration status:
# π΄ Red: Expired (ready for cleanup)
# π‘ Yellow: Expiring soon (within 7 days)
# π’ Green: Expiring later (more than 7 days away)Example output:
β INFO
β Found 4 cleanup files:
β
2025-09-28 (EXPIRED 5 days ago) /projects/old-feature
2025-10-01 (EXPIRED 2 days ago) /temp/downloads
2025-10-06 (in 3 days) /cache/build-artifacts
2025-10-13 (in 10 days) /logs/october
The --list option is perfect for:
- π Getting an overview of scheduled cleanups
- π Checking what's about to expire
- β Verifying cleanup files before running actual deletion
To create a cleanup file that will expire after a specified duration:
With bbin installation:
bb-maid clean-in 7d [path]With local repository:
bb clean-in 7d [path]This command creates a file named cleanup-maid-YYYY-MM-DD with a date 7 days in the future. You can use any number of days (e.g., 1d, 30d, 90d).
If no path is provided, it defaults to the current directory.
# Create cleanup file in current directory (expires in 7 days)
bb-maid clean-in 7d
# Create cleanup file in specific directory (expires in 30 days)
bb-maid clean-in 30d ~/temp-projects
# Create cleanup file AND add to .gitignore in one command
bb-maid clean-in 7d --gitignore
# Create in specific directory with gitignore
bb-maid clean-in 14d ~/projects/temp --gitignoreAlternatively, you can manually create a cleanup file using:
touch cleanup-maid-$(date -d "+7 days" +"%Y-%m-%d" 2>/dev/null || date -v+7d +"%Y-%m-%d")Tab completion helps you work faster by auto-completing commands and suggesting common durations.
bb-maid <TAB>β suggestscleanandclean-incommandsbb-maid clean <TAB>β shows available directoriesbb-maid clean --<TAB>β shows available options (--max-depth, --follow-links, --yes, --dry-run)bb-maid clean-in <TAB>β suggests common durations (1d, 7d, 14d, 30d, 60d, 90d)
Add this to your ~/.zshrc:
# bb-maid tab completion
# If installed via bbin:
fpath=(~/.gitlibs/libs/io.github.simonneutert/bb-maid/*/completions(N) $fpath) && autoload -Uz compinit && compinit# If cloned from git:
fpath=(/path/to/your/clone/bb-maid/completions $fpath)
autoload -Uz compinit && compinitThen restart your terminal or run source ~/.zshrc.
Add this to your ~/.bashrc:
# bb-maid tab completion
# If installed via bbin:
for f in ~/.gitlibs/libs/io.github.simonneutert/bb-maid/*/completions/bb-maid.bash(N); do
source "$f"
done# If cloned from git:
source /path/to/your/clone/bb-maid/completions/bb-maid.bashThen restart your terminal or run source ~/.bashrc.
Add this to your Fish config (~/.config/fish/config.fish):
# bb-maid tab completion
# If installed via bbin:
if not contains ~/.gitlibs/libs/io.github.simonneutert/bb-maid/*/completions $fish_complete_path
set -gx fish_complete_path ~/.gitlibs/libs/io.github.simonneutert/bb-maid/*/completions $fish_complete_path
end# If cloned from git:
if not contains /path/to/your/clone/bb-maid/completions $fish_complete_path
set -gx fish_complete_path /path/to/your/clone/bb-maid/completions $fish_complete_path
endThen restart your terminal or run source ~/.config/fish/config.fish.
Note: The if not contains check prevents duplicate paths when reopening Fish sessions. If you're updating from a previous version or have duplicate paths, clean them up in Fish:
# Remove all bb-maid paths from current session
set -gx fish_complete_path (string match -v "*bb-maid*" $fish_complete_path)Then restart Fish and the updated config will add the path cleanly.
- Recursive Scanning: The script recursively scans all subdirectories of the given entry point, searching through the entire directory tree.
- Pattern Matching: It looks for filenames matching
cleanup-maid-YYYY-MM-DD. - Date Check: If the date in the filename is past today, the script identifies the directory as expired.
- User Confirmation: Before any deletion, the script prompts you for confirmation.
- Safe Deletion: Only after confirmation, the parent directory (and all its contents) is deleted.
- Directory Validation: The script validates that the specified directory exists before attempting any operations. If a non-existent directory is provided, it will display a clear error message and exit gracefully.
- Symlinks: The script does NOT follow symbolic links by default, preventing infinite loops and protecting content outside the target directory tree. When symlinks are encountered, they are:
- Logged with warnings: Each skipped symlink is reported with a yellow warning message
- Summarized: A final count shows total symlinks skipped
- Optional traversal: Use
--follow-linksflag to traverse symlinks if needed
- Confirmation Required: Every deletion requires explicit user confirmation (no silent deletions).
- Non-destructive by default: The script only suggests deletions; you have final control.
- Dry-run mode: Test operations safely with
--dry-runbefore actual deletion.
Since cleanup files are temporary markers that indicate when directories should be deleted, you typically don't want to commit them to your Git repository. bb-maid provides simple commands to automatically handle Git exclusion:
The easiest way to exclude cleanup files from Git is to use the --gitignore option when creating cleanup files:
# Create cleanup file and add to .gitignore in one command
bb-maid clean-in 7d --gitignoreOr add the pattern to an existing project:
# Add cleanup-maid-* pattern to .gitignore
bb-maid gitignoreπ‘ Smart Git Detection: When you run bb-maid clean-in in a Git repository without the --gitignore flag, bb-maid will automatically show you a helpful tip suggesting the --gitignore option:
β INFO
β π‘ Tip: You're in a Git repository! Use --gitignore to automatically add cleanup files to .gitignore:
β bb-maid clean-in 7d --gitignore
β
If you prefer to set up Git exclusion manually, here are platform-specific instructions:
# Add to project's .gitignore
echo "cleanup-maid-*" >> .gitignore
git add .gitignore
git commit -m "Ignore cleanup-maid files"macOS/Linux:
echo "cleanup-maid-*" >> ~/.gitignore_global
git config --global core.excludesfile ~/.gitignore_globalWindows (PowerShell):
"cleanup-maid-*" | Out-File -FilePath "$env:USERPROFILE\.gitignore_global" -Encoding UTF8 -Append
git config --global core.excludesfile "$env:USERPROFILE\.gitignore_global"To test if exclusion works:
- Create a test cleanup file:
touch cleanup-maid-2025-12-31 - Check Git status:
git status - The file should not appear in untracked files
- Clean up:
rm cleanup-maid-2025-12-31
Note: If cleanup files are already tracked in Git, remove them first:
git rm --cached cleanup-maid-*
git commit -m "Remove tracked cleanup-maid files"Contributions are welcome! For development setup, testing, and contribution guidelines, please see the Development Guide.
MIT License