-
Notifications
You must be signed in to change notification settings - Fork 0
Expand file tree
/
Copy pathsets_warp.sh
More file actions
executable file
·197 lines (168 loc) · 8.54 KB
/
sets_warp.sh
File metadata and controls
executable file
·197 lines (168 loc) · 8.54 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
#!/bin/sh
# SETS.sh — entry point for SETS-WARP (Linux / macOS)
SCRIPT_DIR="$(cd "$(dirname "$0")" && pwd)"
cd "$SCRIPT_DIR" || { echo "[Error] Cannot change to script directory."; exit 1; }
if [ ! -r "." ] || [ ! -w "." ]; then
echo "[Error] The current folder must be readable and writable."
exit 1
fi
# Export SETS_DIR so bootstrap.py and main.py always know where they live,
# regardless of Python's __file__ or .pyc cache pointing elsewhere
export SETS_DIR="$SCRIPT_DIR"
# ── Linux desktop integration ─────────────────────────────────────────────────
# Each install path gets its own .desktop file (keyed by a hash of SCRIPT_DIR)
# so multiple installations coexist without overwriting each other.
if [ "$(uname)" = "Linux" ] && [ -f "$SCRIPT_DIR/installer/install_desktop.sh" ]; then
# 8-char hash of install path — stable, unique per location
_PHASH=$(printf '%s' "$SCRIPT_DIR" | sha256sum 2>/dev/null | cut -c1-8)
if [ -z "$_PHASH" ]; then
_PHASH=$(printf '%s' "$SCRIPT_DIR" | md5sum 2>/dev/null | cut -c1-8)
fi
export SETS_DESKTOP_NAME="sets-warp-${_PHASH:-default}"
_DESKTOP="$HOME/.local/share/applications/${SETS_DESKTOP_NAME}.desktop"
# Migrate legacy sets-warp.desktop if it belongs to this install
_LEGACY="$HOME/.local/share/applications/sets-warp.desktop"
if [ -f "$_LEGACY" ] && grep -qF "Exec=$SCRIPT_DIR/" "$_LEGACY" 2>/dev/null; then
mv "$_LEGACY" "$_DESKTOP" 2>/dev/null || true
fi
# Create entry if not present yet for this install path
if [ ! -f "$_DESKTOP" ]; then
bash "$SCRIPT_DIR/installer/install_desktop.sh" > /dev/null 2>&1 || true
fi
unset _PHASH _DESKTOP _LEGACY
fi
# Prevent Python from using stale .pyc cache from a previous location
export PYTHONDONTWRITEBYTECODE=1
export PYTHONPYCACHEPREFIX="$SCRIPT_DIR/.pycache"
# Clear stale compiled cache on every start — ensures code changes take effect
# immediately without needing manual cleanup after updates.
if [ -d "$SCRIPT_DIR/.pycache" ]; then
rm -rf "$SCRIPT_DIR/.pycache"
fi
VENV_PYTHON="$SCRIPT_DIR/.venv/bin/python"
# Always go through bootstrap — it does a fast venv health-check (~0.5s)
# and auto-repairs missing/wrong-version packages before launching main.py.
# On a healthy venv bootstrap just relaunches immediately, so startup is fast.
if [ -x "$VENV_PYTHON" ]; then
exec "$VENV_PYTHON" "$SCRIPT_DIR/bootstrap.py" "$@"
fi
# ── First run — find Python 3.11+ to run bootstrap ────────────────────────────
PYTHON=""
for candidate in python3.14 python3.13 python3.12 python3.11 python3 python; do
if command -v "$candidate" > /dev/null 2>&1; then
ok=$("$candidate" -c "import sys; print(1 if sys.version_info >= (3,11) else 0)" 2>/dev/null)
if [ "$ok" = "1" ]; then
PYTHON="$candidate"
break
fi
fi
done
if [ -z "$PYTHON" ]; then
echo ""
echo " [SETS] Error: No Python 3.11+ found."
echo ""
echo " Please install Python 3.11 or newer, then re-run SETS."
echo " https://www.python.org/downloads/"
echo ""
exit 1
fi
# ── Check tkinter availability ─────────────────────────────────────────────────
# tkinter is needed to show the installer GUI on first run.
# The portable Python we download has tkinter built-in, so this is only
# needed once. If missing we show distro-specific install instructions.
TKINTER_OK=$("$PYTHON" -c "import tkinter" 2>/dev/null && echo "1" || echo "0")
if [ "$TKINTER_OK" = "0" ]; then
echo ""
echo " ╔══════════════════════════════════════════════════════════════╗"
echo " ║ SETS — Missing dependency: tkinter ║"
echo " ║ ║"
echo " ║ tkinter is required to display the installer window. ║"
echo " ║ It is NOT part of SETS — it must be installed system-wide. ║"
echo " ╚══════════════════════════════════════════════════════════════╝"
echo ""
# Detect distro from /etc/os-release (systemd standard, available on
# virtually all modern Linux distros: Debian, Ubuntu, Fedora, Arch,
# openSUSE, Alpine, Void, Gentoo, NixOS, Slackware derivatives, etc.)
DISTRO_ID=""
DISTRO_LIKE=""
if [ -f /etc/os-release ]; then
DISTRO_ID=$(. /etc/os-release && echo "${ID:-}" | tr '[:upper:]' '[:lower:]')
DISTRO_LIKE=$(. /etc/os-release && echo "${ID_LIKE:-}" | tr '[:upper:]' '[:lower:]')
fi
# Helper: check if a string contains a word
contains() { echo "$1" | grep -qw "$2"; }
# Match distro → install command
# We check ID first, then fall back to ID_LIKE for derivatives
# (e.g. Linux Mint has ID=linuxmint, ID_LIKE=ubuntu debian)
INSTALL_CMD=""
if contains "$DISTRO_ID $DISTRO_LIKE" "ubuntu" || \
contains "$DISTRO_ID $DISTRO_LIKE" "debian" || \
contains "$DISTRO_ID $DISTRO_LIKE" "linuxmint" || \
contains "$DISTRO_ID $DISTRO_LIKE" "pop" || \
contains "$DISTRO_ID $DISTRO_LIKE" "elementary" || \
contains "$DISTRO_ID $DISTRO_LIKE" "zorin" || \
contains "$DISTRO_ID $DISTRO_LIKE" "kali" || \
contains "$DISTRO_ID $DISTRO_LIKE" "raspbian"; then
PKG="python3-tk"
INSTALL_CMD="sudo apt install $PKG"
elif contains "$DISTRO_ID $DISTRO_LIKE" "fedora" || \
contains "$DISTRO_ID $DISTRO_LIKE" "rhel" || \
contains "$DISTRO_ID $DISTRO_LIKE" "centos" || \
contains "$DISTRO_ID $DISTRO_LIKE" "almalinux" || \
contains "$DISTRO_ID $DISTRO_LIKE" "rocky" || \
contains "$DISTRO_ID $DISTRO_LIKE" "ol"; then
PKG="python3-tkinter"
INSTALL_CMD="sudo dnf install $PKG"
elif contains "$DISTRO_ID $DISTRO_LIKE" "arch" || \
contains "$DISTRO_ID $DISTRO_LIKE" "manjaro" || \
contains "$DISTRO_ID $DISTRO_LIKE" "endeavouros" || \
contains "$DISTRO_ID $DISTRO_LIKE" "garuda"; then
PKG="tk"
INSTALL_CMD="sudo pacman -S $PKG"
elif contains "$DISTRO_ID $DISTRO_LIKE" "opensuse" || \
contains "$DISTRO_ID $DISTRO_LIKE" "suse"; then
PKG="python3-tk"
INSTALL_CMD="sudo zypper install $PKG"
elif contains "$DISTRO_ID $DISTRO_LIKE" "alpine"; then
PKG="py3-tkinter"
INSTALL_CMD="sudo apk add $PKG"
elif contains "$DISTRO_ID $DISTRO_LIKE" "void"; then
PKG="python3-tkinter"
INSTALL_CMD="sudo xbps-install $PKG"
elif contains "$DISTRO_ID $DISTRO_LIKE" "gentoo"; then
INSTALL_CMD="sudo emerge -av dev-lang/python[tk] (rebuild Python with USE=tk)"
elif contains "$DISTRO_ID $DISTRO_LIKE" "nixos" || \
contains "$DISTRO_ID $DISTRO_LIKE" "nix"; then
INSTALL_CMD="nix-env -iA nixpkgs.python3Packages.tkinter"
elif contains "$DISTRO_ID $DISTRO_LIKE" "slackware"; then
INSTALL_CMD="installpkg python3-tkinter (from Slackware extras or SlackBuilds)"
elif [ "$(uname)" = "Darwin" ]; then
INSTALL_CMD="brew install python-tk (or reinstall Python from python.org)"
fi
if [ -n "$INSTALL_CMD" ]; then
echo " Detected: ${DISTRO_ID:-unknown}${DISTRO_LIKE:+ (like: $DISTRO_LIKE)}"
echo ""
echo " Run this command to install tkinter:"
echo ""
echo " $INSTALL_CMD"
echo ""
echo " Then re-run: ./SETS.sh"
else
echo " Could not detect your Linux distribution automatically."
echo ""
echo " Install the tkinter package for your Python version, for example:"
echo " - Debian/Ubuntu: sudo apt install python3-tk"
echo " - Fedora/RHEL: sudo dnf install python3-tkinter"
echo " - Arch Linux: sudo pacman -S tk"
echo " - openSUSE: sudo zypper install python3-tk"
echo " - Alpine: sudo apk add py3-tkinter"
echo " - Void Linux: sudo xbps-install python3-tkinter"
echo ""
echo " Then re-run: ./SETS.sh"
fi
echo ""
exit 1
fi
echo "[SETS-WARP] First run — starting setup (this will take a few minutes)..."
echo "[SETS-WARP] SCRIPT_DIR=$SCRIPT_DIR"
exec "$PYTHON" "$SCRIPT_DIR/bootstrap.py" "$@"