# Copyright 2026 Gentoo Authors # Distributed under the terms of the GNU General Public License v2 EAPI=8 inherit desktop xdg MY_PN="${PN/-bin/}" # Canary version: PV=2026.3.20.913 → upstream tag v2026.3.20-canary.913 # PV format: YYYY.M.D.BUILD (Portage-compatible flattening of YYYY.M.D-canary.BUILD) CANARY_VER="${PV%.*}-canary.${PV##*.}" DESCRIPTION="AFFiNE Canary - Bleeding-edge knowledge base (docs, whiteboards, databases)" HOMEPAGE="https://affine.pro https://github.com/toeverything/AFFiNE" SRC_URI="https://github.com/toeverything/AFFiNE/releases/download/v${CANARY_VER}/affine-${CANARY_VER}-canary-linux-x64.appimage" S="${WORKDIR}" LICENSE="MIT" SLOT="0" KEYWORDS="~amd64" RESTRICT="mirror strip bindist" RDEPEND=" >=app-accessibility/at-spi2-core-2.46.0:2 dev-libs/expat dev-libs/glib:2 dev-libs/nspr dev-libs/nss media-libs/alsa-lib media-libs/mesa sys-apps/dbus x11-libs/cairo x11-libs/gtk+:3 x11-libs/libdrm x11-libs/libX11 x11-libs/libxcb x11-libs/libXcomposite x11-libs/libXdamage x11-libs/libXext x11-libs/libXfixes x11-libs/libxkbcommon x11-libs/libXrandr x11-libs/pango x11-misc/xdg-utils " QA_PREBUILT="*" # Install path: /opt/affine-canary/ (separate from stable to allow CI to build both) AFFINE_HOME="/opt/${MY_PN}" src_unpack() { cp "${DISTDIR}/affine-${CANARY_VER}-canary-linux-x64.appimage" "${S}/${MY_PN}.AppImage" || die chmod +x "${S}/${MY_PN}.AppImage" || die "${S}/${MY_PN}.AppImage" --appimage-extract >/dev/null 2>&1 || die "AppImage extraction failed" rm "${S}/${MY_PN}.AppImage" || die } src_prepare() { default } src_install() { # Use cp -r (like windsurf-bin) to preserve native permissions from AppImage. mkdir -p "${ED}${AFFINE_HOME}" || die cp -rT squashfs-root "${ED}${AFFINE_HOME}" || die # Chrome sandbox: setuid root with restricted permissions (Electron requires this) fperms 4755 "${AFFINE_HOME}/usr/lib/affine-electron/chrome-sandbox" # Wrapper symlink → /usr/bin/affine-canary dosym "${AFFINE_HOME}/usr/bin/AFFiNE-canary" /usr/bin/${MY_PN} # Desktop file (renamed to avoid collision with stable) local desktop_file for desktop_file in squashfs-root/AFFiNE-canary.desktop squashfs-root/AFFiNE.desktop squashfs-root/affine-electron.desktop; do if [[ -f "${desktop_file}" ]]; then sed -i \ -e "s|Exec=.*|Exec=${MY_PN} %U|g" \ -e "s|Icon=.*|Icon=${MY_PN}|g" \ -e "s|Name=.*|Name=AFFiNE Canary|g" \ "${desktop_file}" || die newmenu "${desktop_file}" ${MY_PN}.desktop break fi done # Icons from hicolor theme (renamed to affine-canary.png) local size icon_path for size in 16 32 48 64 128 256 512 1024; do for icon_path in \ squashfs-root/usr/share/icons/hicolor/${size}x${size}/apps/affine-electron.png; do if [[ -f "${icon_path}" ]]; then newicon -s ${size} "${icon_path}" ${MY_PN}.png break fi done done # Fallback pixmap (root icon may be a symlink, dereference it) if [[ -e squashfs-root/affine-electron.png ]]; then newicon "$(realpath squashfs-root/affine-electron.png)" ${MY_PN}.png fi } pkg_postinst() { xdg_pkg_postinst # Chrome sandbox setuid must be applied here (runs as root). # fperms in src_install runs as portage user → kernel silently drops setuid. chmod 4755 /opt/affine-canary/usr/lib/affine-electron/chrome-sandbox 2>/dev/null elog "AFFiNE Canary has been installed to ${AFFINE_HOME}" elog "" elog "To launch: affine-canary" elog "" elog "WARNING: This is the canary (bleeding-edge) channel." elog "It may contain bugs and breaking changes." elog "For stability, use app-office/affine-bin instead." elog "" elog "Upstream: https://affine.pro" }