mirror of
https://github.com/mileswolfallen2/gelectron.git
synced 2026-09-08 12:43:16 +00:00
feat: enhance native binary resolution and add bundled Node.js runtime
- Refactored gelectron.js to improve native binary discovery with additional paths and environment variable support. - Implemented a function to find the Node.js runtime, allowing bundled Node.js to be used when available. - Updated package.json to include gelectron-packager as a CLI command. - Enhanced gelectron-packager.js to locate installed gelectron runtime and added compatibility for bundled Node.js. - Modified install-release.sh to download and install a private Node.js runtime alongside the gelectron binary. - Updated NSIS installer script to include bundled Node.js runtime. - Enhanced AppImage and DMG packaging scripts to include Node.js runtime. - Added clipboard, nativeTheme, and screen modules for Electron compatibility. - Implemented native bridge request handling for clipboard operations.
This commit is contained in:
@@ -80,8 +80,10 @@ esac
|
||||
if [[ "$UNINSTALL" == "1" ]]; then
|
||||
rm -f "$PREFIX/gelectron"
|
||||
rm -f "$PREFIX/gelectron.exe"
|
||||
rm -f "$PREFIX/node"
|
||||
rm -f "$PREFIX/node.exe"
|
||||
rm -rf "$PREFIX/compat"
|
||||
echo "Removed $PREFIX/gelectron and $PREFIX/compat"
|
||||
echo "Removed $PREFIX/gelectron, $PREFIX/node and $PREFIX/compat"
|
||||
exit 0
|
||||
fi
|
||||
|
||||
@@ -145,6 +147,37 @@ if [[ -d "$STAGE/compat" ]]; then
|
||||
install -m 644 "$STAGE"/compat/*.js "$PREFIX/compat/"
|
||||
fi
|
||||
|
||||
# Download a private Node.js runtime next to the binary so `gelectron <app>`
|
||||
# works on machines that don't have Node installed. The binary's runtime
|
||||
# resolution checks its own directory first, so this private copy wins.
|
||||
NODE_VERSION="20.18.1"
|
||||
NODE_INSTALLED="$PREFIX/node"
|
||||
if [[ "$PLATFORM" == "win32" ]]; then NODE_INSTALLED="$PREFIX/node.exe"; fi
|
||||
if [[ ! -x "$NODE_INSTALLED" ]]; then
|
||||
echo "==> Installing private Node.js v$NODE_VERSION ..."
|
||||
case "$PLATFORM-$ARCH" in
|
||||
darwin-*) NODE_PLATFORM="darwin-$ARCH"; NODE_EXT="tar.gz" ;;
|
||||
linux-*) NODE_PLATFORM="linux-$ARCH"; NODE_EXT="tar.xz" ;;
|
||||
win32-*) NODE_PLATFORM="win-$ARCH"; NODE_EXT="zip" ;;
|
||||
esac
|
||||
NODE_URL="https://nodejs.org/dist/v${NODE_VERSION}/node-v${NODE_VERSION}-${NODE_PLATFORM}.${NODE_EXT}"
|
||||
NODE_ARCHIVE="$(mktemp /tmp/gelectron-node.XXXXXX.${NODE_EXT})"
|
||||
curl -fsSL -L "$NODE_URL" -o "$NODE_ARCHIVE"
|
||||
NODE_STAGE="$(mktemp -d "${TMPDIR:-/tmp}/gelectron-node-stage.XXXXXX")"
|
||||
case "$NODE_EXT" in
|
||||
zip) unzip -qo "$NODE_ARCHIVE" -d "$NODE_STAGE" ;;
|
||||
tar.gz) tar -xzf "$NODE_ARCHIVE" -C "$NODE_STAGE" ;;
|
||||
tar.xz) tar -xJf "$NODE_ARCHIVE" -C "$NODE_STAGE" ;;
|
||||
esac
|
||||
NODE_BIN="$(find "$NODE_STAGE" -type f \( -name 'node.exe' -o -name 'node' \) | head -n1)"
|
||||
if [[ -n "$NODE_BIN" ]]; then
|
||||
install -m 755 "$NODE_BIN" "$NODE_INSTALLED"
|
||||
else
|
||||
echo " warning: could not install private Node.js — apps will require a system Node" >&2
|
||||
fi
|
||||
rm -rf "$NODE_STAGE" "$NODE_ARCHIVE"
|
||||
fi
|
||||
|
||||
# Downloaded-from-GitHub binaries carry a quarantine attribute on macOS and
|
||||
# Gatekeeper will block the first launch. Clear it — the binary is ad-hoc
|
||||
# signed, so this is the only thing standing in the way.
|
||||
|
||||
@@ -49,12 +49,14 @@ Section "Install"
|
||||
SetOutPath "$INSTDIR"
|
||||
|
||||
File "gelectron.exe"
|
||||
; Bundled Node.js runtime so packaged apps run with no system Node install
|
||||
File "node.exe"
|
||||
File /r "compat"
|
||||
|
||||
WriteUninstaller "$INSTDIR\Uninstall.exe"
|
||||
|
||||
CreateDirectory "$SMPROGRAMS\${APPNAME}"
|
||||
CreateShortcut "$SMPROGRAMS\${APPNAME}\${APPNAME}.lnk" "$INSTDIR\gelectron.exe"
|
||||
CreateShortcut "$SMPROGRAMS\${APPNAME}\${APPNAME} CLI.lnk" "$INSTDIR\gelectron.exe"
|
||||
|
||||
WriteRegStr HKLM "${UNINST_KEY}" "DisplayName" "${APPNAME}"
|
||||
WriteRegStr HKLM "${UNINST_KEY}" "DisplayVersion" "${VERSION}"
|
||||
@@ -80,7 +82,7 @@ Section "Uninstall"
|
||||
WriteRegExpandStr ${ENV_KEY} "Path" $1
|
||||
SendMessage ${HWND_BROADCAST} ${WM_SETTINGCHANGE} 0 "STR:Environment"
|
||||
|
||||
Delete "$SMPROGRAMS\${APPNAME}\${APPNAME}.lnk"
|
||||
Delete "$SMPROGRAMS\${APPNAME}\${APPNAME} CLI.lnk"
|
||||
RMDir "$SMPROGRAMS\${APPNAME}"
|
||||
|
||||
DeleteRegKey HKLM "${UNINST_KEY}"
|
||||
|
||||
@@ -4,12 +4,13 @@
|
||||
# and a Node.js runtime into a single self-contained, downloadable AppImage.
|
||||
#
|
||||
# Gelectron-<version>-x86_64.AppImage
|
||||
# Gelectron-<version>-aarch64.AppImage
|
||||
#
|
||||
# Requires: the gelectron binary (built against webkit2gtk-4.1), compat layer,
|
||||
# and network access (downloads Node.js + appimagetool).
|
||||
#
|
||||
# Usage:
|
||||
# scripts/pkg/make-appimage.sh -v VERSION [--binary PATH] [--compat DIR] [-o DIR]
|
||||
# scripts/pkg/make-appimage.sh -v VERSION [--binary PATH] [--compat DIR] [-o DIR] [-a ARCH]
|
||||
|
||||
set -euo pipefail
|
||||
|
||||
@@ -20,19 +21,21 @@ VERSION=""
|
||||
BINARY=""
|
||||
COMPAT="$REPO_DIR/src/electron"
|
||||
OUT_DIR="$REPO_DIR/dist"
|
||||
ARCH="x64"
|
||||
|
||||
usage() {
|
||||
cat <<'EOF'
|
||||
Linux AppImage builder
|
||||
|
||||
Usage:
|
||||
scripts/pkg/make-appimage.sh -v VERSION [--binary PATH] [--compat DIR] [-o DIR]
|
||||
scripts/pkg/make-appimage.sh -v VERSION [--binary PATH] [--compat DIR] [-o DIR] [-a ARCH]
|
||||
|
||||
Options:
|
||||
-v, --version VER Version string (e.g. 0.1.1)
|
||||
-b, --binary PATH Path to the gelectron binary
|
||||
-c, --compat DIR Path to the compat layer (default: <repo>/src/electron)
|
||||
-o, --out DIR Output directory (default: <repo>/dist)
|
||||
-a, --arch ARCH x64 | arm64 (default: x64)
|
||||
-h, --help Show this help
|
||||
EOF
|
||||
}
|
||||
@@ -43,6 +46,7 @@ while [[ $# -gt 0 ]]; do
|
||||
-b|--binary) BINARY="${2:-}"; shift 2 ;;
|
||||
-c|--compat) COMPAT="${2:-}"; shift 2 ;;
|
||||
-o|--out) OUT_DIR="${2:-}"; shift 2 ;;
|
||||
-a|--arch) ARCH="${2:-}"; shift 2 ;;
|
||||
-h|--help) usage; exit 0 ;;
|
||||
*) echo "error: unknown option: $1" >&2; usage; exit 1 ;;
|
||||
esac
|
||||
@@ -50,12 +54,22 @@ done
|
||||
|
||||
VERSION="${VERSION#v}"
|
||||
[[ -n "$VERSION" ]] || { echo "error: --version required" >&2; exit 1; }
|
||||
case "$ARCH" in x64|arm64) ;; *) echo "error: unsupported arch: $ARCH" >&2; exit 1 ;; esac
|
||||
if [[ -z "$BINARY" ]]; then
|
||||
BINARY="$REPO_DIR/target/release/gelectron"
|
||||
fi
|
||||
[[ -f "$BINARY" ]] || { echo "error: binary not found: $BINARY" >&2; exit 1; }
|
||||
[[ -d "$COMPAT" ]] || { echo "error: compat dir not found: $COMPAT" >&2; exit 1; }
|
||||
|
||||
# Map to appimg / node arch naming
|
||||
if [[ "$ARCH" == "arm64" ]]; then
|
||||
NODE_ARCH="arm64"
|
||||
TARGET_ARCH="aarch64"
|
||||
else
|
||||
NODE_ARCH="x64"
|
||||
TARGET_ARCH="x86_64"
|
||||
fi
|
||||
|
||||
log() { echo "==> $*"; }
|
||||
|
||||
STAGE="$(mktemp -d "${TMPDIR:-/tmp}/gelectron-appimage.XXXXXX")"
|
||||
@@ -76,17 +90,16 @@ install -m 644 "$COMPAT"/*.js "$APPDIR/usr/bin/compat/"
|
||||
# Node.js runtime (gelectron's Node mode requires node on PATH)
|
||||
NODE_DIR="$STAGE/node"
|
||||
if [[ ! -d "$NODE_DIR" ]]; then
|
||||
log "Downloading Node.js v$NODE_VERSION..."
|
||||
log "Downloading Node.js v$NODE_VERSION ($NODE_ARCH)..."
|
||||
mkdir -p "$NODE_DIR"
|
||||
NODE_ARCHIVE="$STAGE/node.tar.xz"
|
||||
curl -fsSL "https://nodejs.org/dist/v${NODE_VERSION}/node-v${NODE_VERSION}-linux-x64.tar.xz" -o "$NODE_ARCHIVE"
|
||||
curl -fsSL "https://nodejs.org/dist/v${NODE_VERSION}/node-v${NODE_VERSION}-linux-${NODE_ARCH}.tar.xz" -o "$NODE_ARCHIVE"
|
||||
tar -xJf "$NODE_ARCHIVE" -C "$NODE_DIR"
|
||||
fi
|
||||
install -m 755 "$NODE_DIR"/node-v${NODE_VERSION}-linux-x64/bin/node "$APPDIR/usr/bin/node"
|
||||
install -m 644 "$NODE_DIR"/node-v${NODE_VERSION}-linux-x64/lib/libnode.so* "$APPDIR/usr/lib/" 2>/dev/null || true
|
||||
install -m 755 "$NODE_DIR"/node-v${NODE_VERSION}-linux-${NODE_ARCH}/bin/node "$APPDIR/usr/bin/node"
|
||||
|
||||
mkdir -p "$APPDIR/usr/lib"
|
||||
cp "$NODE_DIR"/node-v${NODE_VERSION}-linux-x64/lib/libnode.so* "$APPDIR/usr/lib/" 2>/dev/null || true
|
||||
cp "$NODE_DIR"/node-v${NODE_VERSION}-linux-${NODE_ARCH}/lib/libnode.so* "$APPDIR/usr/lib/" 2>/dev/null || true
|
||||
|
||||
# ── AppImage metadata ───────────────────────────────────────────────────────
|
||||
|
||||
@@ -119,19 +132,19 @@ fi
|
||||
|
||||
TOOL="$STAGE/appimagetool"
|
||||
if [[ ! -f "$TOOL" ]]; then
|
||||
log "Downloading appimagetool..."
|
||||
curl -fsSL "https://github.com/AppImage/appimagetool/releases/download/continuous/appimagetool-x86_64.AppImage" -o "$TOOL"
|
||||
log "Downloading appimagetool ($TARGET_ARCH)..."
|
||||
curl -fsSL "https://github.com/AppImage/appimagetool/releases/download/continuous/appimagetool-${TARGET_ARCH}.AppImage" -o "$TOOL"
|
||||
fi
|
||||
chmod +x "$TOOL"
|
||||
|
||||
# ── Build ───────────────────────────────────────────────────────────────────
|
||||
|
||||
mkdir -p "$OUT_DIR"
|
||||
APPIMAGE_NAME="Gelectron-$VERSION-x86_64.AppImage"
|
||||
APPIMAGE_NAME="Gelectron-$VERSION-$TARGET_ARCH.AppImage"
|
||||
APPIMAGE_PATH="$OUT_DIR/$APPIMAGE_NAME"
|
||||
|
||||
export VERSION="$VERSION"
|
||||
export ARCH="x86_64"
|
||||
export ARCH="$TARGET_ARCH"
|
||||
# Run appimagetool without FUSE (Ubuntu 24.04+ runners don't ship libfuse2)
|
||||
export APPIMAGE_EXTRACT_AND_RUN=1
|
||||
log "Creating $APPIMAGE_NAME ..."
|
||||
|
||||
+37
-7
@@ -1,7 +1,11 @@
|
||||
#!/usr/bin/env bash
|
||||
#
|
||||
# Build the macOS installer: a .pkg (installs the gelectron runtime +
|
||||
# compat layer to /usr/local/bin) wrapped in a .dmg for distribution.
|
||||
# Build the macOS installer: a .pkg wrapped in a .dmg for distribution.
|
||||
#
|
||||
# The package is fully self-contained — it installs the gelectron runtime, the
|
||||
# Electron compatibility layer AND a private Node.js runtime into
|
||||
# /usr/local/lib/gelectron and symlinks gelectron into /usr/local/bin. Apps run
|
||||
# with `gelectron <app>` with no other runtime installed on the machine.
|
||||
#
|
||||
# Gelectron-<version>-<arch>.dmg
|
||||
# └── Install gelectron.pkg (double-click, runs macOS Installer as root)
|
||||
@@ -18,6 +22,7 @@ ARCH=""
|
||||
BINARY=""
|
||||
COMPAT="$REPO_DIR/src/electron"
|
||||
OUT_DIR="$REPO_DIR/dist"
|
||||
NODE_VERSION="20.18.1"
|
||||
|
||||
usage() {
|
||||
cat <<'EOF'
|
||||
@@ -64,9 +69,9 @@ log() { echo "==> $*"; }
|
||||
STAGE="$(mktemp -d "${TMPDIR:-/tmp}/gelectron-dmg.XXXXXX")"
|
||||
trap 'rm -rf "$STAGE"' EXIT
|
||||
|
||||
# ── Payload root (what pkgbuild installs into /usr/local/bin) ─────────────
|
||||
# ── Payload root: what pkgbuild installs into /usr/local/lib/gelectron ─────
|
||||
|
||||
PAYLOAD="$STAGE/gelectron"
|
||||
PAYLOAD="$STAGE/payload/usr/local/lib/gelectron"
|
||||
mkdir -p "$PAYLOAD"
|
||||
|
||||
log "Staging payload..."
|
||||
@@ -74,21 +79,46 @@ install -m 755 "$BINARY" "$PAYLOAD/gelectron"
|
||||
mkdir -p "$PAYLOAD/compat"
|
||||
install -m 644 "$COMPAT"/*.js "$PAYLOAD/compat/"
|
||||
|
||||
# Private Node.js runtime so the installed CLI works with no system Node
|
||||
NODE_ARCH="$( [[ "$ARCH" == "arm64" ]] && echo arm64 || echo x64 )"
|
||||
NODE_ARCHIVE="$STAGE/node.tar.gz"
|
||||
if [[ ! -f "$NODE_ARCHIVE" ]]; then
|
||||
log "Downloading Node.js v$NODE_VERSION..."
|
||||
curl -fsSL "https://nodejs.org/dist/v${NODE_VERSION}/node-v${NODE_VERSION}-darwin-${NODE_ARCH}.tar.gz" -o "$NODE_ARCHIVE"
|
||||
fi
|
||||
log "Extracting Node.js..."
|
||||
mkdir -p "$STAGE/node"
|
||||
tar -xzf "$NODE_ARCHIVE" -C "$STAGE/node"
|
||||
install -m 755 "$STAGE/node"/node-v${NODE_VERSION}-darwin-${NODE_ARCH}/bin/node "$PAYLOAD/node"
|
||||
|
||||
if command -v codesign >/dev/null 2>&1; then
|
||||
log "Ad-hoc signing binary..."
|
||||
codesign --force --sign - "$PAYLOAD/gelectron" 2>/dev/null || echo " (warning: codesign failed)"
|
||||
fi
|
||||
|
||||
# ── Postinstall script: symlink /usr/local/bin/gelectron → runtime ─────────
|
||||
|
||||
SCRIPTS="$STAGE/scripts"
|
||||
mkdir -p "$SCRIPTS"
|
||||
cat > "$SCRIPTS/postinstall" <<'EOF'
|
||||
#!/bin/bash
|
||||
set -e
|
||||
ln -sf /usr/local/lib/gelectron/gelectron /usr/local/bin/gelectron
|
||||
exit 0
|
||||
EOF
|
||||
chmod +x "$SCRIPTS/postinstall"
|
||||
|
||||
# ── Component package ───────────────────────────────────────────────────────
|
||||
|
||||
PKG="$STAGE/Install gelectron.pkg"
|
||||
log "Building package (installs to /usr/local/bin)..."
|
||||
log "Building package (installs to /usr/local/lib/gelectron)..."
|
||||
pkgbuild \
|
||||
--root "$PAYLOAD" \
|
||||
--root "$STAGE/payload" \
|
||||
--scripts "$SCRIPTS" \
|
||||
--identifier "com.gelectron.runtime.$ARCH" \
|
||||
--version "$VERSION" \
|
||||
--ownership recommended \
|
||||
--install-location /usr/local/bin \
|
||||
--install-location / \
|
||||
"$PKG"
|
||||
|
||||
# ── DMG ────────────────────────────────────────────────────────────────────
|
||||
|
||||
@@ -1,6 +1,7 @@
|
||||
# Gelectron Windows installer builder (NSIS)
|
||||
#
|
||||
# Stages the payload and compiles the installer EXE with makensis:
|
||||
# Stages the payload (gelectron runtime + bundled Node.js + compat layer) and
|
||||
# compiles the installer EXE with makensis:
|
||||
# Gelectron-<version>-<arch>.exe
|
||||
#
|
||||
# Usage:
|
||||
@@ -17,7 +18,8 @@ param(
|
||||
[Parameter(Mandatory = $true)][string]$Version,
|
||||
[string]$Arch = "x64",
|
||||
[string]$Out = "dist",
|
||||
[string]$NsiPath = "scripts/pkg/gelectron.nsi"
|
||||
[string]$NsiPath = "scripts/pkg/gelectron.nsi",
|
||||
[string]$NodeVersion = "20.18.1"
|
||||
)
|
||||
|
||||
$ErrorActionPreference = "Stop"
|
||||
@@ -35,6 +37,19 @@ try {
|
||||
Copy-Item -Recurse -Force $Compat (Join-Path $Stage "compat")
|
||||
Copy-Item $NsiPath (Join-Path $Stage "gelectron.nsi") -Force
|
||||
|
||||
# Bundled Node.js runtime so the installed CLI works with no system Node.
|
||||
$NodeArch = if ($Arch -eq "arm64") { "arm64" } else { "x64" }
|
||||
$NodeArchive = Join-Path $Stage "node.zip"
|
||||
$NodeUrl = "https://nodejs.org/dist/v$NodeVersion/node-v$NodeVersion-win-$NodeArch.zip"
|
||||
Write-Host "==> Downloading Node.js v$NodeVersion ($NodeArch)..."
|
||||
Invoke-WebRequest -Uri $NodeUrl -OutFile $NodeArchive -UseBasicParsing
|
||||
|
||||
$NodeExtract = Join-Path $Stage "node"
|
||||
Expand-Archive -Path $NodeArchive -DestinationPath $NodeExtract -Force
|
||||
$NodeExe = Get-ChildItem $NodeExtract -Recurse -Filter node.exe | Select-Object -First 1
|
||||
if (-not $NodeExe) { throw "node.exe not found in Node.js archive" }
|
||||
Copy-Item $NodeExe.FullName (Join-Path $Stage "node.exe") -Force
|
||||
|
||||
Write-Host "==> Compiling installer (makensis)..."
|
||||
Push-Location $Stage
|
||||
try {
|
||||
|
||||
Reference in New Issue
Block a user