#!/usr/bin/env bash # Local Git Server Simulation for Team Workflows # Creates a local bare repository to simulate a remote server for testing git workflows set -euo pipefail SCRIPT_DIR="$(cd "$(dirname "${BASH_SOURCE[0]}")" && pwd)" PROJECT_ROOT="$(cd "$SCRIPT_DIR/.." && pwd)" LOCAL_SERVER_DIR="$PROJECT_ROOT/.git-local-server" BARE_REPO_DIR="$LOCAL_SERVER_DIR/mev-bot.git" # Colors GREEN='\033[0;32m' YELLOW='\033[1;33m' BLUE='\033[0;34m' RED='\033[0;31m' NC='\033[0m' log() { echo -e "${GREEN}[GIT-SERVER]${NC} $*" } warn() { echo -e "${YELLOW}[WARNING]${NC} $*" } error() { echo -e "${RED}[ERROR]${NC} $*" } info() { echo -e "${BLUE}[INFO]${NC} $*" } usage() { cat << EOF Local Git Server Simulation for MEV Bot Development USAGE: $0 [args] SERVER MANAGEMENT: init - Initialize local git server start - Start local git server (if using daemon) stop - Stop local git server status - Show server status clean - Clean server data REPOSITORY OPERATIONS: clone-fresh - Clone fresh copy from local server push-all - Push all branches to local server pull-all - Pull all branches from local server sync-remotes - Sync with local server TEAM SIMULATION: simulate-dev - Simulate developer workflow simulate-pr - Simulate PR workflow simulate-conflict - Create merge conflict scenario simulate-team - Multi-developer simulation EXAMPLES: $0 init # Setup local git server $0 clone-fresh alice # Create alice's working copy $0 simulate-dev bob # Simulate bob's development $0 simulate-pr feature/new-algo # Simulate PR workflow EOF } # Initialize local git server init_server() { log "Initializing local git server..." # Create server directory mkdir -p "$LOCAL_SERVER_DIR" # Create bare repository if [[ -d "$BARE_REPO_DIR" ]]; then warn "Local server already exists at: $BARE_REPO_DIR" read -p "Reinitialize? (y/N): " -n 1 -r echo if [[ ! $REPLY =~ ^[Yy]$ ]]; then exit 0 fi rm -rf "$BARE_REPO_DIR" fi # Initialize bare repository git init --bare "$BARE_REPO_DIR" # Push current repository to server cd "$PROJECT_ROOT" # Add local server as remote if not exists if ! git remote get-url local-server >/dev/null 2>&1; then git remote add local-server "$BARE_REPO_DIR" else git remote set-url local-server "$BARE_REPO_DIR" fi # Push all branches log "Pushing current repository to local server..." git push local-server --all 2>/dev/null || true git push local-server --tags 2>/dev/null || true # Create post-receive hook for CI integration cat > "$BARE_REPO_DIR/hooks/post-receive" << 'EOF' #!/usr/bin/env bash # Post-receive hook - Run CI on pushes to main branches while read oldrev newrev refname; do branch=$(echo $refname | sed -n 's/^refs\/heads\///p') if [[ "$branch" == "master" ]] || [[ "$branch" == "main" ]] || [[ "$branch" == "develop" ]]; then echo "๐Ÿš€ Running CI for $branch branch..." # Create temporary checkout temp_dir=$(mktemp -d) git --git-dir="$PWD" --work-tree="$temp_dir" checkout -f "$branch" # Run CI in the temporary directory ( cd "$temp_dir" if [[ -f "Makefile" ]] && command -v make >/dev/null 2>&1; then echo "Running CI pipeline..." make ci-quick || echo "CI failed for $branch" else echo "No CI configuration found" fi ) # Cleanup rm -rf "$temp_dir" fi done EOF chmod +x "$BARE_REPO_DIR/hooks/post-receive" log "โœ… Local git server initialized at: $BARE_REPO_DIR" log "๐Ÿ“ Remote added as: local-server" log "๐ŸŽฏ Server URL: $BARE_REPO_DIR" # Create server info file cat > "$LOCAL_SERVER_DIR/server-info.txt" << EOF MEV Bot Local Git Server ======================== Repository: $BARE_REPO_DIR Remote name: local-server Initialized: $(date) Available commands: git clone $BARE_REPO_DIR git remote add origin $BARE_REPO_DIR git push local-server git pull local-server Hooks installed: - post-receive: CI integration for main branches EOF log "๐Ÿ“‹ Server info saved to: $LOCAL_SERVER_DIR/server-info.txt" } # Show server status show_status() { if [[ ! -d "$BARE_REPO_DIR" ]]; then error "Local git server not initialized" echo "Run: $0 init" exit 1 fi log "Local Git Server Status" echo "" echo "๐Ÿ“ Server Location: $BARE_REPO_DIR" echo "๐Ÿ“Š Repository Size: $(du -sh "$BARE_REPO_DIR" 2>/dev/null | cut -f1)" echo "" echo "๐ŸŒฟ Branches:" git --git-dir="$BARE_REPO_DIR" branch -a || echo "No branches" echo "" echo "๐Ÿท๏ธ Tags:" git --git-dir="$BARE_REPO_DIR" tag -l | head -10 || echo "No tags" echo "" echo "๐Ÿ“ˆ Recent Activity:" git --git-dir="$BARE_REPO_DIR" log --oneline --all -10 2>/dev/null || echo "No commits" echo "" echo "๐Ÿ”— Remote Configuration in Main Repo:" cd "$PROJECT_ROOT" if git remote get-url local-server >/dev/null 2>&1; then echo "โœ… local-server: $(git remote get-url local-server)" else echo "โŒ local-server remote not configured" fi } # Clone fresh copy from local server clone_fresh() { local clone_name="$1" if [[ -z "$clone_name" ]]; then error "Clone name required" echo "Usage: $0 clone-fresh " exit 1 fi if [[ ! -d "$BARE_REPO_DIR" ]]; then error "Local git server not initialized" echo "Run: $0 init" exit 1 fi local clone_dir="$LOCAL_SERVER_DIR/clones/$clone_name" if [[ -d "$clone_dir" ]]; then warn "Clone already exists: $clone_dir" read -p "Remove and re-clone? (y/N): " -n 1 -r echo if [[ $REPLY =~ ^[Yy]$ ]]; then rm -rf "$clone_dir" else exit 0 fi fi log "Creating fresh clone: $clone_name" # Create clone directory mkdir -p "$(dirname "$clone_dir")" # Clone from local server git clone "$BARE_REPO_DIR" "$clone_dir" # Set up useful configuration cd "$clone_dir" # Configure git for this clone git config user.name "Developer $clone_name" git config user.email "$clone_name@mev-bot.local" # Add convenience aliases git config alias.st status git config alias.co checkout git config alias.br branch git config alias.ci commit git config alias.up "pull --rebase" log "โœ… Fresh clone created: $clone_dir" log "๐Ÿ’ก To use this clone:" log " cd $clone_dir" log " git checkout -b feature/your-feature" log " # ... make changes ..." log " git push origin feature/your-feature" } # Simulate developer workflow simulate_dev() { local dev_name="$1" if [[ -z "$dev_name" ]]; then error "Developer name required" echo "Usage: $0 simulate-dev " exit 1 fi log "Simulating developer workflow for: $dev_name" # Create or use existing clone local clone_dir="$LOCAL_SERVER_DIR/clones/$dev_name" if [[ ! -d "$clone_dir" ]]; then log "Creating clone for $dev_name..." clone_fresh "$dev_name" fi cd "$clone_dir" # Simulate development workflow log "๐Ÿ”„ Pulling latest changes..." git checkout develop 2>/dev/null || git checkout master git pull origin "$(git branch --show-current)" # Create feature branch local feature_name="feature/$dev_name-$(date +%H%M%S)" log "๐ŸŒฟ Creating feature branch: $feature_name" git checkout -b "$feature_name" # Simulate some development echo "// Development by $dev_name at $(date)" >> "dev-notes-$dev_name.txt" echo "Implemented new feature for MEV optimization" >> "dev-notes-$dev_name.txt" git add "dev-notes-$dev_name.txt" # Commit with conventional format git commit -m "feat($dev_name): implement MEV optimization feature - Add new optimization algorithm - Improve performance by 15% - Update documentation Closes #123" # Run CI before push log "๐Ÿงช Running CI validation..." if [[ -f "../../../Makefile" ]]; then make -C "../../.." ci-quick 2>/dev/null || warn "CI validation failed" fi # Push feature branch log "๐Ÿš€ Pushing feature branch..." git push origin "$feature_name" log "โœ… Developer workflow completed for $dev_name" log "๐Ÿ“‚ Working directory: $clone_dir" log "๐ŸŒฟ Feature branch: $feature_name" log "๐Ÿ’ก Next: Simulate PR with: $0 simulate-pr $feature_name" } # Simulate PR workflow simulate_pr() { local branch_name="$1" if [[ -z "$branch_name" ]]; then error "Branch name required" echo "Usage: $0 simulate-pr " exit 1 fi log "Simulating PR workflow for branch: $branch_name" # Find which clone has this branch local clone_dir="" for dir in "$LOCAL_SERVER_DIR/clones"/*; do if [[ -d "$dir" ]]; then cd "$dir" if git show-ref --verify --quiet "refs/heads/$branch_name" 2>/dev/null; then clone_dir="$dir" break fi fi done if [[ -z "$clone_dir" ]]; then error "Branch $branch_name not found in any clone" exit 1 fi cd "$clone_dir" log "๐Ÿ“‹ PR Simulation: $branch_name โ†’ develop" # Show PR summary echo "" echo "๐Ÿ“ PR Summary:" git log --oneline "develop..$branch_name" 2>/dev/null || git log --oneline "master..$branch_name" echo "" echo "๐Ÿ“Š Changed files:" git diff --name-status "develop..$branch_name" 2>/dev/null || git diff --name-status "master..$branch_name" # Run PR validation log "๐Ÿ” Running PR validation..." git checkout "$branch_name" # Simulate CI for PR if [[ -f "../../../Makefile" ]]; then log "Running CI pipeline..." make -C "../../.." ci-dev 2>/dev/null || warn "CI validation had issues" fi # Check for conflicts log "๐Ÿ”€ Checking for merge conflicts..." local target_branch="develop" if ! git show-ref --verify --quiet "refs/heads/$target_branch" 2>/dev/null; then target_branch="master" fi if git merge-tree "$(git merge-base "$target_branch" "$branch_name")" "$target_branch" "$branch_name" | grep -q "<<<<<<< "; then warn "โš ๏ธ Merge conflicts detected" echo "Conflicts would need resolution before merge" else log "โœ… No merge conflicts detected" fi log "๐Ÿ“‹ PR Status: Ready for review and merge" log "๐Ÿ’ก To merge: $0 merge-pr $branch_name $target_branch" } # Simulate merge conflicts simulate_conflict() { log "Simulating merge conflict scenario..." # Create two conflicting branches local dev1_clone="$LOCAL_SERVER_DIR/clones/dev1" local dev2_clone="$LOCAL_SERVER_DIR/clones/dev2" # Ensure clones exist [[ ! -d "$dev1_clone" ]] && clone_fresh "dev1" [[ ! -d "$dev2_clone" ]] && clone_fresh "dev2" # Dev1 makes changes cd "$dev1_clone" git checkout develop 2>/dev/null || git checkout master git pull origin "$(git branch --show-current)" git checkout -b "feature/dev1-conflict" echo "// Configuration by dev1" > shared-config.go echo "const DefaultValue = 100" >> shared-config.go git add shared-config.go git commit -m "feat(config): set default value to 100" git push origin "feature/dev1-conflict" # Dev2 makes conflicting changes cd "$dev2_clone" git checkout develop 2>/dev/null || git checkout master git pull origin "$(git branch --show-current)" git checkout -b "feature/dev2-conflict" echo "// Configuration by dev2" > shared-config.go echo "const DefaultValue = 200" >> shared-config.go git add shared-config.go git commit -m "feat(config): set default value to 200" git push origin "feature/dev2-conflict" log "โœ… Conflict scenario created" log "๐Ÿ”€ Two branches with conflicting changes:" log " - feature/dev1-conflict (sets value to 100)" log " - feature/dev2-conflict (sets value to 200)" log "๐Ÿ’ก Try merging one into develop to see conflict resolution" } # Push all branches to local server push_all() { cd "$PROJECT_ROOT" if ! git remote get-url local-server >/dev/null 2>&1; then error "local-server remote not configured" echo "Run: $0 init" exit 1 fi log "Pushing all branches to local server..." git push local-server --all git push local-server --tags log "โœ… All branches and tags pushed to local server" } # Clean server data clean_server() { warn "This will remove all local server data" read -p "Continue? (y/N): " -n 1 -r echo if [[ ! $REPLY =~ ^[Yy]$ ]]; then echo "Cancelled" exit 0 fi log "Cleaning local git server data..." # Remove server directory if [[ -d "$LOCAL_SERVER_DIR" ]]; then rm -rf "$LOCAL_SERVER_DIR" log "โœ… Server data removed" fi # Remove local-server remote from main repo cd "$PROJECT_ROOT" if git remote get-url local-server >/dev/null 2>&1; then git remote remove local-server log "โœ… local-server remote removed" fi log "๐Ÿงน Cleanup completed" } # Main command dispatcher main() { if [[ $# -eq 0 ]]; then usage exit 0 fi local command="$1" shift case "$command" in init) init_server ;; status) show_status ;; clone-fresh) clone_fresh "$@" ;; simulate-dev) simulate_dev "$@" ;; simulate-pr) simulate_pr "$@" ;; simulate-conflict) simulate_conflict ;; push-all) push_all ;; clean) clean_server ;; *) error "Unknown command: $command" usage exit 1 ;; esac } # Run main function main "$@"