Skip to content
New issue

Have a question about this project? Sign up for a free GitHub account to open an issue and contact its maintainers and the community.

By clicking “Sign up for GitHub”, you agree to our terms of service and privacy statement. We’ll occasionally send you account related emails.

Already on GitHub? Sign in to your account

feat: introduce experimental withTimeout helper #355

Merged
merged 1 commit into from Mar 18, 2022
Merged
Show file tree
Hide file tree
Changes from all commits
Commits
File filter

Filter by extension

Filter by extension

Conversations
Failed to load comments.
Jump to
Jump to file
Failed to load files.
Diff view
Diff view
10 changes: 10 additions & 0 deletions README.md
Expand Up @@ -418,6 +418,16 @@ await $`long-running command`
stop()
```

#### `withTimeout()`

Runs and sets a timeout for a cmd.

```js
import {withTimeout} from 'zx/experimental'

await withTimeout(100, 'SIGTERM')`sleep 9999`
```

### FAQ

#### Passing env variables
Expand Down
9 changes: 4 additions & 5 deletions src/experimental.d.ts
Expand Up @@ -12,18 +12,17 @@
// See the License for the specific language governing permissions and
// limitations under the License.

import {ProcessOutput} from './index'
import {ZxTemplate} from './index'

interface Echo {
(pieces: TemplateStringsArray, ...args: any[]): void
(...args: any[]): void
}
export const echo: Echo

interface Retry {
(pieces: TemplateStringsArray, ...args: any[]): Promise<ProcessOutput>
}
export const retry: (count?: number, delay?: number) => Retry
export const retry: (count?: number, delay?: number) => ZxTemplate

export const withTimeout: (delay?: number, signal?: string | number) => ZxTemplate

type StopSpinner = () => void
export function startSpinner(title: string): StopSpinner
10 changes: 10 additions & 0 deletions src/experimental.mjs
Expand Up @@ -25,6 +25,16 @@ export const retry = (count = 5, delay = 0) => async (cmd, ...args) => {
}
}

// Runs and sets a timeout for a cmd
export const withTimeout = (timeout, signal) => async (cmd, ...args) => {
let p = $(cmd, ...args)
if (!timeout) return p

let timer = setTimeout(() => p.kill(signal), timeout)

return p.finally(() => clearTimeout(timer))
}

// A console.log() alternative which can take ProcessOutput.
export function echo(pieces, ...args) {
if (Array.isArray(pieces) && pieces.every(isString) && pieces.length - 1 === args.length) {
Expand Down
4 changes: 3 additions & 1 deletion src/index.d.ts
Expand Up @@ -24,9 +24,11 @@ import _fetch from 'node-fetch'
import {ParsedArgs} from 'minimist'
import * as _which from 'which'

interface $ {
export interface ZxTemplate {
(pieces: TemplateStringsArray, ...args: any[]): ProcessPromise<ProcessOutput>
}

interface $ extends ZxTemplate {
verbose: boolean
shell: string
prefix: string
Expand Down
19 changes: 16 additions & 3 deletions test.mjs
Expand Up @@ -13,7 +13,7 @@
// limitations under the License.

import {strict as assert} from 'assert'
import {retry} from './src/experimental.mjs'
import {retry, withTimeout} from './src/experimental.mjs'

let всегоТестов = 0

Expand Down Expand Up @@ -245,6 +245,10 @@ if (test('YAML works')) {
console.log(chalk.greenBright('YAML works'))
}

if (test('which available')) {
assert.equal(which.sync('npm'), await which('npm'))
}

if (test('Retry works')) {
let exitCode = 0
let now = Date.now()
Expand All @@ -257,8 +261,17 @@ if (test('Retry works')) {
assert(Date.now() >= now + 50 * (5 - 1))
}

if (test('which available')) {
assert.equal(which.sync('npm'), await which('npm'))
if (test('withTimeout works')) {
let exitCode = 0
let signal
try {
await withTimeout(100, 'SIGKILL')`sleep 9999`
} catch (p) {
exitCode = p.exitCode
signal = p.signal
}
assert.equal(exitCode, null)
assert.equal(signal, 'SIGKILL')
}

let version
Expand Down