Created
November 18, 2025 22:38
-
-
Save leek/db70f197bd06b47b4fbe8d3db0016e4b to your computer and use it in GitHub Desktop.
This file contains hidden or bidirectional Unicode text that may be interpreted or compiled differently than what appears below. To review, open the file in an editor that reveals hidden Unicode characters.
Learn more about bidirectional Unicode characters
| #!/usr/bin/env bash | |
| set -euo pipefail | |
| APP_DIRS=( | |
| "/Applications" | |
| "$HOME/Applications" | |
| ) | |
| if ! command -v brew >/dev/null 2>&1; then | |
| echo "Error: Homebrew not found in PATH" >&2 | |
| exit 1 | |
| fi | |
| # Cache list of installed casks | |
| mapfile -t INSTALLED_CASKS < <(brew list --cask 2>/dev/null || true) | |
| is_installed_cask() { | |
| local token="$1" | |
| for c in "${INSTALLED_CASKS[@]}"; do | |
| [[ "$c" == "$token" ]] && return 0 | |
| done | |
| return 1 | |
| } | |
| guess_token_from_appname() { | |
| local appname="$1" | |
| echo "$appname" \ | |
| | tr 'A-Z' 'a-z' \ | |
| | sed -E 's/[^a-z0-9+]+/-/g; s/^-+//; s/-+$//' | |
| } | |
| test_cask_dryrun() { | |
| local cask="$1" | |
| # quiet dry run test; return code determines success | |
| if brew install --cask --adopt --dry-run "$cask" >/dev/null 2>&1; then | |
| return 0 | |
| fi | |
| return 1 | |
| } | |
| echo "# These casks passed a dry-run and are adoptable:" | |
| echo | |
| for dir in "${APP_DIRS[@]}"; do | |
| [[ -d "$dir" ]] || continue | |
| while IFS= read -r -d '' app; do | |
| app_basename="$(basename "$app")" | |
| appname="${app_basename%.app}" | |
| token_guess="$(guess_token_from_appname "$appname")" | |
| chosen_cask="" | |
| # 1. Try direct token guess | |
| if [[ -n "$token_guess" ]] && ! is_installed_cask "$token_guess"; then | |
| if brew info --cask "$token_guess" >/dev/null 2>&1; then | |
| chosen_cask="$token_guess" | |
| fi | |
| fi | |
| # 2. Try searching by name | |
| if [[ -z "$chosen_cask" ]]; then | |
| search_results="$(brew search --cask "$appname" 2>/dev/null | head -n 5 || true)" | |
| while IFS= read -r candidate; do | |
| [[ -z "$candidate" ]] && continue | |
| is_installed_cask "$candidate" && continue | |
| if brew info --cask "$candidate" >/dev/null 2>&1; then | |
| chosen_cask="$candidate" | |
| break | |
| fi | |
| done <<< "$search_results" | |
| fi | |
| # 3. Only print if it passes a dry-run install | |
| if [[ -n "$chosen_cask" ]]; then | |
| if test_cask_dryrun "$chosen_cask"; then | |
| echo "brew install --cask --adopt \"$chosen_cask\" # $app_basename" | |
| fi | |
| fi | |
| done < <(find "$dir" -maxdepth 1 -type d -name '*.app' -print0) | |
| done |
Sign up for free
to join this conversation on GitHub.
Already have an account?
Sign in to comment