-
Notifications
You must be signed in to change notification settings - Fork 35
/
Copy pathinstall.sh
executable file
·294 lines (260 loc) · 10.5 KB
/
install.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
152
153
154
155
156
157
158
159
160
161
162
163
164
165
166
167
168
169
170
171
172
173
174
175
176
177
178
179
180
181
182
183
184
185
186
187
188
189
190
191
192
193
194
195
196
197
198
199
200
201
202
203
204
205
206
207
208
209
210
211
212
213
214
215
216
217
218
219
220
221
222
223
224
225
226
227
228
229
230
231
232
233
234
235
236
237
238
239
240
241
242
243
244
245
246
247
248
249
250
251
252
253
254
255
256
257
258
259
260
261
262
263
264
265
266
267
268
269
270
271
272
273
274
275
276
277
278
279
280
281
282
283
284
285
286
287
288
289
290
291
292
293
294
#!/bin/bash
######################################################################
# 🧰 Lissy93/Dotfiles - All-in-One Install and Setup Script for Unix #
######################################################################
# Fetches latest changes, symlinks files, and installs dependencies #
# Then sets up ZSH, TMUX, Vim as well as OS-specific tools and apps #
# For docs and more info, see: /~https://github.com/lissy93/dotfiles #
# #
# IMPORTANT: Before running, read through everything very carefully! #
# #
# Licensed under MIT (C) Alicia Sykes 2022 <https://aliciasykes.com> #
######################################################################
# Configuration Params
REPO_NAME="${REPO_NAME:-Lissy93/Dotfiles}"
REPO_PATH="/~https://github.com/${REPO_NAME}.git"
SYMLINK_FILE="${SYMLINK_FILE:-symlinks.yaml}"
DOTBOT_DIR="dotbot"
DOTBOT_BIN="bin/dotbot"
CURRENT_DIR=$(cd "$(dirname ${BASH_SOURCE[0]})" && pwd)
DOTFILES_DIR="${DOTFILES_DIR:-$HOME/Documents/config/dotfiles}"
TITLE="🧰 ${REPO_NAME} Setup"
# Color Variables
CYAN_B='\033[1;96m'
YELLOW_B='\033[1;93m'
RED_B='\033[1;31m'
GREEN_B='\033[1;32m'
PLAIN_B='\033[1;37m'
RESET='\033[0m'
GREEN='\033[0;32m'
PURPLE='\033[0;35m'
# Other params
PROMPT_TIMEOUT=15 # When user is prompted for input, skip after x seconds
# Clear the screen
clear
# Start timer
start_time=`date +%s`
# Get system type - Linux / MacOS (Darwin)
system_type=$(uname -s)
# Function that prints important text in a banner with colored border
# First param is the text to output, then optional color and padding
make_banner () {
bannerText=$1
lineColor="${2:-$CYAN_B}"
padding="${3:-0}"
titleLen=$(expr ${#bannerText} + 2 + $padding);
lineChar="─"; line=""
for (( i = 0; i < "$titleLen"; ++i )); do line="${line}${lineChar}"; done
banner="${lineColor}╭${line}╮\n│ ${PLAIN_B}${bannerText}${lineColor} │\n╰${line}╯"
echo -e "\n${banner}\n${RESET}"
}
# Explain to the user what changes will be made
make_intro () {
C2="\033[0;35m"
C3="\x1b[2m"
echo -e "${CYAN_B}The seup script will do the following:${RESET}"
echo -e "${C2}(1) Pre-Setup Tasls"
echo -e " ${C3}- Check that all requirements are met, and system is compatible"
echo -e "${C2}(2) Setup Dotfiles"
echo -e " ${C3}- Clone or update dotfiles from git, and apply symlinks"
echo -e "${C2}(3) Install packages"
echo -e " ${C3}- Update packeges, and prompt to install apps"
echo -e "${C2}(4) Configure sytstem"
echo -e " ${C3}- Setup Vim, Tmux and ZSH plugins"
echo -e " ${C3}- Configure OS and apply app user preferences"
echo -e "\n${PURPLE}You will be prompted at each stage, before any changes are made.${RESET}"
}
# Checks if a given package is installed
command_exists () {
hash "$1" 2> /dev/null
}
# On error, displays death banner, and terminates app with exit code 1
terminate () {
make_banner "Installation failed. Terminating..." ${RED_B}
exit 1
}
# Checks if command / package (in $1) exists and then shows
# either shows a warning or error, depending if package required ($2)
system_verify () {
if ! command_exists $1; then
if $2; then
echo -e "🚫 ${RED_B}Error:${PLAIN_B} $1 is not installed${RESET}"
terminate
else
echo -e "⚠️ ${YELLOW_B}Warning:${PLAIN_B} $1 is not installed${RESET}"
fi
fi
}
# Prints welcome banner, verifies that requirements are met
function pre_setup_tasks () {
# Show starting banner
make_banner "${TITLE}" "${CYAN_B}" 1
# Print list of what will be applied
make_intro
# Confirm user would like to proceed
echo -e "\n${CYAN_B}Are you happy to continue? (y/N)${RESET}"
read -t $PROMPT_TIMEOUT -n 1 -r
if [[ ! $REPLY =~ ^[Yy]$ ]]; then
echo -e "\n${PURPLE}No worries, feel free to come back another time.\nTerminating...${RESET}"
exit 0
fi
echo
# Verify required packages are installed
system_verify "git" true
system_verify "zsh" false
system_verify "vim" false
system_verify "nvim" false
system_verify "tmux" false
}
# Downloads / updates dotfiles and symlinks them
function setup_dot_files () {
# Download / update dotfiles repo with git
if [[ ! -d "$DOTFILES_DIR" ]]
then
echo -e "${PURPLE}Dotfiles not yet present. Will download ${REPO_NAME} into ${DOTFILES_DIR}${RESET}"
mkdir -p "${DOTFILES_DIR}"
git clone --recursive ${REPO_PATH} ${DOTFILES_DIR}
else
echo -e "${PURPLE}Pulling changes from ${REPO_NAME} into ${DOTFILES_DIR}${RESET}"
cd "${DOTFILES_DIR}" && git pull origin master && git submodule update --recursive
fi
# If git clone / pull failed, then exit with error
ret=$?
if ! test "$ret" -eq 0
then
echo >&2 "${RED_B}Failed to fetch dotfiels $ret${RESET}"
terminate
fi
# Set up symlinks with dotbot
echo -e "${PURPLE}Setting up Symlinks${RESET}"
cd "${DOTFILES_DIR}"
git -C "${DOTBOT_DIR}" submodule sync --quiet --recursive
git submodule update --init --recursive "${DOTBOT_DIR}"
chmod +x dotbot/bin/dotbot
"${DOTFILES_DIR}/${DOTBOT_DIR}/${DOTBOT_BIN}" -d "${DOTFILES_DIR}" -c "${SYMLINK_FILE}" "${@}"
}
# Applies application-specific preferences, and runs some setup tasks
function apply_preferences () {
# If ZSH not the default shell, ask user if they'd like to set it
if [[ $SHELL != *"zsh"* ]] && command_exists zsh; then
read -t $PROMPT_TIMEOUT -p "$(echo -e $CYAN_B)Would you like to set ZSH as your default shell? (y/N)" -n 1 -r
echo
if [[ $REPLY =~ ^[Yy]$ ]]; then
echo -e "${PURPLE}Setting ZSH as default shell${RESET}"
chsh -s $(which zsh) $USER
fi
fi
# Install / update vim plugins with Plug
echo -e "\n${PURPLE}Installing Vim Plugins${RESET}"
vim +PlugInstall +qall
# Install / update Tmux plugins with TPM
echo -e "${PURPLE}Installing TMUX Plugins${RESET}"
chmod ug+x "${XDG_DATA_HOME}/tmux/tpm"
sh "${TMUX_PLUGIN_MANAGER_PATH}/tpm/bin/install_plugins"
sh "${XDG_DATA_HOME}/tmux/plugins/tpm/bin/install_plugins"
# Install / update ZSH plugins with Antigen
echo -e "${PURPLE}Installing ZSH Plugins${RESET}"
/bin/zsh -i -c "antigen update && antigen-apply"
# Apply general system, app and OS security preferences (prompt user first)
read -t $PROMPT_TIMEOUT -p "$(echo -e $CYAN_B)Would you like to apply system preferences? (y/N)" -n 1 -r
if [[ $REPLY =~ ^[Yy]$ ]]; then
if [ "$system_type" = "Darwin" ]; then
echo -e "\n${PURPLE}Applying MacOS system preferences, ensure you've understood before proceeding${RESET}\n"
macos_settings_dir="$DOTFILES_DIR/system-specific/macos/system-settings"
for macScript in "macos-security.sh" "macos-preferences.sh" "macos-apps.sh"; do
chmod +x $macos_settings_dir/$macScript && $macos_settings_dir/$macScript --quick-exit
done
fi
fi
}
# Setup Brew, install / update packages, organize launchpad and checks for macOS updates
function intall_macos_packages () {
# Homebrew not installed, ask user if they'd like to download it now
if ! command_exists brew; then
read -t $PROMPT_TIMEOUT -p "$(echo -e $CYAN_B)Would you like to install Homebrew? (y/N)" -n 1 -r
echo
if [[ $REPLY =~ ^[Yy]$ ]]; then
echo -en "🍺 ${PURPLE}Installing Homebrew...${RESET}\n"
/bin/bash -c "$(curl -fsSL https://raw.githubusercontent.com/Homebrew/install/HEAD/install.sh)"
export PATH=/opt/homebrew/bin:$PATH
fi
fi
# Update / Install the Homebrew packages in ~/.Brewfile
if command_exists brew && [ -f "$DOTFILES_DIR/installs/Brewfile" ]; then
echo -e "\n${PURPLE}Updating homebrew and packages...${RESET}"
brew update
brew upgrade
brew bundle --global --file $HOME/.Brewfile
brew cleanup
else
echo -e "${PURPLE}Skipping Homebrew as requirements not met${RESET}"
fi
# Restore launchpad structure with lporg
launchpad_layout="${DOTFILES_DIR}/system-specific/macos/app-configs/launchpad.yml"
if command_exists lporg && [ -f $launchpad_layout ]; then
echo -e "${PURPLE}Restoring Launchpad Layout...${RESET}"
yes "" | lporg load $launchpad_layout
fi
# Check for MacOS software updates, and ask user if they'd like to install
echo -e "${PURPLE}Checking for software updates...${RESET}"
pending_updates=$(softwareupdate -l 2>&1)
if [[ ! $pending_updates == *"No new software available."* ]]; then
echo -e "${PURPLE}A new version of Mac OS is availbile${RESET}"
read -t $PROMPT_TIMEOUT -p "$(echo -e $CYAN_B)Would you like to update to the latest version of MacOS? (y/N)" -n 1 -r
echo -e "${RESET}"
if [[ $REPLY =~ ^[Yy]$ ]]; then
echo "${PURPLE}Updating MacOS${RESET}"
softwareupdate -i -a
fi
else
echo -e "${GREEN}System is up-to-date."\
"Running $(sw_vers -productName) version $(sw_vers -productVersion)${RESET}"
fi
}
# Based on system type, uses appropriate package manager to install / updates apps
function install_packages () {
read -t $PROMPT_TIMEOUT -p "$(echo -e $CYAN_B)Would you like to install / update system packages? (y/N) " -n 1 -r
echo
if [[ ! $REPLY =~ ^[Yy]$ ]]; then
echo -e "${PURPLE}Skipping package installs${RESET}"
return
fi
# Mac OS
if [ "$system_type" = "Darwin" ]; then
intall_macos_packages
fi
# If running in Linux desktop mode, prompt to install desktop apps via Flatpak
flatpak_script="${DOTFILES_DIR}/installs/flatpak.sh"
if [[ $(uname -s) == "Linux" ]] && [ ! -z $XDG_CURRENT_DESKTOP ] && [ -f $flatpak_script ]; then
chmod +x $flatpak_script
$flatpak_script
fi
}
# Updates current session, and outputs summary
function finishing_up () {
# Update source to ZSH entry point
source "${HOME}/.zshenv"
# Print success message, and time taken
total_time=$((`date +%s`-start_time))
make_banner "✨ Dotfiles configured succesfully in $total_time seconds" ${GREEN_B} 1
echo -e "\033[0;92m .--.\n |o_o |\n |:_/ |\n // \
\ \\ \n (| | ) \n /'\_ _/\`\\ \n \\___)=(___/\n"
# Refresh ZSH sesssion
SKIP_WELCOME=true || exec zsh
# Exit script with success code
echo -e "${CYAN_B}Press any key to exit.${RESET}\n"
read -t $PROMPT_TIMEOUT -n 1 -s
exit 0
}
# If --help flag passed in, just show the help menu
if [[ $* == "--help" ]]; then
make_intro
exit 0
fi
# Let's Begin!
pre_setup_tasks # Print start message, and check requirements are met
setup_dot_files # Clone / updatae dotfiles, and create the symlinks
install_packages # Prompt to install / update OS-specific packages
apply_preferences # Apply settings for individual applications
finishing_up # Refresh current session, print summary and exit
# All done :)