Skip to content

Commit 4f7d401

Browse files
committed
Add example documentation for the output handler
1 parent a3a94e7 commit 4f7d401

File tree

3 files changed

+85
-2
lines changed

3 files changed

+85
-2
lines changed

examples/git-output-handler.md

+49
Original file line numberDiff line numberDiff line change
@@ -0,0 +1,49 @@
1+
## Output Handler
2+
3+
As `simple-git` receives data on either `stdout` or `stderr` streams from the `git`
4+
child processes it spawns, the data is buffered for parsing when the process has
5+
completed.
6+
7+
Add an `outputHandler` to the instance to pipe these streams to another target, for
8+
example piping to the main process `stdout` / `stderr`:
9+
10+
```typescript
11+
import { InitResult, SimpleGit, simpleGit } from "simple-git";
12+
13+
const git: SimpleGit = simpleGit()
14+
.outputHandler((_command, stdout, stderr) => {
15+
stdout.pipe(process.stdout);
16+
stderr.pipe(process.stderr);
17+
});
18+
19+
const init: InitResult = await git.init();
20+
```
21+
22+
Note: there is a single `outputHandler` per `simple-git` instance, calling the method again
23+
will overwrite the existing `outputHandler`.
24+
25+
Other uses for the `outputHandler` can include tracking the processes for metrics purposes,
26+
such as checking how many commands are currently being executed:
27+
28+
```typescript
29+
let processes = new Set();
30+
const currentlyRunning = () => processes.size;
31+
const git = context.git.outputHandler((_command, stdout, stderr) => {
32+
const start = new Date();
33+
const onClose = () => processes.delete(start);
34+
35+
stdout.on('close', onClose);
36+
stderr.on('close', onClose);
37+
38+
processes.add(start);
39+
});
40+
41+
expect(currentlyRunning()).toBe(0);
42+
const queue = [git.init(), git.add('*.txt')];
43+
44+
await wait(0);
45+
expect(currentlyRunning()).toBe(2);
46+
47+
await Promise.all(queue);
48+
expect(currentlyRunning()).toBe(0);
49+
```

simple-git/readme.md

+2-2
Original file line numberDiff line numberDiff line change
@@ -186,7 +186,7 @@ For type details of the response for each of the tasks, please see the [TypeScri
186186
# API
187187

188188
| API | What it does |
189-
| ---------------------------------------------------- | ---------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------- |
189+
| ---------------------------------------------------- |------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------|
190190
| `.add([fileA, ...], handlerFn)` | adds one or more files to be under source control |
191191
| `.addAnnotatedTag(tagName, tagMessage, handlerFn)` | adds an annotated tag to the head of the current branch |
192192
| `.addTag(name, handlerFn)` | adds a lightweight tag to the head of the current branch |
@@ -201,7 +201,7 @@ For type details of the response for each of the tasks, please see the [TypeScri
201201
| `.fetch([options, ] handlerFn)` | update the local working copy database with changes from the default remote repo and branch, when supplied the options argument can be a standard [options object](#how-to-specify-options) either an array of string commands as supported by the [git fetch](https://git-scm.com/docs/git-fetch). |
202202
| `.fetch(remote, branch, handlerFn)` | update the local working copy database with changes from a remote repo |
203203
| `.fetch(handlerFn)` | update the local working copy database with changes from the default remote repo and branch |
204-
| `.outputHandler(handlerFn)` | attaches a handler that will be called with the name of the command being run and the `stdout` and `stderr` [readable streams](https://nodejs.org/api/stream.html#stream_class_stream_readable) created by the [child process](https://nodejs.org/api/child_process.html#child_process_class_childprocess) running that command |
204+
| `.outputHandler(handlerFn)` | attaches a handler that will be called with the name of the command being run and the `stdout` and `stderr` [readable streams](https://nodejs.org/api/stream.html#stream_class_stream_readable) created by the [child process](https://nodejs.org/api/child_process.html#child_process_class_childprocess) running that command, see [examples](https://github.com/steveukx/git-js/blob/main/examples/git-output-handler.md) |
205205
| `.raw(args, [handlerFn])` | Execute any arbitrary array of commands supported by the underlying git binary. When the git process returns a non-zero signal on exit and it printed something to `stderr`, the command will be treated as an error, otherwise treated as a success. |
206206
| `.rebase([options,] handlerFn)` | Rebases the repo, `options` should be supplied as an array of string parameters supported by the [git rebase](https://git-scm.com/docs/git-rebase) command, or an object of options (see details below for option formats). |
207207
| `.revert(commit , [options , [handlerFn]])` | reverts one or more commits in the working copy. The commit can be any regular commit-ish value (hash, name or offset such as `HEAD~2`) or a range of commits (eg: `master~5..master~2`). When supplied the [options](#how-to-specify-options) argument contain any options accepted by [git-revert](https://git-scm.com/docs/git-revert). |
Original file line numberDiff line numberDiff line change
@@ -0,0 +1,34 @@
1+
import { createTestContext, setUpInit, SimpleGitTestContext, wait } from '@simple-git/test-utils';
2+
3+
describe('outputHandler', function () {
4+
let context: SimpleGitTestContext;
5+
6+
beforeEach(async () => (context = await createTestContext()));
7+
beforeEach(async () => {
8+
await setUpInit(context);
9+
await context.files('aaa.txt', 'bbb.txt', 'ccc.other');
10+
});
11+
12+
it('using the outputHandler to count currently running processes', async () => {
13+
let processes = new Set();
14+
const currentlyRunning = () => processes.size;
15+
const git = context.git.outputHandler((_x, stdout, stderr) => {
16+
const start = new Date();
17+
const onClose = () => processes.delete(start);
18+
19+
stdout.on('close', onClose);
20+
stderr.on('close', onClose);
21+
22+
processes.add(start);
23+
});
24+
25+
expect(currentlyRunning()).toBe(0);
26+
const queue = [git.init(), git.add('*.txt')];
27+
28+
await wait(0);
29+
expect(currentlyRunning()).toBe(2);
30+
31+
await Promise.all(queue);
32+
expect(currentlyRunning()).toBe(0);
33+
});
34+
});

0 commit comments

Comments
 (0)