diff --git a/src/index.ts b/src/index.ts index 6539974..1b3a8be 100644 --- a/src/index.ts +++ b/src/index.ts @@ -9,7 +9,7 @@ import { import { randomBytes } from 'crypto'; import { join } from 'path'; import { mkdir, writeFile, appendFile, readFile, access } from 'fs/promises'; -import { exec, ExecOptions } from 'child_process'; +import { exec, execFile, ExecOptions } from 'child_process'; import { promisify } from 'util'; import { platform } from 'os'; @@ -52,6 +52,7 @@ if (ENV_CONFIG.type === 'conda' && !ENV_CONFIG.conda_name) { await mkdir(CODE_STORAGE_DIR, { recursive: true }); const execAsync = promisify(exec); +const execFileAsync = promisify(execFile); /** * Get platform-specific command for environment activation and execution @@ -324,38 +325,41 @@ async function installDependencies(packages: string[]) { }; } - // Build the install command based on environment type - let installCmd = ''; - const packageList = packages.join(' '); - + let file = ''; + let args: string[] = []; + const isWindows = platform() === 'win32'; + switch (ENV_CONFIG.type) { case 'conda': if (!ENV_CONFIG.conda_name) { throw new Error("conda_name is required for conda environment"); } - installCmd = `conda install -y -n ${ENV_CONFIG.conda_name} ${packageList}`; + file = 'conda'; + args = ['install', '-y', '-n', ENV_CONFIG.conda_name, ...packages]; break; case 'venv': - installCmd = `pip install ${packageList}`; + if (!ENV_CONFIG.venv_path) { + throw new Error("venv_path is required for virtualenv"); + } + file = isWindows + ? join(ENV_CONFIG.venv_path, 'Scripts', 'pip.exe') + : join(ENV_CONFIG.venv_path, 'bin', 'pip'); + args = ['install', ...packages]; break; case 'venv-uv': - installCmd = `uv pip install ${packageList}`; + file = 'uv'; + args = ['pip', 'install', ...packages]; break; default: throw new Error(`Unsupported environment type: ${ENV_CONFIG.type}`); } - // Get platform-specific command - const { command, options } = getPlatformSpecificCommand(installCmd); - - // Execute installation with unbuffered Python - const { stdout, stderr } = await execAsync(command, { + const { stdout, stderr } = await execFileAsync(file, args, { cwd: CODE_STORAGE_DIR, - env: { ...process.env, PYTHONUNBUFFERED: '1' }, - ...options + env: { ...process.env, PYTHONUNBUFFERED: '1' } }); const response = {