Last active
July 24, 2025 17:21
-
-
Save koad/e5deed3441f83be97aecc96115edbd39 to your computer and use it in GitHub Desktop.
Revisions
-
koad revised this gist
Jul 24, 2025 . 1 changed file with 2 additions and 2 deletions.There are no files selected for viewing
This file contains hidden or bidirectional Unicode text that may be interpreted or compiled differently than what appears below. To review, open the file in an editor that reveals hidden Unicode characters. Learn more about bidirectional Unicode charactersOriginal file line number Diff line number Diff line change @@ -24,9 +24,9 @@ # - Automatically excludes node_modules, .meteor, .local, .npm, dist, and build directories # - Focuses on JavaScript/TypeScript files (*.js, *.jsx, *.ts, *.tsx) # # Author: koad via claude # Version: 1.0 # Date: July 24 2025 # # =================================================================== -
koad created this gist
Jul 24, 2025 .There are no files selected for viewing
This file contains hidden or bidirectional Unicode text that may be interpreted or compiled differently than what appears below. To review, open the file in an editor that reveals hidden Unicode characters. Learn more about bidirectional Unicode charactersOriginal file line number Diff line number Diff line change @@ -0,0 +1,539 @@ #!/bin/bash # # =================================================================== # Meteor 3.0 Migration Analysis Script # =================================================================== # # Purpose: # This script scans Meteor applications for deprecated functions and patterns # that need to be updated for Meteor 3.0 compatibility. It provides detailed # reports with file locations, line numbers, and migration advice. # # Requirements: # - ripgrep (rg command) - much faster and more powerful than grep # # Usage: # ./meteor3-migration-checker.sh [directory] # # Examples: # ./meteor3-migration-checker.sh # Scans current directory recursively # ./meteor3-migration-checker.sh ./my-app # Scans specific directory recursively # # Notes: # - Searches recursively through all subdirectories by default # - Automatically excludes node_modules, .meteor, .local, .npm, dist, and build directories # - Focuses on JavaScript/TypeScript files (*.js, *.jsx, *.ts, *.tsx) # # Author: [Your Name] # Version: 1.0 # Date: July 2025 # # =================================================================== # ================================================================= # SCRIPT CONFIGURATION AND SETUP # ================================================================= # Don't exit on errors - we want to complete the full scan even if some parts fail # This ensures we get a complete report of all issues set +e # Store the start time to calculate total execution time at the end START_TIME=$(date +%s) # Directory to scan (default is current directory) # The ${1:-.} syntax means "use the first argument if provided, otherwise use '.'" SCAN_DIR="${1:-.}" # ================================================================= # COLOR DEFINITIONS - Making Terminal Output Pretty # ================================================================= # ANSI escape codes tell the terminal to change text colors and styles # Format: \033[COLORm where COLOR is a number code # These variables make the rest of the script more readable # Text colors RED='\033[0;31m' # Critical issues (must fix) BRIGHT_RED='\033[1;31m' # Section headings YELLOW='\033[0;33m' # Warnings (should fix) GREEN='\033[0;32m' # Success messages BLUE='\033[0;34m' # Information CYAN='\033[0;36m' # File paths and technical details MAGENTA='\033[0;35m' # Progress indicators GRAY='\033[0;90m' # Less important information WHITE='\033[1;37m' # Highlighted content NC='\033[0m' # No Color - resets to default terminal color # Text styles BOLD='\033[1m' UNDERLINE='\033[4m' ITALIC='\033[3m' # ================================================================= # UNICODE SYMBOLS FOR BETTER READABILITY # ================================================================= # These symbols make the output more visual and easier to scan CHECK="✓" # Success/completed CROSS="✗" # Error/issue found WARN="⚠" # Warning INFO="ℹ" # Information ARROW="➤" # Pointing to specific line ROCKET="🚀" # Progress/action MAGNIFY="🔍" # Searching LIGHTBULB="💡" # Tip/suggestion TOOLS="🔧" # Fix required HOURGLASS="⏳" # Processing/waiting # ================================================================= # CHECK FOR REQUIRED TOOLS # ================================================================= # Check if ripgrep is installed - exit with instructions if not found check_requirements() { echo -e "${BLUE}${HOURGLASS} Checking requirements...${NC}" if ! command -v rg &> /dev/null; then echo -e "${RED}${CROSS} Error: ripgrep (rg) is not installed${NC}" echo echo -e "${YELLOW}Ripgrep is required for this script. Please install it:${NC}" echo echo -e "${CYAN}On Ubuntu/Debian:${NC}" echo " sudo apt-get update" echo " sudo apt-get install ripgrep" echo echo -e "${CYAN}On MacOS:${NC}" echo " brew install ripgrep" echo echo -e "${CYAN}On CentOS/RHEL:${NC}" echo " sudo yum install ripgrep" echo echo -e "${CYAN}On Windows (with Chocolatey):${NC}" echo " choco install ripgrep" echo echo -e "${CYAN}Or download from: ${UNDERLINE}https://github.com/BurntSushi/ripgrep/releases${NC}" echo exit 1 fi echo -e "${GREEN}${CHECK} All requirements satisfied${NC}" echo } # ================================================================= # SEARCH PATTERNS # ================================================================= # These arrays define what we're looking for in the codebase # Each array holds patterns for a specific category of migration issues # Critical Issues (must fix) - Breaking changes that will stop the app from running declare -a critical_patterns=( # Fiber-related patterns "Fiber\.yield" "Fiber\.current" "Promise\.await" "Meteor\.wrapAsync" "fibers/future" "Npm\.require\(['\"]fibers['\"]" # Synchronous MongoDB operations "\.find\(\)\.fetch\(\)" "\.findOne\(" "\.insert\(" "\.update\(" "\.remove\(" "\.upsert\(" ) # Critical pattern descriptions - matches order with the array above declare -a critical_descriptions=( "Fiber.yield() - Fibers have been removed in Meteor 3" "Fiber.current - Fibers have been removed in Meteor 3" "Promise.await() - No longer needed, use native await" "Meteor.wrapAsync() - No longer needed, use async/await" "fibers/future - Future package import (removed in Meteor 3)" "Npm.require('fibers') - Fibers dependency import" "Collection.find().fetch() - Synchronous fetch() operation" "Collection.findOne() - Synchronous findOne() operation" "Collection.insert() - Synchronous insert() operation" "Collection.update() - Synchronous update() operation" "Collection.remove() - Synchronous remove() operation" "Collection.upsert() - Synchronous upsert() operation" ) # Critical fix suggestions - matches order with the arrays above declare -a critical_fixes=( "Replace with 'await' and make containing function async" "Replace with modern async/await pattern" "Replace with native 'await' keyword" "Replace with direct use of async/await" "Remove Future imports and use async/await pattern" "Remove Fibers dependency import" "Replace with 'await Collection.find().fetchAsync()'" "Replace with 'await Collection.findOneAsync()'" "Replace with 'await Collection.insertAsync()'" "Replace with 'await Collection.updateAsync()'" "Replace with 'await Collection.removeAsync()'" "Replace with 'await Collection.upsertAsync()'" ) # High Priority Issues (should fix) - Features that may work but are deprecated declare -a high_patterns=( # Method calls (recommended to update) "Meteor\.call\([^,]+,[^,]+,\s*function" # API renames "Accounts\.setPassword" "Accounts\.addEmail" "Assets\.getText" "Assets\.getBinary" "Meteor\.user\(\)" ) # High pattern descriptions declare -a high_descriptions=( "Meteor.call() with callback - Better to use callAsync" "Accounts.setPassword - Renamed in Meteor 3" "Accounts.addEmail - Renamed in Meteor 3" "Assets.getText - Renamed in Meteor 3" "Assets.getBinary - Renamed in Meteor 3" "Meteor.user() - Server-side should use userAsync" ) # High fix suggestions declare -a high_fixes=( "Replace with 'const result = await Meteor.callAsync(...)'" "Replace with 'await Accounts.setPasswordAsync()'" "Replace with 'await Accounts.addEmailAsync()'" "Replace with 'await Assets.getTextAsync()'" "Replace with 'await Assets.getBinaryAsync()'" "Replace with 'await Meteor.userAsync()' on server-side" ) # Medium Priority Issues (consider fixing) - API changes that have alternatives declare -a medium_patterns=( # WebApp API changes "WebApp\.connectHandlers" "WebApp\.rawConnectHandlers" "WebApp\.connectApp" ) # Medium pattern descriptions declare -a medium_descriptions=( "WebApp.connectHandlers - Connect API replaced with Express" "WebApp.rawConnectHandlers - Connect API replaced with Express" "WebApp.connectApp - Connect API replaced with Express" ) # Medium fix suggestions declare -a medium_fixes=( "Replace with 'WebApp.handlers'" "Replace with 'WebApp.rawHandlers'" "Replace with 'WebApp.expressApp'" ) # ================================================================= # HELPER FUNCTIONS # ================================================================= # Print a separator line to make output more readable # No parameters needed - just prints a line of a fixed length print_separator() { echo -e "${GRAY}━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━${NC}" } # Print a section heading to organize output # $1: Text to display as a heading print_heading() { echo print_separator echo -e "${BRIGHT_RED}${BOLD}$1${NC}" print_separator } # Print information about what we're searching for # $1: Search pattern description # $2: Current pattern number # $3: Total number of patterns print_searching() { echo echo -e "${MAGENTA}${MAGNIFY} [$2/$3] Searching for: ${CYAN}$1${NC}" print_separator } # Format file paths to be more readable # $1: File path to format format_file_path() { echo -e "${CYAN}${BOLD}$1${NC}" } # Count files in the directory to be scanned # Takes no parameters but uses the global SCAN_DIR variable count_files() { # Find all JS/TS files that might contain Meteor code # Using -not -path to exclude node_modules, .local, .meteor and other non-source directories # This ensures we're counting the same files that ripgrep will search local file_count=$(find "$SCAN_DIR" -type f \( -name "*.js" -o -name "*.jsx" -o -name "*.ts" -o -name "*.tsx" \) \ -not -path "*/node_modules/*" \ -not -path "*/.meteor/*" \ -not -path "*/.local/*" \ -not -path "*/.npm/*" \ -not -path "*/dist/*" \ -not -path "*/build/*" \ | wc -l) echo "$file_count" } # ================================================================= # MAIN SEARCH FUNCTIONS # ================================================================= # Search for a specific pattern with ripgrep and display results # $1: Search pattern (regex) # $2: Pattern description # $3: Fix suggestion # $4: Severity color (RED, YELLOW, etc.) # $5: Severity label (CRITICAL, HIGH, etc.) # Sets global PATTERN_MATCH_COUNT with number of matches found search_pattern() { local pattern="$1" local description="$2" local fix="$3" local color="$4" local severity="$5" PATTERN_MATCH_COUNT=0 # This command runs ripgrep with: # -i: Case insensitive matching # --context=2: Show 2 lines before and after the match # -g: Glob patterns to include only JavaScript/TypeScript files # --iglob: Glob patterns to exclude (node_modules, .local, .npm, etc.) # --color=always: Force color output # -n: Show line numbers # Note: ripgrep searches recursively by default local results=$(rg -i --context=2 -g "*.{js,jsx,ts,tsx}" \ --iglob "!node_modules" \ --iglob "!.meteor" \ --iglob "!.local" \ --iglob "!.npm" \ --iglob "!dist" \ --iglob "!build" \ --color=always \ -n "$pattern" "$SCAN_DIR" 2>/dev/null || true) # If we found matches, display them with context if [[ -n "$results" ]]; then # Count lines that have the pattern (ignoring context lines) # Get a clean count by counting lines with our pattern count=$(rg -i --no-heading --no-line-number \ -g "*.{js,jsx,ts,tsx}" \ --iglob "!node_modules" \ --iglob "!.meteor" \ --iglob "!.local" \ --iglob "!.npm" \ --iglob "!dist" \ --iglob "!build" \ "$pattern" "$SCAN_DIR" 2>/dev/null | wc -l) # Make sure we have valid count if [[ -z "$count" ]] || [[ "$count" -lt 1 ]]; then count=0 fi echo -e "${color}${severity}: Found ${count} instances${NC}" echo # Much simpler approach - just echo the results directly # This avoids complex processing that might hang # Add some basic formatting to make it more readable echo "$results" | sed "s/^--$//" | sed "s/^$//" | \ sed "s/^\([^:]*\):\([0-9]*\):\(.*\)/${CYAN}📁 \1${NC}\n ${GRAY}\2 │${NC} ${color}${ARROW} \3${NC}/" | \ sed "s/^\([0-9]*\)\([-:]\)\(.*\)/ ${GRAY}\1 │${NC} \3/" echo "" # Print the fix suggestion echo -e "${GREEN}${LIGHTBULB} Migration: ${fix}${NC}" echo # Store count in global variable PATTERN_MATCH_COUNT=$count else PATTERN_MATCH_COUNT=0 fi } # Process an entire array of patterns # $1: Array of patterns # $2: Array of descriptions # $3: Array of fixes # $4: Color for display # $5: Severity label # Returns: Total number of issues found process_patterns() { local -n patterns=$1 local -n descriptions=$2 local -n fixes=$3 local color=$4 local severity=$5 local total=0 local current=0 # Loop through all patterns for i in "${!patterns[@]}"; do current=$((current + 1)) # Calculate global pattern number and total for progress display local global_current=$((global_pattern_current + current)) local global_total=$((global_pattern_total)) # Show what we're searching for print_searching "${descriptions[$i]}" "$global_current" "$global_total" # Search for the pattern and get count PATTERN_MATCH_COUNT=0 search_pattern "${patterns[$i]}" "${descriptions[$i]}" "${fixes[$i]}" "$color" "$severity" local count=$PATTERN_MATCH_COUNT # Add to the total total=$((total + count)) # Update statistics by severity if [[ "$severity" == "CRITICAL" ]]; then critical_total=$((critical_total + count)) elif [[ "$severity" == "HIGH" ]]; then high_total=$((high_total + count)) elif [[ "$severity" == "MEDIUM" ]]; then medium_total=$((medium_total + count)) fi done # Update the global pattern counter global_pattern_current=$((global_pattern_current + ${#patterns[@]})) # Make sure we return a valid total even if something goes wrong if [[ $total -lt 0 ]]; then total=0 fi return $total } # ================================================================= # MAIN EXECUTION # ================================================================= # Initialize global variables and counters for statistics PATTERN_MATCH_COUNT=0 critical_total=0 high_total=0 medium_total=0 global_pattern_current=0 global_pattern_total=$((${#critical_patterns[@]} + ${#high_patterns[@]} + ${#medium_patterns[@]})) # Print banner echo -e "${BRIGHT_RED}${BOLD}" echo " __ __ _ _____ __ __ _ _ _ " echo " | \/ | ___| |_ ___ ___ _ __ |___ / | \/ (_) __ _ _ __ __ _| |_(_) ___ _ __ " echo " | |\/| |/ _ \ __/ _ \/ _ \| '__| |_ \ | |\/| | |/ _\` | '__/ _\` | __| |/ _ \| '_ \ " echo " | | | | __/ || __/ (_) | | ___) | | | | | | (_| | | | (_| | |_| | (_) | | | |" echo " |_| |_|\___|\__\___|\___/|_| |____/___|_| |_|_|\__, |_| \__,_|\__|_|\___/|_| |_|" echo " |_____| |___/ " echo -e "${NC}" echo -e "${BLUE}${BOLD}A comprehensive Meteor 3.0 migration analysis tool${NC}" echo -e "${GRAY}Analyzes your Meteor codebase for deprecated functions and patterns${NC}" echo # Check for required tools check_requirements # Show scan information echo -e "${BLUE}${INFO} Scan Information:${NC}" echo -e " ${GRAY}Directory:${NC} ${CYAN}$SCAN_DIR${NC}" # Count files to scan file_count=$(count_files) echo -e " ${GRAY}Files to scan:${NC} ${CYAN}$file_count${NC} JavaScript/TypeScript files" echo -e " ${GRAY}Patterns to check:${NC} ${CYAN}$global_pattern_total${NC} deprecated functions and patterns" echo # Begin scan print_heading "BEGINNING SCAN" echo -e "${BLUE}${ROCKET} Starting comprehensive scan for Meteor 3.0 migration issues...${NC}" echo # Process each category of patterns print_heading "CRITICAL ISSUES (Must Fix)" echo -e "${RED}These issues will break your application in Meteor 3.0${NC}" process_patterns critical_patterns critical_descriptions critical_fixes "$RED" "CRITICAL" critical_count=$? print_heading "HIGH PRIORITY ISSUES (Should Fix)" echo -e "${YELLOW}These issues are important to address for Meteor 3.0${NC}" process_patterns high_patterns high_descriptions high_fixes "$YELLOW" "HIGH" high_count=$? print_heading "MEDIUM PRIORITY ISSUES (Consider Fixing)" echo -e "${BLUE}These issues are recommended to address but may not break functionality${NC}" process_patterns medium_patterns medium_descriptions medium_fixes "$BLUE" "MEDIUM" medium_count=$? # Make sure totals are valid if [[ $critical_total -lt 0 ]]; then critical_total=0; fi if [[ $high_total -lt 0 ]]; then high_total=0; fi if [[ $medium_total -lt 0 ]]; then medium_total=0; fi # Calculate total issues total_issues=$((critical_total + high_total + medium_total)) # Calculate execution time END_TIME=$(date +%s) EXECUTION_TIME=$((END_TIME - START_TIME)) # Print summary print_heading "SCAN COMPLETE" echo -e "${GREEN}${CHECK} Scan completed in ${CYAN}${EXECUTION_TIME}${NC} seconds" echo echo -e "${BLUE}${INFO} Summary:${NC}" echo -e " ${GRAY}Files scanned:${NC} ${CYAN}$file_count${NC}" echo -e " ${GRAY}Patterns checked:${NC} ${CYAN}$global_pattern_total${NC}" echo -e " ${GRAY}Total issues found:${NC} ${CYAN}$total_issues${NC}" echo echo -e " ${RED}Critical issues:${NC} ${CYAN}$critical_total${NC} ${GRAY}(Must fix for Meteor 3.0)${NC}" echo -e " ${YELLOW}High priority issues:${NC} ${CYAN}$high_total${NC} ${GRAY}(Should fix for best practices)${NC}" echo -e " ${BLUE}Medium priority issues:${NC} ${CYAN}$medium_total${NC} ${GRAY}(Consider fixing)${NC}" echo # Add migration advice based on findings if [ $total_issues -eq 0 ]; then echo -e "${GREEN}${CHECK} Great news! No migration issues found. Your app appears ready for Meteor 3.0.${NC}" elif [ $critical_total -eq 0 ]; then echo -e "${YELLOW}${WARN} Your app has some non-critical issues but may work with Meteor 3.0.${NC}" echo -e "${YELLOW}${LIGHTBULB} Recommendation: Address the high priority issues for better compatibility.${NC}" else echo -e "${RED}${CROSS} Your app needs updates before it will work with Meteor 3.0.${NC}" echo -e "${RED}${LIGHTBULB} Focus first on fixing the ${CYAN}$critical_total${NC} ${RED}critical issues.${NC}" fi echo echo -e "${BLUE}${INFO} Next Steps:${NC}" echo -e " ${GRAY}1. Fix critical issues first (red items)${NC}" echo -e " ${GRAY}2. Address high priority issues (yellow items)${NC}" echo -e " ${GRAY}3. Consider fixing medium priority issues (blue items)${NC}" echo -e " ${GRAY}4. Run Meteor with ${CYAN}--release 3.3.0${NC} ${GRAY}to test${NC}" echo echo -e "${BLUE}${INFO} For more information, see:${NC}" echo -e " ${CYAN}https://docs.meteor.com/v3-migration-guide${NC}" echo # Exit with status code based on findings (helpful for CI/CD pipelines) if [ $critical_total -gt 0 ]; then exit 1 # Critical issues found elif [ $total_issues -gt 0 ]; then exit 0 # Issues found but not critical else exit 0 # No issues found fi