#!/usr/bin/env bash # Script to build and maintain a Mesk repository # Automatically discovers, validates, and indexes .mesk packages set -e # Exit on any error # Configuration SCRIPT_DIR="$(cd "$(dirname "${BASH_SOURCE[0]}")" && pwd)" REPO_DIR="${1:-$SCRIPT_DIR/repo}" # Use first argument or default to 'repo' SOURCE_DIR="${2:-$SCRIPT_DIR/packages}" # Directory to scan for .mesk files MESK_BIN="${MESK_BIN:-$SCRIPT_DIR/target/release/mesk}" # Colors for output RED='\033[0;31m' GREEN='\033[0;32m' YELLOW='\033[1;33m' BLUE='\033[0;34m' NC='\033[0m' # No Color # Logging functions log_info() { echo -e "${BLUE}[INFO]${NC} $1" } log_success() { echo -e "${GREEN}[SUCCESS]${NC} $1" } log_warning() { echo -e "${YELLOW}[WARNING]${NC} $1" } log_error() { echo -e "${RED}[ERROR]${NC} $1" } # Check if mesk binary exists if [ ! -f "$MESK_BIN" ]; then log_error "Mesk binary not found at: $MESK_BIN" log_info "Looking for mesk in PATH..." MESK_BIN=$(which mesk 2>/dev/null || echo "") if [ -z "$MESK_BIN" ]; then log_error "Mesk binary not found in PATH either." log_info "Please build mesk first with: cargo build --release" exit 1 else log_info "Found mesk at: $MESK_BIN" fi else log_info "Using mesk binary: $MESK_BIN" fi # Create directories if they don't exist mkdir -p "$REPO_DIR" mkdir -p "$SOURCE_DIR" # Function to validate a .mesk package validate_package() { local package="$1" log_info "Validating package: $(basename "$package")" if "$MESK_BIN" validate "$package" >/dev/null 2>&1; then log_success "Package $(basename "$package") is valid" return 0 else log_error "Package $(basename "$package") is invalid" return 1 fi } # Main function to build repository build_repository() { log_info "Starting repository build process..." log_info "Repository directory: $REPO_DIR" log_info "Source directory: $SOURCE_DIR" # Find all .mesk files in source directory (recursively) local package_files=() while IFS= read -r -d '' file; do package_files+=("$file") done < <(find "$SOURCE_DIR" -name "*.mesk" -type f -print0) if [ ${#package_files[@]} -eq 0 ]; then log_warning "No .mesk packages found in $SOURCE_DIR" log_info "Place your .mesk files in the source directory and run again" # Still generate index even if no packages log_info "Generating empty repository index..." if "$MESK_BIN" gen-index "$REPO_DIR"; then log_success "Empty repository index generated" else log_error "Failed to generate empty repository index" exit 1 fi return 0 fi log_info "Found ${#package_files[@]} .mesk package(s) to process" # Validate packages first local valid_packages=() local invalid_count=0 for package in "${package_files[@]}"; do if validate_package "$package"; then valid_packages+=("$package") else ((invalid_count++)) fi done if [ $invalid_count -ne 0 ]; then log_warning "$invalid_count package(s) failed validation" log_info "Only processing valid packages" fi if [ ${#valid_packages[@]} -eq 0 ]; then log_error "No valid packages to process" log_info "Repository build failed" exit 1 fi # Copy valid packages to repository directory log_info "Copying valid packages to repository..." for package in "${valid_packages[@]}"; do local package_name=$(basename "$package") local dest_path="$REPO_DIR/$package_name" # Compare timestamps to avoid unnecessary copies if [ ! -f "$dest_path" ] || [ "$package" -nt "$dest_path" ]; then cp "$package" "$REPO_DIR/" log_info "Copied $(basename "$package") to repository" else log_info "Package $(basename "$package") already exists and is up to date" fi done # Generate repository index log_info "Generating repository index..." if "$MESK_BIN" gen-index "$REPO_DIR"; then log_success "Repository index generated successfully" else log_error "Failed to generate repository index" exit 1 fi # Create/update repository info file local timestamp=$(date -u +"%Y-%m-%dT%H:%M:%SZ") cat > "$REPO_DIR/REPO_INFO" << EOF # Repository Information Generated At: $timestamp Total Packages: ${#valid_packages[@]} Invalid Packages: $invalid_count Source Directory: $SOURCE_DIR Repository Directory: $REPO_DIR Valid Packages: EOF for package in "${valid_packages[@]}"; do echo "- $(basename "$package")" >> "$REPO_DIR/REPO_INFO" done log_success "Repository build completed successfully!" log_info "Repository location: $REPO_DIR" log_info "Packages processed: ${#valid_packages[@]}" if [ $invalid_count -ne 0 ]; then log_info "Invalid packages: $invalid_count" fi } # Function to show help show_help() { echo "Usage: $0 [REPO_DIR] [SOURCE_DIR]" echo "" echo "Automatically builds a Mesk repository from .mesk packages." echo "" echo "Arguments:" echo " REPO_DIR Directory to create/build repository (default: ./repo)" echo " SOURCE_DIR Directory containing .mesk files to add (default: ./packages)" echo "" echo "Environment:" echo " MESK_BIN Path to mesk binary (default: ./target/release/mesk or in PATH)" echo "" echo "Example:" echo " $0 /path/to/repo /path/to/packages" echo " $0" # will use defaults } # Parse command line options case "${1:-}" in -h|--help) show_help exit 0 ;; *) build_repository ;; esac