-
Notifications
You must be signed in to change notification settings - Fork 0
Expand file tree
/
Copy pathget.sh
More file actions
executable file
·222 lines (199 loc) · 6.18 KB
/
get.sh
File metadata and controls
executable file
·222 lines (199 loc) · 6.18 KB
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
#!/usr/bin/env sh
set -eu
check() {
required_commands="git curl sh bash which chsh"
for cmd in $required_commands; do
if ! command -v "$cmd" >/dev/null 2>&1; then
printf "Error: required command '%s' is not installed.\n" "$cmd"
return 1
fi
done
}
extend_sudo_timeout() {
# Check if already running (prevent duplicate processes)
if [ -n "${_DOTFILES_SUDO_KEEPER_PID:-}" ] && kill -0 "$_DOTFILES_SUDO_KEEPER_PID" 2>/dev/null; then
# Sudo keeper already running, nothing to do
return 0
fi
# Check if sudo is available and we're on a system that uses it
if ! command -v sudo >/dev/null 2>&1; then
# sudo not available, nothing to do
return 0
fi
# Prompt for sudo credentials once to extend the timeout
# This reduces password prompts during the installation process
printf "Some installation steps require administrative privileges.\n"
printf "Please enter your password to proceed (you won't be asked again for a while):\n"
if sudo -v; then
# Keep sudo session alive in background
# This updates the timestamp every 60 seconds
(
while true; do
sleep 60
sudo -n true 2>/dev/null || exit
done
) &
_DOTFILES_SUDO_KEEPER_PID=$!
# Set up cleanup trap to kill the background process
trap 'kill "$_DOTFILES_SUDO_KEEPER_PID" 2>/dev/null || true' EXIT INT TERM
printf "Sudo session extended. (PID: %s)\n" "$_DOTFILES_SUDO_KEEPER_PID"
else
printf "Warning: Failed to authenticate with sudo. Installation may prompt for password multiple times.\n"
return 1
fi
}
get() {
DOTFILES_DIR=${DOTFILES_DIR:-"$HOME/dotfiles"}
DOTFILES_REPO=${DOTFILES_REPO:-"https://github.com/HectorCastelli/dotfiles.git"}
printf "Checking mandatory dependencies...\n"
if ! check; then
printf "Error: missing required dependencies.\n"
return 1
else
printf "All required dependencies are installed.\n"
fi
# Extend sudo timeout to reduce password prompts during installation
extend_sudo_timeout
if [ -d "$DOTFILES_DIR" ]; then
if [ -d "$DOTFILES_DIR/.git" ]; then
CURRENT_REMOTE=$(git -C "$DOTFILES_DIR" remote get-url origin 2>/dev/null || echo "")
if [ "$CURRENT_REMOTE" = "$DOTFILES_REPO" ]; then
printf "Directory '%s' is already a git repository pointing to the correct remote.\n" "$DOTFILES_DIR"
printf "Would you like to update it instead? [y/N]: "
read -r update_ans </dev/tty
case "$(printf '%s' "$update_ans" | tr '[:upper:]' '[:lower:]')" in
y | yes)
printf "Updating existing repository...\n"
if git -C "$DOTFILES_DIR" pull; then
printf "Update successful.\n"
else
printf "Error: git pull failed.\n"
return 2
fi
;;
*)
printf "Update skipped.\n"
;;
esac
else
printf "Error: '%s' is a git repository but points to a different remote.\n" "$DOTFILES_DIR"
printf "Current remote: %s\n" "$CURRENT_REMOTE"
printf "Expected remote: %s\n" "$DOTFILES_REPO"
return 3
fi
else
printf "Error: '%s' exists but is not a git repository.\n" "$DOTFILES_DIR"
return 4
fi
else
printf "Cloning %s into %s ...\n" "$DOTFILES_REPO" "$DOTFILES_DIR"
if git clone "$DOTFILES_REPO" "$DOTFILES_DIR"; then
printf "Clone successful.\n"
else
printf "Error: git clone failed.\n"
return 5
fi
fi
# Pull submodules
if git -C "$DOTFILES_DIR" submodule update --init --recursive --remote; then
printf "Submodules updated successfully.\n"
else
printf "Error: failed to update submodules.\n"
return 6
fi
install
}
install() {
DOTFILES_DIR=${DOTFILES_DIR:-"$HOME/dotfiles"}
TARGET_DIR="${TARGET_DIR:-$DOTFILES_DIR/.target}"
# Extend sudo timeout to reduce password prompts during installation
extend_sudo_timeout
printf "Initializing target directory...\n"
if sh "$DOTFILES_DIR/scripts/target.sh" initialize; then
printf "Target directory initialized successfully.\n"
else
printf "Error: target directory initialization failed.\n"
return 1
fi
PROFILES=$("$DOTFILES_DIR/scripts/profiles.sh" list)
for profile in $PROFILES; do
if ! grep -qxF "$profile" "$TARGET_DIR/.dotfiles_profiles" 2>/dev/null; then
if [ ! -f "$DOTFILES_DIR/profiles/$profile/.mandatory" ]; then
printf "Optional profile available: %s\n" "$profile"
printf "Would you like to install '%s'? [y/N]: " "$profile"
read -r ans </dev/tty
case "$(printf '%s' "$ans" | tr '[:upper:]' '[:lower:]')" in
y | yes) ;;
*)
printf "Skipped optional profile: %s\n" "$profile"
continue
;;
esac
else
printf "Profile '%s' is mandatory.\n" "$profile"
fi
else
printf "Profile '%s' is already installed.\n" "$profile"
fi
if sh "$DOTFILES_DIR/scripts/target.sh" install_profile "$profile"; then
printf "Installed profile: %s\n" "$profile"
else
printf "Error: failed to install profile '%s'.\n" "$profile"
return 2
fi
done
printf "Building target configuration...\n"
if sh "$DOTFILES_DIR/scripts/target.sh" build; then
printf "Target configuration built successfully.\n"
else
printf "Error: failed to build target configuration.\n"
return 3
fi
printf "If you would like to review the target first, please look into the '%s' directory.\n" "$TARGET_DIR"
# Open target directory in VS Code if available
if command -v code >/dev/null 2>&1; then
printf "Opening target directory in VS Code...\n"
code "$TARGET_DIR"
fi
printf "Do you want to proceed with the installation? [y/N]: "
read -r apply_ans </dev/tty
case "$(printf '%s' "$apply_ans" | tr '[:upper:]' '[:lower:]')" in
y | yes)
printf "Applying target configuration...\n"
if sh "$DOTFILES_DIR/scripts/target.sh" apply; then
printf "Target configuration applied successfully.\n"
else
printf "Error: failed to apply target configuration.\n"
return 4
fi
;;
*)
printf "Installation skipped. You can apply the configuration later by running:\n"
printf " sh %s/scripts/target.sh apply\n" "$DOTFILES_DIR"
;;
esac
}
case "${1:-}" in
get)
get
;;
install)
install
;;
check)
check
;;
help)
USAGE="Usage:
$(basename "$0") <command>
Available commands:
get Download the dotfiles repository, then installs it
install Installs the dotfiles repository
check Checks for required dependencies
help Show this help message"
printf "%s\n" "$USAGE"
;;
*)
# script was sourced, so we do nothing.
;;
esac