@@ -30,14 +30,16 @@ GITHUB_API="https://api.github.com/repos/$REPO_OWNER/$REPO_NAME/releases"
30
30
# GitHub Release address
31
31
GITHUB_REL=" https://github.com/$REPO_OWNER /$REPO_NAME /releases/download"
32
32
33
- # Default install directory ( will be adjusted for Windows)
34
- DEFAULT_BIN_DIR=" /usr/local/bin "
33
+ # Default install directories will be set based on OS
34
+ DEFAULT_BIN_DIR=" "
35
35
36
36
# Default to empty (meaning get latest version)
37
37
VERSION=" "
38
38
39
39
# Is this Windows?
40
40
IS_WINDOWS=0
41
+ # Is this macOS?
42
+ IS_MACOS=0
41
43
42
44
# FUNCTIONS
43
45
@@ -68,6 +70,63 @@ print_warning() {
68
70
printf " ${YELLOW} [WARNING]${DEFAULT} $1 \n"
69
71
}
70
72
73
+ # Check if ctx is already installed and get its location
74
+ check_existing_installation () {
75
+ print_header " Checking for existing installation"
76
+
77
+ # Get the binary name based on OS
78
+ if [ " $IS_WINDOWS " -eq 1 ]; then
79
+ binary_to_find=" ${PNAME} .exe"
80
+ else
81
+ binary_to_find=" $PNAME "
82
+ fi
83
+
84
+ # Try to find existing installation
85
+ if command -v " $PNAME " > /dev/null 2>&1 ; then
86
+ existing_path=$( command -v " $PNAME " )
87
+ existing_dir=$( dirname " $existing_path " )
88
+ print_success " Found existing installation at: $existing_path "
89
+
90
+ # Set default bin directory to the location of the existing installation
91
+ DEFAULT_BIN_DIR=" $existing_dir "
92
+
93
+ # Get current version if possible
94
+ if " $existing_path " --version > /dev/null 2>&1 ; then
95
+ current_version=$( " $existing_path " --version | grep -o ' [0-9]\+\.[0-9]\+\.[0-9]\+' | head -1)
96
+ if [ -n " $current_version " ]; then
97
+ print_status " Current version: $current_version "
98
+ fi
99
+ fi
100
+
101
+ return 0
102
+ else
103
+ # Check common directories for the binary
104
+ for check_dir in /usr/local/bin /usr/bin " $HOME /.local/bin" " $HOME /bin" " $HOME /AppData/Local/bin" ; do
105
+ if [ -f " $check_dir /$binary_to_find " ]; then
106
+ existing_path=" $check_dir /$binary_to_find "
107
+ existing_dir=" $check_dir "
108
+ print_success " Found existing installation at: $existing_path "
109
+
110
+ # Set default bin directory to the location of the existing installation
111
+ DEFAULT_BIN_DIR=" $existing_dir "
112
+
113
+ # Get current version if possible
114
+ if " $existing_path " --version > /dev/null 2>&1 ; then
115
+ current_version=$( " $existing_path " --version | grep -o ' [0-9]\+\.[0-9]\+\.[0-9]\+' | head -1)
116
+ if [ -n " $current_version " ]; then
117
+ print_status " Current version: $current_version "
118
+ fi
119
+ fi
120
+
121
+ return 0
122
+ fi
123
+ done
124
+
125
+ print_status " No existing installation found"
126
+ return 1
127
+ fi
128
+ }
129
+
71
130
# Gets the version either from user input or latest from GitHub
72
131
# Sets the $latest and $latestV variables.
73
132
# Returns 0 in case of success, 1 otherwise.
@@ -107,6 +166,17 @@ get_latest() {
107
166
108
167
if [ -n " $latest " ]; then
109
168
print_success " Latest version found: $latestV "
169
+
170
+ # Compare versions if we have a current version
171
+ if [ -n " $current_version " ] && [ " $latest " = " $current_version " ]; then
172
+ print_warning " You already have the latest version installed"
173
+ if ! prompt_for_confirmation " Do you want to reinstall the same version?" ; then
174
+ print_status " Installation cancelled by user."
175
+ exit 0
176
+ fi
177
+ elif [ -n " $current_version " ]; then
178
+ print_status " Upgrading from version $current_version to $latestV "
179
+ fi
110
180
fi
111
181
112
182
return 0
@@ -131,16 +201,48 @@ get_os() {
131
201
# ---
132
202
' Darwin' )
133
203
os=' darwin'
204
+ IS_MACOS=1
134
205
;;
135
206
136
207
# ---
137
208
* )
138
209
return 1
139
210
;;
140
211
esac
212
+
213
+ # Set default bin directory based on OS
214
+ set_default_bin_dir
215
+
141
216
return 0
142
217
}
143
218
219
+ # Sets the default bin directory based on detected OS
220
+ set_default_bin_dir () {
221
+ if [ " $IS_WINDOWS " -eq 1 ]; then
222
+ # For Windows, we'll use AppData\Local\bin or HOME\bin
223
+ if [ -d " $HOME /AppData/Local/bin" ]; then
224
+ DEFAULT_BIN_DIR=" $HOME /AppData/Local/bin"
225
+ else
226
+ DEFAULT_BIN_DIR=" $HOME /bin"
227
+ fi
228
+ elif [ " $IS_MACOS " -eq 1 ]; then
229
+ # For macOS, check if user has write access to /usr/local/bin
230
+ if [ -w " /usr/local/bin" ]; then
231
+ DEFAULT_BIN_DIR=" /usr/local/bin"
232
+ else
233
+ # Otherwise use ~/.local/bin for non-sudo installation
234
+ DEFAULT_BIN_DIR=" $HOME /.local/bin"
235
+ fi
236
+ else
237
+ # For Linux and other systems
238
+ if [ -w " /usr/local/bin" ]; then
239
+ DEFAULT_BIN_DIR=" /usr/local/bin"
240
+ else
241
+ DEFAULT_BIN_DIR=" $HOME /.local/bin"
242
+ fi
243
+ fi
244
+ }
245
+
144
246
# Gets the architecture by setting the $arch variable.
145
247
# Returns 0 in case of success, 1 otherwise.
146
248
get_arch () {
@@ -193,12 +295,6 @@ detect_windows_dir() {
193
295
}
194
296
195
297
ensure_bin_dir () {
196
- # Handle Windows-specific directories
197
- if [ " $IS_WINDOWS " -eq 1 ] && [ " $bin_dir " = " $DEFAULT_BIN_DIR " ]; then
198
- detect_windows_dir
199
- print_status " Windows detected. Setting installation directory to: $bin_dir "
200
- fi
201
-
202
298
# Create bin directory if it doesn't exist
203
299
if [ ! -d " $bin_dir " ]; then
204
300
print_status " Creating directory $bin_dir ..."
@@ -223,6 +319,9 @@ ensure_bin_dir() {
223
319
printf " ${GREEN} 6. Click 'OK' on all dialogs${DEFAULT} \n\n"
224
320
printf " Or in PowerShell, run:${DEFAULT} \n"
225
321
printf " ${GREEN} \$ env:Path += \" ;$bin_dir \" ${DEFAULT} \n\n"
322
+ elif [ " $IS_MACOS " -eq 1 ]; then
323
+ printf " You might want to add the following line to your shell profile (~/.zshrc or ~/.bash_profile):\n"
324
+ printf " ${GREEN} export PATH=\"\$ PATH:$bin_dir \" ${DEFAULT} \n\n"
226
325
else
227
326
printf " You might want to add the following line to your shell profile (.bashrc, .zshrc, etc.):\n"
228
327
printf " ${GREEN} export PATH=\"\$ PATH:$bin_dir \" ${DEFAULT} \n\n"
@@ -231,39 +330,6 @@ ensure_bin_dir() {
231
330
}
232
331
233
332
download_and_install () {
234
- # Get the latest version
235
- print_header " Checking for updates"
236
-
237
- if ! get_latest; then
238
- fetch_release_failure_usage
239
- exit 1
240
- fi
241
-
242
- if [ " $latest " = ' ' ]; then
243
- fetch_release_failure_usage
244
- exit 1
245
- fi
246
-
247
- # Fill $os variable.
248
- if ! get_os; then
249
- not_available_failure_usage
250
- exit 1
251
- fi
252
- # Fill $arch variable.
253
- if ! get_arch; then
254
- not_available_failure_usage
255
- exit 1
256
- fi
257
-
258
- # Add .exe extension for Windows
259
- binary_name=" $PNAME "
260
- if [ " $IS_WINDOWS " -eq 1 ]; then
261
- binary_name=" ${PNAME} .exe"
262
- release_file=" $PNAME -$latest -$os -$arch .exe"
263
- else
264
- release_file=" $PNAME -$latest -$os -$arch "
265
- fi
266
-
267
333
# Download the binary file
268
334
print_header " Downloading the latest version"
269
335
print_status " Preparing download from: $GITHUB_REL /$latestV /$release_file "
@@ -286,7 +352,7 @@ download_and_install() {
286
352
# Use curl with progress bar but suppress most headers
287
353
if ! curl --fail -L " $GITHUB_REL /$latestV /$release_file " -o " $temp_file " \
288
354
--progress-bar --write-out " %{http_code}" | grep -q " ^2" ; then
289
- printf " ] ${RED} Failed!${DEFAULT} \n "
355
+ echo " ] ${RED} Failed!${DEFAULT} "
290
356
print_error " Failed to download $GITHUB_REL /$latestV /$release_file "
291
357
rm -f " $temp_file "
292
358
exit 1
@@ -316,22 +382,61 @@ download_and_install() {
316
382
print_success " Successfully replaced the binary file"
317
383
print_success " Successfully installed $latestV to $bin_dir /$binary_name \n"
318
384
319
- printf " You can now run it using:\n "
385
+ echo " You can now run it using:"
320
386
if [ " $IS_WINDOWS " -eq 1 ]; then
321
- printf " ${BOLD} $binary_name ${DEFAULT} \n\n "
387
+ echo " ${BOLD} $binary_name ${DEFAULT} "
322
388
else
323
- printf " ${BOLD} $PNAME ${DEFAULT} \n\n"
389
+ echo " ${BOLD} $PNAME ${DEFAULT} "
390
+ fi
391
+ echo " 📚 Documentation: https://docs.ctxgithub.com"
392
+ echo " 🚀 Happy AI coding!"
393
+ }
394
+
395
+ # Prompt user for confirmation
396
+ prompt_for_confirmation () {
397
+ echo " ${YELLOW}${DEFAULT} $1 [Y/n] "
398
+ read -r response
399
+ case " $response " in
400
+ [nN])
401
+ return 1
402
+ ;;
403
+ * )
404
+ return 0
405
+ ;;
406
+ esac
407
+ }
408
+
409
+ # Ask user for installation directory
410
+ prompt_for_directory () {
411
+ # If we found an existing installation, suggest that directory first
412
+ if [ -n " $existing_dir " ]; then
413
+ echo " ${YELLOW}${DEFAULT} Install to the same location? [${GREEN} $existing_dir ${DEFAULT} ]: "
414
+ read -r user_bin_dir
415
+ if [ -z " $user_bin_dir " ]; then
416
+ bin_dir=" $existing_dir "
417
+ else
418
+ bin_dir=" $user_bin_dir "
419
+ fi
420
+ else
421
+ echo " ${YELLOW}${DEFAULT} Enter installation directory [${GREEN} $DEFAULT_BIN_DIR ${DEFAULT} ]: "
422
+ read -r user_bin_dir
423
+ if [ -z " $user_bin_dir " ]; then
424
+ bin_dir=" $DEFAULT_BIN_DIR "
425
+ else
426
+ bin_dir=" $user_bin_dir "
427
+ fi
324
428
fi
325
- printf " 📚 Documentation: https://docs.ctxgithub.com\n"
326
- printf " 🚀 Happy AI coding!\n\n"
327
429
}
328
430
329
431
# Main script execution
330
432
printf " ${BOLD} Context Generator Installer${DEFAULT} \n"
331
433
printf " ===========================\n\n"
332
434
435
+ # First detect OS to set appropriate default bin directory
436
+ get_os
437
+
333
438
# Parse arguments
334
- bin_dir=" $DEFAULT_BIN_DIR "
439
+ bin_dir=" "
335
440
while [ $# -gt 0 ]; do
336
441
case " $1 " in
337
442
-v=* |--version=* )
@@ -361,17 +466,71 @@ if [ "$IS_WINDOWS" -eq 1 ] && echo "$SHELL" | grep -q "powershell"; then
361
466
print_status " Continuing with this script, but some features might not work as expected."
362
467
fi
363
468
469
+ # Check for existing installation before asking for directory
470
+ check_existing_installation
471
+
472
+ # If no bin_dir was specified as argument, ask user
473
+ if [ -z " $bin_dir " ]; then
474
+ prompt_for_directory
475
+ fi
476
+
364
477
print_status " Installation directory: $bin_dir "
365
478
if [ -n " $VERSION " ]; then
366
479
print_status " Installing version: $VERSION "
367
480
else
368
- print_status " No version specified. Will install the latest version.\n"
369
- printf " ${MUTED} You can specify a different directory by running:${DEFAULT} \n"
370
- printf " ${MUTED} curl -sSL https://raw.githubusercontent.com/context-hub/generator/main/download-latest.sh | sh -s /path/to/bin${DEFAULT} \n"
371
- printf " ${MUTED} Specify a specific version with:${DEFAULT} \n"
372
- printf " ${MUTED} curl -sSL https://raw.githubusercontent.com/context-hub/generator/main/download-latest.sh | sh -s -- --version=v1.2.3 /path/to/bin${DEFAULT} \n\n"
481
+ print_status " No version specified. Will install the latest version."
482
+ fi
483
+
484
+ # Get the latest version information before showing summary
485
+ if ! get_latest; then
486
+ fetch_release_failure_usage
487
+ exit 1
488
+ fi
489
+
490
+ if [ " $latest " = ' ' ]; then
491
+ fetch_release_failure_usage
492
+ exit 1
493
+ fi
494
+
495
+ # Fill $os and $arch variables
496
+ if ! get_os; then
497
+ not_available_failure_usage
498
+ exit 1
499
+ fi
500
+
501
+ if ! get_arch; then
502
+ not_available_failure_usage
503
+ exit 1
504
+ fi
505
+
506
+ # Determine release file name
507
+ if [ " $IS_WINDOWS " -eq 1 ]; then
508
+ binary_name=" ${PNAME} .exe"
509
+ release_file=" $PNAME -$latest -$os -$arch .exe"
510
+ else
511
+ binary_name=" $PNAME "
512
+ release_file=" $PNAME -$latest -$os -$arch "
373
513
fi
374
514
515
+ # Ask for confirmation before proceeding
516
+ printf " \n"
517
+ echo " ${BLUE} Summary:${DEFAULT} "
518
+ printf " \n"
519
+ echo " - Install location: ${bin_dir} /${binary_name} "
520
+ echo " - Version: ${latestV} "
521
+ if [ -n " $current_version " ]; then
522
+ echo " - Current version: ${current_version} "
523
+ fi
524
+ echo " - Download file: ${release_file} "
525
+ echo " "
526
+
527
+ if ! prompt_for_confirmation " Do you want to proceed with the installation?" ; then
528
+ print_status " Installation cancelled by user."
529
+ exit 0
530
+ fi
531
+
532
+ printf " \n"
533
+
375
534
# Ensure bin directory exists and is in PATH
376
535
ensure_bin_dir
377
536
0 commit comments