170 lines
3.8 KiB
Bash
170 lines
3.8 KiB
Bash
#!/bin/bash
|
|
#
|
|
# Build script for Path Juggler
|
|
# Creates a standalone macOS .app bundle with ad-hoc code signing
|
|
#
|
|
|
|
set -e
|
|
|
|
SCRIPT_DIR="$(cd "$(dirname "$0")" && pwd)"
|
|
APP_NAME="Path Juggler"
|
|
BUNDLE_ID="com.pathjuggler.app"
|
|
VENV_DIR="$SCRIPT_DIR/.build_venv"
|
|
DIST_DIR="$SCRIPT_DIR/dist"
|
|
|
|
echo "=== Path Juggler - Build Script ==="
|
|
echo ""
|
|
|
|
# Check for Python 3
|
|
if ! command -v python3 &> /dev/null; then
|
|
echo "Error: python3 is required but not found"
|
|
exit 1
|
|
fi
|
|
|
|
PYTHON_VERSION=$(python3 -c 'import sys; print(f"{sys.version_info.major}.{sys.version_info.minor}")')
|
|
echo "Using Python $PYTHON_VERSION"
|
|
|
|
# Create virtual environment
|
|
echo ""
|
|
echo "=== Creating virtual environment ==="
|
|
if [ -d "$VENV_DIR" ]; then
|
|
echo "Removing existing build environment..."
|
|
rm -rf "$VENV_DIR"
|
|
fi
|
|
|
|
python3 -m venv "$VENV_DIR"
|
|
source "$VENV_DIR/bin/activate"
|
|
|
|
# Upgrade pip
|
|
echo ""
|
|
echo "=== Installing build dependencies ==="
|
|
pip install --upgrade pip --quiet
|
|
pip install pyinstaller watchdog --quiet
|
|
|
|
echo "Installed:"
|
|
pip list | grep -E "(pyinstaller|watchdog)"
|
|
|
|
# Create PyInstaller spec file for more control
|
|
echo ""
|
|
echo "=== Creating build configuration ==="
|
|
|
|
cat > "$SCRIPT_DIR/path_juggler.spec" << 'SPEC'
|
|
# -*- mode: python ; coding: utf-8 -*-
|
|
|
|
import sys
|
|
from pathlib import Path
|
|
|
|
block_cipher = None
|
|
|
|
a = Analysis(
|
|
['path_juggler_gui.py'],
|
|
pathex=[],
|
|
binaries=[],
|
|
datas=[],
|
|
hiddenimports=[
|
|
'watchdog.observers',
|
|
'watchdog.observers.fsevents',
|
|
'watchdog.events',
|
|
],
|
|
hookspath=[],
|
|
hooksconfig={},
|
|
runtime_hooks=[],
|
|
excludes=[],
|
|
win_no_prefer_redirects=False,
|
|
win_private_assemblies=False,
|
|
cipher=block_cipher,
|
|
noarchive=False,
|
|
)
|
|
|
|
pyz = PYZ(a.pure, a.zipped_data, cipher=block_cipher)
|
|
|
|
exe = EXE(
|
|
pyz,
|
|
a.scripts,
|
|
[],
|
|
exclude_binaries=True,
|
|
name='Path Juggler',
|
|
debug=False,
|
|
bootloader_ignore_signals=False,
|
|
strip=False,
|
|
upx=True,
|
|
console=False, # No terminal window
|
|
disable_windowed_traceback=False,
|
|
argv_emulation=True, # Important for macOS
|
|
target_arch=None,
|
|
codesign_identity=None,
|
|
entitlements_file=None,
|
|
)
|
|
|
|
coll = COLLECT(
|
|
exe,
|
|
a.binaries,
|
|
a.zipfiles,
|
|
a.datas,
|
|
strip=False,
|
|
upx=True,
|
|
upx_exclude=[],
|
|
name='Path Juggler',
|
|
)
|
|
|
|
app = BUNDLE(
|
|
coll,
|
|
name='Path Juggler.app',
|
|
icon=None,
|
|
bundle_identifier='com.pathjuggler.app',
|
|
info_plist={
|
|
'CFBundleName': 'Path Juggler',
|
|
'CFBundleDisplayName': 'Path Juggler',
|
|
'CFBundleVersion': '1.0.0',
|
|
'CFBundleShortVersionString': '1.0.0',
|
|
'NSHighResolutionCapable': True,
|
|
'LSMinimumSystemVersion': '10.13.0',
|
|
'NSAppleEventsUsageDescription': 'Path Juggler needs to access files.',
|
|
},
|
|
)
|
|
SPEC
|
|
|
|
# Build the app
|
|
echo ""
|
|
echo "=== Building application ==="
|
|
pyinstaller --clean --noconfirm path_juggler.spec
|
|
|
|
# Sign the app with ad-hoc signature
|
|
echo ""
|
|
echo "=== Signing application (ad-hoc) ==="
|
|
APP_PATH="$DIST_DIR/Path Juggler.app"
|
|
|
|
if [ -d "$APP_PATH" ]; then
|
|
# Remove any existing signatures
|
|
codesign --remove-signature "$APP_PATH" 2>/dev/null || true
|
|
|
|
# Sign with ad-hoc signature (dash means ad-hoc)
|
|
codesign --force --deep --sign - "$APP_PATH"
|
|
|
|
echo "Signature applied"
|
|
codesign -dv "$APP_PATH" 2>&1 | head -5
|
|
else
|
|
echo "Error: App bundle not found at $APP_PATH"
|
|
exit 1
|
|
fi
|
|
|
|
# Clean up
|
|
echo ""
|
|
echo "=== Cleaning up ==="
|
|
rm -rf "$SCRIPT_DIR/build"
|
|
rm -f "$SCRIPT_DIR/path_juggler.spec"
|
|
deactivate
|
|
rm -rf "$VENV_DIR"
|
|
|
|
echo ""
|
|
echo "=== Build complete ==="
|
|
echo ""
|
|
echo "Application created at:"
|
|
echo " $APP_PATH"
|
|
echo ""
|
|
echo "To install, drag the app to your Applications folder:"
|
|
echo " open \"$DIST_DIR\""
|
|
echo ""
|
|
echo "Note: On first launch, you may need to right-click and select 'Open'"
|
|
echo "to bypass Gatekeeper since this is a self-signed app."
|