-
Notifications
You must be signed in to change notification settings - Fork 0
/
diff.sh
executable file
·151 lines (117 loc) · 4.86 KB
/
diff.sh
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
113
114
115
116
117
118
119
120
121
122
123
124
125
126
127
128
129
130
131
132
133
134
135
136
137
138
139
140
141
142
143
144
145
146
147
148
149
150
151
#!/usr/bin/env bash
set -euo pipefail
# This script detects differences between git-versioned config and the local system.
# It offers options for what to do about them.
# It is called without arguments.
# TODO allowed patch for e.g. work starship.toml
# TODO something about WIZARD and other symlinks
# TODO why are things printed three times oops
# TODO merge tomls for work starship
declare -A dotfiles
dotfiles=(
["$HOME/.tmux.conf"]="tmux/.tmux.conf"
["$HOME/.config/tmux/"]="tmux/config"
["$HOME/.vim/vimrc"]="vim/vimrc"
["$HOME/.vim/syntax/"]="vim/syntax"
["$HOME/.vim/customsnippets/"]="vim/customsnippets"
["$HOME/.vale.ini"]="vale/.vale.ini"
["$HOME/.shellcheckrc"]="shellcheck/.shellcheckrc"
["$HOME/.alexrc.js"]="alex/.alexrc.js"
["$HOME/.config/starship.toml"]="starship/starship.toml"
["$HOME/.gitconfig"]="git/.gitconfig"
["$HOME/.config/git/gitignore"]="git/config/gitignore"
["$HOME/.config/git/tokyonight_day.gitconfig"]="git/config/tokyonight_day.gitconfig"
["$HOME/.config/git/gitmessage"]="git/config/gitmessage"
["$HOME/.config/pre-commit/config-personal.yaml"]="git/pre-commit-config.yaml"
["$HOME/.config/pre-commit/config-work.yaml"]="git/pre-commit-config-work.yaml"
["$HOME/.config/git/hooks/pre-commit"]="git/global-pre-commit-hook"
["$HOME/.config/iterm2/tokyonight_day.itermcolors"]="iterm2/tokyonight_day.itermcolors"
["$HOME/.config/iterm2/com.googlecode.iterm2.plist"]="iterm2/com.googlecode.iterm2.plist"
["$HOME/.config/bat/"]="bat/config/"
["$HOME/.config/ripgreprc"]="ripgreprc"
["$HOME/.config/yamllint/config"]="yamllint_config.yaml"
["$HOME/.config/fish/fish_plugins"]="fish/config/fish_plugins"
["$HOME/.config/fish/config.fish"]="fish/config/config.fish"
["$HOME/.config/fish/themes/"]="fish/config/themes"
["$HOME/Library/Application Support/ruff/pyproject.toml"]="ruff/pyproject.toml"
["$HOME/Documents/Tokyonight Day.terminal"]="terminal.app/Tokyonight Day.terminal"
["$HOME/.config/python/global-requirements.txt"]="python/global-requirements.txt"
["$HOME/bin/"]="bin"
["$HOME/.local/share/update.d/"]="update.d"
)
# Compare two files to see if they match
function compare_file {
local LOCAL="$1"
local GIT="$2"
if ! [ -f "$LOCAL" ]; then
echo "=================================================================================="
echo "Local dotfile does not exist: $LOCAL" >&2
return 1
fi
if ! [ -f "$GIT" ]; then
echo "=================================================================================="
# TODO doesn't work in tmux scrollback
echo "$GIT does not exist. Run:" >&2
printf " cp \033]8;;file://%s\033\\%s\033]8;;\033\\ %s\n" "$LOCAL" "$LOCAL" "$GIT"
return 0
fi
if diff -u --ignore-trailing-space --ignore-blank-lines --strip-trailing-cr "$(realpath "$LOCAL")" "$GIT" | delta --pager cat --width "$(tput cols)"; then
# echo "EQUAL: $LOCAL $GIT"
return 0
fi
echo "=================================================================================="
echo "edit files:"
echo " vimdiff $LOCAL $GIT"
echo "clobber local:"
echo " command cp $GIT $LOCAL"
echo "clobber remote:"
echo " command cp $LOCAL $GIT"
}
# Recurse
function compare_maybe_dir {
local LOCAL GIT
LOCAL="$(echo "$1" | tr -s /)"
GIT="$(echo "$2" | tr -s /)"
if ! [ -e "$LOCAL" ]; then
echo "=================================================================================="
echo "Expected dotfile does not exist: $LOCAL" >&2
echo "add to local:"
if ! [ -d "$(dirname "$LOCAL")" ]; then
printf " mkdir -p \"%s\" &&" "$(dirname "$LOCAL")"
fi
echo " command cp $GIT $LOCAL"
return
fi
if [ -f "$LOCAL" ]; then
compare_file "$LOCAL" "$GIT"
return
fi
if [ -d "$LOCAL" ]; then
for local_maybe_dir in "$LOCAL"/*; do
local final
final="$(basename "$local_maybe_dir")"
compare_maybe_dir "$local_maybe_dir" "${GIT}/${final}"
done
# TODO remove dupes, add copy cmd
for git_maybe_dir in "$GIT"/*; do
local final
final="$(basename "$git_maybe_dir")"
compare_maybe_dir "${LOCAL}/${final}" "$git_maybe_dir"
done
return
fi
echo "This should never happen" >&2
return 1
}
for local in "${!dotfiles[@]}"; do
compare_maybe_dir "$(echo "$local" | tr -s /)" "${dotfiles[$local]}"
done
# All my fish configs are in the form 30_pyenv.fish
# So we can exclude the ones created by fish_plugins
for config in "$HOME/.config/fish/conf.d"/*; do
if basename "$config" | grep -qE '^\d\d' ; then
gitconfig=fish/config/conf.d/"$(basename "$config")"
compare_file "$config" "$gitconfig"
fi
done
# TODO add "--install" flag