Skip to content

Commit 54c41a4

Browse files
committed
Add options to ignore stdErr or stdOut in the timeout plugin
1 parent add5c29 commit 54c41a4

File tree

4 files changed

+58
-12
lines changed

4 files changed

+58
-12
lines changed

docs/PLUGIN-TIMEOUT.md

Lines changed: 29 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -25,3 +25,32 @@ catch (err) {
2525
}
2626
}
2727
```
28+
29+
## Task Timeouts and Progress Events
30+
31+
The default behaviour of the timeout plugin is to listen for data being received on both the
32+
`stdOut` and `stdErr` streams from the `git` child process.
33+
34+
When using the `progress` plugin, `git` will be streaming regular progress updates to `stdErr`,
35+
so you may see that the timeout is never reached and `simple-git` patiently waits for `git` to
36+
finish whatever it is doing.
37+
38+
Configure this with the optional `stdOut` and `stdErr` properties of the `timeout` plugin
39+
configuration:
40+
41+
```typescript
42+
import { simpleGit, GitPluginError, SimpleGit, SimpleGitProgressEvent } from "simple-git";
43+
44+
const git: SimpleGit = simpleGit({
45+
baseDir: "/some/path",
46+
progress({method, stage, progress}) {
47+
console.log(`git.${method} ${stage} stage ${progress}% complete`);
48+
},
49+
timeout: {
50+
block: 2000,
51+
stdOut: true, // default behaviour, resets the 2s timer every time data arrives on stdOut
52+
stdErr: false // custom behaviour, ignore the progress events being written to stdErr
53+
}
54+
});
55+
56+
```

simple-git/src/lib/plugins/timout-plugin.ts

Lines changed: 4 additions & 2 deletions
Original file line numberDiff line numberDiff line change
@@ -5,6 +5,8 @@ import { GitPluginError } from '../errors/git-plugin-error';
55

66
export function timeoutPlugin({
77
block,
8+
stdErr = true,
9+
stdOut = true,
810
}: Exclude<SimpleGitOptions['timeout'], undefined>): SimpleGitPlugin<'spawn.after'> | void {
911
if (block > 0) {
1012
return {
@@ -30,8 +32,8 @@ export function timeoutPlugin({
3032
context.kill(new GitPluginError(undefined, 'timeout', `block timeout reached`));
3133
}
3234

33-
context.spawned.stdout?.on('data', wait);
34-
context.spawned.stderr?.on('data', wait);
35+
stdOut && context.spawned.stdout?.on('data', wait);
36+
stdErr && context.spawned.stderr?.on('data', wait);
3537
context.spawned.on('exit', stop);
3638
context.spawned.on('close', stop);
3739

simple-git/src/lib/types/index.ts

Lines changed: 12 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -105,6 +105,18 @@ export interface SimpleGitPluginConfig {
105105
* content on the stdOut/stdErr streams before forcibly closing the git process.
106106
*/
107107
block: number;
108+
109+
/**
110+
* Reset timeout plugin after receiving data on `stdErr` - set to `false` to ignore
111+
* `stdErr` content when determining whether to kill the process (defaults to `true`).
112+
*/
113+
stdErr?: boolean;
114+
115+
/**
116+
* Reset timeout plugin after receiving data on `stdOut` - set to `false` to ignore
117+
* `stdOut` content when determining whether to kill the process (defaults to `true`).
118+
*/
119+
stdOut?: boolean;
108120
};
109121

110122
spawnOptions: Pick<SpawnOptions, 'uid' | 'gid'>;

simple-git/test/integration/timeout-progress-combo.spec.ts

Lines changed: 13 additions & 10 deletions
Original file line numberDiff line numberDiff line change
@@ -1,25 +1,29 @@
1-
import {promiseError} from "@kwsites/promise-result";
2-
import {assertGitError, createTestContext, newSimpleGit, SimpleGitTestContext} from "@simple-git/test-utils";
1+
import { promiseError } from '@kwsites/promise-result';
2+
import {
3+
assertGitError,
4+
createTestContext,
5+
newSimpleGit,
6+
SimpleGitTestContext,
7+
} from '@simple-git/test-utils';
38

4-
import {GitPluginError} from '../..';
9+
import { GitPluginError, SimpleGitOptions } from '../..';
510

611
describe('timeout-progress-combo', () => {
7-
812
let context: SimpleGitTestContext;
913
const url = 'https://github.com/nodejs/node';
10-
const progress = ({method, stage, progress}) => {
11-
console.log(`git.${method} ${stage} stage ${progress}% complete`);
12-
};
13-
const timeout = {
14+
const progress: SimpleGitOptions['progress'] = jest.fn();
15+
const timeout: SimpleGitOptions['timeout'] = {
1416
block: 5000,
17+
stdOut: true,
18+
stdErr: false,
1519
};
1620

1721
jest.setTimeout(10 * 1000);
1822

1923
beforeEach(async () => (context = await createTestContext()));
2024

2125
it('succeeds', async () => {
22-
const options = {
26+
const options: Partial<SimpleGitOptions> = {
2327
baseDir: context.root,
2428
timeout,
2529
progress,
@@ -38,5 +42,4 @@ describe('timeout-progress-combo', () => {
3842
const threw = await promiseError(newSimpleGit(options).clone(url));
3943
assertGitError(threw, 'block timeout reached', GitPluginError);
4044
});
41-
4245
});

0 commit comments

Comments
 (0)