Skip to content

Commit f08eab6

Browse files
author
vincent067
committed
docs(examples): add advanced patterns example
Add a new example file demonstrating execa's advanced features: - Line-by-line processing with the 'lines' option - Command piping with .pipe() - Verbose mode for debugging - Script syntax with $ - Graceful error handling Also update examples readme to include the new example and improve documentation. This helps users discover and understand execa's more powerful features beyond basic command execution.
1 parent f3a2e84 commit f08eab6

2 files changed

Lines changed: 218 additions & 0 deletions

File tree

examples/advanced-patterns.js

Lines changed: 166 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -0,0 +1,166 @@
1+
import { execa, $ } from 'execa';
2+
3+
/**
4+
* Advanced patterns with execa
5+
* Demonstrates powerful features: lines, pipes, verbose mode, and script syntax
6+
*/
7+
8+
/**
9+
* Process command output line by line using the lines option
10+
* Perfect for log analysis and line-oriented processing
11+
*/
12+
async function processLinesExample() {
13+
console.log('📋 Processing git log line by line:\n');
14+
15+
// Get recent commits and process each line individually
16+
const { stdout } = await execa({
17+
lines: true,
18+
verbose: 'short',
19+
}) `git log --oneline -5`;
20+
21+
// stdout is now an array of lines
22+
for (const [index, line] of stdout.entries()) {
23+
console.log(` ${index + 1}. ${line}`);
24+
}
25+
}
26+
27+
/**
28+
* Pipe multiple commands together
29+
* Equivalent to: git log --oneline | grep -i "docs" | wc -l
30+
*/
31+
async function pipeExample() {
32+
console.log('\n🔗 Piping commands together:\n');
33+
34+
// Count docs commits in recent history
35+
// Note: Using reject: false for grep since it exits 1 when no matches
36+
try {
37+
const count = await execa({
38+
lines: true,
39+
}) `git log --oneline -30`
40+
.pipe({
41+
lines: true,
42+
reject: false, // Don't throw on non-zero exit
43+
}) `grep -i docs`
44+
.pipe `wc -l`;
45+
46+
console.log(` Found ${count.stdout.trim()} docs-related commits in recent history`);
47+
} catch (error) {
48+
console.log(` Note: ${error.message}`);
49+
}
50+
}
51+
52+
/**
53+
* Use verbose mode for debugging
54+
* Shows exactly what's being executed
55+
*/
56+
async function verboseExample() {
57+
console.log('\n🐛 Verbose mode (shows command execution details):\n');
58+
59+
// 'short' shows command name and main options
60+
await execa({
61+
verbose: 'short',
62+
}) `node --version`;
63+
64+
// 'full' also shows environment variables, data, etc.
65+
console.log('\n --- Full verbose example (truncated output) ---');
66+
await execa({
67+
verbose: 'full',
68+
}) `echo "Hello from execa"`;
69+
}
70+
71+
/**
72+
* Script syntax with $ - perfect for shell-like scripts
73+
*/
74+
async function scriptSyntaxExample() {
75+
console.log('\n📜 Script syntax with $:\n');
76+
77+
// The $ function provides a shell-like experience
78+
const os = process.platform;
79+
console.log(` Running on: ${os}`);
80+
81+
if (os === 'darwin') {
82+
// macOS
83+
const { stdout } = await $ `sw_vers -productVersion`;
84+
console.log(` macOS version: ${stdout}`);
85+
} else if (os === 'linux') {
86+
// Linux
87+
try {
88+
const { stdout } = await $ `lsb_release -d -s`;
89+
console.log(` Linux distro: ${stdout}`);
90+
} catch {
91+
console.log(' Linux (lsb_release not available)');
92+
}
93+
}
94+
95+
// Template expressions are escaped automatically
96+
const filename = 'file with spaces.txt';
97+
console.log(` Safe filename handling: "${filename}"`);
98+
// await $ `cat ${filename}`; // Automatically escaped, no shell injection risk
99+
}
100+
101+
/**
102+
* Graceful error handling with detailed error information
103+
*/
104+
async function errorHandlingExample() {
105+
console.log('\n❌ Graceful error handling:\n');
106+
107+
try {
108+
await execa({
109+
verbose: 'short',
110+
}) `nonexistent-command-xyz`;
111+
} catch (error) {
112+
console.log(` Command failed with exit code: ${error.exitCode}`);
113+
console.log(` Error message: ${error.message}`);
114+
console.log(' 💡 Tip: Use reject: false option to prevent throwing');
115+
}
116+
}
117+
118+
/**
119+
* All-in-one: Practical CI/CD pipeline example
120+
*/
121+
async function ciPipelineExample() {
122+
console.log('\n🚀 CI Pipeline simulation:\n');
123+
124+
const steps = [
125+
{ name: 'Lint', cmd: () => $ `echo "Running linter..."` },
126+
{ name: 'Test', cmd: () => $ `echo "Running tests..."` },
127+
{ name: 'Build', cmd: () => $ `echo "Building project..."` },
128+
];
129+
130+
for (const step of steps) {
131+
process.stdout.write(` ${step.name}... `);
132+
try {
133+
await step.cmd();
134+
console.log('✅');
135+
} catch {
136+
console.log('❌');
137+
return;
138+
}
139+
}
140+
console.log('\n 🎉 All steps completed successfully!');
141+
}
142+
143+
// Run all examples
144+
if (import.meta.url === `file://${process.argv[1]}`) {
145+
console.log('🎯 Advanced Execa Patterns\n');
146+
console.log('='.repeat(50));
147+
148+
await processLinesExample();
149+
await pipeExample();
150+
await verboseExample();
151+
await scriptSyntaxExample();
152+
await errorHandlingExample();
153+
await ciPipelineExample();
154+
155+
console.log('\n' + '='.repeat(50));
156+
console.log('\n✨ Learn more: https://github.com/sindresorhus/execa#readme');
157+
}
158+
159+
export {
160+
processLinesExample,
161+
pipeExample,
162+
verboseExample,
163+
scriptSyntaxExample,
164+
errorHandlingExample,
165+
ciPipelineExample,
166+
};

examples/readme.md

Lines changed: 52 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -0,0 +1,52 @@
1+
# Execa Examples
2+
3+
This directory contains practical examples demonstrating common and advanced use cases with `execa`.
4+
5+
## Examples
6+
7+
### build-script.js
8+
Build automation with error handling. Shows how to chain build commands and handle failures gracefully.
9+
10+
```bash
11+
node examples/build-script.js
12+
```
13+
14+
### git-helpers.js
15+
Git operation wrappers. Demonstrates async helper functions for common git operations.
16+
17+
```bash
18+
node examples/git-helpers.js
19+
```
20+
21+
### parallel-tasks.js
22+
Running commands in parallel. Shows concurrent execution with `Promise.allSettled()` and progress tracking.
23+
24+
```bash
25+
node examples/parallel-tasks.js
26+
```
27+
28+
### stream-processing.js
29+
Output filtering with transforms. Demonstrates using Node.js Transform streams to process command output.
30+
31+
```bash
32+
node examples/stream-processing.js
33+
```
34+
35+
### advanced-patterns.js ⭐ New
36+
Advanced features demonstration including:
37+
- **Line-by-line processing**: Using the `lines` option for array output
38+
- **Command piping**: Chaining multiple commands with `.pipe()`
39+
- **Verbose debugging**: Using `verbose` option for debugging
40+
- **Script syntax**: Using `$` for shell-like scripting
41+
- **Graceful error handling**: Detailed error information
42+
43+
```bash
44+
node examples/advanced-patterns.js
45+
```
46+
47+
## Notes
48+
49+
- All examples use ES modules (`.js` extension with `import` syntax)
50+
- Each example can be run directly or imported as a module
51+
- Error handling is included in all examples
52+
- The `advanced-patterns.js` example requires a git repository to demonstrate git-related features

0 commit comments

Comments
 (0)