#!/bin/bash # UnitForge Migration Script: pip → uv # Migrates existing UnitForge installations from pip-based to uv-only workflow set -e # Load centralized color utility SCRIPT_DIR="$(cd "$(dirname "${BASH_SOURCE[0]}")" && pwd)" source "${SCRIPT_DIR}/scripts/colors.sh" echo -e "${BLUE}╔══════════════════════════════════════════════╗${NC}" echo -e "${BLUE}║ UnitForge Migration to uv v1.1 ║${NC}" echo -e "${BLUE}║ Upgrading from pip-based workflow ║${NC}" echo -e "${BLUE}╚══════════════════════════════════════════════╝${NC}" echo "" # Function to check if command exists command_exists() { command -v "$1" >/dev/null 2>&1 } # Function to backup files backup_file() { local file="$1" if [[ -f "$file" ]]; then cp "$file" "${file}.backup.$(date +%Y%m%d_%H%M%S)" echo -e "${YELLOW} ✓ Backed up $file${NC}" fi } echo -e "${CYAN}🔍 Analyzing current installation...${NC}" echo "" # Check if we're in UnitForge directory if [[ ! -f "pyproject.toml" || ! -f "unitforge-cli" ]]; then echo -e "${RED}Error: Not in UnitForge project directory${NC}" echo "Please navigate to your UnitForge project root and try again." exit 1 fi echo -e "${GREEN}✓ UnitForge project detected${NC}" # Check current Python setup if [[ -d "venv" ]]; then echo -e "${YELLOW}⚠ Found old 'venv' directory${NC}" OLD_VENV="venv" elif [[ -d ".venv" ]]; then echo -e "${BLUE}ℹ Found '.venv' directory${NC}" OLD_VENV=".venv" else echo -e "${BLUE}ℹ No existing virtual environment found${NC}" OLD_VENV="" fi # Check for pip-based installations PIP_INSTALLED=false if [[ -n "$OLD_VENV" && -f "$OLD_VENV/bin/activate" ]]; then echo -e "${BLUE}Checking existing environment...${NC}" # Check if UnitForge is installed in pip mode if source "$OLD_VENV/bin/activate" 2>/dev/null && pip show unitforge >/dev/null 2>&1; then PIP_INSTALLED=true echo -e "${YELLOW}⚠ UnitForge is installed via pip${NC}" fi fi echo "" echo -e "${CYAN}📋 Migration Plan:${NC}" echo "" if [[ -n "$OLD_VENV" ]]; then echo -e "${YELLOW}1. Backup existing virtual environment${NC}" fi echo -e "${YELLOW}2. Install uv package manager${NC}" echo -e "${YELLOW}3. Create new uv-based environment${NC}" echo -e "${YELLOW}4. Install dependencies with uv${NC}" echo -e "${YELLOW}5. Update development scripts${NC}" echo -e "${YELLOW}6. Verify functionality${NC}" echo -e "${YELLOW}7. Clean up old environment${NC}" echo "" read -p "Proceed with migration? (y/N): " -n 1 -r echo if [[ ! $REPLY =~ ^[Yy]$ ]]; then echo "Migration cancelled." exit 0 fi echo "" echo -e "${CYAN}🚀 Starting migration...${NC}" echo "" # Step 1: Backup existing environment if [[ -n "$OLD_VENV" ]]; then echo -e "${BLUE}Step 1: Backing up existing environment...${NC}" if [[ "$OLD_VENV" == "venv" ]]; then mv venv venv.backup.$(date +%Y%m%d_%H%M%S) echo -e "${GREEN}✓ Backed up old 'venv' directory${NC}" elif [[ "$OLD_VENV" == ".venv" ]]; then mv .venv .venv.backup.$(date +%Y%m%d_%H%M%S) echo -e "${GREEN}✓ Backed up old '.venv' directory${NC}" fi # Save requirements if possible if [[ -f "backend/requirements.txt" ]]; then backup_file "backend/requirements.txt" fi echo "" fi # Step 2: Install uv echo -e "${BLUE}Step 2: Installing uv package manager...${NC}" if command_exists uv; then UV_VERSION=$(uv --version 2>/dev/null | grep -oE '[0-9]+\.[0-9]+\.[0-9]+' || echo "unknown") echo -e "${GREEN}✓ uv ${UV_VERSION} already installed${NC}" else echo -e "${YELLOW}Installing uv...${NC}" if command_exists curl; then curl -LsSf https://astral.sh/uv/install.sh | sh elif command_exists wget; then wget -qO- https://astral.sh/uv/install.sh | sh else echo -e "${RED}Error: Neither curl nor wget found${NC}" echo "Please install uv manually: https://github.com/astral-sh/uv#installation" exit 1 fi # Add uv to PATH for current session export PATH="$HOME/.cargo/bin:$PATH" if command_exists uv; then echo -e "${GREEN}✓ uv installed successfully${NC}" else echo -e "${RED}Error: uv installation failed${NC}" echo "Please install uv manually and restart this script" exit 1 fi fi echo "" # Step 3: Create new uv-based environment echo -e "${BLUE}Step 3: Creating new uv-based environment...${NC}" uv venv .venv echo -e "${GREEN}✓ Created .venv with uv${NC}" # Step 4: Install dependencies echo -e "${BLUE}Step 4: Installing dependencies with uv...${NC}" source .venv/bin/activate uv pip install -e ".[dev,web]" success "All dependencies installed with uv" echo "" # Step 5: Update development scripts echo -e "${BLUE}Step 5: Updating development scripts...${NC}" # Make sure all scripts are executable chmod +x unitforge-cli chmod +x start-server.sh chmod +x setup-dev.sh chmod +x demo.sh chmod +x check-uv.sh echo -e "${GREEN}✓ Scripts updated and made executable${NC}" echo "" # Step 6: Verify functionality echo -e "${BLUE}Step 6: Verifying functionality...${NC}" # Test CLI if ./unitforge-cli --help >/dev/null 2>&1; then echo -e "${GREEN}✓ CLI tool working${NC}" else echo -e "${RED}✗ CLI tool test failed${NC}" fi # Test template listing if ./unitforge-cli template list >/dev/null 2>&1; then echo -e "${GREEN}✓ Template system working${NC}" else echo -e "${RED}✗ Template system test failed${NC}" fi # Test unit file creation if ./unitforge-cli create --type service --name migration-test --exec-start "/bin/true" --output migration-test.service >/dev/null 2>&1; then echo -e "${GREEN}✓ Unit file creation working${NC}" rm -f migration-test.service else echo -e "${RED}✗ Unit file creation test failed${NC}" fi # Test pytest if uv run pytest tests/ --tb=no -q >/dev/null 2>&1; then echo -e "${GREEN}✓ Test suite working${NC}" else echo -e "${YELLOW}⚠ Some tests failed (this may be expected)${NC}" fi echo "" # Step 7: Clean up options echo -e "${BLUE}Step 7: Cleanup options...${NC}" echo "" BACKUP_DIRS=$(find . -maxdepth 1 -name "*.backup.*" -type d 2>/dev/null || true) BACKUP_FILES=$(find . -maxdepth 2 -name "*.backup.*" -type f 2>/dev/null || true) if [[ -n "$BACKUP_DIRS" || -n "$BACKUP_FILES" ]]; then echo -e "${YELLOW}Found backup files/directories:${NC}" [[ -n "$BACKUP_DIRS" ]] && echo "$BACKUP_DIRS" [[ -n "$BACKUP_FILES" ]] && echo "$BACKUP_FILES" echo "" read -p "Remove backup files? (y/N): " -n 1 -r echo if [[ $REPLY =~ ^[Yy]$ ]]; then [[ -n "$BACKUP_DIRS" ]] && rm -rf $BACKUP_DIRS [[ -n "$BACKUP_FILES" ]] && rm -f $BACKUP_FILES echo -e "${GREEN}✓ Backup files removed${NC}" else echo -e "${BLUE}ℹ Backup files preserved${NC}" fi fi echo "" echo -e "${GREEN}🎉 Migration to uv completed successfully!${NC}" echo "" # Show new workflow echo -e "${CYAN}📋 New uv-based workflow:${NC}" echo "" echo -e "${BLUE}Development commands:${NC}" echo -e " ${CYAN}make setup-dev # Complete development setup${NC}" echo -e " ${CYAN}make server # Start development server${NC}" echo -e " ${CYAN}make test # Run test suite${NC}" echo -e " ${CYAN}make test-cov # Tests with coverage${NC}" echo -e " ${CYAN}make lint # Code quality checks${NC}" echo -e " ${CYAN}make format # Auto-format code${NC}" echo -e " ${CYAN}make docker-dev # Docker development${NC}" echo -e " ${CYAN}make clean # Clean cache files${NC}" echo "" echo -e "${BLUE}Package management:${NC}" echo -e " ${CYAN}uv pip install # Install package${NC}" echo -e " ${CYAN}uv pip list # List packages${NC}" echo -e " ${CYAN}uv pip show # Show package info${NC}" echo -e " ${CYAN}uv venv # Create environment${NC}" echo "" echo -e "${BLUE}Key improvements:${NC}" echo -e " ${GREEN}⚡ 10-100x faster installs${NC}" echo -e " ${GREEN}🔒 Better dependency resolution${NC}" echo -e " ${GREEN}🎯 Modern Python standards${NC}" echo -e " ${GREEN}🛠 Integrated development tools${NC}" echo -e " ${GREEN}🐳 Optimized Docker workflows${NC}" echo "" echo -e "${CYAN}Next steps:${NC}" echo -e " ${YELLOW}1. Test your workflow: make test${NC}" echo -e " ${YELLOW}2. Start development: make server${NC}" echo -e " ${YELLOW}3. Check system status: ./check-uv.sh${NC}" echo -e " ${YELLOW}4. Read updated README.md${NC}" echo "" echo -e "${BLUE}Environment Information:${NC}" if command_exists uv; then UV_VERSION=$(uv --version 2>/dev/null | grep -oE '[0-9]+\.[0-9]+\.[0-9]+' || echo "unknown") echo -e " ${CYAN}uv version: ${UV_VERSION}${NC}" fi echo -e " ${CYAN}Python version: $(python3 --version | cut -d' ' -f2)${NC}" echo -e " ${CYAN}Virtual environment: .venv${NC}" echo -e " ${CYAN}Package manager: uv (no pip fallback)${NC}" echo "" echo -e "${GREEN}Welcome to the future of Python development! 🚀${NC}"