From baa39555a836228a93591b343225851306fae599 Mon Sep 17 00:00:00 2001 From: Titus Owuor <54272773+titusowuor30@users.noreply.github.com> Date: Thu, 7 Aug 2025 05:08:42 +0300 Subject: [PATCH] feat: Add automated runtime installation scripts and documentation - Add install-runtimes.js script for bulk runtime installation - Create npm scripts for easy runtime management - Add comprehensive runtime installation guide to README - Support line-by-line runtime installation with progress tracking - Include error handling and automatic file creation - Add verification commands for testing installations --- .gitignore | 1 + install-runtimes.js | 211 ++++++++++++++++++++++++++++++++++++++++++++ package.json | 6 ++ readme.md | 75 ++++++++++++++++ runtimes.txt | 114 ++++++++++++++++++++++++ 5 files changed, 407 insertions(+) create mode 100644 install-runtimes.js create mode 100644 runtimes.txt diff --git a/.gitignore b/.gitignore index e82d86f..d5cb192 100644 --- a/.gitignore +++ b/.gitignore @@ -2,3 +2,4 @@ data/ .piston_env node_modules .vscode/ +.env diff --git a/install-runtimes.js b/install-runtimes.js new file mode 100644 index 0000000..1993db4 --- /dev/null +++ b/install-runtimes.js @@ -0,0 +1,211 @@ +const fs = require('fs'); +const path = require('path'); +const { execSync } = require('child_process'); + +// Function to create runtimes.txt from CLI list +function createRuntimesFile() { + try { + console.log('Creating runtimes.txt from available packages...'); + const command = 'node cli/index.js ppman list'; + const output = execSync(command, { encoding: 'utf8' }); + + // Parse the output and extract runtime information + const lines = output.split('\n').filter(line => line.trim()); + const runtimes = []; + + for (const line of lines) { + // Remove bullet points and clean the line + const cleanLine = line.replace(/^[•\s]+/, '').trim(); + if (!cleanLine) continue; + + // Split by space to get language and version + const parts = cleanLine.split(' '); + if (parts.length >= 2) { + const language = parts[0]; + const version = parts[1]; + runtimes.push(`${language} ${version}`); + } + } + + // Write to runtimes.txt + const runtimesFile = path.join(__dirname, 'runtimes.txt'); + fs.writeFileSync(runtimesFile, runtimes.join('\n') + '\n'); + console.log(`✓ Created runtimes.txt with ${runtimes.length} runtimes`); + + return runtimes.length; + } catch (error) { + console.error('Error creating runtimes.txt:', error.message); + return 0; + } +} + +// Function to parse runtimes from file line by line +function parseRuntimesLineByLine(filePath) { + try { + const content = fs.readFileSync(filePath, 'utf8'); + const lines = content.split('\n').filter(line => line.trim()); + + const runtimes = []; + for (const line of lines) { + // Clean up the line and extract runtime info + const cleanLine = line.replace(/[^\x00-\x7F]/g, '').trim(); + if (!cleanLine) continue; + + // Split by space to get language and version + const parts = cleanLine.split(' '); + if (parts.length >= 2) { + const language = parts[0]; + const version = parts[1]; + runtimes.push({ language, version }); + } + } + + return runtimes; + } catch (error) { + console.error('Error reading runtimes file:', error.message); + return []; + } +} + +// Function to install a single runtime +function installRuntime(language, version) { + try { + console.log(`Installing ${language} ${version}...`); + const command = `node cli/index.js ppman install ${language}=${version}`; + execSync(command, { stdio: 'inherit' }); + console.log(`✓ Successfully installed ${language} ${version}`); + return true; + } catch (error) { + console.error(`✗ Failed to install ${language} ${version}:`, error.message); + return false; + } +} + +// Function to install runtimes line by line +async function installRuntimesLineByLine() { + const runtimesFile = path.join(__dirname, 'runtimes.txt'); + + if (!fs.existsSync(runtimesFile)) { + console.log('runtimes.txt not found. Creating it from available packages...'); + const count = createRuntimesFile(); + if (count === 0) { + console.error('Failed to create runtimes.txt'); + process.exit(1); + } + } + + console.log('Reading runtimes from runtimes.txt line by line...'); + const runtimes = parseRuntimesLineByLine(runtimesFile); + + if (runtimes.length === 0) { + console.error('No runtimes found in runtimes.txt'); + process.exit(1); + } + + console.log(`Found ${runtimes.length} runtimes to install`); + console.log('Starting installation...\n'); + + let successCount = 0; + let failureCount = 0; + let currentIndex = 0; + + for (const runtime of runtimes) { + currentIndex++; + console.log(`[${currentIndex}/${runtimes.length}] Processing: ${runtime.language} ${runtime.version}`); + + const success = installRuntime(runtime.language, runtime.version); + if (success) { + successCount++; + } else { + failureCount++; + } + + // Add a delay between installations to avoid overwhelming the system + if (currentIndex < runtimes.length) { + console.log('Waiting 2 seconds before next installation...\n'); + await new Promise(resolve => setTimeout(resolve, 2000)); + } + } + + console.log('\n=== Installation Summary ==='); + console.log(`Successfully installed: ${successCount}`); + console.log(`Failed installations: ${failureCount}`); + console.log(`Total runtimes: ${runtimes.length}`); + + if (failureCount > 0) { + console.log('\nSome installations failed. You may want to retry failed ones manually.'); + } +} + +// Function to update runtimes.txt with clean format +function updateRuntimesFile() { + const runtimesFile = path.join(__dirname, 'runtimes.txt'); + const backupFile = path.join(__dirname, 'runtimes.backup.txt'); + + try { + // Create backup + if (fs.existsSync(runtimesFile)) { + fs.copyFileSync(runtimesFile, backupFile); + console.log('Created backup: runtimes.backup.txt'); + } + + // Read and clean the content + const content = fs.readFileSync(runtimesFile, 'utf8'); + const lines = content.split('\n').filter(line => line.trim()); + + // Clean up special characters and format properly + const cleanLines = lines.map(line => { + const cleanLine = line.replace(/[^\x00-\x7F]/g, '').trim(); + return cleanLine; + }).filter(line => line.length > 0); + + // Write back clean content + fs.writeFileSync(runtimesFile, cleanLines.join('\n') + '\n'); + console.log('✓ Cleaned up runtimes.txt file'); + + } catch (error) { + console.error('Error updating runtimes file:', error.message); + } +} + +// Main execution +if (require.main === module) { + const args = process.argv.slice(2); + + if (args.includes('--clean')) { + console.log('Cleaning runtimes.txt file...'); + updateRuntimesFile(); + process.exit(0); + } + + if (args.includes('--create')) { + console.log('Creating runtimes.txt from available packages...'); + createRuntimesFile(); + process.exit(0); + } + + if (args.includes('--help')) { + console.log('Usage: node install-runtimes.js [options]'); + console.log('Options:'); + console.log(' --clean Clean up the runtimes.txt file (remove special characters)'); + console.log(' --create Create runtimes.txt from available packages'); + console.log(' --help Show this help message'); + console.log(''); + console.log('If no options provided, will create runtimes.txt if not exists and install all runtimes'); + process.exit(0); + } + + // Default behavior: create runtimes.txt if not exists and install all runtimes + installRuntimesLineByLine().catch(error => { + console.error('Error during installation:', error); + process.exit(1); + }); +} + +module.exports = { + parseRuntimesLineByLine, + installRuntime, + installRuntimesLineByLine, + updateRuntimesFile, + createRuntimesFile +}; \ No newline at end of file diff --git a/package.json b/package.json index 8f07606..e48f80a 100644 --- a/package.json +++ b/package.json @@ -1,4 +1,10 @@ { + "scripts": { + "install-runtimes": "node install-runtimes.js", + "install-runtimes:clean": "node install-runtimes.js --clean", + "install-runtimes:create": "node install-runtimes.js --create", + "install-runtimes:help": "node install-runtimes.js --help" + }, "devDependencies": { "prettier": "2.4.1" } diff --git a/readme.md b/readme.md index 7724fdb..016af0d 100644 --- a/readme.md +++ b/readme.md @@ -198,6 +198,81 @@ cli/index.js run python test.py -l 3 If you are operating on a remote machine, add the `-u` flag like so: ```sh + +### Runtime Installation Scripts + +For easier runtime management, we've provided convenient npm scripts to install runtimes automatically: + +#### Quick Start + +```sh +# Install all available runtimes (recommended for first-time setup) +npm run install-runtimes +``` + +This will: +1. Create `runtimes.txt` from available packages if it doesn't exist +2. Install all runtimes line by line with progress tracking +3. Provide detailed logging and error handling + +#### Available Scripts + +```sh +# Install all runtimes from runtimes.txt +npm run install-runtimes + +# Create runtimes.txt from available packages +npm run install-runtimes:create + +# Clean up special characters from runtimes.txt +npm run install-runtimes:clean + +# Show help information +npm run install-runtimes:help +``` + +#### Manual Runtime Installation + +If you prefer to install runtimes manually or need specific versions: + +```sh +# List all available packages +node cli/index.js ppman list + +# Install specific runtime +node cli/index.js ppman install python=3.12.0 +node cli/index.js ppman install node=20.11.1 +node cli/index.js ppman install bash=5.2.0 +``` + +#### Runtime Installation Features + +- **Line-by-line processing**: Installs runtimes one at a time to avoid overwhelming the system +- **Progress tracking**: Shows current runtime being installed (e.g., [1/114]) +- **Error handling**: Continues installation even if some runtimes fail +- **Automatic file creation**: Creates `runtimes.txt` if it doesn't exist +- **Clean formatting**: Removes special characters from the file +- **Delay between installations**: 2-second delay to prevent system overload + +#### Verification + +After installation, verify your runtimes are available: + +```sh +# Check available runtimes via API +curl http://localhost:2000/api/v2/runtimes + +# Test a simple execution +curl -X POST http://localhost:2000/api/v2/execute \ + -H "Content-Type: application/json" \ + -d '{ + "language": "bash", + "version": "5.2.0", + "files": [{"name": "test.sh", "content": "echo \"Hello from Piston!\""}] + }' +``` + +### API cli/index.js -u http://piston.server:2000 ppman list ``` diff --git a/runtimes.txt b/runtimes.txt new file mode 100644 index 0000000..f93ff9e --- /dev/null +++ b/runtimes.txt @@ -0,0 +1,114 @@ +MATL 22.5.0 +MATL 22.7.4 +bash 5.1.0 +bash 5.2.0 +befunge93 0.2.0 +bqn 1.0.0 +brachylog 1.0.0 +brainfuck 2.7.3 +cjam 0.6.5 +clojure 1.10.3 +cobol 3.1.2 +coffeescript 2.5.1 +cow 1.0.0 +crystal 0.36.1 +crystal 1.9.2 +dart 2.12.1 +dart 2.19.6 +dart 3.0.1 +dash 0.5.11 +deno 1.16.2 +deno 1.32.3 +deno 1.7.5 +dotnet 5.0.201 +dragon 1.9.8 +elixir 1.11.3 +emacs 27.1.0 +emojicode 1.0.2 +erlang 23.0.0 +file 0.0.1 +forte 1.0.0 +forth 0.7.3 +freebasic 1.8.0 +freebasic 1.9.0 +gawk 5.1.0 +gcc 10.2.0 +go 1.16.2 +golfscript 1.0.0 +groovy 3.0.7 +haskell 9.0.1 +husk 1.0.0 +iverilog 11.0.0 +japt 2.0.0 +java 15.0.2 +jelly 0.1.31 +julia 1.5.4 +julia 1.6.1 +julia 1.8.5 +kotlin 1.4.31 +kotlin 1.8.20 +lisp 2.1.2 +llvm_ir 12.0.1 +lolcode 0.11.2 +lua 5.4.2 +lua 5.4.4 +mono 6.12.0 +nasm 2.15.5 +nim 1.4.4 +nim 1.6.2 +node 15.10.0 +node 16.3.0 +node 18.15.0 +node 20.11.1 +ocaml 4.12.0 +octave 6.2.0 +octave 8.1.0 +osabie 1.0.1 +paradoc 0.6.0 +pascal 3.2.0 +pascal 3.2.2 +perl 5.26.1 +perl 5.36.0 +php 8.0.2 +php 8.2.3 +ponylang 0.39.0 +prolog 8.2.4 +pure 0.68.0 +pwsh 7.1.4 +pyth 1.0.0 +python 2.7.18 +python 3.10.0 +python 3.11.0 +python 3.12.0 +python 3.5.10 +python 3.9.1 +python 3.9.4 +racket 8.3.0 +raku 6.100.0 +retina 1.2.0 +rockstar 1.0.0 +rscript 4.1.1 +ruby 2.5.1 +ruby 3.0.1 +rust 1.50.0 +rust 1.56.1 +rust 1.62.0 +rust 1.63.0 +rust 1.65.0 +rust 1.68.2 +samarium 0.3.1 +scala 3.0.0 +scala 3.2.2 +smalltalk 3.2.3 +sqlite3 3.36.0 +swift 5.3.3 +typescript 4.2.3 +typescript 5.0.3 +vlang 0.1.13 +vlang 0.3.3 +vyxal 2.4.1 +yeethon 3.10.0 +zig 0.10.1 +zig 0.7.1 +zig 0.8.0 +zig 0.9.1