main dotfiles.sh
Eric Bower  ·  2026-06-13
 1#!/usr/bin/env bash
 2
 3declare -A TRACKED
 4TRACKED=(
 5  [bin/]="$HOME/.local/bin/"
 6  [dot_pi/agent/extensions/]="$HOME/.pi/agent/extensions/"
 7  [dot_pi/agent/settings.json]="$HOME/.pi/agent/settings.json"
 8  [dot_config/]="$HOME/.config/"
 9  [dot/gitconfig]="$HOME/.gitconfig"
10  [dot/mbsyncrc]="$HOME/.mbsyncrc"
11  [dot_gnupg/gpg-agent.conf]="$HOME/.gnupg/gpg-agent.conf"
12  [dot_ssh/config]="$HOME/.ssh/config"
13  [dot_mblaze/mblaze]="$HOME/.mblaze/profile"
14  [dot/msmtprc]="$HOME/.msmtprc"
15  [dot/npmrc]="$HOME/.npmrc"
16  [dot/editorconfig]="$HOME/.editorconfig"
17)
18
19find_files() {
20  local tfo="$1"
21  if [[ ${tfo} == */ ]]; then
22    find "$PWD/${tfo}" -type d -exec find {} -maxdepth 1 -type f \; | sed "s|$PWD/${tfo}||" | sed "s|^/||"
23  fi
24}
25
26link_file() {
27  if [[ ! -L "$2" && ! -f "$2" && ! -d "$2" ]]; then
28    echo "Creating a link from $1 to $2"
29    mkdir -p "$(dirname "$2")"
30    ln -s "$1" "$2"
31  fi
32}
33
34unlink_file() {
35  if [[ -L "$1" ]]; then
36    echo "Unlinking $1"
37    unlink "$1"
38  fi
39}
40
41case "${1:-link}" in
42  link)
43    for tf in "${!TRACKED[@]}"; do
44      tl="${TRACKED[$tf]}"
45      link_file "$PWD/${tf}" "${tl}"
46      while IFS= read -r file; do
47        link_file "$PWD/${tf}${file}" "${tl}${file}"
48      done < <(find_files "$tf")
49    done
50    ;;
51  cleanup)
52    for tf in "${!TRACKED[@]}"; do
53      tl="${TRACKED[$tf]}"
54      unlink_file "${tl}"
55      while IFS= read -r file; do
56        unlink_file "${tl}${file}"
57      done < <(find_files "$tf")
58    done
59    ;;
60  *)
61    echo "Usage: $0 [link|cleanup]" >&2
62    exit 1
63    ;;
64esac