Skip to content

Commit b512b72

Browse files
authored
Merge pull request #104 from httpsphl/feat/deb-prerm
feat(release): removing the .deb stops the background service
2 parents a4033a4 + c0ebe50 commit b512b72

3 files changed

Lines changed: 40 additions & 1 deletion

File tree

‎app/src-tauri/linux/prerm.sh‎

Lines changed: 33 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -0,0 +1,33 @@
1+
#!/bin/sh
2+
# Botloft's .deb pre-removal script (spec 15.4). dpkg runs it as root
3+
# before it removes the package, and before an upgrade replaces it. On a
4+
# removal only, it stops Botloft's background service for every user who
5+
# has one, as `botloftd service uninstall` does, and removes the entry that
6+
# opens the app at sign-in. An upgrade (the in-app updater installs the
7+
# new .deb) leaves both alone. Bots and data stay in each user's folders.
8+
set -u
9+
10+
case "${1:-}" in
11+
remove | purge) ;;
12+
*) exit 0 ;;
13+
esac
14+
15+
for unit in /home/*/.config/systemd/user/botloft.service /root/.config/systemd/user/botloft.service; do
16+
[ -f "$unit" ] || continue
17+
home=${unit%/.config/systemd/user/botloft.service}
18+
user=$(stat -c %U "$home") || continue
19+
uid=$(id -u "$user") || continue
20+
data="$home/.local/share/Botloft"
21+
daemon="$data/bin/botloftd"
22+
if [ -x "$daemon" ] && [ -S "/run/user/$uid/bus" ]; then
23+
# The user's service manager runs: the daemon stops its own service.
24+
runuser -u "$user" -- env HOME="$home" XDG_RUNTIME_DIR="/run/user/$uid" \
25+
DBUS_SESSION_BUS_ADDRESS="unix:path=/run/user/$uid/bus" \
26+
"$daemon" --home "$data" service uninstall >/dev/null 2>&1 || true
27+
fi
28+
# Signed out, or the daemon could not: nothing runs it, so its files go.
29+
rm -f "$unit" "$home/.config/systemd/user/default.target.wants/botloft.service"
30+
rm -f "$home/.config/autostart/botloft.desktop"
31+
done
32+
33+
exit 0
Lines changed: 6 additions & 1 deletion
Original file line numberDiff line numberDiff line change
@@ -1,6 +1,11 @@
11
{
22
"$schema": "https://schema.tauri.app/config/2",
33
"bundle": {
4-
"targets": ["deb", "appimage"]
4+
"targets": ["deb", "appimage"],
5+
"linux": {
6+
"deb": {
7+
"preRemoveScript": "linux/prerm.sh"
8+
}
9+
}
510
}
611
}

‎docs/spec.md‎

Lines changed: 1 addition & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -856,6 +856,7 @@ Identidade: o mascote do Botloft é uma chama com olhos. O ícone do app (`app/a
856856
- Editor antigo: até a 0.6.0 o `bundle.publisher` ficava vazio e o Tauri usava `github`, a segunda parte do identificador, o que num programa sem assinatura parece alguém se passando pelo GitHub. O Tauri também dá o nome do editor à chave que guarda a pasta de instalação (`Software\<editor>\Botloft`), lida para atualizar na mesma pasta e para o "desinstalar antes de instalar" do assistente. Por isso os hooks adotam a instalação antiga: `BotloftAdoptOldFolder` copia a pasta de `Software\github\Botloft` para `Software\Botloft\Botloft` quando a chave nova não existe e passa a instalar nela, a menos que `/D` tenha escolhido outra. Roda antes da primeira tela (`MUI_CUSTOMFUNCTION_GUIINIT`), o que cobre o assistente e a atualização passiva, e no começo da instalação (`NSIS_HOOK_PREINSTALL`), para o modo silencioso, que não tem telas. Depois de instalar, o `NSIS_HOOK_POSTINSTALL` apaga a chave antiga, e a `Software\github` só se ficar vazia. A tela de instalação (15.7) lê a chave nova e, na falta dela, a antiga. **Verificado** (Windows 11 25H2, 2026-09-30): sobre a 0.6.0 instalada com o editor antigo e com o app aberto, o instalador novo rodado como o atualizador (`/P /UPDATE /R`) terminou em 3 s, criou `Software\Botloft\Botloft` com a pasta que estava na chave antiga, apagou a antiga e a `Software\github` vazia, deixou o editor "Botloft" em Aplicativos instalados e reabriu o app da mesma pasta; o daemon não foi tocado. Os casos de pasta escolhida pelo dono, `/D` e modo silencioso foram testados com um instalador mínimo compilado com o mesmo arquivo de hooks e chaves de teste.
857857
- O manifesto do app (`src-tauri/windows/app.manifest`) é o padrão do Tauri (controles comuns v6) mais `longPathAware`.
858858
- **Linux e macOS** (18, item 8): o mesmo `pnpm bundle` gera os pacotes do sistema em que roda. O Tauri junta ao `tauri.conf.json` o `tauri.linux.conf.json` ou o `tauri.macos.conf.json`, que escolhem os pacotes. Linux: `.deb` (o Tauri põe as dependências: WebKitGTK, GTK e o `libayatana-appindicator3-1` do ícone na bandeja) e AppImage, feitos no Ubuntu 22.04 para o AppImage rodar em distribuições mais antigas (ele usa a glibc do sistema em que foi feito). macOS: `.app` e `.dmg` para Apple Silicon, a partir do macOS 11. Sem conta Apple Developer, o app não é notarizado: tem só assinatura ad-hoc (`signingIdentity = "-"`). Sem nenhuma assinatura, o macOS diria que o app está danificado; assinado assim, quem baixa o libera uma vez em Ajustes do Sistema → Privacidade e Segurança → Abrir Mesmo Assim. O sidecar vai dentro do pacote, ao lado do app, como no Windows. A tela de instalação (15.7) é só do Windows.
859+
- **Remover o `.deb`** faz o que o hook de desinstalação do NSIS faz. O `prerm` (`src-tauri/linux/prerm.sh`, `preRemoveScript`) roda como root, só com `remove` ou `purge`: a atualização pelo app instala o `.deb` novo e chama o `prerm` com `upgrade`, que não mexe em nada. Para cada `~/.config/systemd/user/botloft.service` em `/home/*` e `/root`, roda `botloftd --home ~/.local/share/Botloft service uninstall` como o dono da pasta (`runuser`, com `HOME`, `XDG_RUNTIME_DIR` e o bus da sessão dele), se o gerenciador do usuário estiver no ar (`/run/user/<uid>/bus`). Depois apaga a unit, o link de `default.target.wants` e `~/.config/autostart/botloft.desktop`, o que cobre quem está fora da sessão. Bots e dados ficam. Só a unit da pasta padrão (`botloft.service`) é tratada; um daemon de dev com outra pasta é de quem o instalou. O AppImage e o `.app` do macOS não têm desinstalador: o README e a política de assinatura dizem para rodar `botloftd service uninstall` antes. **Testado** num contêiner Debian, com usuários de mentira e um `botloftd` falso: com `upgrade` nada muda; com `remove`, o daemon de quem tem sessão é chamado como esse usuário, com a pasta certa, e os arquivos de todos saem.
859860

860861
### 15.5 Atualizações
861862

0 commit comments

Comments
 (0)