Skip to main content
Glama

Git MCP Server

make-executable.ts4.49 kB
#!/usr/bin/env node /** * @fileoverview Utility script to make files executable (chmod +x) on Unix-like systems. * @module scripts/make-executable * On Windows, this script does nothing but exits successfully. * Useful for CLI applications where built output needs executable permissions. * Default target (if no args): dist/index.js. * Ensures output paths are within the project directory for security. * * @example * // Add to package.json build script: * // "build": "tsc && ts-node --esm scripts/make-executable.ts dist/index.js" * * @example * // Run directly with custom files: * // ts-node --esm scripts/make-executable.ts path/to/script1 path/to/script2 */ import fs from 'fs/promises'; import os from 'os'; import path from 'path'; const isUnix = os.platform() !== 'win32'; const projectRoot = process.cwd(); const EXECUTABLE_MODE = 0o755; // rwxr-xr-x /** * Represents the result of an attempt to make a file executable. * @property file - The relative path of the file targeted. * @property status - The outcome of the operation ('success', 'error', or 'skipped'). * @property reason - If status is 'error' or 'skipped', an explanation. */ interface ExecutableResult { file: string; status: 'success' | 'error' | 'skipped'; reason?: string; } /** * Main function to make specified files executable. * Skips operation on Windows. Processes command-line arguments for target files * or defaults to 'dist/index.js'. Reports status for each file. */ const makeExecutable = async (): Promise<void> => { try { const targetFiles: string[] = process.argv.slice(2).length > 0 ? process.argv.slice(2) : ['dist/index.js']; if (!isUnix) { console.log( 'Skipping chmod operation: Script is running on Windows (not applicable).', ); return; } console.log( `Attempting to make files executable: ${targetFiles.join(', ')}`, ); const results = await Promise.allSettled( targetFiles.map(async (targetFile): Promise<ExecutableResult> => { const normalizedPath = path.resolve(projectRoot, targetFile); if ( !normalizedPath.startsWith(projectRoot + path.sep) && normalizedPath !== projectRoot ) { return { file: targetFile, status: 'error', reason: `Path resolves outside project boundary: ${normalizedPath}`, }; } try { await fs.access(normalizedPath); // Check if file exists await fs.chmod(normalizedPath, EXECUTABLE_MODE); return { file: targetFile, status: 'success' }; } catch (error) { const err = error as NodeJS.ErrnoException; if (err.code === 'ENOENT') { return { file: targetFile, status: 'error', reason: 'File not found', }; } console.error( `Error setting executable permission for ${targetFile}: ${err.message}`, ); return { file: targetFile, status: 'error', reason: err.message }; } }), ); let hasErrors = false; results.forEach((result) => { if (result.status === 'fulfilled') { const { file, status, reason } = result.value; if (status === 'success') { console.log(`Successfully made executable: ${file}`); } else if (status === 'error') { console.error(`Error for ${file}: ${reason}`); hasErrors = true; } else if (status === 'skipped') { // This status is not currently generated by the mapAsync logic but kept for future flexibility console.warn(`Skipped ${file}: ${reason}`); } } else { console.error( `Unexpected failure for one of the files: ${result.reason}`, ); hasErrors = true; } }); if (hasErrors) { console.error( 'One or more files could not be made executable. Please check the errors above.', ); // process.exit(1); // Uncomment to exit with error if any file fails } else { console.log('All targeted files processed successfully.'); } } catch (error) { console.error( 'A fatal error occurred during the make-executable script:', error instanceof Error ? error.message : error, ); process.exit(1); } }; // Intentionally not awaiting; internal try/catch handles errors. void makeExecutable();

MCP directory API

We provide all the information about MCP servers via our MCP API.

curl -X GET 'https://glama.ai/api/mcp/v1/servers/cyanheads/git-mcp-server'

If you have feedback or need assistance with the MCP directory API, please join our Discord server