#!/usr/bin/env tsx import { execSync } from 'node:child_process'; import { performance } from 'node:perf_hooks'; interface Step { name: string; command: string; emoji: string; description: string; } const steps: Step[] = [ { name: 'lint', command: 'turbo run lint --ui=stream', emoji: '๐Ÿ”', description: 'Running linter checks' }, { name: 'build', command: 'turbo run build --ui=stream', emoji: '๐Ÿ—๏ธ', description: 'Building all packages' }, { name: 'test', command: 'turbo run test', emoji: '๐Ÿงช', description: 'Running all tests' } ]; function formatTime(ms: number): string { if (ms < 1000) { return `${Math.round(ms)}ms`; } const seconds = ms / 1000; if (seconds < 60) { return `${seconds.toFixed(1)}s`; } const minutes = Math.floor(seconds / 60); const remainingSeconds = Math.floor(seconds % 60); return `${minutes}m ${remainingSeconds}s`; } function runStep(step: Step, stepNumber: number, totalSteps: number): boolean { console.log(`\n${step.emoji} [${stepNumber}/${totalSteps}] ${step.description}...`); console.log(`๐Ÿ“ Command: ${step.command}`); const startTime = performance.now(); try { execSync(step.command, { stdio: 'inherit', cwd: process.cwd() }); const endTime = performance.now(); const duration = formatTime(endTime - startTime); console.log(`โœ… ${step.name} completed successfully in ${duration}`); return true; } catch (error) { const endTime = performance.now(); const duration = formatTime(endTime - startTime); console.log(`โŒ ${step.name} failed after ${duration}`); console.error(`๐Ÿ’ฅ Error in ${step.name}:`, error); return false; } } function main() { console.log('๐Ÿš€ Starting pre-PR checks...\n'); console.log('๐ŸŽฏ This will run: lint โ†’ build โ†’ test'); console.log('โฑ๏ธ Grab a coffee, this might take a while!\n'); console.log('โ•'.repeat(50)); const overallStartTime = performance.now(); let failedSteps: string[] = []; for (let i = 0; i < steps.length; i++) { const step = steps[i]; const success = runStep(step, i + 1, steps.length); if (!success) { failedSteps.push(step.name); break; // Stop on first failure } } const overallEndTime = performance.now(); const totalDuration = formatTime(overallEndTime - overallStartTime); console.log('\n' + 'โ•'.repeat(50)); if (failedSteps.length === 0) { console.log('๐ŸŽ‰ All pre-PR checks passed!'); console.log('โœจ Your code is ready for review!'); console.log(`โฐ Total time: ${totalDuration}`); console.log('๐Ÿšข Safe to create that PR! ๐Ÿšข'); process.exit(0); } else { console.log('๐Ÿ’ฅ Pre-PR checks failed!'); console.log(`โŒ Failed steps: ${failedSteps.join(', ')}`); console.log(`โฐ Total time: ${totalDuration}`); console.log('๐Ÿ”ง Please fix the issues above before creating a PR.'); process.exit(1); } } // Handle Ctrl+C gracefully process.on('SIGINT', () => { console.log('\n\n๐Ÿ›‘ Pre-PR checks interrupted by user'); console.log('๐Ÿ‘‹ See you next time!'); process.exit(130); }); main();