System command execution utilities for running external processes, managing system operations, and integrating with operating system functionality.
Core functions for executing system commands with different execution patterns and output handling.
/**
* Execute command using execa with full result object
* @param command - Command string to execute
* @param options - Execution options (execa options)
* @returns Promise resolving to full execa result object
*/
exec(command: string, options?: any): Promise<{
stdout: string;
stderr: string;
exitCode: number;
command: string;
escapedCommand: string;
failed: boolean;
timedOut: boolean;
isCanceled: boolean;
killed: boolean;
signal?: string;
signalDescription?: string;
}>;
/**
* Execute command and return trimmed stdout
* @param command - Command string to execute
* @param options - Execution options
* @returns Promise resolving to trimmed stdout string
*/
run(command: string, options?: any): Promise<string>;
/**
* Spawn command using cross-spawn
* @param command - Command string to spawn
* @param options - Spawn options (cross-spawn options)
* @returns Promise resolving to spawn result
*/
spawn(command: string, options?: any): Promise<any>;Command Execution Examples:
import { system } from "gluegun";
// Get simple output
const nodeVersion = await system.run("node --version");
console.log(`Node.js: ${nodeVersion}`); // "Node.js: v18.17.0"
// Full execution details
try {
const result = await system.exec("npm install --silent");
if (result.exitCode === 0) {
console.log("Installation successful");
}
} catch (error) {
console.error(`Command failed: ${error.stderr}`);
}
// Spawn interactive process
await system.spawn("npm run dev", {
stdio: "inherit", // Pass through stdin/stdout/stderr
cwd: "./my-project"
});Utilities for finding and validating system commands and executables.
/**
* Find command location in system PATH
* @param command - Command name to locate
* @returns Command path if found, null otherwise
*/
which(command: string): string | null;Command Discovery Examples:
import { system } from "gluegun";
// Check if commands are available
const gitPath = system.which("git");
if (gitPath) {
console.log(`Git found at: ${gitPath}`);
const version = await system.run("git --version");
console.log(version);
} else {
console.log("Git not found in PATH");
}
// Conditional command execution
const hasYarn = system.which("yarn");
const packageManager = hasYarn ? "yarn" : "npm";
await system.run(`${packageManager} install`);Utilities for measuring command execution time and performance monitoring.
/**
* Create a timer function for measuring elapsed time
* @returns Timer function that returns milliseconds elapsed
*/
startTimer(): GluegunTimer;
/**
* Timer function type that returns elapsed milliseconds
*/
type GluegunTimer = () => number;Timing Examples:
import { system } from "gluegun";
// Time a build process
const timer = system.startTimer();
await system.run("npm run build");
const elapsed = timer();
console.log(`Build completed in ${elapsed}ms`);
// Time multiple operations
const overallTimer = system.startTimer();
const stepTimer = system.startTimer();
await system.run("npm run lint");
console.log(`Linting: ${stepTimer()}ms`);
stepTimer = system.startTimer();
await system.run("npm run test");
console.log(`Testing: ${stepTimer()}ms`);
console.log(`Total: ${overallTimer()}ms`);Extended error interface for system command failures with detailed information.
/**
* Extended error interface for system command failures
*/
interface GluegunError extends Error {
/** Command stdout output */
stdout?: string;
/** Command stderr output */
stderr?: string;
/** Process exit code */
exitCode?: number;
/** Whether command was killed */
killed?: boolean;
/** Signal that terminated the process */
signal?: string;
/** Whether command timed out */
timedOut?: boolean;
}Error Handling Examples:
import { system } from "gluegun";
try {
await system.exec("some-failing-command");
} catch (error: GluegunError) {
console.error(`Command failed with exit code: ${error.exitCode}`);
if (error.stdout) {
console.log("STDOUT:", error.stdout);
}
if (error.stderr) {
console.error("STDERR:", error.stderr);
}
if (error.timedOut) {
console.error("Command timed out");
}
if (error.killed) {
console.error(`Command killed by signal: ${error.signal}`);
}
}Options for controlling command execution behavior, environment, and output handling.
// Common execution options (varies by function)
interface CommandOptions {
/** Working directory for command */
cwd?: string;
/** Environment variables */
env?: { [key: string]: string };
/** Stdio configuration */
stdio?: 'pipe' | 'ignore' | 'inherit' | Array<'pipe' | 'ignore' | 'inherit'>;
/** Command timeout in milliseconds */
timeout?: number;
/** Kill signal to use on timeout */
killSignal?: string;
/** Encoding for output */
encoding?: string;
/** Shell to use for execution */
shell?: boolean | string;
/** Suppress command output */
silent?: boolean;
}Advanced Options Examples:
import { system } from "gluegun";
// Execute with custom environment
await system.run("node script.js", {
env: {
...process.env,
NODE_ENV: "production",
API_KEY: "secret-key"
}
});
// Execute in different directory
await system.exec("npm install", {
cwd: "./my-project",
stdio: "inherit" // Show output in real-time
});
// Execute with timeout
try {
await system.exec("long-running-command", {
timeout: 30000, // 30 seconds
killSignal: "SIGKILL"
});
} catch (error) {
if (error.timedOut) {
console.error("Command timed out after 30 seconds");
}
}interface GluegunSystem {
/**
* Execute command with full result details
* @param command - Command to execute
* @param options - Execution options
* @returns Promise with detailed execution result
*/
exec(command: string, options?: any): Promise<any>;
/**
* Execute command and return stdout
* @param command - Command to execute
* @param options - Execution options
* @returns Promise with trimmed stdout
*/
run(command: string, options?: any): Promise<string>;
/**
* Spawn command with cross-spawn
* @param command - Command to spawn
* @param options - Spawn options
* @returns Promise with spawn result
*/
spawn(command: string, options?: any): Promise<any>;
/**
* Find command in system PATH
* @param command - Command name
* @returns Command path or null
*/
which(command: string): string | null;
/**
* Create performance timer
* @returns Timer function
*/
startTimer(): GluegunTimer;
}
/**
* Timer function that returns elapsed milliseconds
*/
type GluegunTimer = () => number;
/**
* Extended error for command failures
*/
interface GluegunError extends Error {
stdout?: string;
stderr?: string;
exitCode?: number;
killed?: boolean;
signal?: string;
timedOut?: boolean;
}Comprehensive Usage Example:
import { build } from "gluegun";
// CLI command that uses system tools extensively
export = {
name: "deploy",
description: "Deploy application with build and testing",
run: async (toolbox) => {
const { system, print, filesystem } = toolbox;
// Check prerequisites
const hasGit = system.which("git");
const hasNode = system.which("node");
if (!hasGit || !hasNode) {
print.error("Missing required tools: git and node must be installed");
return;
}
// Show versions
const nodeVersion = await system.run("node --version");
const gitVersion = await system.run("git --version");
print.info(`Using ${nodeVersion} and ${gitVersion}`);
const overallTimer = system.startTimer();
try {
// Clean and install
let stepTimer = system.startTimer();
print.info("Installing dependencies...");
await system.exec("npm ci", { silent: true });
print.success(`Dependencies installed (${stepTimer()}ms)`);
// Run tests
stepTimer = system.startTimer();
print.info("Running tests...");
const testResult = await system.exec("npm test", {
env: { ...process.env, NODE_ENV: "test" }
});
if (testResult.exitCode !== 0) {
throw new Error("Tests failed");
}
print.success(`Tests passed (${stepTimer()}ms)`);
// Build
stepTimer = system.startTimer();
print.info("Building application...");
await system.exec("npm run build", {
cwd: process.cwd(),
stdio: "pipe"
});
print.success(`Build completed (${stepTimer()}ms)`);
// Deploy
stepTimer = system.startTimer();
print.info("Deploying to server...");
await system.spawn("rsync -av --delete dist/ server:/var/www/", {
stdio: "inherit"
});
print.success(`Deployment completed (${stepTimer()}ms)`);
const totalTime = overallTimer();
print.success(`๐ Full deployment completed in ${totalTime}ms`);
} catch (error) {
print.error(`Deployment failed: ${error.message}`);
if (error.stderr) {
print.error(`Error details: ${error.stderr}`);
}
process.exit(1);
}
}
};