UNPKG

gitarsenal-cli

Version:

CLI tool for creating Modal sandboxes with GitHub repositories

164 lines (135 loc) 4.05 kB
const path = require('path'); const fs = require('fs-extra'); const { spawn } = require('child_process'); const chalk = require('chalk'); const ora = require('ora'); const { promisify } = require('util'); const { exec } = require('child_process'); const os = require('os'); const { runE2BSandbox } = require('./e2b-sandbox'); const execAsync = promisify(exec); /** * Get the path to the Python script * @returns {string} - Path to the Python script */ function getPythonScriptPath() { // First check if the script exists in the package directory const packageScriptPath = path.join(__dirname, '..', 'python', 'test_modalSandboxScript.py'); if (fs.existsSync(packageScriptPath)) { return packageScriptPath; } // If not found, return the path where it will be copied during installation return path.join(os.homedir(), '.gitarsenal', 'python', 'test_modalSandboxScript.py'); } /** * Run a container with the given options * @param {Object} options - Container options * @returns {Promise<void>} */ async function runContainer(options = {}) { const { showExamples = false, repoUrl = '', gpuType = 'A10G', gpuCount = 1, volumeName = '', setupCommands = [], yes = false, userId = '', userName = '', userEmail = '', apiKeys = {}, analysisData = null, sandboxProvider = 'modal' } = options; // Check if this is just a request to show examples if (showExamples) { const scriptPath = getPythonScriptPath(); const pythonProcess = spawn('python', [ scriptPath, '--show-examples' ], { stdio: 'inherit' }); return new Promise((resolve, reject) => { pythonProcess.on('close', (code) => { if (code === 0) { resolve(); } else { reject(new Error(`Process exited with code ${code}`)); } }); }); } // Choose sandbox provider if (sandboxProvider === 'e2b') { console.log(chalk.blue('🚀 Using E2B sandbox provider')); return runE2BSandbox({ repoUrl, setupCommands, userId, userName, userEmail, apiKeys }); } console.log(chalk.blue('🚀 Using Modal sandbox provider')); // Get the path to the Python script const scriptPath = getPythonScriptPath(); if (!fs.existsSync(scriptPath)) { throw new Error(`Python script not found at ${scriptPath}`); } console.log('Launching container...'); // Convert setup commands to JSON for passing to Python const setupCommandsJson = JSON.stringify(setupCommands); // Convert analysis data to JSON for passing to Python const analysisDataJson = analysisData ? JSON.stringify(analysisData) : ''; // Convert API keys to JSON for passing to Python const apiKeysJson = JSON.stringify(apiKeys); // Build the command arguments const args = [ scriptPath, '--gpu', gpuType, ]; if (gpuCount && gpuCount > 1) { args.push('--gpu-count', gpuCount.toString()); } if (repoUrl) { args.push('--repo-url', repoUrl); } if (volumeName) { args.push('--volume-name', volumeName); } if (setupCommands && setupCommands.length > 0) { args.push('--setup-commands-json', setupCommandsJson); } if (userId) { args.push('--user-id', userId); } if (userName) { args.push('--user-name', userName); } if (userEmail) { args.push('--display-name', userEmail); } if (analysisDataJson) { args.push('--analysis-data', analysisDataJson); } if (yes) { args.push('--yes'); } // Use system Python instead of virtual env Python const pythonCmd = process.platform === 'win32' ? 'python' : 'python3'; // Run the Python script const pythonProcess = spawn(pythonCmd, args, { stdio: 'inherit' }); return new Promise((resolve, reject) => { pythonProcess.on('close', (code) => { if (code === 0) { resolve(); } else { reject(new Error(`Process exited with code ${code}`)); } }); }); } module.exports = { runContainer };