From 5a7d9cf060c6a04461e92e9997f01b25648b0696 Mon Sep 17 00:00:00 2001 From: David Tomaschik Date: Tue, 26 May 2026 14:12:32 -0700 Subject: [PATCH] Update skel, common functions. --- dotfiles/commonrc.sh | 63 ++++++++++++++++++++++++++ dotfiles/zshrc | 21 +-------- dotfiles/zshrc.d/functions.zsh | 21 ++------- install.sh | 83 ++++++++++++++++++++++++++++------ 4 files changed, 137 insertions(+), 51 deletions(-) create mode 100644 dotfiles/commonrc.sh diff --git a/dotfiles/commonrc.sh b/dotfiles/commonrc.sh new file mode 100644 index 0000000..2a74872 --- /dev/null +++ b/dotfiles/commonrc.sh @@ -0,0 +1,63 @@ +#!/bin/sh +# shellcheck disable=SC1090 + +# common functions for use in shell scripts + +find_first() { + while [ "$#" -gt 0 ]; do + if test -e "${1}" ; then + echo "${1}" + return 0 + fi + shift + done + return 1 +} + +have_command() { + command -v "$1" >/dev/null 2>&1 +} + +# Helper function: Returns 0 if the directory is in PATH, 1 otherwise +path_contains() { + case ":${PATH}:" in + *:"$1":*) return 0 ;; + *) return 1 ;; + esac +} + +# Prepend a directory to PATH if it's not already there +path_prepend() { + if [ -d "$1" ] && ! path_contains "$1"; then + PATH="$1:${PATH}" + fi +} + +# Append a directory to PATH if it's not already there +path_append() { + if [ -d "$1" ] && ! path_contains "$1"; then + PATH="${PATH}:$1" + fi +} + +source_first_existing() { + _sfe_script="$(find_first "$@")" + _sfe_status=$? + + if [ "$_sfe_status" -eq 0 ]; then + . "$_sfe_script" + # Clean up our temporary variables before returning success + unset -v _sfe_script _sfe_status + return 0 + fi + + # Clean up our temporary variables before returning failure + unset -v _sfe_script _sfe_status + return 1 +} + +source_if_existing() { + if [ -f "$1" ]; then + . "$1" + fi +} diff --git a/dotfiles/zshrc b/dotfiles/zshrc index 19fe628..b1c1fe5 100755 --- a/dotfiles/zshrc +++ b/dotfiles/zshrc @@ -59,6 +59,8 @@ DIRSTACKSIZE=16 export OS="$(uname 2>/dev/null || echo "Unknown")" +source ~/.commonrc.sh + # Set terminal title case $TERM in # Only set the title for terminals that are likely to support it @@ -163,25 +165,6 @@ bindkey '^r' history-incremental-search-backward # delete really deletes bindkey "^[[3~" delete-char -source_if_existing() { - [[ -f "${1}" ]] && source "${1}" -} - -source_first_existing() { - while (($#)); do - if test -e "${1}" ; then - source "${1}" - return - fi - shift - done - return 1 -} - -have_command() { - command -v "${1}" &>/dev/null -} - if test -d ${HOME}/.local/bin ; then export PATH="${HOME}/.local/bin:${PATH}" fi diff --git a/dotfiles/zshrc.d/functions.zsh b/dotfiles/zshrc.d/functions.zsh index db8188f..ec8f122 100644 --- a/dotfiles/zshrc.d/functions.zsh +++ b/dotfiles/zshrc.d/functions.zsh @@ -2,31 +2,18 @@ function dumpenv { if [ "$(uname)" = "Linux" ]; then tr '\0' '\n' < /proc/${1}/environ elif [ "$(uname)" = "Darwin" ]; then - # macOS doesn't have /proc, use ps instead. + # macOS doesn't have /proc, use ps instead. # Note: this may truncate if environment is very large. ps -p ${1} -wwwe -o command= | tr ' ' '\n' | grep '=' fi } -if test -x "/sbin/starship" ; then - _STARSHIP_PATH="/sbin/starship" +_STARSHIP_PATH="$(find_first "$(command -v starship)" /sbin/starship "${HOME}/tools/starship/starship" "${HOME}/.local/bin/starship" /usr/local/bin/starship)" +if test -n "$_STARSHIP_PATH" ; then function starship_prompt { - eval "$(/sbin/starship init zsh)" - } -elif test -x "${HOME}/tools/starship/starship" ; then - _STARSHIP_PATH="${HOME}/tools/starship/starship" - function starship_prompt { - eval "$($HOME/tools/starship/starship init zsh)" + eval "$($_STARSHIP_PATH init zsh)" } fi -if test -f ${HOME}/.zprompt ; then - if test "$(cat ${HOME}/.zprompt)" = "starship" ; then - if test -n "${_STARSHIP_PATH:-}" ; then - eval "$(${_STARSHIP_PATH} init zsh)" - fi - fi -fi -unset _STARSHIP_PATH function hashall { tee >(md5sum) | tee >(sha1sum) | sha256sum diff --git a/install.sh b/install.sh index 3baff84..e034b22 100755 --- a/install.sh +++ b/install.sh @@ -7,14 +7,30 @@ set -o errexit set -o shwordsplit 2>/dev/null || true # Make zsh behave like bash HOME=${HOME:-$(cd ~ && pwd)} - - +LOCAL_BIN="${HOME}/.local/bin" +STARSHIP_INSTALL_HASH="52c64f14a558034ebeb1907ea9364e802b32474576fd3e68265f73bc33cc8fbb" have_command() { command -v "${1}" >/dev/null 2>&1 } +sudo_group() { + if [[ "$(id -u)" -eq 0 ]] ; then + return 0 + fi + have_command sudo && ( id -Gn | grep -q '\bsudo\b' ) +} +maybe_sudo() { + if [[ "$(id -u)" -eq 0 ]] ; then + "$@" + return + fi + if ! have_command sudo ; then + return 1 + fi + sudo "$@" +} link_directory_contents() { local SRCDIR="${1}" @@ -176,6 +192,41 @@ install_dotfiles() { fi } +install_starship() { + if have_command starship ; then return 0 ; fi + if have_command apt-get && sudo_group ; then + if maybe_sudo apt-get install -qy starship ; then + return 0 + fi + echo "apt-get install starship failed, installing locally" >&2 + fi + local tmpd + tmpd="$(mktemp -d tmp.starship.XXXXXX)" + local install_path="${tmpd}/install.sh" + if have_command curl ; then + curl -sSL --show-error -o "${install_path}" https://starship.rs/install.sh + elif have_command wget ; then + wget -q -O "${install_path}" --https-only https://starship.rs/install.sh + else + echo "No curl or wget available!!" >&2 + return 1 + fi + local dl_hash + dl_hash="$(sha256sum "${install_path}" | awk '{print $1}')" + if [[ "$dl_hash" != "${STARSHIP_INSTALL_HASH}" ]] ; then + echo "Hash check failed!!" >&2 + echo "Expected: ${STARSHIP_INSTALL_HASH}, got ${dl_hash} on ${install_path}" >&2 + return 1 + fi + if sudo_group ; then + if maybe_sudo sh "${install_path}" ; then + return 0 + fi + echo "root installation failed, falling back to user-local" >&2 + fi + sh "${install_path}" -b "${LOCAL_BIN}" +} + install_main() { if [[ -d "${BASEDIR}/.git" ]] && have_command git ; then if [[ -z "$(git -C "${BASEDIR}" status --porcelain)" ]]; then @@ -185,6 +236,8 @@ install_main() { fi fi [[ "$MINIMAL" = 1 ]] || { + mkdir -p "${LOCAL_BIN}" + install_starship # Install vim-plug if not already present local VIM_PLUG_URL="https://raw.githubusercontent.com/junegunn/vim-plug/master/plug.vim" @@ -199,22 +252,22 @@ install_main() { else echo "Error: curl not found. Cannot install vim-plug." >&2 fi - fi + fi - # Install TPM (Tmux Plugin Manager) if not already present - local TPM_DIR="${HOME}/.tmux/plugins/tpm" - local TPM_REPO="https://github.com/tmux-plugins/tpm" + # Install TPM (Tmux Plugin Manager) if not already present + local TPM_DIR="${HOME}/.tmux/plugins/tpm" + local TPM_REPO="https://github.com/tmux-plugins/tpm" - if [[ ! -d "${TPM_DIR}" ]]; then - verbose "Installing TPM (Tmux Plugin Manager)..." - if have_command git; then - git clone --depth 1 "${TPM_REPO}" "${TPM_DIR}" - else - echo "Error: git not found. Cannot install TPM." >&2 - fi - fi + if [[ ! -d "${TPM_DIR}" ]]; then + verbose "Installing TPM (Tmux Plugin Manager)..." + if have_command git; then + git clone --depth 1 "${TPM_REPO}" "${TPM_DIR}" + else + echo "Error: git not found. Cannot install TPM." >&2 + fi + fi - # try to update dotfile overlays + # try to update dotfile overlays if [[ -d "${BASEDIR}/dotfile_overlays" ]] ; then for dotfiledir in "${BASEDIR}/dotfile_overlays/"* ; do if [[ -d "${dotfiledir}/.git" ]] ; then