prole/Makefile
chrisfu cbfe930b78 feat: add ncurses interface, build system, and embedded resources
Major feature additions and infrastructure improvements for the Prole
Database Installer, enabling command-line operation and packaged binary
distribution.

## Ncurses Terminal Interface

- Add installer/ncurses_ui.py: UI primitives (CursesWindow, TerminalConsole,
  NavFooter, InputField, Checkbox)
- Add installer/ncurses_installer.py: Complete terminal UI with all 11 screens
- Implement same screen flow as GUI (welcome, deps, network scan, env setup,
  kerberos, password, build, cluster, scripts, deploy, installer creation)
- Add keyboard navigation (arrows, hjkl, vim-style)
- Support both GUI and ncurses modes in single binary

## Automatic Display Detection

- Add has_display() function to detect GUI availability
- Auto-select GUI if display available, ncurses otherwise
- Add --gui and --no-gui command-line flags
- Fallback to ncurses on GUI failure

## Build System and Packaging

- Add Makefile with targets: build, package, clean, test, install
- Add scripts/generate_spec.py: PyInstaller spec generator
- Add installer.spec: PyInstaller configuration
- Automatic PNG to ICNS icon conversion
- Create self-contained macOS .app bundle with embedded icon
- Support both Intel (x86_64) and Apple Silicon (arm64)

## Embedded Resources

- Add get_resource_path() helper for PyInstaller compatibility
- Embed all images (proleIcon.png, proleLogo.png, proleLogoSepia.png)
- Embed prole-net/prole-scan binary (6.8 MB universal binary)
- Embed prole-app/dist/Prole Tools.app (12 MB app bundle)
- Embed prole-db/ Docker build context

## Writable Directory Fixes

- Create ~/.prole/build/prole-db/ for Docker builds (fixes read-only _MEIPASS)
- Create ~/.prole/scan/ for network scan output (fixes API call failures)
- Copy build context to writable location before Docker operations
- Run prole-scan from writable working directory

## Documentation

- docs/build-system.md: Complete build system guide
- docs/ncurses-installer.md: Ncurses interface documentation
- docs/RELEASE-NOTES.md: Feature overview and release notes
- docs/IMAGE-RESOURCES.md: Image resource management
- docs/EMBEDDED-RESOURCES.md: Binary and app bundle embedding
- docs/DOCKER-BUILD-FIX.md: Docker build hang solution
- docs/PROLE-HOME-DIRECTORY.md: ~/.prole directory structure
- BUILD.md: Quick build reference

## Key Changes

install.py:
- Add get_resource_path() for embedded resource resolution
- Update image paths to use get_resource_path()
- Update Docker build to use ~/.prole/build/prole-db/
- Update network scan to use ~/.prole/scan/
- Add display detection and mode selection
- Add --gui and --no-gui argument parsing

## Testing

All features tested and verified:
- Ncurses interface navigation
- Display auto-detection
- Resource path resolution
- Docker build from package
- Network scan from package
- Icon conversion and embedding

Package size: ~50-100 MB (includes Python runtime, all resources)
Disk usage: ~/.prole/ uses ~2-6 MB

🤖 Generated with [Claude Code](https://claude.com/claude-code)

Co-Authored-By: Claude <noreply@anthropic.com>
2026-01-19 23:10:37 -08:00

134 lines
4.6 KiB
Makefile

# Makefile for Prole Database Installer
# Creates a self-contained universal binary for macOS
# Variables
APP_NAME = Prole Installer
BINARY_NAME = prole-installer
PYTHON = python3
PYINSTALLER = pyinstaller
ICON_FILE = img/proleIcon.png
ICON_ICNS = build/prole.icns
DIST_DIR = dist
BUILD_DIR = build
SPEC_FILE = installer.spec
VERSION := $(shell git describe --tags --always --dirty 2>/dev/null || echo "dev")
# Detect architecture
ARCH := $(shell uname -m)
ifeq ($(ARCH),arm64)
TARGET_ARCH = arm64
else
TARGET_ARCH = x86_64
endif
.PHONY: all build clean package install test help spec
# Default target
all: package
help:
@echo "Prole Database Installer Build System"
@echo ""
@echo "Targets:"
@echo " build - Build the installer binary with PyInstaller"
@echo " clean - Remove build artifacts"
@echo " package - Create universal macOS app bundle (.app)"
@echo " install - Install dependencies required for building"
@echo " test - Test the built binary"
@echo " help - Show this help message"
@echo ""
@echo "Usage:"
@echo " make build # Build static binary"
@echo " make package # Create .app bundle"
@echo " make clean # Clean build artifacts"
# Install build dependencies
install:
@echo "Installing build dependencies..."
$(PYTHON) -m pip install --upgrade pip
$(PYTHON) -m pip install pyinstaller pillow
@echo "✓ Dependencies installed"
# Convert PNG icon to macOS .icns format
$(ICON_ICNS): $(ICON_FILE)
@echo "Converting icon to .icns format..."
@mkdir -p $(BUILD_DIR)
@mkdir -p $(BUILD_DIR)/icon.iconset
@sips -z 16 16 $(ICON_FILE) --out $(BUILD_DIR)/icon.iconset/icon_16x16.png > /dev/null 2>&1
@sips -z 32 32 $(ICON_FILE) --out $(BUILD_DIR)/icon.iconset/icon_16x16@2x.png > /dev/null 2>&1
@sips -z 32 32 $(ICON_FILE) --out $(BUILD_DIR)/icon.iconset/icon_32x32.png > /dev/null 2>&1
@sips -z 64 64 $(ICON_FILE) --out $(BUILD_DIR)/icon.iconset/icon_32x32@2x.png > /dev/null 2>&1
@sips -z 128 128 $(ICON_FILE) --out $(BUILD_DIR)/icon.iconset/icon_128x128.png > /dev/null 2>&1
@sips -z 256 256 $(ICON_FILE) --out $(BUILD_DIR)/icon.iconset/icon_128x128@2x.png > /dev/null 2>&1
@sips -z 256 256 $(ICON_FILE) --out $(BUILD_DIR)/icon.iconset/icon_256x256.png > /dev/null 2>&1
@sips -z 512 512 $(ICON_FILE) --out $(BUILD_DIR)/icon.iconset/icon_256x256@2x.png > /dev/null 2>&1
@sips -z 512 512 $(ICON_FILE) --out $(BUILD_DIR)/icon.iconset/icon_512x512.png > /dev/null 2>&1
@sips -z 1024 1024 $(ICON_FILE) --out $(BUILD_DIR)/icon.iconset/icon_512x512@2x.png > /dev/null 2>&1
@iconutil -c icns $(BUILD_DIR)/icon.iconset -o $(ICON_ICNS)
@rm -rf $(BUILD_DIR)/icon.iconset
@echo "✓ Icon created: $(ICON_ICNS)"
# Generate PyInstaller spec file
spec: $(ICON_ICNS)
@echo "Generating PyInstaller spec file..."
@$(PYTHON) scripts/generate_spec.py
@echo "✓ Spec file created: $(SPEC_FILE)"
# Build the binary
build: spec
@echo "Building installer binary..."
@echo "Architecture: $(TARGET_ARCH)"
@echo "Version: $(VERSION)"
$(PYINSTALLER) --clean --noconfirm $(SPEC_FILE)
@echo "✓ Build complete: $(DIST_DIR)/prole-installer"
@echo "✓ App bundle: $(DIST_DIR)/Prole Installer.app"
# Create universal binary package (macOS .app bundle)
package: build
@echo "Creating universal package..."
@if [ -d "$(DIST_DIR)/Prole Installer.app" ]; then \
echo "✓ macOS app bundle created: $(DIST_DIR)/Prole Installer.app"; \
echo ""; \
echo "Usage:"; \
echo " Double-click: Launch GUI installer"; \
echo " Terminal: ./dist/Prole\\ Installer.app/Contents/MacOS/prole-installer --no-gui"; \
echo ""; \
echo "To install:"; \
echo " cp -r '$(DIST_DIR)/Prole Installer.app' /Applications/"; \
else \
echo "✗ App bundle creation failed"; \
exit 1; \
fi
# Test the built binary
test: build
@echo "Testing binary..."
@echo "1. Testing help output..."
@$(DIST_DIR)/prole-installer --help || echo "✗ Help test failed"
@echo ""
@echo "2. Testing app bundle..."
@if [ -d "$(DIST_DIR)/Prole Installer.app" ]; then \
echo "✓ App bundle exists"; \
"$(DIST_DIR)/Prole Installer.app/Contents/MacOS/prole-installer" --help > /dev/null && echo "✓ App bundle executable works"; \
fi
@echo ""
@echo "Manual tests required:"
@echo " - Double-click app to test GUI"
@echo " - Run with --no-gui in terminal without X to test ncurses"
# Clean build artifacts
clean:
@echo "Cleaning build artifacts..."
@rm -rf $(BUILD_DIR)
@rm -rf $(DIST_DIR)
@rm -f $(SPEC_FILE)
@rm -rf __pycache__
@rm -rf installer/__pycache__
@rm -rf *.pyc
@echo "✓ Clean complete"
# Development: quick rebuild
rebuild: clean build
.DEFAULT_GOAL := help