#!/usr/bin/env bash
# packs/tmux/install-040-plugins.sh -- install the team TPM plugin set.
#
# The scriptable equivalent of pressing prefix + I inside tmux, so a fresh
# clone converges from bootstrap.sh alone instead of leaving TPM installed
# but the plugin set absent (yank silently dead, prefix_highlight empty).
#
# Mutates: clones every @plugin declared in files/tmux.conf into
# ~/.tmux/plugins/<name>, via TPM's own bin/install_plugins. Plugins already
# present are left untouched. Side effect: TPM resolves its plugin path by
# asking tmux ("tmux start-server \; show-environment"), so this starts a
# tmux server if none is running; running sessions are not modified.
#
# Usage: bash install-040-plugins.sh [TOOLKIT_DRY_RUN=1 to preview]
# Exit codes: 0 PROCEED, 1 HOLD (a plugin failed to download),
# 2 precondition missing (tmux, git, TPM, or config absent).
# ASCII + LF.
set -euo pipefail
shopt -s inherit_errexit 2>/dev/null || true
IFS=$'\n\t'
PACK_DIR="$(cd "$(dirname "${BASH_SOURCE[0]}")" && pwd)"
. "$PACK_DIR/../../lib/lib-install.sh"
require_cmd git "apt-get install git"
require_cmd tmux "run install-010-core.sh first"
INSTALLER="$HOME/.tmux/plugins/tpm/bin/install_plugins"
if [ ! -x "$INSTALLER" ]; then
fail "TPM not installed: $INSTALLER missing (run install-030-tpm.sh first)"
exit 2
fi
# The @plugin lines in this pack's tmux.conf are authoritative (plugins.list
# mirrors them for humans). TPM itself reads the LIVE config at ~/.tmux.conf,
# so if that is not our symlink the set it installs would differ from ours.
CONF="$PACK_DIR/files/tmux.conf"
LIVE_CONF="$HOME/.tmux.conf"
if [ ! -e "$LIVE_CONF" ]; then
fail "$LIVE_CONF missing (run install-020-config.sh first)"
exit 2
fi
if [ "$(readlink -f "$LIVE_CONF" || true)" != "$(readlink -f "$CONF" || true)" ]; then
warn "$LIVE_CONF is not this pack's tmux.conf; TPM installs the set declared there, not ours"
fi
PLUGINS=()
while IFS= read -r p; do
[ -n "$p" ] && PLUGINS+=("$p")
done < <(sed -n "s/^[[:space:]]*set[^#]*@plugin[[:space:]]*['\"]\([^'\"]*\)['\"].*/\1/p" "$CONF")
if [ "${#PLUGINS[@]}" -eq 0 ]; then
fail "no @plugin lines found in $CONF"
exit 2
fi
# plugin_dir NAME -- the directory TPM clones a plugin into.
plugin_dir() {
local name=${1##*/}
printf '%s/.tmux/plugins/%s' "$HOME" "${name%.git}"
}
MISSING=0
for p in "${PLUGINS[@]}"; do
if [ -d "$(plugin_dir "$p")" ]; then
ok "already installed: $p"
else
info "not installed: $p"
MISSING=$((MISSING + 1))
fi
done
if [ "$MISSING" -eq 0 ]; then
ok "plugin set converged (${#PLUGINS[@]} plugins); nothing to do"
exit 0
fi
# TPM prints its own per-plugin progress and exits non-zero if any failed.
if ! run_mut "$INSTALLER"; then
fail "TPM reported at least one plugin download failure"
exit 1
fi
if [ "${TOOLKIT_DRY_RUN:-0}" = "1" ]; then
exit 0
fi
STILL_MISSING=()
for p in "${PLUGINS[@]}"; do
[ -d "$(plugin_dir "$p")" ] || STILL_MISSING+=("$p")
done
if [ "${#STILL_MISSING[@]}" -gt 0 ]; then
fail "plugins still missing after install:$(printf ' %s' "${STILL_MISSING[@]}")"
exit 1
fi
ok "plugin set installed (${#PLUGINS[@]} plugins)"
info "already-running sessions pick them up with: prefix + r"