Skip to content

Commit 66be06d

Browse files
committed
docs: add one-line Linux install script (deb/rpm)
1 parent 5fcae86 commit 66be06d

2 files changed

Lines changed: 225 additions & 1 deletion

File tree

docs/index.md

Lines changed: 9 additions & 1 deletion
Original file line numberDiff line numberDiff line change
@@ -78,7 +78,15 @@ curl -fsSL https://nucleus.kdroidfilter.com/install.sh | bash
7878

7979
This automatically detects your architecture (Apple Silicon or Intel), downloads the latest release, installs it to `/Applications`, and launches the app.
8080

81-
**On other platforms**, download the appropriate installer from the [releases page](https://github.com/kdroidFilter/Nucleus/releases).
81+
**On Linux** (Debian/Ubuntu, Fedora, openSUSE, etc.):
82+
83+
```bash
84+
curl -fsSL https://nucleus.kdroidfilter.com/install-linux.sh | bash
85+
```
86+
87+
This detects your architecture and package manager, then downloads and installs the appropriate `.deb` or `.rpm` package.
88+
89+
**On Windows**, download the appropriate installer from the [releases page](https://github.com/kdroidFilter/Nucleus/releases).
8290

8391
Here's what you'll see:
8492

docs/install-linux.sh

Lines changed: 216 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -0,0 +1,216 @@
1+
#!/usr/bin/env bash
2+
3+
set -e
4+
5+
# ─── Config ───────────────────────────────────────────────────────────
6+
repo="kdroidFilter/Nucleus"
7+
app_name="nucleusdemo"
8+
9+
# ─── Colors & Symbols ────────────────────────────────────────────────
10+
BOLD='\033[1m'
11+
DIM='\033[2m'
12+
RESET='\033[0m'
13+
GREEN='\033[1;32m'
14+
CYAN='\033[1;36m'
15+
YELLOW='\033[1;33m'
16+
RED='\033[1;31m'
17+
MAGENTA='\033[1;35m'
18+
BLUE='\033[1;34m'
19+
WHITE='\033[1;37m'
20+
21+
CHECK="${GREEN}${RESET}"
22+
CROSS="${RED}${RESET}"
23+
ARROW="${CYAN}${RESET}"
24+
SPARKLE="${MAGENTA}${RESET}"
25+
26+
# ─── Banner ───────────────────────────────────────────────────────────
27+
print_banner() {
28+
echo ""
29+
echo -e "${CYAN}${BOLD}"
30+
echo " ╔╗╔╦ ╦╔═╗╦ ╔═╗╦ ╦╔═╗"
31+
echo " ║║║║ ║║ ║ ║╣ ║ ║╚═╗"
32+
echo " ╝╚╝╚═╝╚═╝╩═╝╚═╝╚═╝╚═╝"
33+
echo -e "${RESET}"
34+
echo -e " ${DIM}Installer for Linux${RESET}"
35+
echo ""
36+
}
37+
38+
# ─── Helpers ──────────────────────────────────────────────────────────
39+
step() {
40+
echo -e " ${ARROW} ${BOLD}$1${RESET}"
41+
}
42+
43+
success() {
44+
echo -e " ${CHECK} ${GREEN}$1${RESET}"
45+
}
46+
47+
fail() {
48+
echo -e " ${CROSS} ${RED}$1${RESET}"
49+
exit 1
50+
}
51+
52+
spin() {
53+
local pid=$1
54+
local msg=$2
55+
local frames=("" "" "" "" "" "" "" "" "" "")
56+
local i=0
57+
58+
tput civis 2>/dev/null || true
59+
while kill -0 "$pid" 2>/dev/null; do
60+
printf "\r ${CYAN}${frames[$i]}${RESET} ${DIM}%s${RESET}" "$msg"
61+
i=$(( (i + 1) % ${#frames[@]} ))
62+
sleep 0.08
63+
done
64+
printf "\r\033[2K"
65+
tput cnorm 2>/dev/null || true
66+
}
67+
68+
download_with_progress() {
69+
local url="$1"
70+
local output="$2"
71+
local bar_width=40
72+
73+
# Get total file size via HEAD request (follow redirects)
74+
local total_size
75+
total_size=$(curl -sIL "$url" | grep -i '^content-length:' | tail -1 | tr -dc '0-9')
76+
77+
if [ -z "$total_size" ] || [ "$total_size" -eq 0 ]; then
78+
curl -sL --output "$output" "$url" &
79+
spin $! "Downloading"
80+
return
81+
fi
82+
83+
# Download silently in background
84+
curl -sL --output "$output" "$url" &
85+
local curl_pid=$!
86+
87+
tput civis 2>/dev/null || true
88+
89+
while kill -0 "$curl_pid" 2>/dev/null; do
90+
if [ -f "$output" ]; then
91+
local current_size
92+
current_size=$(stat -c%s "$output" 2>/dev/null || stat -f%z "$output" 2>/dev/null || echo 0)
93+
local pct=$((current_size * 100 / total_size))
94+
[ "$pct" -gt 100 ] && pct=100
95+
local filled=$((pct * bar_width / 100))
96+
local empty=$((bar_width - filled))
97+
local bar=""
98+
for ((j=0; j<filled; j++)); do bar+=""; done
99+
for ((j=0; j<empty; j++)); do bar+=""; done
100+
local mb_done mb_total
101+
mb_done=$(echo "scale=1; $current_size / 1048576" | bc)
102+
mb_total=$(echo "scale=1; $total_size / 1048576" | bc)
103+
printf "\r \033[1;35m✦\033[0m \033[2mDownloading\033[0m \033[1;34m%s\033[0m \033[1;37m%3d%%\033[0m \033[2m(%s / %s MB)\033[0m" "$bar" "$pct" "$mb_done" "$mb_total"
104+
fi
105+
sleep 0.15
106+
done
107+
108+
# Final 100%
109+
local bar=""
110+
for ((j=0; j<bar_width; j++)); do bar+=""; done
111+
local mb_total
112+
mb_total=$(echo "scale=1; $total_size / 1048576" | bc)
113+
printf "\r \033[1;35m✦\033[0m \033[2mDownloading\033[0m \033[1;34m%s\033[0m \033[1;37m100%%\033[0m \033[2m(%s / %s MB)\033[0m" "$bar" "$mb_total" "$mb_total"
114+
echo ""
115+
116+
tput cnorm 2>/dev/null || true
117+
wait "$curl_pid"
118+
}
119+
120+
# ─── Main ─────────────────────────────────────────────────────────────
121+
print_banner
122+
123+
# Resolve latest version
124+
step "Fetching latest release ..."
125+
version=$(curl -sI "https://github.com/${repo}/releases/latest" | grep -i '^location:' | sed 's/.*tag\///' | tr -d '\r\n')
126+
127+
if [ -z "$version" ]; then
128+
fail "Could not determine latest version"
129+
fi
130+
131+
version_number="${version#v}"
132+
success "Found ${BOLD}${YELLOW}${version}${RESET}"
133+
134+
# Detect architecture
135+
machine=$(uname -m)
136+
case "$machine" in
137+
x86_64) deb_arch="amd64"; rpm_arch="x86_64" ;;
138+
aarch64) deb_arch="arm64"; rpm_arch="aarch64" ;;
139+
*) fail "Unsupported CPU architecture: $machine" ;;
140+
esac
141+
142+
# Detect package manager and select format
143+
pkg_format=""
144+
if command -v dpkg >/dev/null 2>&1; then
145+
pkg_format="deb"
146+
pkg_url="https://github.com/${repo}/releases/download/${version}/${app_name}-${version_number}-linux-${deb_arch}.deb"
147+
pkg_file="${app_name}.deb"
148+
elif command -v rpm >/dev/null 2>&1; then
149+
pkg_format="rpm"
150+
pkg_url="https://github.com/${repo}/releases/download/${version}/${app_name}-${version_number}-linux-${rpm_arch}.rpm"
151+
pkg_file="${app_name}.rpm"
152+
else
153+
fail "No supported package manager found (dpkg or rpm required)"
154+
fi
155+
156+
success "Architecture: ${BOLD}${machine}${RESET}"
157+
success "Package format: ${BOLD}${pkg_format}${RESET}"
158+
echo ""
159+
160+
# Temp directory
161+
tmpdir="$(mktemp -d -t nucleus-install.XXXXXX)"
162+
tmpfile="$tmpdir/$pkg_file"
163+
164+
cleanup() {
165+
cd "$HOME" || true
166+
[ -e "$tmpfile" ] && rm -f "$tmpfile"
167+
rmdir "$tmpdir" 2>/dev/null || true
168+
}
169+
trap cleanup EXIT
170+
171+
# Download
172+
step "Downloading ${YELLOW}${app_name}${RESET} ${DIM}(${version_number})${RESET} ..."
173+
download_with_progress "$pkg_url" "$tmpfile"
174+
success "Download complete"
175+
echo ""
176+
177+
# Install
178+
step "Installing ${YELLOW}${app_name}${RESET} ..."
179+
if [ "$pkg_format" = "deb" ]; then
180+
sudo dpkg -i "$tmpfile" >/dev/null 2>&1 || sudo apt-get install -f -y >/dev/null 2>&1
181+
elif [ "$pkg_format" = "rpm" ]; then
182+
if command -v dnf >/dev/null 2>&1; then
183+
sudo dnf install -y "$tmpfile" >/dev/null 2>&1
184+
elif command -v yum >/dev/null 2>&1; then
185+
sudo yum install -y "$tmpfile" >/dev/null 2>&1
186+
elif command -v zypper >/dev/null 2>&1; then
187+
sudo zypper install -y "$tmpfile" >/dev/null 2>&1
188+
else
189+
sudo rpm -i "$tmpfile" >/dev/null 2>&1
190+
fi
191+
fi
192+
success "Package installed"
193+
194+
# Launch
195+
echo ""
196+
step "Launching ${YELLOW}${app_name}${RESET} ..."
197+
if command -v "$app_name" >/dev/null 2>&1; then
198+
nohup "$app_name" >/dev/null 2>&1 &
199+
success "Application started"
200+
elif [ -f "/usr/bin/${app_name}" ]; then
201+
nohup "/usr/bin/${app_name}" >/dev/null 2>&1 &
202+
success "Application started"
203+
elif [ -f "/opt/${app_name}/${app_name}" ]; then
204+
nohup "/opt/${app_name}/${app_name}" >/dev/null 2>&1 &
205+
success "Application started"
206+
else
207+
success "Package installed — launch ${BOLD}${app_name}${RESET} from your application menu"
208+
fi
209+
210+
# Done
211+
echo ""
212+
echo -e " ${SPARKLE}${SPARKLE}${SPARKLE} ${GREEN}${BOLD}All done!${RESET} ${SPARKLE}${SPARKLE}${SPARKLE}"
213+
echo ""
214+
215+
cleanup
216+
exit 0

0 commit comments

Comments
 (0)