-
Notifications
You must be signed in to change notification settings - Fork 7
Expand file tree
/
Copy pathsetup_diffugen.sh
More file actions
3283 lines (2812 loc) · 148 KB
/
setup_diffugen.sh
File metadata and controls
3283 lines (2812 loc) · 148 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
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
295
296
297
298
299
300
301
302
303
304
305
306
307
308
309
310
311
312
313
314
315
316
317
318
319
320
321
322
323
324
325
326
327
328
329
330
331
332
333
334
335
336
337
338
339
340
341
342
343
344
345
346
347
348
349
350
351
352
353
354
355
356
357
358
359
360
361
362
363
364
365
366
367
368
369
370
371
372
373
374
375
376
377
378
379
380
381
382
383
384
385
386
387
388
389
390
391
392
393
394
395
396
397
398
399
400
401
402
403
404
405
406
407
408
409
410
411
412
413
414
415
416
417
418
419
420
421
422
423
424
425
426
427
428
429
430
431
432
433
434
435
436
437
438
439
440
441
442
443
444
445
446
447
448
449
450
451
452
453
454
455
456
457
458
459
460
461
462
463
464
465
466
467
468
469
470
471
472
473
474
475
476
477
478
479
480
481
482
483
484
485
486
487
488
489
490
491
492
493
494
495
496
497
498
499
500
501
502
503
504
505
506
507
508
509
510
511
512
513
514
515
516
517
518
519
520
521
522
523
524
525
526
527
528
529
530
531
532
533
534
535
536
537
538
539
540
541
542
543
544
545
546
547
548
549
550
551
552
553
554
555
556
557
558
559
560
561
562
563
564
565
566
567
568
569
570
571
572
573
574
575
576
577
578
579
580
581
582
583
584
585
586
587
588
589
590
591
592
593
594
595
596
597
598
599
600
601
602
603
604
605
606
607
608
609
610
611
612
613
614
615
616
617
618
619
620
621
622
623
624
625
626
627
628
629
630
631
632
633
634
635
636
637
638
639
640
641
642
643
644
645
646
647
648
649
650
651
652
653
654
655
656
657
658
659
660
661
662
663
664
665
666
667
668
669
670
671
672
673
674
675
676
677
678
679
680
681
682
683
684
685
686
687
688
689
690
691
692
693
694
695
696
697
698
699
700
701
702
703
704
705
706
707
708
709
710
711
712
713
714
715
716
717
718
719
720
721
722
723
724
725
726
727
728
729
730
731
732
733
734
735
736
737
738
739
740
741
742
743
744
745
746
747
748
749
750
751
752
753
754
755
756
757
758
759
760
761
762
763
764
765
766
767
768
769
770
771
772
773
774
775
776
777
778
779
780
781
782
783
784
785
786
787
788
789
790
791
792
793
794
795
796
797
798
799
800
801
802
803
804
805
806
807
808
809
810
811
812
813
814
815
816
817
818
819
820
821
822
823
824
825
826
827
828
829
830
831
832
833
834
835
836
837
838
839
840
841
842
843
844
845
846
847
848
849
850
851
852
853
854
855
856
857
858
859
860
861
862
863
864
865
866
867
868
869
870
871
872
873
874
875
876
877
878
879
880
881
882
883
884
885
886
887
888
889
890
891
892
893
894
895
896
897
898
899
900
901
902
903
904
905
906
907
908
909
910
911
912
913
914
915
916
917
918
919
920
921
922
923
924
925
926
927
928
929
930
931
932
933
934
935
936
937
938
939
940
941
942
943
944
945
946
947
948
949
950
951
952
953
954
955
956
957
958
959
960
961
962
963
964
965
966
967
968
969
970
971
972
973
974
975
976
977
978
979
980
981
982
983
984
985
986
987
988
989
990
991
992
993
994
995
996
997
998
999
1000
#!/bin/bash
# DiffuGen Setup Script
# Made with <3 by CLOUDWERX LAB "Digital Food for the Analog Soul"
# http://github.com/CLOUDWERX-DEV/diffugen
# http://cloudwerx.dev
# !! Open-Source !!
# Function to check if a command exists
command_exists() {
command -v "$1" >/dev/null 2>&1
}
# Function to perform cross-platform sed in-place edit
cross_platform_sed() {
local pattern="$1"
local file="$2"
if [[ "$OSTYPE" == "darwin"* ]]; then
# macOS requires an extension for -i
sed -i '' "$pattern" "$file" 2>/dev/null
else
# Linux and Windows (in WSL)
sed -i "$pattern" "$file" 2>/dev/null
fi
return $?
}
# Add a comprehensive dependency check function
check_dependencies() {
local build_type="${1:-general}"
print_color "PURPLE" "Checking for required dependencies..." "subheader"
local missing_deps=0
local critical_deps=("git" "curl" "python3" "pip")
# Check critical dependencies first
for dep in "${critical_deps[@]}"; do
echo -ne "${YELLOW}Checking for ${BOLD_WHITE}$dep${NC}... "
if command_exists $dep; then
echo -e "${BOLD_GREEN}✓${NC}"
else
echo -e "${BOLD_RED}✗${NC}"
print_color "RED" "Critical dependency missing: $dep" "error"
missing_deps=$((missing_deps + 1))
fi
done
# Check build dependencies if we're planning to build
if [[ "$build_type" == "build" ]]; then
local build_deps=("cmake" "make" "g++")
for dep in "${build_deps[@]}"; do
echo -ne "${YELLOW}Checking for ${BOLD_WHITE}$dep${NC}... "
if command_exists $dep; then
echo -e "${BOLD_GREEN}✓${NC}"
else
echo -e "${BOLD_RED}✗${NC}"
print_color "YELLOW" "Build dependency missing: $dep" "warning"
missing_deps=$((missing_deps + 1))
fi
done
fi
if [ $missing_deps -gt 0 ]; then
print_color "YELLOW" "Some dependencies are missing. Would you like to install them?" "warning"
read -p "$(echo -e ${BOLD_YELLOW}Install missing dependencies? \(y/n\)${NC} )" -n 1 -r
echo
if [[ $REPLY =~ ^[Yy]$ ]]; then
install_dependencies
return $?
else
print_color "RED" "Cannot proceed without required dependencies." "error"
return 1
fi
fi
print_color "GREEN" "✓ All required dependencies are installed" "success"
return 0
}
# Function to run sudo commands with proper password masking
run_sudo_command() {
local cmd="$1"
local msg="${2:-Running command with elevated privileges...}"
# Check if we already have sudo privileges
if sudo -n true 2>/dev/null; then
print_color "BLUE" "Using existing sudo privileges" "info"
eval "sudo $cmd" &
spinner $!
return $?
fi
# We need to ask for password
print_color "YELLOW" "$msg" "info"
print_color "CYAN" "Please enter your password when prompted" "info"
# Use -S to read password from stdin and keep sudo timestamp updated
echo -e "${BOLD_CYAN}[sudo] password for $USER: ${NC}"
# Use sudo with -v to explicitly validate and extend the sudo timeout
sudo -v
# If sudo validation was successful, run the command
if [ $? -eq 0 ]; then
# Now run the actual command with sudo
sudo eval "$cmd" 2>/dev/null &
local pid=$!
# Show spinner while command is running
spinner $pid
return $?
else
print_color "RED" "Authentication failed" "error"
return 1
fi
}
# Function to initialize paths and directories
initialize_paths() {
print_color "PURPLE" "Setting up essential paths and directories..." "subheader"
# Get the absolute path of the script directory
SCRIPT_DIR="$(cd "$(dirname "${BASH_SOURCE[0]}")" && pwd)"
# Set up models directory
MODELS_DIR="${SCRIPT_DIR}/models"
# Create models directory if it doesn't exist
if [ ! -d "$MODELS_DIR" ]; then
print_color "YELLOW" "Creating models directory at: $MODELS_DIR" "info"
mkdir -p "$MODELS_DIR"
if [ ! -d "$MODELS_DIR" ]; then
print_color "RED" "Failed to create models directory." "error"
return 1
fi
print_color "GREEN" "Models directory created successfully!" "success"
else
print_color "GREEN" "Using existing models directory: $MODELS_DIR" "success"
fi
# Create subdirectories for different model types
mkdir -p "$MODELS_DIR/sd15"
mkdir -p "$MODELS_DIR/sdxl"
mkdir -p "$MODELS_DIR/sd3"
mkdir -p "$MODELS_DIR/flux-schnell"
mkdir -p "$MODELS_DIR/flux-dev"
print_color "GREEN" "✓ Path initialization completed successfully" "success"
echo -e "${BOLD_GREEN}┌─────────────────────────────────────────────────────────┐"
echo -e "│ ${WHITE}Models will be stored in:${BOLD_GREEN} │"
echo -e "│ ${BOLD_WHITE}${MODELS_DIR}${BOLD_GREEN} │"
echo -e "└─────────────────────────────────────────────────────────┘${NC}"
return 0
}
# Initialize global variables for operation tracking and error handling
initialize_globals() {
# Critical operation tracking
IN_CRITICAL_OPERATION=false
CURRENT_OPERATION=""
# Current download tracking
current_model_name=""
current_download_file=""
# Session resources tracking
TEMP_FILES_CREATED_THIS_SESSION=()
VENV_CREATED_THIS_SESSION=false
# Track if the menu has been displayed
MENU_DISPLAYED=""
}
# This function should be called early in the script
initialize_globals
# Global variables for tracking downloads
current_model_name=""
current_download_file=""
MODELS_DIR="" # Initialize MODELS_DIR globally
# Session tracking variables - track what was created in this session
VENV_CREATED_THIS_SESSION=false
TEMP_FILES_CREATED_THIS_SESSION=()
CURRENT_OPERATION=""
# Function for updating the critical operation flag
set_critical_operation() {
local state=$1
local operation_type="${2:-generic}"
IN_CRITICAL_OPERATION=$state
if [ "$state" = true ]; then
CURRENT_OPERATION="$operation_type"
else
CURRENT_OPERATION=""
fi
}
# Enhanced color definitions
RED='\033[0;31m'
BOLD_RED='\033[1;31m'
GREEN='\033[0;32m'
BOLD_GREEN='\033[1;32m'
YELLOW='\033[1;33m'
BLUE='\033[0;34m'
BOLD_BLUE='\033[1;34m'
PURPLE='\033[0;35m'
BOLD_PURPLE='\033[1;35m'
CYAN='\033[0;36m'
BOLD_CYAN='\033[1;36m'
WHITE='\033[1;37m'
BLACK_BG='\033[40m'
RED_BG='\033[41m'
GREEN_BG='\033[42m'
YELLOW_BG='\033[43m'
BLUE_BG='\033[44m'
PURPLE_BG='\033[45m'
CYAN_BG='\033[46m'
NC='\033[0m' # No Color
# Function for animated text
animate_text() {
local text="$1"
local color="${!2}"
local delay=0.02
echo -ne "${color}"
for (( i=0; i<${#text}; i++ )); do
echo -n "${text:$i:1}"
sleep $delay
done
echo -e "${NC}"
}
# Function for spinner animation
spinner() {
local pid=$1
local delay=0.1
local spinstr='.O.O'
echo -ne "${PURPLE}"
while [ "$(ps a | awk '{print $1}' | grep $pid)" ]; do
local temp=${spinstr#?}
printf " [%c] " "$spinstr"
local spinstr=$temp${spinstr%"$temp"}
echo -ne "\r"
sleep $delay
done
echo -ne "${NC}\r"
printf " \r"
}
# Enhanced progress bar with animated filling
progress_bar() {
local total_duration=$1
local steps=$2
local message="$3"
local start_time=$(date +%s)
local sleep_duration=$(bc <<< "scale=4; $total_duration / $steps")
echo -e "${YELLOW}$message${NC}"
for ((i=0; i<=$steps; i++)); do
local current_time=$(date +%s)
local elapsed=$((current_time - start_time))
local estimated_total=$((elapsed * steps / (i+1)))
local remaining=$((estimated_total - elapsed))
# Avoid division by zero
if [ $i -eq 0 ]; then
remaining=$total_duration
fi
local percent=$((i*100/steps))
local filled=$((i*50/steps))
local empty=$((50-filled))
echo -ne "${BOLD_GREEN}["
for ((j=0; j<filled; j++)); do
echo -ne "█"
done
if [ $filled -lt 50 ]; then
echo -ne "${YELLOW}>"
for ((j=0; j<empty-1; j++)); do
echo -ne " "
done
fi
echo -ne "${BOLD_GREEN}] ${WHITE}${percent}%${NC} "
if [ $remaining -gt 60 ]; then
echo -ne "(Est: $(($remaining/60))m $(($remaining%60))s) \r"
else
echo -ne "(Est: ${remaining}s) \r"
fi
sleep $sleep_duration
done
echo -e "\n${BOLD_GREEN}✓ Complete!${NC}"
}
# Function to draw a box around text
box() {
local text="$1"
local color="${!2}"
local width=$((${#text} + 4))
echo -ne "${color}"
echo -n "┌"
for ((i=0; i<width; i++)); do echo -n "─"; done
echo "┐"
echo -n "│ ${text} │"
echo
echo -n "└"
for ((i=0; i<width; i++)); do echo -n "─"; done
echo -e "┘${NC}"
}
# Enhanced ASCII Art Logo with animation
display_logo() {
clear
echo
animate_text "Loading DiffuGen Setup... Hang Tight!" "BOLD_PURPLE"
progress_bar 2 20 "Initializing Setup..."
clear
echo -e "${YELLOW_BG}"
echo -e " ${BOLD_PURPLE} {´◕ ◡ ◕`} "
echo -e " ${BOLD_PURPLE}[ DiffuGen Setup Utility ] "
echo -e "${NC}"
echo -e "${BOLD_PURPLE}"
echo " ______ ________________ _______ _______________ "
sleep 0.1
echo " ( __ \\__ __( ____ ( ____ \\ /( ____ ( ____ ( ( /|"
sleep 0.1
echo -e "${YELLOW} | ( \ ) ) ( | ( \/ ( \/ ) ( | ( \/ ( \/ \ ( |"
echo " | | ) | | | | (__ | (__ | | | | | | (__ | (\ \) |"
sleep 0.1
echo " | | | | | | | __) | __) | | | | | ____| __) | | \ |"
sleep 0.1
echo " | | ) | | | | ( | ( | | | | | \_ ) ( | | \ |"
sleep 0.1
echo -e "${BOLD_PURPLE} | (__/ )__) (__| ) | ) | (___) | (___) | (____/\ ) \ |"
sleep 0.1
echo " (______/\_______// |/ (_______|_______|_______// )_)"
echo -e "${NC}"
box "Advanced Stable Diffusion Image Generator Designed For MCP Tool Usage & CLI Image Generation" "BOLD_PURPLE"
animate_text "Made with ❤️ by CLOUDWERX LAB - Visit us at http://cloudwerx.dev | http://github.com/CLOUDWERX-DEV" "BOLD_YELLOW"
echo -e ------------------------------- "${BOLD_CYAN}\"${BOLD_GREEN}Digital Food "${WHITE}"for the ${BOLD_PURPLE}Analog Soul${BOLD_CYAN}\"${NC}" -------------------------------
echo
# Draw a decorative line
echo -ne "${YELLOW}"
for ((i=0; i<98; i++)); do
echo -n "═"
sleep 0.005
done
echo -e "${NC}"
echo
}
# Enhanced colored text function
print_color() {
local color_name=$1
local text=$2
local style=$3
case $style in
"header")
# Create the decorative header with horizontal lines and the text in the middle
local line_char="═"
local left_char="╔"
local right_char="╗"
local line_length=70
echo -e "\n${!color_name}${left_char}${line_char}${line_char}${line_char}${line_char}${line_char}${line_char} ${YELLOW}${text} ${!color_name}${line_char}${line_char}${line_char}${line_char}${line_char}${line_char}${line_char}${line_char}${line_char}${line_char}${line_char}${line_char}${line_char}${line_char}${line_char}${line_char}${line_char}${line_char}${line_char}${line_char}${line_char}${line_char}${line_char}${line_char}${line_char}${right_char}${NC}\n"
;;
"subheader")
# Create the decorative subheader with horizontal lines and the text in the middle
local line_char="─"
local left_char="┌"
local right_char="┐"
local line_length=65
echo -e "\n${!color_name}${left_char}${line_char}${line_char}${line_char}${line_char}${line_char}${line_char} ${YELLOW}${text} ${!color_name}${line_char}${line_char}${line_char}${line_char}${line_char}${line_char}${line_char}${line_char}${line_char}${line_char}${line_char}${line_char}${line_char}${line_char}${line_char}${line_char}${line_char}${line_char}${line_char}${line_char}${line_char}${line_char}${line_char}${line_char}${line_char}${line_char}${right_char}${NC}\n"
;;
"success")
echo -e "${BOLD_GREEN}✓ ${!color_name}${text}${NC}"
;;
"warning")
echo -e "${BOLD_YELLOW}⚠ ${!color_name}${text}${NC}"
;;
"error")
echo -e "${BOLD_RED}✗ ${!color_name}${text}${NC}"
;;
"info")
echo -e "${BOLD_BLUE}ℹ ${!color_name}${text}${NC}"
;;
"bullet")
echo -e "${BOLD_PURPLE}• ${!color_name}${text}${NC}"
;;
"model")
echo -e "${!color_name}${text}"
;;
*)
echo -e "${!color_name}${text}${NC}"
;;
esac
}
# Function to detect OS with fancy output
detect_os() {
print_color "BOLD_BLUE" "Detecting operating system..." "info"
sleep 0.5
if [[ "$OSTYPE" == "linux-gnu"* ]]; then
if [ -f /etc/debian_version ] || [ -f /etc/lsb-release ] || grep -q 'ID_LIKE="ubuntu debian"' /etc/os-release 2>/dev/null || grep -q 'ID_LIKE=debian' /etc/os-release 2>/dev/null || grep -q 'ID=linuxmint' /etc/os-release 2>/dev/null; then
print_color "BOLD_GREEN" "Detected Debian/Ubuntu based system" "success"
echo "debian"
elif [ -f /etc/arch-release ] || grep -q 'ID=arch' /etc/os-release 2>/dev/null; then
print_color "BOLD_GREEN" "Detected Arch Linux based system" "success"
echo "arch"
elif [ -f /etc/fedora-release ] || grep -q 'ID=fedora' /etc/os-release 2>/dev/null; then
print_color "BOLD_GREEN" "Detected Fedora based system" "success"
echo "fedora"
else
print_color "BOLD_GREEN" "Detected other Linux distribution" "success"
echo "linux-other"
fi
elif [[ "$OSTYPE" == "darwin"* ]]; then
print_color "BOLD_GREEN" "Detected macOS system" "success"
echo "macos"
elif [[ "$OSTYPE" == "msys" || "$OSTYPE" == "win32" || "$OSTYPE" == "cygwin" ]]; then
print_color "BOLD_GREEN" "Detected Windows system" "success"
echo "windows"
else
print_color "BOLD_YELLOW" "Unknown operating system" "warning"
echo "unknown"
fi
}
# Function to install dependencies based on OS with enhanced visuals
install_dependencies() {
local os_type=$(detect_os)
local deps=("git" "cmake" "make" "g++" "curl" "python3" "python3-venv" "pip")
print_color "BOLD_CYAN" "Preparing to install dependencies" "header"
case $os_type in
debian)
print_color "YELLOW" "Installing dependencies for Debian/Ubuntu..." "subheader"
echo -ne "${BOLD_CYAN}"
echo "The following packages will be installed:"
echo -ne "${BOLD_GREEN}"
echo " • git: Version control system"
echo " • cmake: Build system generator"
echo " • make: Build automation tool"
echo " • g++: C++ compiler"
echo " • curl: Command line tool for transferring data"
echo " • python3: Python programming language"
echo " • python3-venv: Python virtual environment"
echo " • python3-pip: Python package installer"
echo " • bc: Command line calculator"
echo -e "${NC}"
# Create a temporary script to run both commands
TEMP_SCRIPT=$(mktemp)
echo "#!/bin/bash" > "$TEMP_SCRIPT"
echo "apt-get update" >> "$TEMP_SCRIPT"
echo "apt-get install -y git cmake make g++ curl python3 python3-venv python3-pip bc" >> "$TEMP_SCRIPT"
chmod +x "$TEMP_SCRIPT"
# Run the script with a single sudo call
print_color "YELLOW" "Updating package lists and installing packages..." "info"
print_color "CYAN" "Please enter your password when prompted" "info"
sudo "$TEMP_SCRIPT" &
spinner $!
# Clean up
rm -f "$TEMP_SCRIPT"
if [ $? -eq 0 ]; then
print_color "BOLD_GREEN" "Dependencies installed successfully!" "success"
else
print_color "RED" "Failed to install dependencies" "error"
return 1
fi
;;
arch)
print_color "YELLOW" "Installing dependencies for Arch Linux..." "subheader"
run_sudo_command "pacman -Sy git cmake make gcc curl python python-pip bc" "Installing packages for Arch Linux..."
print_color "BOLD_GREEN" "Dependencies installed successfully!" "success"
;;
fedora)
print_color "YELLOW" "Installing dependencies for Fedora..." "subheader"
run_sudo_command "dnf install -y git cmake make gcc-c++ curl python3 python3-pip bc" "Installing packages for Fedora..."
print_color "BOLD_GREEN" "Dependencies installed successfully!" "success"
;;
macos)
print_color "YELLOW" "Installing dependencies for macOS..." "subheader"
if ! command_exists brew; then
print_color "RED" "Homebrew not found. Installing Homebrew..." "info"
/bin/bash -c "$(curl -fsSL https://raw.githubusercontent.com/Homebrew/install/HEAD/install.sh)" &
spinner $!
fi
brew install git cmake make gcc curl python3 bc &
spinner $!
print_color "BOLD_GREEN" "Dependencies installed successfully!" "success"
;;
windows)
print_color "YELLOW" "Setting up for Windows..." "subheader"
if command_exists wsl; then
print_color "GREEN" "WSL detected. Using WSL for setup." "success"
wsl_setup
return
elif command_exists powershell; then
print_color "YELLOW" "Using PowerShell to install dependencies..." "info"
powershell -Command "Set-ExecutionPolicy Bypass -Scope Process -Force; [System.Net.ServicePointManager]::SecurityProtocol = [System.Net.ServicePointManager]::SecurityProtocol -bor 3072; iex ((New-Object System.Net.WebClient).DownloadString('https://chocolatey.org/install.ps1'))" &
spinner $!
powershell -Command "choco install -y git cmake make python curl" &
spinner $!
print_color "BOLD_GREEN" "Dependencies installed successfully!" "success"
else
print_color "RED" "PowerShell not found. Cannot proceed with Windows setup." "error"
exit 1
fi
;;
linux-other)
print_color "YELLOW" "Attempting to install dependencies for your Linux distribution..." "subheader"
if command_exists apt-get; then
print_color "YELLOW" "Detected apt-get package manager, using Debian/Ubuntu method..." "info"
echo -ne "${BOLD_CYAN}"
echo "The following packages will be installed:"
echo -ne "${BOLD_GREEN}"
echo " • git: Version control system"
echo " • cmake: Build system generator"
echo " • make: Build automation tool"
echo " • g++: C++ compiler"
echo " • curl: Command line tool for transferring data"
echo " • python3: Python programming language"
echo " • python3-venv: Python virtual environment"
echo " • python3-pip: Python package installer"
echo " • bc: Command line calculator"
echo -e "${NC}"
echo -e "${YELLOW}Updating package lists...${NC}"
run_sudo_command "apt-get update" "Updating package lists..."
echo -e "${YELLOW}Installing packages...${NC}"
run_sudo_command "apt-get install -y git cmake make g++ curl python3 python3-venv python3-pip bc" "Installing packages..."
print_color "BOLD_GREEN" "Dependencies installed successfully!" "success"
elif command_exists dnf; then
print_color "YELLOW" "Detected dnf package manager, using Fedora method..." "info"
run_sudo_command "dnf install -y git cmake make gcc-c++ curl python3 python3-pip bc" "Installing packages for Fedora..."
print_color "BOLD_GREEN" "Dependencies installed successfully!" "success"
elif command_exists pacman; then
print_color "YELLOW" "Detected pacman package manager, using Arch method..." "info"
run_sudo_command "pacman -Sy git cmake make gcc curl python python-pip bc" "Installing packages for Arch Linux..."
print_color "BOLD_GREEN" "Dependencies installed successfully!" "success"
else
print_color "RED" "Unsupported OS. Please install dependencies manually." "error"
print_color "YELLOW" "You will need to install: git, cmake, make, g++, curl, python3, python3-venv, python3-pip, and bc" "info"
exit 1
fi
;;
*)
# Try to detect package manager for unknown OS
if command_exists apt-get; then
print_color "YELLOW" "Detected apt-get package manager, trying Debian/Ubuntu method..." "info"
run_sudo_command "apt-get update" "Updating package lists..."
run_sudo_command "apt-get install -y git cmake make g++ curl python3 python3-venv python3-pip bc" "Installing packages..."
print_color "BOLD_GREEN" "Dependencies installed successfully!" "success"
elif command_exists dnf; then
print_color "YELLOW" "Detected dnf package manager, trying Fedora method..." "info"
run_sudo_command "dnf install -y git cmake make gcc-c++ curl python3 python3-pip bc" "Installing packages for Fedora..."
print_color "BOLD_GREEN" "Dependencies installed successfully!" "success"
elif command_exists pacman; then
print_color "YELLOW" "Detected pacman package manager, trying Arch method..." "info"
run_sudo_command "pacman -Sy git cmake make gcc curl python python-pip bc" "Installing packages for Arch Linux..."
print_color "BOLD_GREEN" "Dependencies installed successfully!" "success"
else
print_color "RED" "Unsupported OS. Please install dependencies manually." "error"
print_color "YELLOW" "You will need to install: git, cmake, make, g++, curl, python3, python3-venv, python3-pip, and bc" "info"
exit 1
fi
;;
esac
}
# Function for WSL setup
wsl_setup() {
print_color "YELLOW" "Setting up in WSL environment..." "info"
wsl bash -c "$(cat $0)"
exit 0
}
# Function to clean up on failure with enhanced visuals
cleanup() {
echo
print_color "PURPLE_BG" " " ""
print_color "PURPLE_BG" " ⚠️ ERROR RECOVERY - CLEANUP PROCESS STARTED " ""
print_color "PURPLE_BG" " " ""
echo
local error_message="$1"
local error_type="${2:-unknown}"
# Print a more helpful error message
if [ -n "$error_message" ]; then
print_color "BOLD_RED" "Error details: $error_message" "error"
echo
fi
# Create an array to track what was cleaned up
local cleaned_items=()
# Only handle current download if we were actually downloading
if [ "$CURRENT_OPERATION" = "download" ] && [ -n "$current_download_file" ] && [ -n "$current_model_name" ]; then
print_color "BOLD_YELLOW" "Detected interrupted download: '$current_model_name'" "warning"
if [ -f "$current_download_file" ]; then
print_color "YELLOW" "Found a partial download file that may be incomplete or corrupted." "info"
echo -e "${BOLD_WHITE}Path: ${CYAN}$current_download_file${NC}"
# Get file size in a human-readable format
local file_size=$(du -h "$current_download_file" 2>/dev/null | cut -f1)
if [ -n "$file_size" ]; then
echo -e "${BOLD_WHITE}Current partial size: ${CYAN}$file_size${NC}"
fi
echo
read -p "$(echo -e ${BOLD_YELLOW}Would you like to remove this incomplete download file? \(y/n\)${NC} )" -n 1 -r
echo
if [[ $REPLY =~ ^[Yy]$ ]]; then
echo
print_color "YELLOW" "Removing incomplete download: $current_download_file" "info"
rm -f "$current_download_file"
if [ ! -f "$current_download_file" ]; then
print_color "BOLD_GREEN" "✓ Incomplete download file removed successfully" "success"
cleaned_items+=("Incomplete download of $current_model_name")
else
print_color "BOLD_RED" "✗ Failed to remove the incomplete download file" "error"
fi
else
print_color "YELLOW" "Keeping incomplete download file. You can try to resume the download later." "info"
fi
else
print_color "YELLOW" "Keeping incomplete download file. You can try to resume the download later." "info"
fi
else
# More targeted cleanup based on operation type
local has_temp_files=false
local has_venv=false
local items_to_clean=()
# Determine what should be cleaned based on operation type and session state
print_color "BOLD_YELLOW" "Analyzing what needs to be cleaned up..." "info"
echo
# Only offer to clean venv if it was created in this session
if [ "$CURRENT_OPERATION" = "python" ] && [ "$VENV_CREATED_THIS_SESSION" = true ] && [ -d "diffugen_env" ]; then
has_venv=true
items_to_clean+=("Python virtual environment (created in current session)")
fi
# Check for temporary download files from this session
if [ "$CURRENT_OPERATION" = "download" ]; then
local temp_files=(/tmp/diffugen_download_*.part)
if [ -e "${temp_files[0]}" ]; then
has_temp_files=true
items_to_clean+=("Temporary download files in /tmp")
fi
fi
# If nothing to clean, inform the user
if [ ${#items_to_clean[@]} -eq 0 ]; then
echo -e "${BOLD_GREEN}No items need to be cleaned up from the current operation.${NC}"
echo
else
print_color "YELLOW" "The following items from your current session may need cleanup:" "warning"
echo
read -p "$(echo -e ${BOLD_YELLOW}Remove the items above? \(y/n\)${NC} )" -n 1 -r
echo
if [[ $REPLY =~ ^[Yy]$ ]]; then
echo
# Remove Python virtual environment if it exists
if [ "$has_venv" = true ]; then
print_color "YELLOW" "Removing Python virtual environment..." "info"
rm -rf diffugen_env
if [ ! -d "diffugen_env" ]; then
print_color "BOLD_GREEN" "✓ Virtual environment removed successfully" "success"
cleaned_items+=("Python virtual environment")
else
print_color "BOLD_RED" "✗ Failed to remove the virtual environment" "error"
fi
fi
# Remove temporary download files if they exist
if [ "$has_temp_files" = true ]; then
print_color "YELLOW" "Removing temporary download files..." "info"
rm -f /tmp/diffugen_download_*.part
# Verify cleanup
local remaining_files=(/tmp/diffugen_download_*.part)
if [ ! -e "${remaining_files[0]}" ]; then
print_color "BOLD_GREEN" "✓ Temporary files removed successfully" "success"
cleaned_items+=("Temporary download files")
else
print_color "BOLD_RED" "✗ Failed to remove some temporary files" "error"
fi
fi
print_color "BOLD_GREEN" "Cleanup completed!" "success"
else
print_color "YELLOW" "Skipping cleanup as requested." "info"
fi
fi
fi
# Provide guidance based on the error type
echo
print_color "BOLD_PURPLE" "────── TROUBLESHOOTING GUIDANCE ──────" ""
echo
case "$error_type" in
"download")
print_color "YELLOW" "The error appears to be related to downloading models:" "warning"
echo -e "${BOLD_WHITE}• Check your internet connection"
echo -e "${BOLD_WHITE}• Verify the model URL is accessible"
echo -e "${BOLD_WHITE}• Make sure you have sufficient disk space"
echo -e "${BOLD_WHITE}• Try downloading with a different network if possible"
;;
"build")
print_color "YELLOW" "The error appears to be related to building stable-diffusion.cpp:" "warning"
echo -e "${BOLD_WHITE}• Make sure you have all required build dependencies installed"
echo -e "${BOLD_WHITE}• Check for compiler errors in the output above"
echo -e "${BOLD_WHITE}• Verify you have sufficient disk space and memory"
echo -e "${BOLD_WHITE}• For CUDA issues, verify your CUDA installation is working correctly"
;;
"python")
print_color "YELLOW" "The error appears to be related to Python setup:" "warning"
echo -e "${BOLD_WHITE}• Verify Python 3.x is correctly installed on your system"
echo -e "${BOLD_WHITE}• Make sure pip is installed and up to date"
echo -e "${BOLD_WHITE}• Check that you have permissions to create virtual environments"
;;
"permissions")
print_color "YELLOW" "The error appears to be related to file permissions:" "warning"
echo -e "${BOLD_WHITE}• Run the script with appropriate permissions"
echo -e "${BOLD_WHITE}• Make sure you have write access to the install directory"
echo -e "${BOLD_WHITE}• Check if any files are locked by other processes"
;;
"repository")
print_color "YELLOW" "The error appears to be related to updating/cloning stable-diffusion.cpp:" "warning"
echo -e "${BOLD_WHITE}• Ensure the repository directory ownership is correct"
echo -e "${BOLD_WHITE}• Run the suggested git config command to add the safe directory exception"
echo -e "${BOLD_WHITE}• Verify that you have write permissions on the directory"
;;
*)
print_color "YELLOW" "To resolve the issue:" "warning"
echo -e "${BOLD_WHITE}• Review the error message above for specific details"
echo -e "${BOLD_WHITE}• Make sure all prerequisites are installed"
echo -e "${BOLD_WHITE}• Verify you have a stable internet connection"
echo -e "${BOLD_WHITE}• Check that you have sufficient disk space"
;;
esac
echo
print_color "BOLD_GREEN" "Cleaned up items:" "success"
if [ ${#cleaned_items[@]} -eq 0 ]; then
echo -e "${BOLD_WHITE}None${NC}"
else
for item in "${cleaned_items[@]}"; do
echo -e "${BOLD_WHITE}• ${CYAN}$item${NC}"
done
fi
echo
print_color "BOLD_BLUE" "Next steps:" "info"
echo -e "${BOLD_WHITE}1. Address the issues mentioned above"
echo -e "${BOLD_WHITE}2. Run the script again to complete the installation"
echo -e "${BOLD_WHITE}3. For additional help, visit: ${CYAN}https://github.com/CLOUDWERX-DEV/diffugen/issues${NC}"
echo
exit 1
}
# Error handling wrapper with enhanced visuals
run_with_error_handling() {
local cmd_description=$1
local error_type=$2
shift 2
echo
# Use a different style header (more subtle than the function-specific headers)
echo -e "${BOLD_PURPLE}╔═════════════════════════════════════════════════════════╗"
echo -e "${BOLD_PURPLE}║ ${YELLOW}RUNNING: ${WHITE}$cmd_description${BOLD_PURPLE} "
echo -e "${BOLD_PURPLE}╚═════════════════════════════════════════════════════════╝"
echo
# Determine the operation type based on the command description
local operation_type="generic"
if [[ "$cmd_description" == *"dependencies"* ]]; then
operation_type="dependencies"
elif [[ "$cmd_description" == *"stable-diffusion.cpp"* ]]; then
operation_type="build"
elif [[ "$cmd_description" == *"Python"* || "$cmd_description" == *"virtual environment"* ]]; then
operation_type="python"
elif [[ "$cmd_description" == *"models"* || "$cmd_description" == *"download"* ]]; then
operation_type="download"
elif [[ "$cmd_description" == *"configuration"* || "$cmd_description" == *"file paths"* ]]; then
operation_type="configuration"
fi
# Set the critical operation flag to true with the determined type
set_critical_operation true "$operation_type"
# Execute the command and capture its return code
"$@"
local return_code=$?
# Reset the critical operation flag
set_critical_operation false
if [ $return_code -eq 0 ]; then
# Success
print_color "BOLD_GREEN" "Completed: $cmd_description" "success"
elif [ $return_code -eq 2 ] && [[ "$cmd_description" == *"Downloading models"* ]]; then
# Special case: model selection with no models selected/downloaded
# Don't show a completion message for this case
return 0
else
# Error occurred
local error_message="Failed during: $cmd_description"
# Determine error type if not provided
if [ -z "$error_type" ]; then
case "$operation_type" in
"dependencies")
error_type="dependencies"
;;
"build")
error_type="build"
;;
"python")
error_type="python"
;;
"download")
error_type="download"
;;
"configuration")
error_type="permissions"
;;
"repository")
error_type="repository"
;;
*)
error_type="unknown"
;;
esac
fi
cleanup "$error_message" "$error_type"
fi
}
# Function to clone or update stable-diffusion.cpp with enhanced visuals
setup_stable_diffusion_cpp() {
# Check for required dependencies first
if ! check_dependencies "build"; then
print_color "RED" "Required dependencies for building are missing." "error"
return 1
fi
if [ -d "stable-diffusion.cpp" ]; then
print_color "YELLOW" "stable-diffusion.cpp directory already exists." "info"
read -p "$(echo -e ${BOLD_CYAN}Would you like to update it? \(y/n\)${NC} )" -n 1 -r
echo
if [[ $REPLY =~ ^[Yy]$ ]]; then
print_color "BLUE" "Updating stable-diffusion.cpp repository..." "info"
(cd stable-diffusion.cpp && {
# First try to pull with fast-forward only
if git pull origin master --ff-only; then
print_color "GREEN" "Repository updated successfully!" "success"
else
# If that fails, offer to reset to origin/master
print_color "YELLOW" "Fast-forward update failed due to divergent branches." "warning"
print_color "YELLOW" "Local changes might be lost if you continue." "warning"
read -p "$(echo -e ${BOLD_YELLOW}Reset to upstream master branch? This will discard local changes. \(y/n\)${NC} )" -n 1 -r
echo
if [[ $REPLY =~ ^[Yy]$ ]]; then
git fetch origin master && git reset --hard origin/master
print_color "GREEN" "Repository reset to origin/master successfully!" "success"
else
print_color "YELLOW" "Continuing with existing repository version." "info"
# Don't return 1 here - continue with existing repo
fi
fi
git submodule init && git submodule update
return 0
})
ret=$?
if [ $ret -ne 0 ]; then
print_color "YELLOW" "There were some issues with the repository update." "warning"
print_color "YELLOW" "This is often due to permission issues or directory ownership." "info"
print_color "YELLOW" "To add an exception for this directory, run:" "info"
safe_dir=$(realpath stable-diffusion.cpp)
echo -e "${BOLD_CYAN}git config --global --add safe.directory ${safe_dir}${NC}"
print_color "BLUE" "Continuing with existing repository version." "info"
# Return success since we already have the repo
return 0
else
print_color "BOLD_GREEN" "Repository update completed successfully!" "success"
fi
else
print_color "YELLOW" "Skipping update as requested." "info"
fi
else
print_color "BLUE" "Cloning stable-diffusion.cpp..." "info"
echo -e "${BOLD_CYAN}This may take a few minutes depending on your internet connection.${NC}"
echo
print_color "YELLOW" "Cloning in progress..." "info"
git clone --recursive https://github.com/leejet/stable-diffusion.cpp
if [ -d "stable-diffusion.cpp" ]; then
print_color "BOLD_GREEN" "Repository cloned successfully!" "success"
else
print_color "BOLD_RED" "Failed to clone repository." "error"
return 1
fi
fi
return 0
}
# Function to build stable-diffusion.cpp
build_stable_diffusion_cpp() {
cd stable-diffusion.cpp || return 1
print_color "PURPLE" "Building stable-diffusion.cpp..." "subheader"
mkdir -p build && cd build || return 1
# Check if CUDA is available
local cuda_available=false
if command_exists nvcc; then
cuda_version=$(nvcc --version | grep "release" | awk '{print $5}' | cut -d',' -f1)
print_color "YELLOW" "CUDA compiler (nvcc) found, version: $cuda_version" "success"
cuda_available=true
else
print_color "YELLOW" "CUDA compiler (nvcc) not found in PATH." "warning"
# Check common CUDA installation locations
if [ -f "/usr/local/cuda/bin/nvcc" ]; then
print_color "YELLOW" "CUDA found at /usr/local/cuda but not in PATH." "info"
print_color "YELLOW" "You may need to add CUDA to your PATH:" "info"
echo -e "${BOLD_CYAN} export PATH=/usr/local/cuda/bin:\$PATH${NC}"
cuda_available=true
elif [ -d "/usr/local/cuda" ]; then
print_color "YELLOW" "CUDA directory found at /usr/local/cuda but nvcc not found." "warning"
print_color "YELLOW" "You may need to install CUDA development tools." "info"
fi
fi
echo
echo -e "${BOLD_PURPLE}┌─────────────────────────────────────────────────────────┐"
echo -e "│ ${YELLOW}CUDA Configuration${BOLD_CYAN} │"
echo -e "└─────────────────────────────────────────────────────────┘${NC}"
echo
read -p "$(echo -e ${BOLD_GREEN}Build Stable-Diffusion.cpp with CUDA support? \(y/n\)${NC} )" -n 1 -r
echo
if [[ $REPLY =~ ^[Yy]$ ]]; then
if [ "$cuda_available" = false ]; then
print_color "YELLOW" "Warning: CUDA compiler not detected, but attempting CUDA build anyway." "warning"
echo -e "${BOLD_PURPLE}┌─────────────────────────────────────────────────────────┐"
echo -e "│ ${YELLOW}CUDA Troubleshooting Guide${BOLD_YELLOW} │"
echo -e "└─────────────────────────────────────────────────────────┘${NC}"
echo
print_color "YELLOW" "If build fails, you may need to:" "bullet"
echo -e "${BOLD_PURPLE} 1. ${YELLOW}Install CUDA toolkit ${CYAN}(https://developer.nvidia.com/cuda-downloads)${NC}"
echo -e "${BOLD_PURPLE} 2. ${YELLOW}Make sure nvcc is in your PATH${NC}"
echo -e "${BOLD_PURPLE} 3. ${YELLOW}Set CUDACXX environment variable to point to nvcc${NC}"
echo -e "${BOLD_PURPLE} 4. ${YELLOW}Try building without CUDA support instead${NC}"
echo
read -p "$(echo -e ${BOLD_YELLOW}Continue with CUDA build attempt? \(y/n\)${NC} )" -n 1 -r