mirror of
https://github.com/ivuorinen/dotfiles.git
synced 2026-03-19 00:06:20 +00:00
Biome 2.x does not support Markdown checking, causing errors on CLAUDE.md. Remove md from the hook's file filter. Also includes minor autofix changes from biome (trailing newlines).
729 lines
19 KiB
Bash
Executable File
729 lines
19 KiB
Bash
Executable File
#!/usr/bin/env bash
|
|
#
|
|
# Dotfiles manager and install helper
|
|
# (c) Ismo Vuorinen <https://github.com/ivuorinen> 2022
|
|
# Licensed under MIT, see LICENSE
|
|
#
|
|
# vim: ft=bash ts=2 sw=2 et
|
|
# shellcheck source-path=$HOME/.dotfiles/local/bin
|
|
#
|
|
# Helper variables, override with ENVs like `VERBOSE=1 dfm help`
|
|
: "${VERBOSE:=0}"
|
|
: "${DOTFILES:=$HOME/.dotfiles}"
|
|
: "${BREWFILE:=$DOTFILES/config/homebrew/Brewfile}"
|
|
: "${HOSTFILES:=$DOTFILES/hosts}"
|
|
export DOTFILES BREWFILE HOSTFILES
|
|
|
|
SCRIPT=$(basename "$0")
|
|
|
|
# Require bash 4.0+ for associative arrays and mapfile
|
|
if ((BASH_VERSINFO[0] < 4)); then
|
|
echo "dfm requires bash 4.0+, found ${BASH_VERSION}"
|
|
if [[ "$(uname)" == "Darwin" ]]; then
|
|
if ! command -v brew &> /dev/null; then
|
|
echo "Installing Homebrew..."
|
|
/bin/bash -c "$(curl -fsSL https://raw.githubusercontent.com/Homebrew/install/HEAD/install.sh)"
|
|
fi
|
|
echo "Installing modern bash via Homebrew..."
|
|
brew install bash
|
|
echo "Done. Restart your shell and run dfm again."
|
|
else
|
|
echo "Install bash 4.0+ and try again."
|
|
fi
|
|
exit 1
|
|
fi
|
|
|
|
# shellcheck disable=SC1091
|
|
source "$DOTFILES/config/shared.sh"
|
|
# shellcheck disable=SC1090
|
|
source "${DOTFILES}/local/bin/msgr"
|
|
|
|
# Get description from a script file's @description tag
|
|
get_script_description()
|
|
{
|
|
local file="$1"
|
|
local desc
|
|
desc=$(sed -n '/@description/s/.*@description *\(.*\)/\1/p' "$file" | head -1)
|
|
echo "${desc:-No description available}"
|
|
}
|
|
|
|
# Menu builder
|
|
menu_builder()
|
|
{
|
|
local title=$1
|
|
local commands=("${@:2}")
|
|
local width=60
|
|
|
|
printf "\n%s\n" "$(printf '%.s─' $(seq 1 "$width"))"
|
|
printf "%-${width}s\n" " $title"
|
|
printf "%s\n" "$(printf '%.s─' $(seq 1 "$width"))"
|
|
|
|
for cmd in "${commands[@]}"; do
|
|
local name=${cmd%%:*}
|
|
local desc=${cmd#*:}
|
|
printf " %-20s %s\n" "$name" "$desc"
|
|
done
|
|
}
|
|
|
|
# Handle install section commands
|
|
section_install()
|
|
{
|
|
USAGE_PREFIX="$SCRIPT install <command>"
|
|
|
|
MENU=(
|
|
"all:Installs everything in the correct order"
|
|
"apt-packages:Install apt packages (Debian/Ubuntu)"
|
|
"cheat-databases:Install cheat external cheatsheet databases"
|
|
"composer:Install composer"
|
|
"dnf-packages:Install dnf packages (Fedora/RHEL)"
|
|
"fonts:Install programming fonts"
|
|
"gh:Install GitHub CLI Extensions"
|
|
"git-crypt:Install git-crypt from source"
|
|
"imagick:Install ImageMagick CLI"
|
|
"macos:Setup nice macOS defaults"
|
|
"mise:Install tools via mise (runtimes + CLI tools)"
|
|
"mise-cleanup:Remove old version manager installations (--dry-run supported)"
|
|
"ntfy:Install ntfy notification tool"
|
|
"python-libs:Install Python libraries (libtmux, pynvim)"
|
|
"shellspec:Install shellspec testing framework"
|
|
"xcode-cli-tools:Install Xcode CLI tools (macOS)"
|
|
"z:Install z"
|
|
)
|
|
|
|
case "$1" in
|
|
all)
|
|
msgr msg "Starting to install all and reloading configurations..."
|
|
|
|
# Tier 0: Platform foundations (OS packages, build tools)
|
|
[[ "$(uname)" == "Darwin" ]] && $0 install macos
|
|
[[ "$(uname)" == "Darwin" ]] && $0 install xcode-cli-tools
|
|
command -v apt &> /dev/null && $0 install apt-packages
|
|
command -v dnf &> /dev/null && $0 install dnf-packages
|
|
|
|
# Tier 1: Package managers & fonts
|
|
$0 brew install
|
|
$0 install fonts
|
|
|
|
# Tier 2: Runtimes and CLI tools via mise, then remaining installers
|
|
$0 install mise || exit 1
|
|
$0 install composer || exit 1
|
|
$0 install python-libs || exit 1
|
|
|
|
# Tier 3: Tool-dependent installers
|
|
$0 install cheat-databases
|
|
$0 install gh
|
|
$0 install git-crypt
|
|
$0 install ntfy
|
|
|
|
# Tier 4: Independent utilities
|
|
$0 install shellspec
|
|
$0 install z
|
|
|
|
msgr msg "Reloading configurations again..."
|
|
# shellcheck disable=SC1091
|
|
source "$DOTFILES/config/shared.sh"
|
|
msgr yay "All done!"
|
|
;;
|
|
|
|
cheat-databases)
|
|
msgr run "Installing cheat databases..."
|
|
for database in "$DOTFILES"/scripts/install-cheat-*.sh; do
|
|
bash "$database" \
|
|
&& msgr run_done "Cheat: $database run"
|
|
done
|
|
;;
|
|
|
|
composer)
|
|
msgr run "Installing composer..."
|
|
bash "$DOTFILES/scripts/install-composer.sh" \
|
|
&& msgr run_done "composer installed!"
|
|
;;
|
|
|
|
fonts)
|
|
msgr run "Installing fonts..."
|
|
bash "$DOTFILES/scripts/install-fonts.sh" \
|
|
&& msgr yay "Installed fonts!"
|
|
;;
|
|
|
|
gh)
|
|
msgr run "Installing GitHub CLI Extensions..."
|
|
bash "$DOTFILES/scripts/install-gh-extensions.sh" \
|
|
&& msgr yay "github cli extensions installed!"
|
|
;;
|
|
|
|
imagick)
|
|
msgr run "Downloading and installing ImageMagick CLI..."
|
|
curl -L https://imagemagick.org/archive/binaries/magick > "$XDG_BIN_HOME/magick" \
|
|
&& chmod +x "$XDG_BIN_HOME/magick" \
|
|
&& msgr yay "imagick downloaded and installed!"
|
|
;;
|
|
|
|
macos)
|
|
msgr run "Setting up macOS defaults..."
|
|
bash "$DOTFILES/scripts/install-macos-defaults.sh" \
|
|
&& msgr yay "macOS defaults set!"
|
|
;;
|
|
|
|
mise)
|
|
msgr run "Installing tools via mise..."
|
|
if ! command -v mise &> /dev/null; then
|
|
msgr nested "Installing mise..."
|
|
curl -fsSL https://mise.run | sh || {
|
|
msgr err "Failed to install mise"
|
|
exit 1
|
|
}
|
|
export PATH="${XDG_BIN_HOME:-$HOME/.local/bin}:$PATH"
|
|
fi
|
|
mise install --yes || {
|
|
msgr err "mise install failed"
|
|
exit 1
|
|
}
|
|
mise reshim || {
|
|
msgr err "mise reshim failed"
|
|
exit 1
|
|
}
|
|
msgr yay "mise tools installed!"
|
|
;;
|
|
|
|
mise-cleanup)
|
|
msgr run "Cleaning up old version manager installations..."
|
|
bash "$DOTFILES/scripts/cleanup-old-version-managers.sh" "${@:2}"
|
|
;;
|
|
|
|
apt-packages)
|
|
msgr run "Installing apt packages..."
|
|
bash "$DOTFILES/scripts/install-apt-packages.sh" \
|
|
&& msgr yay "apt packages installed!"
|
|
;;
|
|
|
|
dnf-packages)
|
|
msgr run "Installing dnf packages..."
|
|
bash "$DOTFILES/scripts/install-dnf-packages.sh" \
|
|
&& msgr yay "dnf packages installed!"
|
|
;;
|
|
|
|
git-crypt)
|
|
msgr run "Installing git-crypt..."
|
|
bash "$DOTFILES/scripts/install-git-crypt.sh" \
|
|
&& msgr yay "git-crypt installed!"
|
|
;;
|
|
|
|
ntfy)
|
|
msgr run "Installing ntfy..."
|
|
bash "$DOTFILES/scripts/install-ntfy.sh" \
|
|
&& msgr yay "ntfy installed!"
|
|
;;
|
|
|
|
python-libs)
|
|
msgr run "Installing Python libraries..."
|
|
bash "$DOTFILES/scripts/install-python-packages.sh" \
|
|
&& msgr yay "Python libraries installed!"
|
|
;;
|
|
|
|
xcode-cli-tools)
|
|
msgr run "Installing Xcode CLI tools..."
|
|
bash "$DOTFILES/scripts/install-xcode-cli-tools.sh" \
|
|
&& msgr yay "Xcode CLI tools installed!"
|
|
;;
|
|
|
|
shellspec)
|
|
msgr run "Installing shellspec..."
|
|
bash "$DOTFILES/scripts/install-shellspec.sh" \
|
|
&& msgr yay "shellspec has been installed!"
|
|
;;
|
|
|
|
z)
|
|
msgr run "Installing z..."
|
|
bash "$DOTFILES/scripts/install-z.sh" \
|
|
&& msgr yay "z has been installed!"
|
|
;;
|
|
|
|
*) menu_builder "$USAGE_PREFIX" "${MENU[@]}" ;;
|
|
esac
|
|
}
|
|
|
|
# Handle Homebrew section commands
|
|
section_brew()
|
|
{
|
|
USAGE_PREFIX="$SCRIPT brew <command>"
|
|
|
|
MENU=(
|
|
"install:Installs items defined in Brewfile"
|
|
"update:Updates and upgrades brew packages"
|
|
"updatebundle:Updates Brewfile with descriptions"
|
|
"autoupdate:Setups brew auto-update and runs it immediately"
|
|
"leaves:List brew leaves (installed on request)"
|
|
"clean:Clean up brew packages"
|
|
"untracked:List untracked brew packages"
|
|
)
|
|
|
|
if ! x-have brew; then
|
|
msgr warn "brew not available, skipping"
|
|
return 0
|
|
fi
|
|
|
|
case "$1" in
|
|
install)
|
|
brew bundle install --file="$BREWFILE" --force --quiet && msgr yay "Done!"
|
|
;;
|
|
|
|
update)
|
|
if brew update && brew outdated && brew upgrade && brew cleanup; then
|
|
msgr yay "Done!"
|
|
else
|
|
msgr err "brew update failed"
|
|
fi
|
|
;;
|
|
|
|
updatebundle)
|
|
# Updates .dotfiles/homebrew/Brewfile with descriptions
|
|
brew bundle dump \
|
|
--force \
|
|
--file="$BREWFILE" \
|
|
--cleanup \
|
|
--tap \
|
|
--formula \
|
|
--cask \
|
|
--describe && msgr yay "Done!"
|
|
;;
|
|
|
|
leaves)
|
|
brew leaves --installed-on-request
|
|
;;
|
|
|
|
untracked)
|
|
declare -a BREW_LIST_ALL
|
|
while IFS= read -r line; do
|
|
BREW_LIST_ALL+=("$line")
|
|
done < <(brew list --formula --installed-on-request -1 --full-name)
|
|
while IFS= read -r c; do
|
|
BREW_LIST_ALL+=("$c")
|
|
done < <(brew list --cask -1 --full-name)
|
|
|
|
# Remove entries that are installed as dependencies
|
|
declare -a BREW_LIST_DEPENDENCIES
|
|
while IFS= read -r l; do
|
|
BREW_LIST_DEPENDENCIES+=("$l")
|
|
done < <(brew list -1 --installed-as-dependency)
|
|
|
|
declare -a BREW_LIST_BUNDLED
|
|
while IFS= read -r b; do
|
|
BREW_LIST_BUNDLED+=("$b")
|
|
done < <(brew bundle list --all --file="$BREWFILE")
|
|
|
|
declare -a BREW_LIST_TRACKED_WITHOUT_DEPS
|
|
for f in "${BREW_LIST_ALL[@]}"; do
|
|
# shellcheck disable=SC2199
|
|
if [[ " ${BREW_LIST_DEPENDENCIES[@]} " != *" ${f} "* ]]; then
|
|
BREW_LIST_TRACKED_WITHOUT_DEPS+=("$f")
|
|
fi
|
|
done
|
|
|
|
array_diff BREW_LIST_UNTRACKED BREW_LIST_TRACKED_WITHOUT_DEPS BREW_LIST_BUNDLED
|
|
|
|
# If there are no untracked packages, return
|
|
if [ ${#BREW_LIST_UNTRACKED[@]} -eq 0 ]; then
|
|
msgr yay "No untracked packages found!"
|
|
return 0
|
|
fi
|
|
|
|
echo "Untracked:"
|
|
for f in "${BREW_LIST_UNTRACKED[@]}"; do
|
|
echo " $f"
|
|
done
|
|
;;
|
|
|
|
autoupdate)
|
|
brew autoupdate delete
|
|
brew autoupdate start 43200 --upgrade --cleanup --immediate
|
|
;;
|
|
|
|
clean) brew bundle cleanup --file="$BREWFILE" && msgr yay "Done!" ;;
|
|
|
|
*) menu_builder "$USAGE_PREFIX" "${MENU[@]}" ;;
|
|
esac
|
|
}
|
|
|
|
# Handle helper utility commands
|
|
section_helpers()
|
|
{
|
|
USAGE_PREFIX="$SCRIPT helpers <command>"
|
|
MENU=(
|
|
"aliases:<shell> (bash, zsh, fish) Show aliases"
|
|
"colors:Show colors"
|
|
"env:Show environment variables"
|
|
"functions:Show functions"
|
|
"nvim:Show nvim keybindings"
|
|
'path:Show $PATH dir by dir'
|
|
"tmux:Show tmux keybindings"
|
|
"wezterm:Show wezterm keybindings"
|
|
)
|
|
|
|
CMD="${1:-}"
|
|
[[ $# -gt 0 ]] && shift
|
|
SECTION="${1:-}"
|
|
[[ $# -gt 0 ]] && shift
|
|
|
|
case "$CMD" in
|
|
path)
|
|
# shellcheck disable=2001
|
|
for i in $(echo "$PATH" | sed 's/:/ /g'); do echo "$i"; done
|
|
;;
|
|
|
|
aliases)
|
|
case "$SECTION" in
|
|
"zsh")
|
|
zsh -ixc : 2>&1 | grep -E '> alias' | sed "s|$HOME|~|" | grep -v "(eval)"
|
|
;;
|
|
"bash")
|
|
bash -ixc : 2>&1 | grep -E '> alias' | sed "s|$HOME|~|" | grep -v "(eval)"
|
|
;;
|
|
"fish")
|
|
fish -ic "alias" | sed "s|$HOME|~|"
|
|
;;
|
|
*)
|
|
echo "$SCRIPT helpers aliases <shell> (bash, zsh, fish)"
|
|
;;
|
|
esac
|
|
;;
|
|
|
|
"colors")
|
|
max=255
|
|
start=0
|
|
|
|
while [ "$start" -le "$max" ]; do
|
|
for i in $(seq "$start" $((start + 9))); do
|
|
if [ "$i" -le "$max" ]; then
|
|
# Outputs colored number
|
|
# printf " \e[38;5;%sm%4s\e[0m" "$i" "$i"
|
|
|
|
# Outputs colored block with number inside
|
|
# printf " \e[48;5;%sm\e[38;5;15m%5s \e[0m" "$i" "$i"
|
|
|
|
# Outputs colored block and color number
|
|
# printf " \e[48;5;%sm \e[0m %3d" "$i" "$i"
|
|
|
|
# Outputs color number and colored block
|
|
printf "%3d \e[48;5;%sm \e[0m " "$i" "$i"
|
|
fi
|
|
done
|
|
printf "\n"
|
|
start=$((start + 10))
|
|
done
|
|
;;
|
|
|
|
"env") env | sort ;;
|
|
"functions") declare -F ;;
|
|
"nvim") cat "$DOTFILES/docs/nvim-keybindings.md" ;;
|
|
"tmux") cat "$DOTFILES/docs/tmux-keybindings.md" ;;
|
|
"wezterm") cat "$DOTFILES/docs/wezterm-keybindings.md" ;;
|
|
*) menu_builder "$USAGE_PREFIX" "${MENU[@]}" ;;
|
|
esac
|
|
}
|
|
|
|
# Handle apt package manager commands
|
|
section_apt()
|
|
{
|
|
USAGE_PREFIX="$SCRIPT apt <command>"
|
|
MENU=(
|
|
"upkeep:Run update, upgrade, autoremove and clean"
|
|
'install:Install packages from $DOTFILES/tools/apt.txt'
|
|
"update:Update apt packages"
|
|
"upgrade:Upgrade apt packages"
|
|
"autoremove:Remove unused apt packages"
|
|
"clean:Clean apt cache"
|
|
)
|
|
|
|
if ! x-have apt; then
|
|
msgr warn "apt not available, skipping"
|
|
return 0
|
|
fi
|
|
|
|
case "$1" in
|
|
upkeep)
|
|
sudo apt update \
|
|
&& sudo apt upgrade -y \
|
|
&& sudo apt autoremove -y \
|
|
&& sudo apt clean
|
|
;;
|
|
|
|
install)
|
|
# if apt.txt is not found, return with error
|
|
if [ ! -f "$DOTFILES/tools/apt.txt" ]; then
|
|
msgr err "apt.txt not found"
|
|
return 1
|
|
fi
|
|
|
|
# Load apt.txt, remove comments (even if trailing comment) and empty lines.
|
|
#
|
|
# Ignoring "Quote this to prevent word splitting."
|
|
# shellcheck disable=SC2046
|
|
sudo apt install \
|
|
-y $(
|
|
grep -vE '^\s*#' "$DOTFILES/tools/apt.txt" \
|
|
| sed -e 's/#.*//' \
|
|
| tr '\n' ' '
|
|
)
|
|
|
|
# If there's a apt.txt file under hosts/$hostname/apt.txt,
|
|
# run install on those lines too.
|
|
HOSTNAME=$(hostname -s)
|
|
HOST_APT="$DOTFILES/hosts/$HOSTNAME/apt.txt"
|
|
[[ -f $HOST_APT ]] && {
|
|
# shellcheck disable=SC2046
|
|
sudo apt install -y $(
|
|
grep -vE '^\s*#' "$HOST_APT" \
|
|
| sed -e 's/#.*//' \
|
|
| tr '\n' ' '
|
|
)
|
|
}
|
|
|
|
# Try this for an alternative way to install packages
|
|
# xargs -a <(awk '! /^ *(#|$)/' "$packagelist") -r -- sudo apt-get install -y
|
|
;;
|
|
|
|
update) sudo apt update ;;
|
|
upgrade) sudo apt upgrade -y ;;
|
|
autoremove) sudo apt autoremove -y ;;
|
|
clean) sudo apt clean ;;
|
|
*) menu_builder "$USAGE_PREFIX" "${MENU[@]}" ;;
|
|
esac
|
|
}
|
|
|
|
# Handle documentation generation commands
|
|
section_docs()
|
|
{
|
|
USAGE_PREFIX="$SCRIPT docs <command>"
|
|
|
|
MENU=(
|
|
"all:Update all keybindings documentations"
|
|
"tmux:Update tmux keybindings documentation"
|
|
"nvim:Update nvim keybindings documentation"
|
|
"wezterm:Update wezterm keybindings documentation"
|
|
)
|
|
|
|
case "$1" in
|
|
all)
|
|
$0 docs tmux
|
|
$0 docs nvim
|
|
$0 docs wezterm
|
|
;;
|
|
tmux) bash "$DOTFILES/local/bin/x-dfm-docs-xterm-keybindings" ;;
|
|
nvim) bash "$DOTFILES/scripts/create-nvim-keymaps.sh" ;;
|
|
wezterm) bash "$DOTFILES/scripts/create-wezterm-keymaps.sh" ;;
|
|
*) menu_builder "$USAGE_PREFIX" "${MENU[@]}" ;;
|
|
esac
|
|
}
|
|
|
|
# Handle dotfiles formatting and reset commands
|
|
section_dotfiles()
|
|
{
|
|
USAGE_PREFIX="$SCRIPT dotfiles <command>"
|
|
|
|
MENU=(
|
|
"fmt:Run all formatters"
|
|
"yamlfmt:Run yamlfmt to all dotfiles, which are in our control"
|
|
"shfmt:Run shfmt to all dotfiles"
|
|
"reset_all:Reset everything, runs all configured reset actions"
|
|
"reset_nvim:Resets nvim. Deletes caches, removes nvim folders and relinks nvim folders"
|
|
)
|
|
|
|
case "$1" in
|
|
fmt)
|
|
msgr run "Running all formatters"
|
|
$0 dotfiles yamlfmt \
|
|
&& $0 dotfiles shfmt \
|
|
&& msgr run_done "...done!"
|
|
;;
|
|
|
|
reset_all)
|
|
msgr ok "Running all reset commands"
|
|
$0 dotfiles reset_nvim
|
|
;;
|
|
|
|
reset_nvim)
|
|
msgr run "Cleaning nvim state, cache and config"
|
|
rm -rf \
|
|
~/.local/share/nvim \
|
|
~/.local/state/nvim \
|
|
~/.cache/nvim \
|
|
~/.config/nvim \
|
|
&& msgr ok "Deleted old nvim files (share, state and cache + config)"
|
|
ln -s "$DOTFILES/config/nvim" ~/.config/nvim \
|
|
&& msgr ok "Linked nvim and astronvim"
|
|
$0 install mise || {
|
|
msgr err "Failed to install mise tools"
|
|
exit 1
|
|
}
|
|
msgr ok "Installed packages"
|
|
msgr run_done "nvim reset!"
|
|
;;
|
|
|
|
yamlfmt)
|
|
# format yaml files
|
|
x-have yamlfmt && yamlfmt -conf "$DOTFILES/.yamlfmt"
|
|
! x-have yamlfmt && msgr err "yamlfmt not found"
|
|
;;
|
|
|
|
shfmt)
|
|
# If system doesn't have fd or shfmt installed, exit
|
|
! x-have fd && msgr err "fd not found, install it to continue"
|
|
! x-have shfmt && msgr err "shfmt not found, install it to continue"
|
|
# Format shell scripts according to following rules.
|
|
fd --full-path "$DOTFILES" -tx \
|
|
--hidden \
|
|
-E '*.pl' -E '*.php' -E '*.py' -E '*.zsh' -E 'plugins' -E 'fzf' -E 'dotbot' \
|
|
-E 'test' -E '**/tldr/*' \
|
|
-x shfmt \
|
|
--language-dialect bash \
|
|
--func-next-line --list --write \
|
|
--indent 2 --case-indent --space-redirects \
|
|
--binary-next-line {} \; \
|
|
&& msgr yay "dotfiles have been shfmt formatted!"
|
|
;;
|
|
|
|
*) menu_builder "$USAGE_PREFIX" "${MENU[@]}" ;;
|
|
esac
|
|
}
|
|
|
|
# Handle system check commands (arch, hostname)
|
|
section_check()
|
|
{
|
|
USAGE_PREFIX="$SCRIPT check <command>"
|
|
X_HOSTNAME=$(hostname)
|
|
X_ARCH=$(uname)
|
|
|
|
MENU=(
|
|
"arch <arch>:Empty <arch> returns current. Exit code 0=match to current, 1=no match."
|
|
"host <host>:Empty <host> returns current. Exit code 0=match to current, 1=no match."
|
|
)
|
|
|
|
case "$1" in
|
|
a | arch)
|
|
[[ $2 == "" ]] && echo "$X_ARCH" && return 0
|
|
[[ $X_ARCH == "$2" ]] && return 0 || return 1
|
|
;;
|
|
|
|
h | host | hostname)
|
|
[[ $2 == "" ]] && echo "$X_HOSTNAME" && return 0
|
|
[[ $X_HOSTNAME == "$2" ]] && return 0 || return 1
|
|
;;
|
|
|
|
*) menu_builder "$USAGE_PREFIX" "${MENU[@]}" ;;
|
|
esac
|
|
}
|
|
|
|
# Handle install script execution
|
|
section_scripts()
|
|
{
|
|
USAGE_PREFIX="$SCRIPT scripts <command>"
|
|
|
|
# Collect scripts and their descriptions
|
|
local menu_items=()
|
|
for script in "$DOTFILES/scripts/install-"*.sh; do
|
|
if [ -f "$script" ]; then
|
|
name=$(basename "$script" .sh | sed 's/install-//')
|
|
desc=$(get_script_description "$script")
|
|
menu_items+=("$name:$desc")
|
|
fi
|
|
done
|
|
|
|
case "$1" in
|
|
"")
|
|
menu_builder "$USAGE_PREFIX" "${menu_items[@]}"
|
|
;;
|
|
*)
|
|
# Run the chosen script
|
|
script_path="$DOTFILES/scripts/install-$1.sh"
|
|
if [ -f "$script_path" ]; then
|
|
bash "$script_path"
|
|
else
|
|
msgr err "Script not found: $1"
|
|
fi
|
|
;;
|
|
esac
|
|
}
|
|
|
|
# Secret menu for visual tests
|
|
section_tests()
|
|
{
|
|
USAGE_PREFIX="$SCRIPT tests <command>"
|
|
|
|
MENU=(
|
|
"msgr:List all available msgr message types"
|
|
"params:List all parameters"
|
|
)
|
|
|
|
case "$1" in
|
|
params)
|
|
echo "All parameters:"
|
|
for i in "$@"; do
|
|
echo " $i"
|
|
done
|
|
;;
|
|
msgr)
|
|
# shellcheck disable=SC1010
|
|
msgr done "msgr done"
|
|
msgr done_suffix "msgr done_suffix"
|
|
msgr err "msgr err"
|
|
msgr nested "msgr nested"
|
|
msgr nested_done "msgr nested_done"
|
|
msgr ok "msgr ok"
|
|
msgr prompt "msgr prompt"
|
|
msgr prompt_done "msgr prompt_done"
|
|
msgr run "msgr run" "second_param"
|
|
msgr run_done "msgr run_done" "second_param"
|
|
msgr warn "msgr warn"
|
|
msgr yay "msgr yay"
|
|
msgr yay_done "msgr yay_done"
|
|
;;
|
|
*) menu_builder "$USAGE_PREFIX" "${MENU[@]}" ;;
|
|
esac
|
|
}
|
|
|
|
# Display main usage information for all sections
|
|
usage()
|
|
{
|
|
echo ""
|
|
msgr prompt "Usage: $SCRIPT <section> <command>"
|
|
echo " Empty <command> prints <section> help."
|
|
echo ""
|
|
section_install
|
|
echo ""
|
|
section_apt
|
|
echo ""
|
|
section_brew
|
|
echo ""
|
|
section_check
|
|
echo ""
|
|
section_dotfiles
|
|
echo ""
|
|
section_docs
|
|
echo ""
|
|
section_scripts
|
|
echo ""
|
|
section_helpers
|
|
}
|
|
|
|
# Parse section argument and dispatch to handler
|
|
main()
|
|
{
|
|
SECTION="${1:-}"
|
|
[[ $# -gt 0 ]] && shift
|
|
# The main loop. The first keyword after $0 triggers section, or help.
|
|
case "$SECTION" in
|
|
install) section_install "$@" ;;
|
|
apt) section_apt "$@" ;;
|
|
brew) section_brew "$@" ;;
|
|
check) section_check "$@" ;;
|
|
dotfiles) section_dotfiles "$@" ;;
|
|
helpers) section_helpers "$@" ;;
|
|
docs) section_docs "$@" ;;
|
|
scripts) section_scripts "$@" ;;
|
|
tests) section_tests "$@" ;;
|
|
*) usage && return 0 ;;
|
|
esac
|
|
}
|
|
|
|
main "$@"
|