import { execFile, spawn } from 'node:child_process'; import { promisify } from 'node:util'; const run = promisify(execFile); // Run a git command inside `cwd`. Returns trimmed stdout; throws with git's // stderr on failure. `env` adds to (never replaces) the process environment. export async function git(cwd, args, { env } = {}) { try { const { stdout } = await run('git', args, { cwd, env: env ? { ...process.env, ...env } : process.env, }); return stdout.trim(); } catch (err) { const detail = (err.stderr || err.message || '').trim(); throw new Error(`git ${args.join(' ')} failed: ${detail}`); } } // Run a git command with inherited stdio so the user sees live progress and can // answer prompts (e.g. an SSH key passphrase). Used for `git push`. export function gitStream(cwd, args) { return new Promise((resolve, reject) => { const child = spawn('git', args, { cwd, stdio: 'inherit' }); child.on('error', reject); child.on('close', (code) => { if (code === 0) resolve(); else reject(new Error(`git ${args.join(' ')} exited with code ${code}`)); }); }); } // A generic .gitignore suited to Node projects. export const NODE_GITIGNORE = `# Dependencies node_modules/ .pnp/ .pnp.js # Logs logs/ *.log npm-debug.log* yarn-debug.log* yarn-error.log* pnpm-debug.log* # Build output dist/ build/ out/ *.tsbuildinfo # Coverage / test output coverage/ .nyc_output/ # Caches .cache/ .parcel-cache/ .eslintcache .npm/ # Environment .env .env.* !.env.example # Editor / OS cruft .DS_Store Thumbs.db .idea/ .vscode/ *.swp `;