diff --git a/scripts/compile-babel.js b/scripts/compile-babel.js index 4f7403dd..6079bda7 100644 --- a/scripts/compile-babel.js +++ b/scripts/compile-babel.js @@ -2,7 +2,7 @@ // ========= Copyright 2025-2026 @ Eigent.ai All Rights Reserved. ========= // Directly use venv's python.exe (not uv run) to avoid Windows .exe launcher // placeholder issues - same reason we use direct python for backend/uvicorn. -/* global process */ +/* global process, console */ import { execSync } from 'child_process'; import fs from 'fs'; @@ -16,13 +16,31 @@ const prebuiltVenvDir = path.join(projectRoot, 'resources', 'prebuilt', 'venv'); const isWindows = process.platform === 'win32'; // Prebuild uses resources/prebuilt/venv; dev may use backend/.venv -const venvDir = fs.existsSync(prebuiltVenvDir) - ? prebuiltVenvDir - : path.join(backendDir, '.venv'); +const devVenvDir = path.join(backendDir, '.venv'); +let venvDir; +if (fs.existsSync(prebuiltVenvDir)) { + venvDir = prebuiltVenvDir; +} else if (fs.existsSync(devVenvDir)) { + venvDir = devVenvDir; +} else { + console.error( + 'No Python venv found. Please run "uv sync" in the backend directory first.' + ); + console.error(` Looked for: ${prebuiltVenvDir}`); + console.error(` And: ${devVenvDir}`); + process.exit(1); +} + const pythonPath = isWindows ? path.join(venvDir, 'Scripts', 'python.exe') : path.join(venvDir, 'bin', 'python'); +if (!fs.existsSync(pythonPath)) { + console.error(`Python executable not found at: ${pythonPath}`); + console.error(' The venv may be corrupted. Please recreate it.'); + process.exit(1); +} + execSync(`"${pythonPath}" -m babel.messages.frontend compile -d lang`, { cwd: backendDir, stdio: 'inherit', diff --git a/scripts/fix-symlinks.js b/scripts/fix-symlinks.js index 8fe36960..6ce3a1ca 100644 --- a/scripts/fix-symlinks.js +++ b/scripts/fix-symlinks.js @@ -138,11 +138,18 @@ function fixVenvSymlinks(venvPath, venvName) { // Check if symlink exists let needsFix = false; let currentTarget = null; + let symlinkExists = false; - if ( - fs.existsSync(symlinkPath) || - fs.lstatSync(symlinkPath).isSymbolicLink() - ) { + // Use lstatSync to check if symlink exists (works for broken symlinks too) + try { + const stat = fs.lstatSync(symlinkPath); + symlinkExists = stat.isSymbolicLink(); + } catch { + // File/symlink doesn't exist at all + symlinkExists = false; + } + + if (symlinkExists) { try { currentTarget = fs.readlinkSync(symlinkPath); @@ -162,7 +169,7 @@ function fixVenvSymlinks(venvPath, venvName) { continue; } } catch (err) { - // Broken symlink + // readlinkSync failed - symlink is broken needsFix = true; console.log( ` ❌ ${symlinkName}: broken symlink (target doesn't exist), ${err.message}` @@ -174,19 +181,13 @@ function fixVenvSymlinks(venvPath, venvName) { } if (needsFix) { - // Remove existing symlink + // Remove existing symlink if it exists try { - if ( - fs.existsSync(symlinkPath) || - fs.lstatSync(symlinkPath).isSymbolicLink() - ) { - fs.unlinkSync(symlinkPath); - } - } catch (err) { - console.error( - ` ❌ Failed to remove ${symlinkName}: ${err.message}` - ); - // Ignore + fs.lstatSync(symlinkPath); + // If lstatSync succeeds, the file/symlink exists + fs.unlinkSync(symlinkPath); + } catch { + // File doesn't exist, nothing to remove } // Calculate relative path from bin/ to the Python executable