From ef93808daf67a1f6019d3b6fd9c48230f0b4ff5a Mon Sep 17 00:00:00 2001 From: ehmicky Date: Sun, 8 May 2022 23:38:41 +0200 Subject: [PATCH 1/5] Drop support for Node 12 --- .github/workflows/main.yml | 12 ++++++------ index.d.ts | 9 ++------- index.test-d.ts | 6 +++++- lib/stream.js | 4 +--- package.json | 3 +-- readme.md | 6 ------ test/error.js | 5 +---- test/override-promise.js | 1 - test/test.js | 31 +++++++++++++------------------ 9 files changed, 29 insertions(+), 48 deletions(-) diff --git a/.github/workflows/main.yml b/.github/workflows/main.yml index 709e96ba4b..40550dbd50 100644 --- a/.github/workflows/main.yml +++ b/.github/workflows/main.yml @@ -10,21 +10,21 @@ jobs: fail-fast: false matrix: node-version: - - 16 - - 14 - - 12 + - 18.0.0 + - 16.4.0 + - 14.18.0 os: - ubuntu-latest - macos-latest # - windows-latest steps: - - uses: actions/checkout@v2 - - uses: actions/setup-node@v2 + - uses: actions/checkout@v3 + - uses: actions/setup-node@v3 with: node-version: ${{ matrix.node-version }} - run: npm install - run: npm test - uses: codecov/codecov-action@v2 - if: matrix.os == 'ubuntu-latest' && matrix.node-version == 16 + if: matrix.os == 'ubuntu-latest' && matrix.node-version == 18.0.0 with: fail_ci_if_error: true diff --git a/index.d.ts b/index.d.ts index f9cf418782..d06e08f63b 100644 --- a/index.d.ts +++ b/index.d.ts @@ -4,6 +4,7 @@ import {Stream, Readable as ReadableStream} from 'node:stream'; export type StdioOption = | 'pipe' + | 'overlapped' | 'ipc' | 'ignore' | 'inherit' @@ -33,8 +34,6 @@ export interface CommonOptions { /** Preferred path to find locally installed binaries in (use with `preferLocal`). - Using a `URL` is only supported in Node.js `14.18.0`, `16.14.0` or above. - @default process.cwd() */ readonly localDir?: string | URL; @@ -113,8 +112,6 @@ export interface CommonOptions { /** Current working directory of the child process. - Using a `URL` is only supported in Node.js `14.18.0`, `16.14.0` or above. - @default process.cwd() */ readonly cwd?: string | URL; @@ -136,15 +133,13 @@ export interface CommonOptions { @default 'pipe' */ - readonly stdio?: 'pipe' | 'ignore' | 'inherit' | readonly StdioOption[]; + readonly stdio?: 'pipe' | 'overlapped' | 'ignore' | 'inherit' | readonly StdioOption[]; /** Specify the kind of serialization used for sending messages between processes when using the `stdio: 'ipc'` option or `execaNode()`: - `json`: Uses `JSON.stringify()` and `JSON.parse()`. - `advanced`: Uses [`v8.serialize()`](https://nodejs.org/api/v8.html#v8_v8_serialize_value) - Requires Node.js `13.2.0` or later. - [More info.](https://nodejs.org/api/child_process.html#child_process_advanced_serialization) @default 'json' diff --git a/index.test-d.ts b/index.test-d.ts index b73cfa0369..fc00f2c9eb 100644 --- a/index.test-d.ts +++ b/index.test-d.ts @@ -97,6 +97,7 @@ execa('unicorns', {input: ''}); execa('unicorns', {input: Buffer.from('')}); execa('unicorns', {input: process.stdin}); execa('unicorns', {stdin: 'pipe'}); +execa('unicorns', {stdin: 'overlapped'}); execa('unicorns', {stdin: 'ipc'}); execa('unicorns', {stdin: 'ignore'}); execa('unicorns', {stdin: 'inherit'}); @@ -104,6 +105,7 @@ execa('unicorns', {stdin: process.stdin}); execa('unicorns', {stdin: 1}); execa('unicorns', {stdin: undefined}); execa('unicorns', {stdout: 'pipe'}); +execa('unicorns', {stdout: 'overlapped'}); execa('unicorns', {stdout: 'ipc'}); execa('unicorns', {stdout: 'ignore'}); execa('unicorns', {stdout: 'inherit'}); @@ -111,6 +113,7 @@ execa('unicorns', {stdout: process.stdout}); execa('unicorns', {stdout: 1}); execa('unicorns', {stdout: undefined}); execa('unicorns', {stderr: 'pipe'}); +execa('unicorns', {stderr: 'overlapped'}); execa('unicorns', {stderr: 'ipc'}); execa('unicorns', {stderr: 'ignore'}); execa('unicorns', {stderr: 'inherit'}); @@ -127,10 +130,11 @@ execa('unicorns', {cwd: new URL('file:///test')}); execa('unicorns', {env: {PATH: ''}}); execa('unicorns', {argv0: ''}); execa('unicorns', {stdio: 'pipe'}); +execa('unicorns', {stdio: 'overlapped'}); execa('unicorns', {stdio: 'ignore'}); execa('unicorns', {stdio: 'inherit'}); execa('unicorns', { - stdio: ['pipe', 'ipc', 'ignore', 'inherit', process.stdin, 1, undefined], + stdio: ['pipe', 'overlapped', 'ipc', 'ignore', 'inherit', process.stdin, 1, undefined], }); execa('unicorns', {serialization: 'advanced'}); execa('unicorns', {detached: true}); diff --git a/lib/stream.js b/lib/stream.js index b140bf14f9..3dcc81d07d 100644 --- a/lib/stream.js +++ b/lib/stream.js @@ -4,9 +4,7 @@ import mergeStream from 'merge-stream'; // `input` option export const handleInput = (spawned, input) => { - // Checking for stdin is workaround for https://github.com/nodejs/node/issues/26852 - // @todo remove `|| spawned.stdin === undefined` once we drop support for Node.js <=12.2.0 - if (input === undefined || spawned.stdin === undefined) { + if (input === undefined) { return; } diff --git a/package.json b/package.json index 90bd07b659..0617800d3f 100644 --- a/package.json +++ b/package.json @@ -13,7 +13,7 @@ "type": "module", "exports": "./index.js", "engines": { - "node": "^12.20.0 || ^14.13.1 || >=16.0.0" + "node": "^14.18.0 || >=16.4.0 || >=18.0.0" }, "scripts": { "test": "xo && c8 ava && tsd" @@ -58,7 +58,6 @@ "get-node": "^12.0.0", "is-running": "^2.1.0", "p-event": "^5.0.1", - "semver": "^7.3.5", "tempfile": "^4.0.0", "tsd": "^0.19.1", "xo": "^0.48.0" diff --git a/readme.md b/readme.md index a529f39033..d94df1383b 100644 --- a/readme.md +++ b/readme.md @@ -361,8 +361,6 @@ Default: `process.cwd()` Preferred path to find locally installed binaries in (use with `preferLocal`). -Using a `URL` is only supported in Node.js `14.18.0`, `16.14.0` or above. - #### execPath Type: `string`\ @@ -452,8 +450,6 @@ Default: `process.cwd()` Current working directory of the child process. -Using a `URL` is only supported in Node.js `14.18.0`, `16.14.0` or above. - #### env Type: `object`\ @@ -483,8 +479,6 @@ Specify the kind of serialization used for sending messages between processes wh - `json`: Uses `JSON.stringify()` and `JSON.parse()`. - `advanced`: Uses [`v8.serialize()`](https://nodejs.org/api/v8.html#v8_v8_serialize_value) -Requires Node.js `13.2.0` or later. - [More info.](https://nodejs.org/api/child_process.html#child_process_advanced_serialization) #### detached diff --git a/test/error.js b/test/error.js index ae7f34b71f..378ef34014 100644 --- a/test/error.js +++ b/test/error.js @@ -79,10 +79,7 @@ test('error.shortMessage does not contain stdout/stderr', async t => { test('Original error.message is kept', async t => { const {originalMessage} = await t.throwsAsync(execa('noop.js', {cwd: 1})); - // On Node >=14.18.0, the error message is - // `The "options.cwd" property must be of type string or an instance of Buffer or URL. Received type number (1)` - t.true(originalMessage.startsWith('The "options.cwd" property must be of type string')); - t.true(originalMessage.includes('. Received type number')); + t.true(originalMessage.startsWith('The "options.cwd" property must be of type string or an instance of Buffer or URL. Received type number')); }); test('failed is false on success', async t => { diff --git a/test/override-promise.js b/test/override-promise.js index 986316e3a4..660ffe45ed 100644 --- a/test/override-promise.js +++ b/test/override-promise.js @@ -3,7 +3,6 @@ import process from 'node:process'; import {fileURLToPath} from 'node:url'; import test from 'ava'; // The helper module overrides Promise on import so has to be imported before `execa`. -// Can't use top-level await (TLA) + `import(…)` since Node.js 12 doesn't support TLA. import {restorePromise} from './helpers/override-promise.js'; // eslint-disable-next-line import/order import {execa} from '../index.js'; diff --git a/test/test.js b/test/test.js index e49e4e846b..69cced782d 100644 --- a/test/test.js +++ b/test/test.js @@ -4,7 +4,6 @@ import {fileURLToPath, pathToFileURL} from 'node:url'; import test from 'ava'; import isRunning from 'is-running'; import getNode from 'get-node'; -import semver from 'semver'; import {execa, execaSync} from '../index.js'; process.env.PATH = fileURLToPath(new URL('fixtures', import.meta.url)) + path.delimiter + process.env.PATH; @@ -167,9 +166,7 @@ if (process.platform !== 'win32') { }); test('execa() rejects with correct error and doesn\'t throw if running non-executable with input', async t => { - // On Node <12.6.0, `EACCESS` is emitted on `childProcess`. - // On Node >=12.6.0, `EPIPE` is emitted on `childProcess.stdin`. - await t.throwsAsync(execa('non-executable.js', {input: 'Hey!'}), {message: /EACCES|EPIPE/}); + await t.throwsAsync(execa('non-executable.js', {input: 'Hey!'}), {message: /EACCES/}); }); } @@ -207,21 +204,19 @@ test('can use `options.cwd` as a string', async t => { t.is(path.toNamespacedPath(stdout), path.toNamespacedPath(cwd)); }); -if (semver.satisfies(process.version, '^14.18.0 || >=16.4.0')) { - test('localDir option can be a URL', async t => { - const command = process.platform === 'win32' ? 'echo %PATH%' : 'echo $PATH'; - const {stdout} = await execa(command, {shell: true, preferLocal: true, localDir: pathToFileURL('/test')}); - const envPaths = stdout.split(path.delimiter); - t.true(envPaths.some(envPath => envPath.endsWith('.bin'))); - }); +test('localDir option can be a URL', async t => { + const command = process.platform === 'win32' ? 'echo %PATH%' : 'echo $PATH'; + const {stdout} = await execa(command, {shell: true, preferLocal: true, localDir: pathToFileURL('/test')}); + const envPaths = stdout.split(path.delimiter); + t.true(envPaths.some(envPath => envPath.endsWith('.bin'))); +}); - test('can use `options.cwd` as a URL', async t => { - const cwd = '/'; - const cwdUrl = pathToFileURL(cwd); - const {stdout} = await execa('node', ['-p', 'process.cwd()'], {cwd: cwdUrl}); - t.is(path.toNamespacedPath(stdout), path.toNamespacedPath(cwd)); - }); -} +test('can use `options.cwd` as a URL', async t => { + const cwd = '/'; + const cwdUrl = pathToFileURL(cwd); + const {stdout} = await execa('node', ['-p', 'process.cwd()'], {cwd: cwdUrl}); + t.is(path.toNamespacedPath(stdout), path.toNamespacedPath(cwd)); +}); test('can use `options.shell: true`', async t => { const {stdout} = await execa('node test/fixtures/noop.js foo', {shell: true}); From b2ee103a4d4861699c092493248380bccdfef2e4 Mon Sep 17 00:00:00 2001 From: ehmicky Date: Mon, 9 May 2022 20:11:06 +0200 Subject: [PATCH 2/5] Fix YAML syntax error --- .github/workflows/main.yml | 2 +- 1 file changed, 1 insertion(+), 1 deletion(-) diff --git a/.github/workflows/main.yml b/.github/workflows/main.yml index 40550dbd50..6628a7fa9c 100644 --- a/.github/workflows/main.yml +++ b/.github/workflows/main.yml @@ -25,6 +25,6 @@ jobs: - run: npm install - run: npm test - uses: codecov/codecov-action@v2 - if: matrix.os == 'ubuntu-latest' && matrix.node-version == 18.0.0 + if: matrix.os == 'ubuntu-latest' && matrix.node-version == '18.0.0' with: fail_ci_if_error: true From bb086908c2b13534a7114efd56475aab24740fda Mon Sep 17 00:00:00 2001 From: ehmicky Date: Mon, 9 May 2022 21:06:42 +0200 Subject: [PATCH 3/5] Fix Node range --- package.json | 2 +- 1 file changed, 1 insertion(+), 1 deletion(-) diff --git a/package.json b/package.json index 0617800d3f..38bbefca5c 100644 --- a/package.json +++ b/package.json @@ -13,7 +13,7 @@ "type": "module", "exports": "./index.js", "engines": { - "node": "^14.18.0 || >=16.4.0 || >=18.0.0" + "node": "^14.18.0 || ^16.4.0 || >=18.0.0" }, "scripts": { "test": "xo && c8 ava && tsd" From 58e7e87feff0bc4c68733bdb998832892aeaf98a Mon Sep 17 00:00:00 2001 From: ehmicky Date: Tue, 10 May 2022 16:24:37 +0200 Subject: [PATCH 4/5] Update package.json Co-authored-by: Sindre Sorhus --- package.json | 2 +- 1 file changed, 1 insertion(+), 1 deletion(-) diff --git a/package.json b/package.json index 38bbefca5c..9c420b204b 100644 --- a/package.json +++ b/package.json @@ -13,7 +13,7 @@ "type": "module", "exports": "./index.js", "engines": { - "node": "^14.18.0 || ^16.4.0 || >=18.0.0" + "node": "^14.18.0 || ^16.14.0 || >=18.0.0" }, "scripts": { "test": "xo && c8 ava && tsd" From 68c94aeffe2c706d80ab81e329a91c73e3ad0027 Mon Sep 17 00:00:00 2001 From: ehmicky Date: Sun, 8 May 2022 11:22:07 +0200 Subject: [PATCH 5/5] Fix Node.js versions --- .github/workflows/main.yml | 8 ++++---- 1 file changed, 4 insertions(+), 4 deletions(-) diff --git a/.github/workflows/main.yml b/.github/workflows/main.yml index 6628a7fa9c..dc2cede0d2 100644 --- a/.github/workflows/main.yml +++ b/.github/workflows/main.yml @@ -10,9 +10,9 @@ jobs: fail-fast: false matrix: node-version: - - 18.0.0 - - 16.4.0 - - 14.18.0 + - 18 + - 16 + - 14 os: - ubuntu-latest - macos-latest @@ -25,6 +25,6 @@ jobs: - run: npm install - run: npm test - uses: codecov/codecov-action@v2 - if: matrix.os == 'ubuntu-latest' && matrix.node-version == '18.0.0' + if: matrix.os == 'ubuntu-latest' && matrix.node-version == 18 with: fail_ci_if_error: true