Skip to content
Merged
Show file tree
Hide file tree
Changes from all commits
Commits
File filter

Filter by extension

Filter by extension

Conversations
Failed to load comments.
Loading
Jump to
Jump to file
Failed to load files.
Loading
Diff view
Diff view
33 changes: 33 additions & 0 deletions app/src-tauri/linux/prerm.sh
Original file line number Diff line number Diff line change
@@ -0,0 +1,33 @@
#!/bin/sh
# Botloft's .deb pre-removal script (spec 15.4). dpkg runs it as root
# before it removes the package, and before an upgrade replaces it. On a
# removal only, it stops Botloft's background service for every user who
# has one, as `botloftd service uninstall` does, and removes the entry that
# opens the app at sign-in. An upgrade (the in-app updater installs the
# new .deb) leaves both alone. Bots and data stay in each user's folders.
set -u

case "${1:-}" in
remove | purge) ;;
*) exit 0 ;;
esac

for unit in /home/*/.config/systemd/user/botloft.service /root/.config/systemd/user/botloft.service; do
[ -f "$unit" ] || continue
home=${unit%/.config/systemd/user/botloft.service}
user=$(stat -c %U "$home") || continue
uid=$(id -u "$user") || continue
data="$home/.local/share/Botloft"
daemon="$data/bin/botloftd"
if [ -x "$daemon" ] && [ -S "/run/user/$uid/bus" ]; then
# The user's service manager runs: the daemon stops its own service.
runuser -u "$user" -- env HOME="$home" XDG_RUNTIME_DIR="/run/user/$uid" \
DBUS_SESSION_BUS_ADDRESS="unix:path=/run/user/$uid/bus" \
"$daemon" --home "$data" service uninstall >/dev/null 2>&1 || true
fi
# Signed out, or the daemon could not: nothing runs it, so its files go.
rm -f "$unit" "$home/.config/systemd/user/default.target.wants/botloft.service"
rm -f "$home/.config/autostart/botloft.desktop"
done

exit 0
7 changes: 6 additions & 1 deletion app/src-tauri/tauri.linux.conf.json
Original file line number Diff line number Diff line change
@@ -1,6 +1,11 @@
{
"$schema": "https://schema.tauri.app/config/2",
"bundle": {
"targets": ["deb", "appimage"]
"targets": ["deb", "appimage"],
"linux": {
"deb": {
"preRemoveScript": "linux/prerm.sh"
}
}
}
}
1 change: 1 addition & 0 deletions docs/spec.md
Original file line number Diff line number Diff line change
Expand Up @@ -855,6 +855,7 @@ Identidade: o mascote do Botloft é uma chama com olhos. O ícone do app (`app/a
- 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.
- O manifesto do app (`src-tauri/windows/app.manifest`) é o padrão do Tauri (controles comuns v6) mais `longPathAware`.
- **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.
- **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.

### 15.5 Atualizações

Expand Down
Loading