Rebuild the frontend. Returns: True if build succeeded, False otherwise.
()
| 69 | |
| 70 | |
| 71 | def rebuild_frontend() -> bool: |
| 72 | """ |
| 73 | Rebuild the frontend. |
| 74 | |
| 75 | Returns: |
| 76 | True if build succeeded, False otherwise. |
| 77 | """ |
| 78 | if not _FRONTEND_DIR.exists(): |
| 79 | logger.warning(f"Frontend directory not found: {_FRONTEND_DIR}") |
| 80 | return False |
| 81 | |
| 82 | if not check_npm_available(): |
| 83 | logger.warning("npm not installed, skipping frontend rebuild") |
| 84 | return False |
| 85 | |
| 86 | # Check if node_modules exists |
| 87 | if not (_FRONTEND_DIR / "node_modules").exists(): |
| 88 | logger.info("[Build] Installing frontend dependencies...") |
| 89 | try: |
| 90 | result = subprocess.run( |
| 91 | ["npm", "install"], |
| 92 | cwd=str(_FRONTEND_DIR), |
| 93 | capture_output=True, |
| 94 | text=True, |
| 95 | timeout=120, |
| 96 | ) |
| 97 | if result.returncode != 0: |
| 98 | logger.error(f"npm install failed: {result.stderr}") |
| 99 | return False |
| 100 | except subprocess.TimeoutExpired: |
| 101 | logger.error("npm install timed out") |
| 102 | return False |
| 103 | except Exception as e: |
| 104 | logger.error(f"npm install error: {e}") |
| 105 | return False |
| 106 | |
| 107 | logger.info("[Build] Building frontend...") |
| 108 | try: |
| 109 | result = subprocess.run( |
| 110 | ["npm", "run", "build"], |
| 111 | cwd=str(_FRONTEND_DIR), |
| 112 | capture_output=True, |
| 113 | text=True, |
| 114 | timeout=60, |
| 115 | ) |
| 116 | if result.returncode == 0: |
| 117 | logger.info("[Build] Frontend build succeeded") |
| 118 | return True |
| 119 | else: |
| 120 | # TypeScript errors go to stdout, other errors to stderr |
| 121 | error_output = result.stdout.strip() or result.stderr.strip() |
| 122 | if error_output: |
| 123 | # Truncate long error messages for readability |
| 124 | if len(error_output) > 500: |
| 125 | error_output = error_output[:500] + "\n... (truncated)" |
| 126 | logger.error(f"Frontend build failed:\n{error_output}") |
| 127 | else: |
| 128 | logger.error(f"Frontend build failed (exit code: {result.returncode})") |
no test coverage detected