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
2 changes: 1 addition & 1 deletion .github/workflows/ci.yml
Original file line number Diff line number Diff line change
Expand Up @@ -147,7 +147,7 @@ jobs:
- run: make ui-deps
- run: make build
# The installer from the README one-liner, against a fake GitHub Releases server
- run: make scripts-lint install-test changed-areas-test release-check-test
- run: make scripts-lint install-test changed-areas-test release-check-test desktop-deps-test

e2e:
name: Browser tests (Playwright)
Expand Down
14 changes: 11 additions & 3 deletions Makefile
Original file line number Diff line number Diff line change
Expand Up @@ -199,16 +199,20 @@ LINUX_GTK ?= gtk4
DESKTOP_TAGS := desktop embedui $(if $(filter gtk3,$(LINUX_GTK)),gtk3)
DESKTOP_BIN := $(DIST)/wapp-debugger-desktop$(EXE)

.PHONY: desktop-deps
desktop-deps: ## Check the C compiler and, on Linux, GTK and WebKitGTK; prints how to install what is missing
scripts/desktop-deps.sh $(LINUX_GTK)

.PHONY: desktop-build
desktop-build: ui-build ## Build the desktop app for the current OS (requires CGO)
desktop-build: desktop-deps ui-build ## Build the desktop app for the current OS (requires CGO)
cd server && CGO_ENABLED=1 go build -tags "$(DESKTOP_TAGS)" -trimpath -ldflags "$(LDFLAGS)" -o $(DESKTOP_BIN) ./cmd/wapp-debugger-desktop

.PHONY: icons
icons: ## Render desktop/icons/icon.svg into the PNG, ICO and ICNS icons (needs ui deps and Playwright's Chromium)
node scripts/icons.mjs

.PHONY: desktop-vet
desktop-vet: ui-build ## go vet the desktop code (with its build tags; the embedded UI must be built)
desktop-vet: desktop-deps ui-build ## go vet the desktop code (with its build tags; the embedded UI must be built)
cd server && CGO_ENABLED=1 go vet -tags "$(DESKTOP_TAGS)" ./cmd/wapp-debugger-desktop

.PHONY: desktop-selftest
Expand Down Expand Up @@ -316,14 +320,18 @@ changed-areas-test: ## Test scripts/changed-areas.sh, which CI uses to skip jobs
release-check-test: ## Test scripts/release-check.sh: no stable release with a pre-release library
scripts/release-check_test.sh

.PHONY: desktop-deps-test
desktop-deps-test: ## Test scripts/desktop-deps.sh against fake pkg-config and compilers
scripts/desktop-deps_test.sh

.PHONY: ssh-e2e
ssh-e2e: ## The viewer against a real OpenSSH server in Docker (throwaway key, no ssh-agent)
scripts/ssh-e2e.sh

.PHONY: scripts-lint
scripts-lint: ## shellcheck the shell scripts (shellcheck binary, or its Docker image)
@if command -v shellcheck >/dev/null 2>&1; then shellcheck scripts/*.sh; \
else docker run --rm -v "$(ROOT)/scripts:/s:ro" koalaman/shellcheck:v0.10.0 /s/install.sh /s/install_test.sh /s/ssh-e2e.sh /s/desktop-package.sh /s/changed-areas.sh /s/changed-areas_test.sh /s/release-check.sh /s/release-check_test.sh; fi
else docker run --rm -v "$(ROOT)/scripts:/s:ro" koalaman/shellcheck:v0.10.0 /s/install.sh /s/install_test.sh /s/ssh-e2e.sh /s/desktop-package.sh /s/changed-areas.sh /s/changed-areas_test.sh /s/release-check.sh /s/release-check_test.sh /s/desktop-deps.sh /s/desktop-deps_test.sh; fi

.PHONY: workflows-lint
workflows-lint: $(ACTIONLINT) ## Lint GitHub Actions workflows
Expand Down
2 changes: 1 addition & 1 deletion README.md
Original file line number Diff line number Diff line change
Expand Up @@ -158,7 +158,7 @@ What the desktop adds to the browser version (**Settings** in the header):
- start at login; the window comes back where it was;
- a notice in the header when a newer version is out (GitHub Releases once a day; can be switched off).

From source: `make desktop-build` (needs GTK4 + WebKitGTK 6.0 on Linux), then `dist/wapp-debugger-desktop [--logs-dir …]`; `--logs-dir` is optional here too. `make desktop-package` builds the installers of the current system; more in [desktop/README.md](desktop/README.md).
From source: `make desktop-build` (needs a C compiler and, on Linux, GTK4 + WebKitGTK 6.0; `make desktop-deps` checks them and prints how to install what is missing on your system), then `dist/wapp-debugger-desktop [--logs-dir …]`; `--logs-dir` is optional here too. `make desktop-package` builds the installers of the current system; more in [desktop/README.md](desktop/README.md).

## Docker

Expand Down
2 changes: 1 addition & 1 deletion README.ru.md
Original file line number Diff line number Diff line change
Expand Up @@ -157,7 +157,7 @@ wapp-debugger serve --logs-dir /var/www/app/tmp/logs # откройте http:/
- запуск при входе в систему; окно открывается там, где было;
- сообщение в шапке о новой версии (GitHub Releases раз в сутки; отключается).

Из исходников: `make desktop-build` (в Linux нужны GTK4 + WebKitGTK 6.0), затем `dist/wapp-debugger-desktop [--logs-dir …]`; `--logs-dir` и здесь необязателен. `make desktop-package` собирает установщики текущей системы; подробнее — в [desktop/README.md](desktop/README.md).
Из исходников: `make desktop-build` (нужен компилятор C, а в Linux ещё GTK4 + WebKitGTK 6.0; `make desktop-deps` проверяет их и подсказывает, как поставить недостающее в вашей системе), затем `dist/wapp-debugger-desktop [--logs-dir …]`; `--logs-dir` и здесь необязателен. `make desktop-package` собирает установщики текущей системы; подробнее — в [desktop/README.md](desktop/README.md).

## Docker

Expand Down
3 changes: 2 additions & 1 deletion desktop/README.md
Original file line number Diff line number Diff line change
Expand Up @@ -3,7 +3,8 @@
The desktop viewer is built with Wails v3 on top of `server/internal/*` and the same UI (`ui/`). Its entry point lives in `server/cmd/wapp-debugger-desktop` (build tag `desktop`).

```sh
make desktop-build # build for the current OS (requires CGO)
make desktop-deps # check the C compiler, GTK and WebKitGTK; prints how to install what is missing
make desktop-build # build for the current OS (requires CGO; runs desktop-deps first)
make desktop-build LINUX_GTK=gtk3 # Linux with GTK3 + WebKit2GTK 4.1 instead of GTK4
make desktop-selftest # open a window and check REST and the event stream inside Wails
make desktop-dev LOGS_DIR=/path/to/project/tmp/logs
Expand Down
158 changes: 158 additions & 0 deletions scripts/desktop-deps.sh
Original file line number Diff line number Diff line change
@@ -0,0 +1,158 @@
#!/bin/bash
# Checks what the desktop build needs from the system (a C compiler for cgo; GTK and WebKitGTK on
# Linux) and, when something is missing, prints how to install it on this system.
# Usage: desktop-deps.sh [gtk4|gtk3]. Exit 0: all there, 1: something is missing.
# Tests set DESKTOP_DEPS_OS (uname -s) and DESKTOP_DEPS_OS_RELEASE (/etc/os-release);
# PKG_CONFIG and CC are the ones cgo uses.
set -euo pipefail

gtk=${1:-gtk4}
os=${DESKTOP_DEPS_OS:-$(uname -s)}
os_release=${DESKTOP_DEPS_OS_RELEASE:-/etc/os-release}
pkg_config=${PKG_CONFIG:-pkg-config}
compiler=${CC:-$(go env CC 2>/dev/null || echo cc)}
compiler=${compiler%% *}

have() { command -v "$1" >/dev/null 2>&1; }

if ! have "$compiler"; then
case $os in
Darwin)
echo "desktop-deps: no C compiler ($compiler) for cgo; install the Xcode command line tools:"
echo " xcode-select --install"
exit 1
;;
MINGW* | MSYS* | CYGWIN* | Windows_NT)
echo "desktop-deps: no C compiler ($compiler) for cgo; install MinGW-w64 GCC, for example from MSYS2"
echo "(https://www.msys2.org/), and put its bin directory on PATH:"
echo " pacman -S mingw-w64-ucrt-x86_64-gcc"
exit 1
;;
esac
fi
case $os in Linux) ;; *) exit 0 ;; esac

# The pkg-config modules of Wails v3 (#cgo lines of github.com/wailsapp/wails/v3)
if [ "$gtk" = gtk3 ]; then
modules="gtk+-3.0 webkit2gtk-4.1 gdk-3.0 libsoup-3.0 gio-unix-2.0 glib-2.0 gobject-2.0 x11"
else
modules="gtk4 webkitgtk-6.0 libsoup-3.0 gio-unix-2.0 glib-2.0 gobject-2.0 x11"
fi

tools=()
have "$compiler" || tools+=(compiler)
missing=()
if have "$pkg_config"; then
for module in $modules; do
"$pkg_config" --exists "$module" || missing+=("$module")
done
else
# Without pkg-config nothing can be checked: the libraries go to the install command as well
tools+=(pkg-config)
read -ra missing <<<"$modules"
fi
[ ${#tools[@]} -eq 0 ] && [ ${#missing[@]} -eq 0 ] && exit 0

id='' id_like='' version_id='' pretty_name=''
if [ -r "$os_release" ]; then
# shellcheck disable=SC1090
{
read -r id
read -r id_like
read -r version_id
read -r pretty_name
} < <(. "$os_release" && printf '%s\n' "${ID:-}" "${ID_LIKE:-}" "${VERSION_ID:-}" "${PRETTY_NAME:-}")
fi
family=''
for candidate in $id $id_like; do
case $candidate in
debian | ubuntu) family=debian ;;
fedora | rhel | centos) family=fedora ;;
arch) family=arch ;;
opensuse* | suse | sles) family=suse ;;
alpine) family=alpine ;;
esac
[ -n "$family" ] && break
done

# The package that provides a pkg-config module, a compiler or pkg-config itself
package() {
case $family:$1 in
debian:compiler) echo build-essential ;;
debian:pkg-config) echo pkg-config ;;
debian:gtk4) echo libgtk-4-dev ;;
debian:webkitgtk-6.0) echo libwebkitgtk-6.0-dev ;;
debian:gtk+-3.0 | debian:gdk-3.0) echo libgtk-3-dev ;;
debian:webkit2gtk-4.1) echo libwebkit2gtk-4.1-dev ;;
debian:libsoup-3.0) echo libsoup-3.0-dev ;;
debian:gio-unix-2.0 | debian:glib-2.0 | debian:gobject-2.0) echo libglib2.0-dev ;;
debian:x11) echo libx11-dev ;;
arch:compiler) echo base-devel ;;
arch:pkg-config) echo pkgconf ;;
arch:gtk4) echo gtk4 ;;
arch:webkitgtk-6.0) echo webkitgtk-6.0 ;;
arch:gtk+-3.0 | arch:gdk-3.0) echo gtk3 ;;
arch:webkit2gtk-4.1) echo webkit2gtk-4.1 ;;
arch:libsoup-3.0) echo libsoup3 ;;
arch:gio-unix-2.0 | arch:glib-2.0 | arch:gobject-2.0) echo glib2 ;;
arch:x11) echo libx11 ;;
alpine:compiler) echo build-base ;;
alpine:pkg-config) echo pkgconf ;;
alpine:gtk4) echo gtk4.0-dev ;;
alpine:webkitgtk-6.0) echo webkit2gtk-6.0-dev ;;
alpine:gtk+-3.0 | alpine:gdk-3.0) echo gtk+3.0-dev ;;
alpine:webkit2gtk-4.1) echo webkit2gtk-4.1-dev ;;
alpine:libsoup-3.0) echo libsoup3-dev ;;
alpine:gio-unix-2.0 | alpine:glib-2.0 | alpine:gobject-2.0) echo glib-dev ;;
alpine:x11) echo libx11-dev ;;
# dnf and zypper install a package by the pkg-config module it provides
fedora:compiler | suse:compiler) echo gcc ;;
fedora:pkg-config) echo pkgconf-pkg-config ;;
suse:pkg-config) echo pkg-config ;;
*) echo "'pkgconfig($1)'" ;;
esac
}
packages() {
local item name list=()
for item in "$@"; do
name=$(package "$item")
[[ " ${list[*]} " == *" $name "* ]] || list+=("$name")
done
echo "${list[*]}"
}
install_command() {
case $family in
debian) echo "sudo apt-get install -y $(packages "$@")" ;;
fedora) echo "sudo dnf install $(packages "$@")" ;;
arch) echo "sudo pacman -S --needed $(packages "$@")" ;;
suse) echo "sudo zypper install $(packages "$@")" ;;
alpine) echo "sudo apk add $(packages "$@")" ;;
esac
}

echo "desktop-deps: the desktop build ($gtk) needs what this system does not have:"
[ ${#tools[@]} -gt 0 ] && echo " tools: ${tools[*]/compiler/a C compiler ($compiler)}"
[ ${#missing[@]} -gt 0 ] && echo " pkg-config modules: ${missing[*]}"
echo

old_release=false
if [ "$gtk" = gtk4 ] && [ -n "$version_id" ]; then
case $id in
ubuntu) [ "$(printf '%s\n' "$version_id" 24.04 | sort -V | head -1)" != 24.04 ] && old_release=true ;;
debian) [ "$(printf '%s\n' "$version_id" 13 | sort -V | head -1)" != 13 ] && old_release=true ;;
esac
fi

if [ "$old_release" = true ]; then
echo "${pretty_name:-This release} has no WebKitGTK 6.0 (it comes with Ubuntu 24.04 and Debian 13)."
echo "Build with GTK3 and WebKit2GTK 4.1 instead:"
echo " $(install_command "${tools[@]}" gtk+-3.0 webkit2gtk-4.1 libsoup-3.0 glib-2.0 x11)"
echo " make desktop-build LINUX_GTK=gtk3"
elif [ -n "$family" ]; then
echo "Install them (${pretty_name:-$id}):"
echo " $(install_command "${tools[@]}" "${missing[@]}")"
else
echo "Install the development packages that provide these pkg-config modules"
echo "(${pretty_name:-an unknown distribution}); their names differ between distributions."
fi
exit 1
92 changes: 92 additions & 0 deletions scripts/desktop-deps_test.sh
Original file line number Diff line number Diff line change
@@ -0,0 +1,92 @@
#!/bin/bash
# Tests scripts/desktop-deps.sh against fake pkg-config and compilers: make desktop-deps-test
set -euo pipefail

ROOT="$(cd "$(dirname "$0")/.." && pwd)"
WORK="$(mktemp -d)"
trap 'rm -rf "$WORK"' EXIT

# pkg-config that knows only the modules in $FAKE_PC_MODULES
cat > "$WORK/pkg-config" <<'EOF'
#!/bin/bash
[ "$1" = --exists ] && shift
for module in "$@"; do
[[ " $FAKE_PC_MODULES " == *" $module "* ]] || exit 1
done
EOF
printf '#!/bin/sh\n' > "$WORK/cc"
chmod +x "$WORK/pkg-config" "$WORK/cc"

GTK4="gtk4 webkitgtk-6.0 libsoup-3.0 gio-unix-2.0 glib-2.0 gobject-2.0 x11"
GTK3="gtk+-3.0 webkit2gtk-4.1 gdk-3.0 libsoup-3.0 gio-unix-2.0 glib-2.0 gobject-2.0 x11"

failures=0
indent() { while IFS= read -r line; do echo " $line"; done <<<"$1"; }
release() { printf 'ID=%s\nID_LIKE="%s"\nVERSION_ID="%s"\nPRETTY_NAME="%s"\n' "$1" "$2" "$3" "$4" > "$WORK/os-release"; }
# expect NAME WANT(ok|missing) OS GTK MODULES [TEXT…]: the exit code and every TEXT in the output
expect() {
local name=$1 want=$2 os=$3 gtk=$4 modules=$5 got=0 out text
shift 5
out=$(DESKTOP_DEPS_OS=$os DESKTOP_DEPS_OS_RELEASE="$WORK/os-release" FAKE_PC_MODULES=$modules \
PKG_CONFIG=${FAKE_PKG_CONFIG:-$WORK/pkg-config} CC=${FAKE_CC:-$WORK/cc} \
"$ROOT/scripts/desktop-deps.sh" "$gtk" 2>&1) || got=$?
if { [ "$want" = ok ] && [ "$got" -ne 0 ]; } || { [ "$want" = missing ] && [ "$got" -eq 0 ]; }; then
echo "FAIL $name: want $want, exit $got"
indent "$out"
failures=$((failures + 1))
return
fi
for text in "$@"; do
if ! grep -qF -- "$text" <<<"$out"; then
echo "FAIL $name: no \"$text\" in"
indent "$out"
failures=$((failures + 1))
fi
done
}

release ubuntu debian 24.04 "Ubuntu 24.04.5 LTS"
expect "everything installed" ok Linux gtk4 "$GTK4"
expect "GTK3 installed" ok Linux gtk3 "$GTK3"
expect "Ubuntu without GTK4 and WebKitGTK" missing Linux gtk4 "glib-2.0 gobject-2.0 gio-unix-2.0 libsoup-3.0 x11" \
"gtk4 webkitgtk-6.0" "Ubuntu 24.04.5 LTS" "sudo apt-get install -y libgtk-4-dev libwebkitgtk-6.0-dev"
expect "Ubuntu with GTK3" missing Linux gtk3 "glib-2.0 gobject-2.0 gio-unix-2.0 x11" \
"sudo apt-get install -y libgtk-3-dev libwebkit2gtk-4.1-dev libsoup-3.0-dev"
FAKE_PKG_CONFIG="$WORK/no-pkg-config" expect "no pkg-config" missing Linux gtk4 "" \
"pkg-config" "sudo apt-get install -y pkg-config"
FAKE_CC="$WORK/no-cc" expect "no C compiler" missing Linux gtk4 "$GTK4" "build-essential"

release ubuntu debian 22.04 "Ubuntu 22.04.4 LTS"
expect "Ubuntu 22.04 has no WebKitGTK 6.0" missing Linux gtk4 "" "LINUX_GTK=gtk3"

release debian "" 13 "Debian GNU/Linux 13 (trixie)"
expect "Debian" missing Linux gtk4 "" "sudo apt-get install -y libgtk-4-dev libwebkitgtk-6.0-dev"

release debian "" "" "Debian GNU/Linux forky/sid"
expect "Debian testing has no version" missing Linux gtk4 "" "sudo apt-get install -y libgtk-4-dev libwebkitgtk-6.0-dev"

release fedora "" 42 "Fedora Linux 42"
expect "Fedora" missing Linux gtk4 "" "sudo dnf install 'pkgconfig(gtk4)' 'pkgconfig(webkitgtk-6.0)'"

release linuxmint "ubuntu debian" 22 "Linux Mint 22"
expect "a derivative of Ubuntu" missing Linux gtk4 "" "sudo apt-get install -y libgtk-4-dev"

release arch "" "" "Arch Linux"
expect "Arch" missing Linux gtk4 "" "sudo pacman -S --needed gtk4 webkitgtk-6.0"

release opensuse-tumbleweed "opensuse suse" 20260101 "openSUSE Tumbleweed"
expect "openSUSE" missing Linux gtk4 "" "sudo zypper install 'pkgconfig(gtk4)'"

release alpine "" 3.22 "Alpine Linux v3.22"
expect "Alpine" missing Linux gtk4 "" "sudo apk add gtk4.0-dev webkit2gtk-6.0-dev"

release gentoo "" 2.17 "Gentoo Linux"
expect "an unknown distribution" missing Linux gtk4 "" "pkg-config modules" "gtk4 webkitgtk-6.0"

expect "macOS with a compiler" ok Darwin gtk4 ""
FAKE_CC="$WORK/no-cc" expect "macOS without a compiler" missing Darwin gtk4 "" "xcode-select --install"
expect "Windows with a compiler" ok MINGW64_NT-10.0-26100 gtk4 ""
FAKE_CC="$WORK/no-cc" expect "Windows without a compiler" missing MINGW64_NT-10.0-26100 gtk4 "" "MSYS2"

[ "$failures" -eq 0 ] && echo "desktop-deps: ok"
exit "$failures"
Loading