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
11 changes: 11 additions & 0 deletions apps/desktop/src-tauri/src/lib.rs
Original file line number Diff line number Diff line change
Expand Up @@ -1702,6 +1702,17 @@ fn app_log(level: String, message: String) {

#[cfg_attr(mobile, tauri::mobile_entry_point)]
pub fn run() {
// Headless `--version` / `-V`: print and exit BEFORE building the GUI, so installers and
// users can verify the binary without a window opening. resolve_db_target() ignores args
// starting with `-`, so without this the flag would be silently dropped and the app would
// launch normally instead.
if std::env::args()
.skip(1)
.any(|a| a == "--version" || a == "-V")
{
println!("red-request {}", env!("CARGO_PKG_VERSION"));
return;
}
tauri::Builder::default()
.plugin(
tauri_plugin_log::Builder::new()
Expand Down
69 changes: 55 additions & 14 deletions install.sh
Original file line number Diff line number Diff line change
Expand Up @@ -166,17 +166,18 @@ clear_appimage_shadow() {
have update-desktop-database && update-desktop-database "$DESKTOP_DIR" >/dev/null 2>&1 || true
}

# The .deb ships red-request/red/red-request-engine in /usr/bin but no `rr`
# alias (it was historically AppImage-only). Always (re)create it pointing at
# the system binary, and ensure $INSTALL_DIR is on PATH, so `rr` works the same
# for both build forms — including a fresh .deb install after an uninstall.
# The .deb ships red-request/red/red-request-engine in /usr/bin but no `rr` alias
# (historically AppImage-only). (Re)create it as a symlink in /usr/local/bin — that dir is
# on PATH for every shell (bash/zsh/fish) out of the box, so `rr` just works with no rc-file
# edits, unlike ~/.local/bin. Points at the system binary so `rr` tracks upgrades.
ensure_deb_shortcut() {
local deb_bin; deb_bin="$(deb_binary_path)"
local deb_bin sudo="" dst="/usr/local/bin/$SHORTCUT"
deb_bin="$(deb_binary_path)"
[[ -n "$deb_bin" ]] || { warn "could not locate the installed $BIN_NAME binary; skipping $SHORTCUT alias"; return 0; }
mkdir -p "$INSTALL_DIR"
ln -sf "$deb_bin" "$INSTALL_DIR/$SHORTCUT"
ok "linked $SHORTCUT → $deb_bin"
ensure_path
[[ $EUID -ne 0 ]] && have sudo && sudo="sudo"
$sudo mkdir -p /usr/local/bin && $sudo ln -sf "$deb_bin" "$dst" \
&& ok "linked $SHORTCUT → $deb_bin ($dst)" \
|| warn "could not create the $SHORTCUT symlink in /usr/local/bin"
}

install_deb() {
Expand Down Expand Up @@ -211,6 +212,7 @@ install_deb() {
ok "${cur:+upgraded to }Red Request $tag installed (.deb)"
clear_appimage_shadow
ensure_deb_shortcut
verify_install "$(deb_binary_path)"
say "launch it from your app menu, or run: $BIN_NAME (or $SHORTCUT . to open the current folder)"
}

Expand All @@ -221,6 +223,7 @@ rc_file() {
case "${SHELL##*/}" in
zsh) printf '%s' "${ZDOTDIR:-$HOME}/.zshrc" ;;
bash) [[ -f "$HOME/.bashrc" ]] && printf '%s' "$HOME/.bashrc" || printf '%s' "$HOME/.profile" ;;
fish) printf '%s' "${XDG_CONFIG_HOME:-$HOME/.config}/fish/config.fish" ;;
*) printf '%s' "$HOME/.profile" ;;
esac
}
Expand All @@ -232,12 +235,23 @@ ensure_path() {
return 0
fi
local rc; rc="$(rc_file)"
mkdir -p "$(dirname "$rc")"
if [[ -f "$rc" ]] && grep -q '# >>> red-request >>>' "$rc"; then return 0; fi
{
printf '\n# >>> red-request >>>\n'
printf 'export PATH="%s:$PATH"\n' "$INSTALL_DIR"
printf '# <<< red-request <<<\n'
} >> "$rc"
# fish doesn't read .profile and uses its own PATH syntax — write the right one for the
# user's shell so the line actually takes effect (a bash `export` in config.fish is inert).
if [[ "${SHELL##*/}" == "fish" ]]; then
{
printf '\n# >>> red-request >>>\n'
printf 'fish_add_path %s\n' "$INSTALL_DIR"
printf '# <<< red-request <<<\n'
} >> "$rc"
else
{
printf '\n# >>> red-request >>>\n'
printf 'export PATH="%s:$PATH"\n' "$INSTALL_DIR"
printf '# <<< red-request <<<\n'
} >> "$rc"
fi
ok "added $INSTALL_DIR to PATH in $rc — open a new shell or: source $rc"
}

Expand Down Expand Up @@ -292,6 +306,7 @@ install_appimage() {
ensure_path

ok "${cur:+upgraded to }Red Request $tag → $INSTALL_DIR/$BIN_NAME"
verify_install "$INSTALL_DIR/$BIN_NAME"
say "run it: $BIN_NAME (or $SHORTCUT . to open the current folder as a project)"
}

Expand All @@ -308,6 +323,32 @@ install_gui() {
return 0
}

# Post-install sanity check: print the binary versions so a broken sidecar (e.g. a glibc-
# incompatible `red`) surfaces here, at install time, instead of as a blank window on first
# launch. $1 is the red-request binary path (it may not be on PATH in this shell yet).
verify_install() { # red_request_path
local rr="$1" red v
say "verifying…"
if [[ -x "$rr" ]]; then
# --version is headless on current builds; `timeout` guards older builds that ignore the
# flag (it would otherwise launch the GUI and hang the installer).
v="$(timeout 10 "$rr" --version 2>/dev/null | head -n1 || true)"
[[ -n "$v" ]] && ok "$v" || warn "$BIN_NAME --version produced no output (build older than this installer expects)"
else
warn "$BIN_NAME not found at $rr"
fi
# The .deb installs a standalone /usr/bin/red; the AppImage bundles it (nothing on disk).
red="$(command -v red 2>/dev/null || true)"
if [[ -n "$red" ]]; then
if v="$("$red" --version 2>&1)"; then
ok "$v"
else
warn "the embedded reddb sidecar (red) failed to run: $v"
warn "the app would open to a blank screen — re-run with --force, or report: $red --version"
fi
fi
}

main() {
detect_platform
case "$OS" in
Expand Down
26 changes: 15 additions & 11 deletions uninstall.sh
Original file line number Diff line number Diff line change
Expand Up @@ -19,25 +19,30 @@ DATA_DIR="${XDG_DATA_HOME:-$HOME/.local/share}/red-request"
DESKTOP_DIR="${XDG_DATA_HOME:-$HOME/.local/share}/applications"

removed=0
SUDO=""; [[ $EUID -ne 0 ]] && command -v sudo >/dev/null 2>&1 && SUDO="sudo"
rm_path() { [[ -e "$1" || -L "$1" ]] && rm -rf "$1" && { echo "✓ removed $1"; removed=1; }; return 0; }

# The `rr` shortcut — only if it points at our binary (don't clobber an unrelated `rr`).
# Match both forms install.sh creates: the AppImage's relative `red-request` and the
# absolute `/usr/bin/red-request` the .deb path re-points it to via clear_appimage_shadow.
if [[ -L "$INSTALL_DIR/$SHORTCUT" ]]; then
rr_tgt="$(readlink "$INSTALL_DIR/$SHORTCUT")"
if [[ "$rr_tgt" == "$BIN_NAME" || "${rr_tgt##*/}" == "$BIN_NAME" ]]; then
rm_path "$INSTALL_DIR/$SHORTCUT"
# install.sh creates it in ~/.local/bin (AppImage) or /usr/local/bin (.deb); the target is
# the AppImage's relative `red-request` or the absolute `/usr/bin/red-request` (.deb).
for sc in "$INSTALL_DIR/$SHORTCUT" "/usr/local/bin/$SHORTCUT"; do
[[ -L "$sc" ]] || continue
rr_tgt="$(readlink "$sc")"
[[ "$rr_tgt" == "$BIN_NAME" || "${rr_tgt##*/}" == "$BIN_NAME" ]] || continue
if [[ "$sc" == /usr/local/* ]]; then
$SUDO rm -f "$sc" && { echo "✓ removed $sc"; removed=1; }
else
rm_path "$sc"
fi
fi
done
rm_path "$INSTALL_DIR/$BIN_NAME"
rm_path "$INSTALL_DIR/$BIN_NAME.new" # stray temp from an interrupted upgrade
rm_path "$DATA_DIR"
rm_path "$DESKTOP_DIR/red-request.desktop"
command -v update-desktop-database >/dev/null 2>&1 && update-desktop-database "$DESKTOP_DIR" >/dev/null 2>&1 || true

# Strip the PATH block install.sh appended, from whichever rc has it.
for rc in "$HOME/.zshrc" "$HOME/.bashrc" "$HOME/.profile"; do
# Strip the PATH block install.sh appended, from whichever rc has it (incl. fish).
for rc in "$HOME/.zshrc" "$HOME/.bashrc" "$HOME/.profile" "${XDG_CONFIG_HOME:-$HOME/.config}/fish/config.fish"; do
[[ -f "$rc" ]] || continue
if grep -q '# >>> red-request >>>' "$rc"; then
tmp="$(mktemp)"
Expand All @@ -51,8 +56,7 @@ done
# deps (libwebkit2gtk-4.1-0, libgtk-3-0, …) other apps may rely on. We only remove
# the red-request package itself; its dependencies stay installed.
if command -v dpkg >/dev/null 2>&1 && dpkg -s "$BIN_NAME" >/dev/null 2>&1; then
sudo=""; [[ $EUID -ne 0 ]] && command -v sudo >/dev/null 2>&1 && sudo="sudo"
if $sudo apt-get purge -y "$BIN_NAME"; then echo "✓ removed apt package $BIN_NAME"; removed=1; fi
if $SUDO apt-get purge -y "$BIN_NAME"; then echo "✓ removed apt package $BIN_NAME"; removed=1; fi
fi

if [[ "$removed" == "1" ]]; then
Expand Down