#!/usr/bin/env bash # Bash 4.0+ only. Faster than using tr or awk + no fork. toLower() { if [[ $# -eq 0 ]]; then while IFS= read -r line; do echo "${line,,}" done else local str="$*" echo "${str,,}" fi } # Return a string corresponding to the current OS. which_os() { case "$OSTYPE" in darwin*) printf "darwin" ;; linux*) if [[ -f /etc/os-release ]]; then # shellcheck disable=SC1091 source /etc/os-release printf "%s" "${ID,,}" else printf "linux" fi ;; esac } # Choose a Charm repo name with Gum. pickCharmRepo() { getCharmRepos | gum filter --height=10 --header "$1" } # Interactively choose a Charm repo. charm_clone() { local repo repo="$(pickCharmRepo "Clone which Charm™ repo?")" if [[ -z "$repo" ]]; then printf "Okay, never mind.\n" return 1 fi git clone "git@github.com:charmbracelet/$repo" "$HOME/src/$repo" } # Interactively use "go get" against a Charm repo. go_get_charm() { local repo repo="$(pickCharmRepo "Which Charm™ repo do you want to ‘go get?’")" if [[ -z "$repo" ]]; then printf "Okay, never mind.\n" return 1 fi go get "github.com/charmbracelet/$repo" } # Returns the number of CPU cores available on the system. num_cores() { nproc 2>/dev/null || sysctl -n hw.ncpu 2>/dev/null || echo "Could not determine core count" } # Return 1 if a given command exists, and 0 if not. command_exists() { if command -v "$1" &>/dev/null; then printf 1 return fi printf 0 } # Return the preferred diff tool for the given OS. gitdiff() { if [[ $(which_os) == darwin ]]; then opendiff else vimdiff fi } #shellcheck disable=1090 decryptAndSource() { source <(gpg --decrypt "$1" 2>/dev/null) } # Print the names of all public and private Charm repos. getCharmRepos() { getRepos() { gh repo list charmbracelet --visibility="$1" --json name } getAllRepos() { printf '%s %s' "$(getRepos "public")" "$(getRepos "private")" | jq -s 'add' } getAllRepos | jq .[].name | tr -d '"' | sort } # Git worktree helper. # This is a function (not a script) because cd must affect the caller's shell. # A script runs in a child process, so cd would only change the subshell. # Usage: # wt create worktree + branch one level up from git root, cd into it # wt wipe [name] destroy current (or named) worktree, cd back to main project wt() { local subcmd="$1" if [[ -z "$subcmd" ]]; then echo "Usage: wt create worktree and branch " echo " wt wipe [name] remove worktree and branch" return 1 fi local root root="$(git rev-parse --show-toplevel 2>/dev/null)" if [[ -z "$root" ]]; then echo "Not in a git repository" >&2 return 1 fi local parent parent="$(dirname "$root")" if [[ "$subcmd" == "wipe" ]]; then local name="$2" if [[ -z "$name" ]]; then name="$(basename "$PWD")" fi local target="$parent/$name" local main_dir="$parent/main" if [[ ! -d "$target" ]]; then echo "Worktree directory '$target' not found" >&2 return 1 fi if ! gum confirm "Remove worktree and branch '$name'?"; then return 0 fi if ! git worktree remove "$target" --force 2>/dev/null; then echo "Failed to remove worktree" >&2 return 1 fi git branch -D "$name" 2>/dev/null if [[ "$PWD" == "$target" || "$PWD" == "$target"* ]]; then cd "$main_dir" || return 1 fi return 0 fi local name="$subcmd" local target="$parent/$name" if [[ "$name" == "wipe" ]]; then echo "Cannot create a worktree named 'wipe'" >&2 return 1 fi if [[ -d "$target" ]]; then echo "Directory '$target' already exists" >&2 return 1 fi if git show-ref --verify --quiet "refs/heads/$name" 2>/dev/null; then # Local branch exists, use it if ! git worktree add "$target" "$name"; then return 1 fi elif git show-ref --verify --quiet "refs/remotes/origin/$name" 2>/dev/null; then # Remote branch exists on origin, use it if ! git worktree add "$target" "origin/$name"; then return 1 fi else # New branch if ! git worktree add -b "$name" "$target" HEAD; then return 1 fi fi cd "$target" || return 1 }