Skip to content
Closed
Show file tree
Hide file tree
Changes from all commits
Commits
File filter

Filter by extension

Filter by extension

Conversations
Failed to load comments.
Loading
Jump to
Jump to file
Failed to load files.
Loading
Diff view
Diff view
39 changes: 39 additions & 0 deletions examples/build-script.js
Original file line number Diff line number Diff line change
@@ -0,0 +1,39 @@
import { execa } from 'execa';

Check failure on line 1 in examples/build-script.js

View workflow job for this annotation

GitHub Actions / Node.js 24 on ubuntu

There should be no space before '}'.

Check failure on line 1 in examples/build-script.js

View workflow job for this annotation

GitHub Actions / Node.js 24 on ubuntu

There should be no space after '{'.

Check failure on line 1 in examples/build-script.js

View workflow job for this annotation

GitHub Actions / Node.js 18 on ubuntu

There should be no space before '}'.

Check failure on line 1 in examples/build-script.js

View workflow job for this annotation

GitHub Actions / Node.js 18 on ubuntu

There should be no space after '{'.

Check failure on line 1 in examples/build-script.js

View workflow job for this annotation

GitHub Actions / Node.js 18 on macos

There should be no space before '}'.

Check failure on line 1 in examples/build-script.js

View workflow job for this annotation

GitHub Actions / Node.js 18 on macos

There should be no space after '{'.

Check failure on line 1 in examples/build-script.js

View workflow job for this annotation

GitHub Actions / Node.js 24 on macos

There should be no space before '}'.

Check failure on line 1 in examples/build-script.js

View workflow job for this annotation

GitHub Actions / Node.js 24 on macos

There should be no space after '{'.

Check failure on line 1 in examples/build-script.js

View workflow job for this annotation

GitHub Actions / Node.js 18 on windows

There should be no space before '}'.

Check failure on line 1 in examples/build-script.js

View workflow job for this annotation

GitHub Actions / Node.js 18 on windows

There should be no space after '{'.

Check failure on line 1 in examples/build-script.js

View workflow job for this annotation

GitHub Actions / Node.js 24 on windows

There should be no space before '}'.

Check failure on line 1 in examples/build-script.js

View workflow job for this annotation

GitHub Actions / Node.js 24 on windows

There should be no space after '{'.

/**
* Build automation example with error handling
* Demonstrates running build commands with proper error handling
*/

async function runBuild() {
console.log('🔨 Starting build process...\n');

try {
// Clean previous build
console.log('🧹 Cleaning previous build...');
await execa('rm', ['-rf', 'dist']);
console.log('✅ Clean complete\n');

// Type checking
console.log('🔍 Running type check...');
await execa('tsc', ['--noEmit'], { stdio: 'inherit' });

Check failure on line 19 in examples/build-script.js

View workflow job for this annotation

GitHub Actions / Node.js 24 on ubuntu

There should be no space before '}'.

Check failure on line 19 in examples/build-script.js

View workflow job for this annotation

GitHub Actions / Node.js 24 on ubuntu

There should be no space after '{'.

Check failure on line 19 in examples/build-script.js

View workflow job for this annotation

GitHub Actions / Node.js 18 on ubuntu

There should be no space before '}'.

Check failure on line 19 in examples/build-script.js

View workflow job for this annotation

GitHub Actions / Node.js 18 on ubuntu

There should be no space after '{'.

Check failure on line 19 in examples/build-script.js

View workflow job for this annotation

GitHub Actions / Node.js 18 on macos

There should be no space before '}'.

Check failure on line 19 in examples/build-script.js

View workflow job for this annotation

GitHub Actions / Node.js 18 on macos

There should be no space after '{'.

Check failure on line 19 in examples/build-script.js

View workflow job for this annotation

GitHub Actions / Node.js 24 on macos

There should be no space before '}'.

Check failure on line 19 in examples/build-script.js

View workflow job for this annotation

GitHub Actions / Node.js 24 on macos

There should be no space after '{'.

Check failure on line 19 in examples/build-script.js

View workflow job for this annotation

GitHub Actions / Node.js 18 on windows

There should be no space before '}'.

Check failure on line 19 in examples/build-script.js

View workflow job for this annotation

GitHub Actions / Node.js 18 on windows

There should be no space after '{'.

Check failure on line 19 in examples/build-script.js

View workflow job for this annotation

GitHub Actions / Node.js 24 on windows

There should be no space before '}'.

Check failure on line 19 in examples/build-script.js

View workflow job for this annotation

GitHub Actions / Node.js 24 on windows

There should be no space after '{'.
console.log('✅ Type check passed\n');

// Building
console.log('📦 Building project...');
const { stdout } = await execa('npm', ['run', 'build']);

Check failure on line 24 in examples/build-script.js

View workflow job for this annotation

GitHub Actions / Node.js 24 on ubuntu

There should be no space before '}'.

Check failure on line 24 in examples/build-script.js

View workflow job for this annotation

GitHub Actions / Node.js 24 on ubuntu

There should be no space after '{'.

Check failure on line 24 in examples/build-script.js

View workflow job for this annotation

GitHub Actions / Node.js 18 on ubuntu

There should be no space before '}'.

Check failure on line 24 in examples/build-script.js

View workflow job for this annotation

GitHub Actions / Node.js 18 on ubuntu

There should be no space after '{'.

Check failure on line 24 in examples/build-script.js

View workflow job for this annotation

GitHub Actions / Node.js 18 on macos

There should be no space before '}'.

Check failure on line 24 in examples/build-script.js

View workflow job for this annotation

GitHub Actions / Node.js 18 on macos

There should be no space after '{'.

Check failure on line 24 in examples/build-script.js

View workflow job for this annotation

GitHub Actions / Node.js 24 on macos

There should be no space before '}'.

Check failure on line 24 in examples/build-script.js

View workflow job for this annotation

GitHub Actions / Node.js 24 on macos

There should be no space after '{'.

Check failure on line 24 in examples/build-script.js

View workflow job for this annotation

GitHub Actions / Node.js 18 on windows

There should be no space before '}'.

Check failure on line 24 in examples/build-script.js

View workflow job for this annotation

GitHub Actions / Node.js 18 on windows

There should be no space after '{'.

Check failure on line 24 in examples/build-script.js

View workflow job for this annotation

GitHub Actions / Node.js 24 on windows

There should be no space before '}'.

Check failure on line 24 in examples/build-script.js

View workflow job for this annotation

GitHub Actions / Node.js 24 on windows

There should be no space after '{'.
console.log(stdout);
console.log('✅ Build successful!\n');

Check failure on line 26 in examples/build-script.js

View workflow job for this annotation

GitHub Actions / Node.js 24 on ubuntu

Block must not be padded by blank lines.

Check failure on line 26 in examples/build-script.js

View workflow job for this annotation

GitHub Actions / Node.js 18 on ubuntu

Block must not be padded by blank lines.

Check failure on line 26 in examples/build-script.js

View workflow job for this annotation

GitHub Actions / Node.js 18 on macos

Block must not be padded by blank lines.

Check failure on line 26 in examples/build-script.js

View workflow job for this annotation

GitHub Actions / Node.js 24 on macos

Block must not be padded by blank lines.

Check failure on line 26 in examples/build-script.js

View workflow job for this annotation

GitHub Actions / Node.js 18 on windows

Block must not be padded by blank lines.

Check failure on line 26 in examples/build-script.js

View workflow job for this annotation

GitHub Actions / Node.js 24 on windows

Block must not be padded by blank lines.

} catch (error) {
console.error('❌ Build failed:', error.message);
process.exit(1);

Check failure on line 30 in examples/build-script.js

View workflow job for this annotation

GitHub Actions / Node.js 24 on ubuntu

Only use `process.exit()` in CLI apps. Throw an error instead.

Check failure on line 30 in examples/build-script.js

View workflow job for this annotation

GitHub Actions / Node.js 24 on ubuntu

Unexpected use of the global variable 'process'. Use 'require("process")' instead.

Check failure on line 30 in examples/build-script.js

View workflow job for this annotation

GitHub Actions / Node.js 18 on ubuntu

Only use `process.exit()` in CLI apps. Throw an error instead.

Check failure on line 30 in examples/build-script.js

View workflow job for this annotation

GitHub Actions / Node.js 18 on ubuntu

Unexpected use of the global variable 'process'. Use 'require("process")' instead.

Check failure on line 30 in examples/build-script.js

View workflow job for this annotation

GitHub Actions / Node.js 18 on macos

Only use `process.exit()` in CLI apps. Throw an error instead.

Check failure on line 30 in examples/build-script.js

View workflow job for this annotation

GitHub Actions / Node.js 18 on macos

Unexpected use of the global variable 'process'. Use 'require("process")' instead.

Check failure on line 30 in examples/build-script.js

View workflow job for this annotation

GitHub Actions / Node.js 24 on macos

Only use `process.exit()` in CLI apps. Throw an error instead.

Check failure on line 30 in examples/build-script.js

View workflow job for this annotation

GitHub Actions / Node.js 24 on macos

Unexpected use of the global variable 'process'. Use 'require("process")' instead.

Check failure on line 30 in examples/build-script.js

View workflow job for this annotation

GitHub Actions / Node.js 18 on windows

Only use `process.exit()` in CLI apps. Throw an error instead.

Check failure on line 30 in examples/build-script.js

View workflow job for this annotation

GitHub Actions / Node.js 18 on windows

Unexpected use of the global variable 'process'. Use 'require("process")' instead.

Check failure on line 30 in examples/build-script.js

View workflow job for this annotation

GitHub Actions / Node.js 24 on windows

Only use `process.exit()` in CLI apps. Throw an error instead.

Check failure on line 30 in examples/build-script.js

View workflow job for this annotation

GitHub Actions / Node.js 24 on windows

Unexpected use of the global variable 'process'. Use 'require("process")' instead.
}
}

// Run if executed directly
if (import.meta.url === `file://${process.argv[1]}`) {

Check failure on line 35 in examples/build-script.js

View workflow job for this annotation

GitHub Actions / Node.js 24 on ubuntu

Unexpected use of the global variable 'process'. Use 'require("process")' instead.

Check failure on line 35 in examples/build-script.js

View workflow job for this annotation

GitHub Actions / Node.js 18 on ubuntu

Unexpected use of the global variable 'process'. Use 'require("process")' instead.

Check failure on line 35 in examples/build-script.js

View workflow job for this annotation

GitHub Actions / Node.js 18 on macos

Unexpected use of the global variable 'process'. Use 'require("process")' instead.

Check failure on line 35 in examples/build-script.js

View workflow job for this annotation

GitHub Actions / Node.js 24 on macos

Unexpected use of the global variable 'process'. Use 'require("process")' instead.

Check failure on line 35 in examples/build-script.js

View workflow job for this annotation

GitHub Actions / Node.js 18 on windows

Unexpected use of the global variable 'process'. Use 'require("process")' instead.

Check failure on line 35 in examples/build-script.js

View workflow job for this annotation

GitHub Actions / Node.js 24 on windows

Unexpected use of the global variable 'process'. Use 'require("process")' instead.
runBuild();
}

export { runBuild };
70 changes: 70 additions & 0 deletions examples/git-helpers.js
Original file line number Diff line number Diff line change
@@ -0,0 +1,70 @@
import { execa } from 'execa';

/**
* Git helper functions using execa
* Wrappers for common git operations
*/

/**
* Get the current git branch
*/
async function getCurrentBranch() {
const { stdout } = await execa('git', ['branch', '--show-current']);
return stdout.trim();
}

/**
* Get the latest commit message
*/
async function getLatestCommit() {
const { stdout } = await execa('git', ['log', '-1', '--pretty=%s']);
return stdout.trim();
}

/**
* Check if working directory is clean
*/
async function isWorkingDirectoryClean() {
try {
await execa('git', ['diff', '--quiet']);
await execa('git', ['diff', '--staged', '--quiet']);
return true;
} catch {
return false;
}
}

/**
* Get repository status
*/
async function getStatus() {
const { stdout } = await execa('git', ['status', '--short']);
return stdout || 'Working directory clean';
}

/**
* Stage all changes and commit
*/
async function stageAndCommit(message) {
await execa('git', ['add', '.']);
await execa('git', ['commit', '-m', message]);
console.log(`✅ Committed: ${message}`);
}

// Demo
if (import.meta.url === `file://${process.argv[1]}`) {
console.log('📁 Git Repository Info\n');

console.log(`Branch: ${await getCurrentBranch()}`);
console.log(`Last commit: ${await getLatestCommit()}`);
console.log(`Working directory: ${await isWorkingDirectoryClean() ? '✅ Clean' : '⚠️ Dirty'}`);
console.log(`Status:\n${await getStatus()}`);
}

export {
getCurrentBranch,
getLatestCommit,
isWorkingDirectoryClean,
getStatus,
stageAndCommit,
};
80 changes: 80 additions & 0 deletions examples/parallel-tasks.js
Original file line number Diff line number Diff line change
@@ -0,0 +1,80 @@
import { execa } from 'execa';

/**
* Running commands in parallel
* Demonstrates concurrent execution with proper error handling
*/

/**
* Run multiple linting tasks in parallel
*/
async function runParallelLints() {
console.log('🔍 Running linters in parallel...\n');

try {
const tasks = [
{ name: 'ESLint', cmd: ['eslint', '.'] },
{ name: 'Prettier', cmd: ['prettier', '--check', '.'] },
{ name: 'TypeScript', cmd: ['tsc', '--noEmit'] },
];

const results = await Promise.allSettled(
tasks.map(async ({ name, cmd }) => {
console.log(`🚀 Starting ${name}...`);
await execa('npx', cmd);
return { name, status: 'passed' };
})
);

console.log('\n📊 Results:');
let hasErrors = false;

for (const result of results) {
if (result.status === 'fulfilled') {
console.log(` ✅ ${result.value.name}`);
} else {
console.log(` ❌ ${result.reason.name || 'Task'}`);
hasErrors = true;
}
}

if (hasErrors) {
process.exit(1);
}

} catch (error) {
console.error('Unexpected error:', error);
process.exit(1);
}
}

/**
* Run multiple independent commands in parallel
* with a limit on concurrency
*/
async function runWithLimit(tasks, limit = 3) {
const results = [];
const executing = [];

for (const [index, task] of tasks.entries()) {
const promise = task().then(result => ({ index, result }));
results.push(promise);

if (tasks.length >= limit) {
executing.push(promise);
if (executing.length >= limit) {
await Promise.race(executing);
executing.splice(executing.findIndex(p => p === promise), 1);
}
}
}

return Promise.all(results);
}

// Demo
if (import.meta.url === `file://${process.argv[1]}`) {
runParallelLints();
}

export { runParallelLints, runWithLimit };
39 changes: 39 additions & 0 deletions examples/readme.md
Original file line number Diff line number Diff line change
@@ -0,0 +1,39 @@
# Execa Examples

This directory contains practical examples demonstrating common use cases with `execa`.

## Examples

### build-script.js
Build automation with error handling. Shows how to chain build commands and handle failures gracefully.

```bash
node examples/build-script.js
```

### git-helpers.js
Git operation wrappers. Demonstrates async helper functions for common git operations.

```bash
node examples/git-helpers.js
```

### parallel-tasks.js
Running commands in parallel. Shows concurrent execution with `Promise.allSettled()` and progress tracking.

```bash
node examples/parallel-tasks.js
```

### stream-processing.js
Output filtering with transforms. Demonstrates using Node.js Transform streams to process command output.

```bash
node examples/stream-processing.js
```

## Notes

- All examples use ES modules (`.js` extension with `import` syntax)
- Each example can be run directly or imported as a module
- Error handling is included in all examples
95 changes: 95 additions & 0 deletions examples/stream-processing.js
Original file line number Diff line number Diff line change
@@ -0,0 +1,95 @@
import { execa } from 'execa';
import { Transform } from 'node:stream';

/**
* Stream processing with transforms
* Demonstrates filtering and transforming command output
*/

/**
* Filter lines containing specific keywords
*/
function createKeywordFilter(keywords) {
return new Transform({
transform(chunk, encoding, callback) {
const lines = chunk.toString().split('\n');
const filtered = lines
.filter(line => keywords.some(kw => line.toLowerCase().includes(kw.toLowerCase())))
.join('\n');
callback(null, filtered ? filtered + '\n' : '');
},
});
}

/**
* Prefix each line with a timestamp
*/
function createTimestampPrefix() {
return new Transform({
transform(chunk, encoding, callback) {
const lines = chunk.toString().split('\n');
const prefixed = lines
.filter(line => line.trim())
.map(line => `[${new Date().toISOString()}] ${line}`)
.join('\n');
callback(null, prefixed + '\n');
},
});
}

/**
* Count lines and show progress
*/
function createProgressCounter() {
let count = 0;
return new Transform({
transform(chunk, encoding, callback) {
const lines = chunk.toString().split('\n');
const nonEmpty = lines.filter(line => line.trim());
count += nonEmpty.length;
process.stdout.write(`\r📊 Processed ${count} lines...`);
callback(null, chunk);
},
flush(callback) {
console.log(`\n✅ Total: ${count} lines`);
callback();
},
});
}

/**
* Run a command and process its output through transforms
*/
async function runWithTransforms(command, args, transforms) {
const subprocess = execa(command, args);

let stream = subprocess.stdout;
for (const transform of transforms) {
stream = stream.pipe(transform);
}

stream.pipe(process.stdout);
await subprocess;
}

// Demo
if (import.meta.url === `file://${process.argv[1]}`) {
console.log('🔍 Running npm audit with filtered output:\n');

try {
await runWithTransforms(
'npm',
['audit', '--json'],
[createKeywordFilter(['severity', 'critical', 'high'])]
);
} catch {
// npm audit exits with non-zero on vulnerabilities
}
}

export {
createKeywordFilter,
createTimestampPrefix,
createProgressCounter,
runWithTransforms,
};
Loading