154 lines
5.3 KiB
Bash
154 lines
5.3 KiB
Bash
#!/usr/bin/env bash
|
|
# Build a Debian package for the OpenPencil Rust desktop shell + `op` CLI.
|
|
#
|
|
# Payload:
|
|
# usr/bin/openpencil-desktop editor binary
|
|
# usr/bin/op CLI binary
|
|
# usr/share/applications/openpencil.desktop
|
|
# Desktop entry with MimeType=application/x-openpencil so .op/.pen
|
|
# double-clicks route to the editor after update-desktop-database.
|
|
# usr/share/mime/packages/openpencil.xml
|
|
# shared-mime-info definition registering the .op/.pen globs.
|
|
# usr/share/icons/hicolor/1024x1024/apps/openpencil.png (+ pixmaps fallback)
|
|
# DEBIAN/control, postinst, postrm
|
|
# postinst refreshes the mime / desktop / icon caches (guarded — the
|
|
# tools are Recommends-level, absent on minimal containers).
|
|
#
|
|
# Usage:
|
|
# package-deb.sh --desktop-bin PATH --cli-bin PATH --icon PATH \
|
|
# --version X.Y.Z --arch amd64|arm64 --out-dir DIR \
|
|
# [--layout-only]
|
|
#
|
|
# --layout-only stage and print the tree without invoking dpkg-deb, so the
|
|
# layout logic can be smoke-tested on machines without dpkg
|
|
# (e.g. macOS dev boxes). CI always does the full build.
|
|
#
|
|
# Output: <out-dir>/OpenPencil-<version>-<x64|arm64>-linux.deb
|
|
# (filename matches electron-builder's artifactName pattern
|
|
# `${productName}-${version}-${arch}-linux.${ext}`; the Debian *control*
|
|
# Architecture field still uses proper dpkg arch names amd64/arm64).
|
|
|
|
set -euo pipefail
|
|
|
|
SCRIPT_DIR="$(cd "$(dirname "${BASH_SOURCE[0]}")" && pwd)"
|
|
# shellcheck source=package-linux-common.sh
|
|
source "$SCRIPT_DIR/package-linux-common.sh"
|
|
|
|
DESKTOP_BIN="" CLI_BIN="" ICON_PNG="" VERSION="" DEB_ARCH="" OUT_DIR=""
|
|
LAYOUT_ONLY=0
|
|
|
|
usage() {
|
|
sed -n '2,28p' "${BASH_SOURCE[0]}" | sed 's/^# \{0,1\}//'
|
|
exit "${1:-1}"
|
|
}
|
|
|
|
while [ $# -gt 0 ]; do
|
|
case "$1" in
|
|
--desktop-bin) DESKTOP_BIN="$2"; shift 2 ;;
|
|
--cli-bin) CLI_BIN="$2"; shift 2 ;;
|
|
--icon) ICON_PNG="$2"; shift 2 ;;
|
|
--version) VERSION="$2"; shift 2 ;;
|
|
--arch) DEB_ARCH="$2"; shift 2 ;;
|
|
--out-dir) OUT_DIR="$2"; shift 2 ;;
|
|
--layout-only) LAYOUT_ONLY=1; shift ;;
|
|
-h|--help) usage 0 ;;
|
|
*) echo "error: unknown argument '$1'" >&2; usage ;;
|
|
esac
|
|
done
|
|
|
|
for req in DESKTOP_BIN CLI_BIN ICON_PNG VERSION DEB_ARCH OUT_DIR; do
|
|
if [ -z "${!req}" ]; then
|
|
echo "error: --$(echo "$req" | tr '[:upper:]_' '[:lower:]-') is required" >&2
|
|
usage
|
|
fi
|
|
done
|
|
for f in "$DESKTOP_BIN" "$CLI_BIN" "$ICON_PNG"; do
|
|
[ -f "$f" ] || { echo "error: input file not found: $f" >&2; exit 1; }
|
|
done
|
|
case "$DEB_ARCH" in
|
|
amd64 | arm64) ;;
|
|
*) echo "error: --arch must be amd64 or arm64 (got '$DEB_ARCH')" >&2; exit 1 ;;
|
|
esac
|
|
|
|
ARTIFACT_ARCH="$(op_artifact_arch "$DEB_ARCH")"
|
|
STAGE="$(mktemp -d)"
|
|
trap 'rm -rf "$STAGE"' EXIT
|
|
|
|
echo "==> staging payload tree"
|
|
op_install_usr_tree "$STAGE" "$DESKTOP_BIN" "$CLI_BIN" "$ICON_PNG"
|
|
|
|
echo "==> writing DEBIAN/ metadata"
|
|
mkdir -p "$STAGE/DEBIAN"
|
|
|
|
# Installed-Size is in KiB of the payload (excludes DEBIAN/).
|
|
INSTALLED_SIZE="$(du -sk "$STAGE/usr" | cut -f1)"
|
|
|
|
cat > "$STAGE/DEBIAN/control" <<EOF
|
|
Package: openpencil
|
|
Version: $VERSION
|
|
Section: graphics
|
|
Priority: optional
|
|
Architecture: $DEB_ARCH
|
|
Maintainer: ZSeven-W <fini.yang@gmail.com>
|
|
Installed-Size: $INSTALLED_SIZE
|
|
Depends: libc6, libfontconfig1, libfreetype6, libegl1, libgles2, libgbm1, libxkbcommon0, libxkbcommon-x11-0, libwayland-client0
|
|
Recommends: shared-mime-info, desktop-file-utils
|
|
Homepage: https://github.com/ZSeven-W/openpencil
|
|
Description: OpenPencil — open-source AI-native vector design tool
|
|
Native desktop editor (openpencil-desktop) built on the Rust shell, plus
|
|
the op command-line client that drives the editor over MCP.
|
|
Registers the application/x-openpencil MIME type for .op and .pen files.
|
|
EOF
|
|
|
|
cat > "$STAGE/DEBIAN/postinst" <<'EOF'
|
|
#!/bin/sh
|
|
set -e
|
|
# Refresh caches so the .op/.pen association is live immediately. Each tool
|
|
# is optional (Recommends), so guard and never fail the install on them.
|
|
if command -v update-mime-database >/dev/null 2>&1; then
|
|
update-mime-database /usr/share/mime || true
|
|
fi
|
|
if command -v update-desktop-database >/dev/null 2>&1; then
|
|
update-desktop-database /usr/share/applications || true
|
|
fi
|
|
if command -v gtk-update-icon-cache >/dev/null 2>&1; then
|
|
gtk-update-icon-cache -q /usr/share/icons/hicolor || true
|
|
fi
|
|
exit 0
|
|
EOF
|
|
|
|
cat > "$STAGE/DEBIAN/postrm" <<'EOF'
|
|
#!/bin/sh
|
|
set -e
|
|
if command -v update-mime-database >/dev/null 2>&1; then
|
|
update-mime-database /usr/share/mime || true
|
|
fi
|
|
if command -v update-desktop-database >/dev/null 2>&1; then
|
|
update-desktop-database /usr/share/applications || true
|
|
fi
|
|
exit 0
|
|
EOF
|
|
|
|
chmod 755 "$STAGE/DEBIAN/postinst" "$STAGE/DEBIAN/postrm"
|
|
|
|
if [ "$LAYOUT_ONLY" = 1 ]; then
|
|
echo "==> layout-only mode: staged tree"
|
|
(cd "$STAGE" && find . \( -type f -o -type l \) | sort)
|
|
echo "==> DEBIAN/control"
|
|
cat "$STAGE/DEBIAN/control"
|
|
exit 0
|
|
fi
|
|
|
|
command -v dpkg-deb >/dev/null 2>&1 || {
|
|
echo "error: dpkg-deb not found — run on a Debian/Ubuntu host or pass --layout-only" >&2
|
|
exit 1
|
|
}
|
|
|
|
mkdir -p "$OUT_DIR"
|
|
DEB_PATH="$OUT_DIR/OpenPencil-$VERSION-$ARTIFACT_ARCH-linux.deb"
|
|
echo "==> dpkg-deb build"
|
|
# --root-owner-group: payload owned by root:root without needing fakeroot
|
|
# (dpkg-deb >= 1.19; Ubuntu 24.04 runners ship 1.22).
|
|
dpkg-deb --build --root-owner-group "$STAGE" "$DEB_PATH"
|
|
echo "Package ready: $DEB_PATH"
|