#!/usr/bin/env bash set -euo pipefail # Rustelo Cross-Compilation Build Script # Builds Rustelo applications for Linux targets on macOS using Docker PROJECT_ROOT="$(pwd)" BUILD_TARGET="${CARGO_BUILD_TARGET:-x86_64-unknown-linux-gnu}" BUILD_MODE="${RUSTELO_MODE:-release}" DOCKER_IMAGE="${RUSTELO_CROSS_IMAGE:-rustelo-cross:latest}" VERBOSE="${RUSTELO_VERBOSE:-false}" # Colors for output RED='\033[0;31m' GREEN='\033[0;32m' YELLOW='\033[1;33m' BLUE='\033[0;34m' NC='\033[0m' log_info() { echo -e "${BLUE}[INFO]${NC} $1"; } log_warn() { echo -e "${YELLOW}[WARN]${NC} $1"; } log_error() { echo -e "${RED}[ERROR]${NC} $1"; } log_success() { echo -e "${GREEN}[SUCCESS]${NC} $1"; } show_help() { cat << EOF Rustelo Cross-Compilation Build Script USAGE: $0 [OPTIONS] [COMMAND] OPTIONS: -t, --target Target architecture (default: x86_64-unknown-linux-gnu) -m, --mode Build mode: dev, release (default: release) -i, --image Docker image to use (default: rustelo-cross:latest) -v, --verbose Enable verbose output -h, --help Show this help message COMMANDS: build Build the Rustelo application (default) assets Process and build assets only deps Install dependencies (npm + cargo) clean Clean build artifacts shell Start interactive shell in container test Run tests in cross-compilation environment EOF } COMMAND="" while [[ $# -gt 0 ]]; do case $1 in -t|--target) BUILD_TARGET="$2"; shift 2 ;; -m|--mode) BUILD_MODE="$2"; shift 2 ;; -i|--image) DOCKER_IMAGE="$2"; shift 2 ;; -v|--verbose) VERBOSE=true; shift ;; -h|--help) show_help; exit 0 ;; *) COMMAND="$1"; shift ;; esac done COMMAND="${COMMAND:-build}" if [[ ! -f "Cargo.toml" ]]; then log_error "No Cargo.toml found. Are you in a Rust project directory?" exit 1 fi setup_cross_dirs() { log_info "Setting up cross-compilation directories..." mkdir -p target-linux node_modules_linux .docker/cache log_success "Cross-compilation directories ready" } build_docker_image() { local dockerfile="${1:-Dockerfile.cross}" if ! docker image inspect "$DOCKER_IMAGE" >/dev/null 2>&1; then log_info "Building Docker image: $DOCKER_IMAGE" if [[ -f "$dockerfile" ]]; then docker build -f "$dockerfile" -t "$DOCKER_IMAGE" . log_success "Docker image built successfully" else log_error "Dockerfile not found: $dockerfile" exit 1 fi else log_info "Using existing Docker image: $DOCKER_IMAGE" fi } docker_run_opts() { echo "--rm --platform linux/amd64 -v ${PROJECT_ROOT}:/workspace -v ${PROJECT_ROOT}/target-linux:/workspace/target -v ${PROJECT_ROOT}/node_modules_linux:/workspace/node_modules -v ${PROJECT_ROOT}/.docker/cache:/root/.cargo/registry -w /workspace -e CARGO_BUILD_TARGET=${BUILD_TARGET} -e RUSTELO_MODE=${BUILD_MODE}" } install_deps() { log_info "Installing dependencies in cross-compilation environment..." docker run $(docker_run_opts) "$DOCKER_IMAGE" bash -c ' set -euo pipefail if [[ -f package.json ]]; then echo "Installing Node.js dependencies..." pnpm install --frozen-lockfile fi echo "Fetching Rust dependencies..." cargo fetch --target $CARGO_BUILD_TARGET echo "Dependencies installed successfully" ' log_success "Dependencies installed" } build_assets() { log_info "Building assets for $BUILD_TARGET..." docker run $(docker_run_opts) "$DOCKER_IMAGE" bash -c ' set -euo pipefail if command -v rustelo >/dev/null 2>&1; then echo "Processing Rustelo assets..." rustelo build --categories static,content,config else echo "Rustelo CLI not found, using fallback asset processing..." if [[ -d assets ]]; then mkdir -p target/assets cp -r assets/* target/assets/ fi fi echo "Assets built successfully" ' log_success "Assets built" } build_rust() { log_info "Building Rust application for $BUILD_TARGET..." docker run $(docker_run_opts) "$DOCKER_IMAGE" bash -c ' set -euo pipefail echo "Building Rust application..." if [[ "$RUSTELO_MODE" == "release" ]]; then cargo build --target $CARGO_BUILD_TARGET --release else cargo build --target $CARGO_BUILD_TARGET fi echo "Build completed successfully" ' log_success "Rust application built" } run_tests() { log_info "Running tests in cross-compilation environment..." docker run $(docker_run_opts) "$DOCKER_IMAGE" bash -c ' set -euo pipefail echo "Running Rust tests..." cargo test --target $CARGO_BUILD_TARGET ' } clean_build() { log_info "Cleaning cross-compilation artifacts..." rm -rf target-linux node_modules_linux .docker/cache log_success "Build artifacts cleaned" } interactive_shell() { log_info "Starting interactive shell in cross-compilation environment..." docker run -it $(docker_run_opts) "$DOCKER_IMAGE" bash } main() { setup_cross_dirs case "$COMMAND" in build) build_docker_image; install_deps; build_assets; build_rust ;; assets) build_docker_image; install_deps; build_assets ;; deps) build_docker_image; install_deps ;; test) build_docker_image; install_deps; run_tests ;; clean) clean_build ;; shell) build_docker_image; interactive_shell ;; *) log_error "Unknown command: $COMMAND"; show_help; exit 1 ;; esac log_success "Cross-compilation completed successfully!" } main "$@"