Skip to content

Commit 617e13d

Browse files
author
Xiang Li
committed
fix(tui): install gum with package repo keys
1 parent e08b438 commit 617e13d

5 files changed

Lines changed: 191 additions & 0 deletions

File tree

README.md

Lines changed: 14 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -160,6 +160,19 @@ TUI 启动后会显示状态面板和功能菜单:
160160

161161
TUI 依赖 [gum](https://github.com/charmbracelet/gum)(Charm 出品的终端 UI 工具)。gum 不是主安装依赖;未安装时仅 `clashctl tui` 不可用,`clashon``clashoff``clashctl select``status``doctor` 等命令不受影响。
162162

163+
安装项目时会询问是否安装 gum,默认跳过;也可以安装后单独执行:
164+
165+
```bash
166+
clashctl tui install-gum
167+
```
168+
169+
非交互安装时可通过环境变量控制:
170+
171+
```bash
172+
CLASH_INSTALL_GUM=true bash install.sh
173+
CLASH_INSTALL_GUM=false bash install.sh
174+
```
175+
163176
```bash
164177
# macOS
165178
brew install gum
@@ -180,6 +193,7 @@ baseurl=https://repo.charm.sh/yum/
180193
enabled=1
181194
gpgcheck=1
182195
gpgkey=https://repo.charm.sh/yum/gpg.key' | sudo tee /etc/yum.repos.d/charm.repo
196+
sudo rpm --import https://repo.charm.sh/yum/gpg.key
183197
sudo yum install gum
184198

185199
# Go

install.sh

Lines changed: 1 addition & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -35,6 +35,7 @@ install_runtime_entry
3535
install_local_dashboard_assets
3636
ensure_controller_secret >/dev/null
3737
set_shell_proxy_persist_enabled "false"
38+
prompt_install_tui
3839

3940
ensure_subscription_bootstrap_for_install "default"
4041
prompt_subscription_if_needed

scripts/core/clashctl.sh

Lines changed: 1 addition & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -35,6 +35,7 @@ Usage:
3535
3636
🕹️ Control:
3737
tui 🖥️ TUI 交互式控制台(需要 gum)
38+
tui install-gum 🧩 安装可选 TUI 依赖 gum
3839
clashui 🕹️ 查看 Web 控制台
3940
secret 🔑 查看或设置 Web 密钥
4041
clashsecret 🔑 查看或设置 Web 密钥

scripts/core/common.sh

Lines changed: 167 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -2841,6 +2841,173 @@ install_runtime_brief_line() {
28412841
esac
28422842
}
28432843

2844+
gum_run_as_root() {
2845+
if [ "$(id -u 2>/dev/null || echo 1)" = "0" ]; then
2846+
"$@"
2847+
return $?
2848+
fi
2849+
2850+
if command -v sudo >/dev/null 2>&1; then
2851+
sudo "$@"
2852+
return $?
2853+
fi
2854+
2855+
echo "❗ 安装 gum 需要 root 权限或 sudo:$*"
2856+
return 1
2857+
}
2858+
2859+
install_gum_with_apt() {
2860+
local key_tmp
2861+
2862+
command -v gpg >/dev/null 2>&1 || {
2863+
echo "❗ Debian/Ubuntu 安装 gum 需要 gpg,请先安装 gnupg"
2864+
return 1
2865+
}
2866+
2867+
key_tmp="$(mktemp)"
2868+
if ! curl_download -fsSL https://repo.charm.sh/apt/gpg.key -o "$key_tmp"; then
2869+
rm -f "$key_tmp" 2>/dev/null || true
2870+
echo "❗ 下载 Charm APT GPG key 失败"
2871+
return 1
2872+
fi
2873+
2874+
gum_run_as_root mkdir -p /etc/apt/keyrings || {
2875+
rm -f "$key_tmp" 2>/dev/null || true
2876+
return 1
2877+
}
2878+
gum_run_as_root gpg --batch --yes --dearmor -o /etc/apt/keyrings/charm.gpg "$key_tmp" || {
2879+
rm -f "$key_tmp" 2>/dev/null || true
2880+
echo "❗ 写入 Charm APT GPG key 失败"
2881+
return 1
2882+
}
2883+
rm -f "$key_tmp" 2>/dev/null || true
2884+
2885+
printf '%s\n' 'deb [signed-by=/etc/apt/keyrings/charm.gpg] https://repo.charm.sh/apt/ * *' \
2886+
| gum_run_as_root tee /etc/apt/sources.list.d/charm.list >/dev/null || return 1
2887+
2888+
gum_run_as_root apt-get update || return 1
2889+
gum_run_as_root apt-get install -y gum
2890+
}
2891+
2892+
install_charm_yum_repo() {
2893+
local repo_tmp
2894+
2895+
command -v rpm >/dev/null 2>&1 || {
2896+
echo "❗ 安装 gum 需要 rpm 命令"
2897+
return 1
2898+
}
2899+
2900+
repo_tmp="$(mktemp)"
2901+
{
2902+
echo "[charm]"
2903+
echo "name=Charm"
2904+
echo "baseurl=https://repo.charm.sh/yum/"
2905+
echo "enabled=1"
2906+
echo "gpgcheck=1"
2907+
echo "gpgkey=https://repo.charm.sh/yum/gpg.key"
2908+
} > "$repo_tmp"
2909+
2910+
gum_run_as_root mkdir -p /etc/yum.repos.d || {
2911+
rm -f "$repo_tmp" 2>/dev/null || true
2912+
return 1
2913+
}
2914+
gum_run_as_root cp "$repo_tmp" /etc/yum.repos.d/charm.repo || {
2915+
rm -f "$repo_tmp" 2>/dev/null || true
2916+
return 1
2917+
}
2918+
rm -f "$repo_tmp" 2>/dev/null || true
2919+
2920+
gum_run_as_root rpm --import https://repo.charm.sh/yum/gpg.key
2921+
}
2922+
2923+
install_gum_with_yum_repo() {
2924+
local manager="$1"
2925+
2926+
install_charm_yum_repo || return 1
2927+
gum_run_as_root "$manager" install -y gum
2928+
}
2929+
2930+
install_gum_with_zypper() {
2931+
install_charm_yum_repo || return 1
2932+
gum_run_as_root zypper refresh || return 1
2933+
gum_run_as_root zypper install -y gum
2934+
}
2935+
2936+
install_gum() {
2937+
if command -v gum >/dev/null 2>&1; then
2938+
echo "🖥️ gum 已安装:$(gum --version 2>/dev/null || echo gum)"
2939+
return 0
2940+
fi
2941+
2942+
echo "🖥️ 正在安装可选 TUI 依赖 gum..."
2943+
2944+
if command -v apt-get >/dev/null 2>&1; then
2945+
install_gum_with_apt
2946+
elif command -v dnf >/dev/null 2>&1; then
2947+
install_gum_with_yum_repo dnf
2948+
elif command -v yum >/dev/null 2>&1; then
2949+
install_gum_with_yum_repo yum
2950+
elif command -v zypper >/dev/null 2>&1; then
2951+
install_gum_with_zypper
2952+
elif command -v pacman >/dev/null 2>&1; then
2953+
gum_run_as_root pacman -S --noconfirm gum
2954+
elif command -v apk >/dev/null 2>&1; then
2955+
gum_run_as_root apk add --no-cache gum
2956+
else
2957+
echo "❗ 未检测到支持的包管理器,请手动安装 gum"
2958+
echo " 见 https://github.com/charmbracelet/gum#installation"
2959+
return 1
2960+
fi
2961+
2962+
if command -v gum >/dev/null 2>&1; then
2963+
echo "✅ gum 安装成功:$(gum --version 2>/dev/null || echo gum)"
2964+
return 0
2965+
fi
2966+
2967+
echo "❗ gum 安装完成后仍不可用,请检查 PATH"
2968+
return 1
2969+
}
2970+
2971+
prompt_install_tui() {
2972+
case "${CLASH_INSTALL_GUM:-}" in
2973+
true|1|yes|YES|y|Y)
2974+
install_gum || true
2975+
return 0
2976+
;;
2977+
false|0|no|NO|n|N)
2978+
return 0
2979+
;;
2980+
esac
2981+
2982+
if command -v gum >/dev/null 2>&1; then
2983+
echo "🖥️ TUI 依赖已就绪(gum $(gum --version 2>/dev/null || echo '?')"
2984+
return 0
2985+
fi
2986+
2987+
[ -t 0 ] || {
2988+
echo "🖥️ 未安装可选 TUI 依赖 gum;需要时可运行:clashctl tui install-gum"
2989+
return 0
2990+
}
2991+
2992+
echo
2993+
echo "🖥️ 可选 TUI 控制台需要 gum(Charm 出品的终端 UI 工具)"
2994+
echo " 安装后可通过 clashctl tui 进入交互式控制台"
2995+
printf " 是否现在安装 gum?[y/N] "
2996+
2997+
local answer
2998+
read -r answer 2>/dev/null || answer=""
2999+
case "${answer:-N}" in
3000+
[Yy]|[Yy][Ee][Ss])
3001+
echo
3002+
install_gum || true
3003+
;;
3004+
*)
3005+
echo
3006+
echo "⏭️ 已跳过 gum 安装,后续可运行:clashctl tui install-gum"
3007+
;;
3008+
esac
3009+
}
3010+
28443011
print_install_summary() {
28453012
local clashctl_file
28463013
local kernel_text project_path arch_text install_actor install_scope_text

scripts/core/tui.sh

Lines changed: 8 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -24,6 +24,7 @@ tui_ensure_gum() {
2424
echo " Arch: pacman -S gum"
2525
echo " Nix: nix-env -iA nixpkgs.gum"
2626
echo " Go: go install github.com/charmbracelet/gum@latest"
27+
echo " 自动安装: clashctl tui install-gum"
2728
echo " 通用: 见 https://github.com/charmbracelet/gum#installation"
2829
echo
2930
exit 1
@@ -1369,6 +1370,13 @@ tui_latency_test() {
13691370
}
13701371

13711372
cmd_tui() {
1373+
case "${1:-}" in
1374+
install-gum|install-deps)
1375+
install_gum
1376+
return $?
1377+
;;
1378+
esac
1379+
13721380
prepare
13731381
tui_ensure_gum
13741382
tui_main_loop

0 commit comments

Comments
 (0)