all repos — dot @ 96c42e431c8252f02556aba9d9f7373dcdf92e41

Shell, editor and terminal configuration, and the tools that go with them

install.sh (view raw)

 1
 2
 3
 4
 5
 6
 7
 8
 9
 10
 11
 12
 13
 14
 15
 16
 17
 18
 19
 20
 21
 22
 23
 24
 25
 26
 27
 28
 29
 30
 31
 32
 33
 34
 35
 36
 37
 38
 39
 40
 41
 42
 43
 44
 45
 46
 47
 48
 49
 50
 51
 52
 53
 54
 55
 56
 57
 58
 59
 60
 61
 62
 63
 64
 65
 66
 67
 68
 69
 70
 71
 72
 73
 74
 75
 76
 77
 78
 79
 80
 81
 82
 83
 84
 85
 86
 87
 88
 89
 90
 91
 92
 93
 94
 95
 96
 97
 98
 99
 100
 101
 102
 103
 104
 105
 106
 107
 108
 109
 110
 111
 112
#!/bin/bash

# Set up this account on a machine: the tools, checkouts and nvim plugins that
# the config link.sh links expects. Run it by hand, after `./link.sh yes`, once
# per machine and again whenever the Brewfile changes; every step only adds
# what is missing. Unlike link.sh it is slow and may stop to ask for a password,
# so nothing runs it on a timer.
#
#   ~/src/soarez/dot/install.sh
#
# On a new Mac, also run ./macos-defaults.sh, once -- see its header. A private
# layer's bootstrap may call both for you.
#
# Runs under macOS's /bin/bash 3.2.

set -euo pipefail

dotfiles_dir="$(cd "$(dirname "$0")" && pwd)"

# 1. Homebrew packages, on macOS. Linux machines get their packages from
#    whatever provisions them, not from here.
if [[ "$(uname)" == "Darwin" ]]; then
  if ! command -v brew >/dev/null 2>&1; then
    for b in /opt/homebrew/bin/brew /usr/local/bin/brew; do
      if [[ -x "${b}" ]]; then
        eval "$("${b}" shellenv)"
        break
      fi
    done
  fi
  # Install Homebrew rather than print the command and stop: on a machine whose
  # whole setup is this repo there is nothing else to run it, and everything
  # below depends on it. NONINTERACTIVE so it does not wait on a RETURN it will
  # never see; it still asks for the sudo password, which is why this script is
  # run by hand and not on a timer.
  if ! command -v brew >/dev/null 2>&1; then
    echo "Homebrew is not installed; installing it now"
    NONINTERACTIVE=1 /bin/bash -c \
      "$(curl -fsSL https://raw.githubusercontent.com/Homebrew/install/HEAD/install.sh)"
    for b in /opt/homebrew/bin/brew /usr/local/bin/brew; do
      if [[ -x "${b}" ]]; then
        eval "$("${b}" shellenv)"
        break
      fi
    done
  fi
  if ! command -v brew >/dev/null 2>&1; then
    >&2 echo "ERROR: Homebrew still not on PATH after installing it. Install it"
    >&2 echo "by hand, then re-run this script:"
    # shellcheck disable=SC2016  # printed for a human to paste, not expanded
    >&2 echo '  /bin/bash -c "$(curl -fsSL https://raw.githubusercontent.com/Homebrew/install/HEAD/install.sh)"'
    exit 1
  fi
  # --no-upgrade: install what is missing and leave what is there alone. Plain
  # `brew bundle` also upgrades every listed package that is out of date.
  #
  # Not fatal: brew bundle fails the whole run if a single entry will not
  # install, and on a managed machine that is routine -- a cask can be blocked
  # by policy ("has been disabled because it does not pass the macOS Gatekeeper
  # check"). One unavailable app is no reason to leave the checkouts, nvim
  # plugins and colours undone, so this warns and carries on. brew has already
  # said which entry failed, right above.
  if ! brew bundle --no-upgrade --file="${dotfiles_dir}/Brewfile"; then
    >&2 echo
    >&2 echo "WARNING: some Brewfile entries did not install (see brew's output"
    >&2 echo "above). Continuing with the rest of the setup."
    >&2 echo
  fi
fi

# 2. Checkouts the config reads: the pure prompt (config/zshrc falls back to a
#    plain one without it) and the extra colour schemes bin/theme lists. Over
#    https: both are public, so a fresh machine needs no ssh key for them.
#    Existing checkouts are left alone.
clone() {
  local url="$1" dest="$2"
  if [[ -d "${dest}/.git" ]]; then
    return
  fi
  mkdir -p "$(dirname "${dest}")"
  git clone --quiet "${url}" "${dest}"
  echo "cloned ${dest}"
}
clone https://github.com/sindresorhus/pure.git         "${HOME}/src/sindresorhus/pure"
clone https://github.com/alacritty/alacritty-theme.git "${HOME}/src/alacritty/alacritty-theme"

# 3. nvim's plugins, so the first real launch does not stop to install them.
#    `install`, not `sync`: install only fetches plugins that are missing, and
#    leaves installed ones where this host's lock file (~/.config/nvim/
#    lazy-lock.json, not in the repo) has them. sync would also update every
#    plugin to its latest version and rewrite that lock file.
if command -v nvim >/dev/null 2>&1; then
  nvim --headless "+Lazy! install" +qa || true
fi

# 4. The colours the terminals, tmux, nvim and bat read. bin/theme writes those
#    files under $XDG_DATA_HOME; until it has run once they are absent, which
#    every config tolerates -- nothing is themed, that is all. Seeded here only
#    when this machine has none, with whatever mode and colourscheme `theme`
#    reports (its own defaults on a fresh machine), so re-running this script
#    never disturbs a machine whose theme is already set.
theme_bin="${dotfiles_dir}/bin/theme"
if [[ ! -e "${XDG_DATA_HOME:-${HOME}/.local/share}/tmux/color.conf" && -x "${theme_bin}" ]]; then
  "${theme_bin}" --set "$("${theme_bin}" --mode)" "$("${theme_bin}" --colors)" || true
fi

if [[ "$(uname)" == "Darwin" ]]; then
  echo
  echo "Setting up a new Mac? Also run this, once:"
  echo "  ${dotfiles_dir}/macos-defaults.sh"
  echo "It applies the baseline Finder, Dock and keyboard settings, and resets the Dock."
fi