123456789101112131415161718192021222324252627282930313233343536373839404142434445464748495051525354555657585960616263646566676869707172737475767778798081828384858687888990919293949596979899100101102103104105106107108109110111112113114115116117118119120121122123124125126127128129130131132133134135136137138139140141142143144145146147148149150151152153154155156157158159160161162163164165166167168169170171172173174175176177178179180181182183184185186187188189190191192193194195196197198199200201202203204205206207208209210211212213214215216217218219220221222223224225226227228229230231232233234235236237238239240241242243244245246247248249250251252253254255256257258259260261262263264265266267268269270271272273274275276277278279280281282283284285286287288289290291292293294295296297298299300301302303304305306307308309310311312313 |
- #!/bin/bash
- # =============================================================================
- # UV Migration Script (Robust Version)
- # =============================================================================
- # Migrates from pip/venv to uv package manager
- # Enhanced error handling for production environments
- # =============================================================================
- # Don't exit on errors - handle them gracefully
- set +e
- # Colors for output
- RED='\033[0;31m'
- GREEN='\033[0;32m'
- YELLOW='\033[1;33m'
- BLUE='\033[0;34m'
- NC='\033[0m' # No Color
- # Script version
- VERSION="1.1.0-robust"
- # Print header
- echo -e "${BLUE}=================================${NC}"
- echo -e "${BLUE} UV Migration Script v${VERSION}${NC}"
- echo -e "${BLUE}=================================${NC}"
- echo ""
- # Function to print colored output
- print_success() {
- echo -e "${GREEN}✅ $1${NC}"
- }
- print_warning() {
- echo -e "${YELLOW}⚠️ $1${NC}"
- }
- print_error() {
- echo -e "${RED}❌ $1${NC}"
- }
- print_info() {
- echo -e "${BLUE}ℹ️ $1${NC}"
- }
- # Function to check if command exists
- command_exists() {
- command -v "$1" >/dev/null 2>&1
- }
- # Function to get file size in human readable format
- get_size() {
- if [[ "$OSTYPE" == "darwin"* ]]; then
- # macOS
- du -h "$1" 2>/dev/null | cut -f1 || echo "0B"
- else
- # Linux
- du -sh "$1" 2>/dev/null | cut -f1 || echo "0B"
- fi
- }
- # Check if we're in the project root
- if [[ ! -f "pyproject.toml" && ! -f "requirements.txt" ]]; then
- print_error "Neither pyproject.toml nor requirements.txt found. Please run this script from the project root."
- exit 1
- fi
- print_info "Starting migration process..."
- echo ""
- # =============================================================================
- # Step 1: Pre-migration Analysis
- # =============================================================================
- echo -e "${BLUE}📊 Pre-migration Analysis${NC}"
- echo "----------------------------"
- # Count cache files before cleanup (with timeout to prevent hanging)
- print_info "Analyzing project files (this may take a moment)..."
- PYCACHE_DIRS=$(timeout 30 find . -path "./.venv" -prune -o -path "./venv" -prune -o -name "__pycache__" -type d -print 2>/dev/null | wc -l | tr -d ' ')
- PYC_FILES=$(timeout 30 find . -path "./.venv" -prune -o -path "./venv" -prune -o -name "*.pyc" -type f -print 2>/dev/null | wc -l | tr -d ' ')
- echo "📁 Cache directories found: $PYCACHE_DIRS"
- echo "📄 .pyc files found: $PYC_FILES"
- # Check if pytest cache exists
- if [[ -d ".pytest_cache" ]]; then
- PYTEST_SIZE=$(get_size ".pytest_cache")
- echo "🧪 Pytest cache size: $PYTEST_SIZE"
- else
- echo "🧪 No pytest cache found"
- fi
- # Check for old venv
- if [[ -d "venv" ]]; then
- print_warning "Old 'venv' directory still exists!"
- VENV_SIZE=$(get_size "venv")
- echo "📦 Old venv size: $VENV_SIZE"
- else
- print_success "No old 'venv' directory found"
- fi
- # Check for requirements.txt
- if [[ -f "requirements.txt" ]]; then
- print_warning "requirements.txt still exists (should be removed after migration)"
- else
- print_success "requirements.txt already removed"
- fi
- echo ""
- # =============================================================================
- # Step 2: UV Installation Check
- # =============================================================================
- echo -e "${BLUE}🔧 UV Installation Check${NC}"
- echo "----------------------------"
- # Add UV to PATH if it exists
- export PATH="$HOME/.local/bin:$PATH"
- if command_exists uv; then
- UV_VERSION=$(uv --version 2>/dev/null | head -1)
- print_success "UV installed: $UV_VERSION"
- else
- print_error "UV not found! Installing UV..."
- if command_exists curl; then
- curl -LsSf https://astral.sh/uv/install.sh | sh
- # Add to PATH for this session
- export PATH="$HOME/.local/bin:$PATH"
- if command_exists uv; then
- UV_VERSION=$(uv --version 2>/dev/null | head -1)
- print_success "UV installed successfully: $UV_VERSION"
- else
- print_error "UV installation failed!"
- exit 1
- fi
- else
- print_error "curl not found! Please install UV manually."
- exit 1
- fi
- fi
- echo ""
- # =============================================================================
- # Step 3: Cache Cleanup (Robust Version)
- # =============================================================================
- echo -e "${BLUE}🧹 Cache Cleanup${NC}"
- echo "-------------------"
- # Ask for confirmation unless --force flag is provided
- if [[ "$1" != "--force" ]]; then
- echo "This will delete:"
- echo " - $PYCACHE_DIRS __pycache__ directories"
- echo " - $PYC_FILES .pyc files"
- echo " - .pytest_cache directory (if exists)"
- echo ""
- read -p "Continue with cleanup? (y/N): " -n 1 -r
- echo
- if [[ ! $REPLY =~ ^[Yy]$ ]]; then
- print_warning "Cleanup cancelled by user"
- exit 0
- fi
- fi
- print_info "Starting cleanup (using robust method for large file counts)..."
- # Method 1: Use xargs for better handling of large file lists
- DELETED_DIRS=0
- DELETED_FILES=0
- # Clean __pycache__ directories in batches
- print_info "Cleaning __pycache__ directories..."
- if find . -path "./.venv" -prune -o -path "./venv" -prune -o -name "__pycache__" -type d -print0 2>/dev/null | xargs -0 -r rm -rf; then
- DELETED_DIRS=$(echo "$PYCACHE_DIRS")
- print_success "Cleaned $DELETED_DIRS cache directories"
- else
- print_warning "Some cache directories could not be deleted (may be permission issues)"
- fi
- # Clean .pyc files in batches
- print_info "Cleaning .pyc files..."
- if find . -path "./.venv" -prune -o -path "./venv" -prune -o -name "*.pyc" -type f -print0 2>/dev/null | xargs -0 -r rm -f; then
- DELETED_FILES=$(echo "$PYC_FILES")
- print_success "Cleaned $DELETED_FILES .pyc files"
- else
- print_warning "Some .pyc files could not be deleted"
- fi
- # Clean .pyo files
- print_info "Cleaning .pyo files..."
- find . -path "./.venv" -prune -o -path "./venv" -prune -o -name "*.pyo" -type f -print0 2>/dev/null | xargs -0 -r rm -f
- # Remove pytest cache
- if [[ -d ".pytest_cache" ]]; then
- if rm -rf ".pytest_cache" 2>/dev/null; then
- print_success "Removed .pytest_cache directory"
- else
- print_warning "Could not remove .pytest_cache directory"
- fi
- fi
- print_success "Cleanup phase completed!"
- echo ""
- # =============================================================================
- # Step 4: UV Environment Setup
- # =============================================================================
- echo -e "${BLUE}🔍 UV Environment Setup${NC}"
- echo "------------------------"
- # Check if pyproject.toml exists
- if [[ ! -f "pyproject.toml" ]]; then
- print_warning "No pyproject.toml found. Creating basic one..."
- cat > pyproject.toml << 'EOF'
- [project]
- name = "trading-bot"
- version = "1.0.0"
- requires-python = ">=3.8"
- dependencies = []
- [build-system]
- requires = ["hatchling"]
- build-backend = "hatchling.build"
- EOF
- print_info "Created basic pyproject.toml - you may need to add your dependencies"
- fi
- # Create/sync UV environment
- print_info "Setting up UV environment..."
- if uv sync; then
- print_success "UV environment ready"
- else
- print_error "UV sync failed!"
- print_info "Trying alternative setup..."
- if uv venv && uv pip install -r requirements.txt 2>/dev/null; then
- print_success "UV environment created with fallback method"
- else
- print_error "Could not create UV environment"
- exit 1
- fi
- fi
- # Test imports
- print_info "Testing environment..."
- if uv run python -c "print('UV environment working!')" 2>/dev/null; then
- print_success "UV environment functional"
- else
- print_warning "UV environment may have issues"
- fi
- echo ""
- # =============================================================================
- # Step 5: Old Files Cleanup (Optional)
- # =============================================================================
- echo -e "${BLUE}🗑️ Old Files Cleanup${NC}"
- echo "-----------------------"
- # Check for old venv directory
- if [[ -d "venv" ]]; then
- VENV_SIZE=$(get_size "venv")
- print_warning "Old 'venv' directory found (${VENV_SIZE})"
-
- if [[ "$1" != "--force" ]]; then
- read -p "Delete old 'venv' directory? (y/N): " -n 1 -r
- echo
- if [[ $REPLY =~ ^[Yy]$ ]]; then
- if rm -rf "venv" 2>/dev/null; then
- print_success "Removed old 'venv' directory"
- else
- print_warning "Could not remove old 'venv' directory (check permissions)"
- fi
- else
- print_warning "Keeping old 'venv' directory"
- fi
- else
- if rm -rf "venv" 2>/dev/null; then
- print_success "Removed old 'venv' directory"
- else
- print_warning "Could not remove old 'venv' directory"
- fi
- fi
- else
- print_success "No old 'venv' directory found"
- fi
- echo ""
- # =============================================================================
- # Final Summary
- # =============================================================================
- echo -e "${GREEN}🎉 Migration Summary${NC}"
- echo "====================="
- echo ""
- print_success "UV migration completed!"
- echo ""
- echo "📋 What was done:"
- echo " ✅ Cleaned up cache files and directories"
- echo " ✅ Installed UV package manager"
- echo " ✅ Set up UV environment"
- echo ""
- echo "🚀 Next steps:"
- echo " • Test: uv run python --version"
- echo " • Run bot: uv run python trading_bot.py"
- echo " • Add packages: uv add package_name"
- echo ""
- echo "🔧 UV Quick Commands:"
- echo " uv sync # Sync dependencies"
- echo " uv add requests # Add package"
- echo " uv run python script.py # Run with UV"
- echo ""
- print_success "Migration complete! 🚀"
|