From 89f5f0d133e264d1d34af9e5931eaf6045960be5 Mon Sep 17 00:00:00 2001 From: Sindre Sorhus Date: Sun, 5 Nov 2023 00:31:47 +0700 Subject: [PATCH] Remove the bundled binaries Fixes #24 Fixes #23 Fixes #22 Fixes #21 Fixes #15 --- index.js | 96 ++++++++++++++++++++--------------- vendor/macos/term-size | Bin 27264 -> 0 bytes vendor/windows/term-size.exe | Bin 17408 -> 0 bytes 3 files changed, 54 insertions(+), 42 deletions(-) delete mode 100755 vendor/macos/term-size delete mode 100644 vendor/windows/term-size.exe diff --git a/index.js b/index.js index 06c78ce..60e3905 100644 --- a/index.js +++ b/index.js @@ -1,7 +1,10 @@ import process from 'node:process'; import {execFileSync} from 'node:child_process'; -import path from 'node:path'; -import {fileURLToPath} from 'node:url'; +import fs from 'node:fs'; +import tty from 'node:tty'; + +const defaultColumns = 80; +const defaultRows = 24; const exec = (command, arguments_, {shell, env} = {}) => execFileSync(command, arguments_, { @@ -12,16 +15,25 @@ const exec = (command, arguments_, {shell, env} = {}) => env, }).trim(); -function execNative(command, {shell} = {}) { - const __dirname = path.dirname(fileURLToPath(import.meta.url)); - return exec(path.join(__dirname, command), [], {shell}).split(/\r?\n/); -} - const create = (columns, rows) => ({ columns: Number.parseInt(columns, 10), rows: Number.parseInt(rows, 10), }); +const createIfNotDefault = (maybeColumns, maybeRows) => { + const {columns, rows} = create(maybeColumns, maybeRows); + + if (Number.isNaN(columns) || Number.isNaN(rows)) { + return; + } + + if (columns === defaultColumns && rows === defaultRows) { + return; + } + + return {columns, rows}; +}; + export default function terminalSize() { const {env, stdout, stderr} = process; @@ -38,46 +50,33 @@ export default function terminalSize() { return create(env.COLUMNS, env.LINES); } - if (process.platform === 'win32') { - try { - // Binary: https://github.com/sindresorhus/win-term-size - const size = execNative('vendor/windows/term-size.exe', {shell: false}); - - if (size.length === 2) { - return create(size[0], size[1]); - } - } catch {} - } else { - if (process.platform === 'darwin') { - try { - // Binary: https://github.com/sindresorhus/macos-term-size - const size = execNative('vendor/macos/term-size', {shell: true}); - - if (size.length === 2) { - return create(size[0], size[1]); - } - } catch {} - } - - // `resize` is preferred as it works even when all file descriptors are redirected - // https://linux.die.net/man/1/resize - try { - const size = exec('resize', ['-u']).match(/\d+/g); + const fallback = { + columns: defaultColumns, + rows: defaultRows, + }; - if (size.length === 2) { - return create(size[0], size[1]); - } - } catch {} + if (process.platform === 'win32') { + // We include `tput` for Windows users using Git Bash. + return tput() ?? fallback; + } - const tputResult = tput(); - if (tputResult) { - return tputResult; - } + if (process.platform === 'darwin') { + return devTty() ?? tput() ?? fallback; } - return create(80, 24); + return devTty() ?? tput() ?? resize() ?? fallback; } +const devTty = () => { + try { + // eslint-disable-next-line no-bitwise + const flags = process.platform === 'darwin' ? fs.constants.O_EVTONLY | fs.constants.O_NONBLOCK : fs.constants.O_NONBLOCK; + // eslint-disable-next-line new-cap + const {columns, rows} = tty.WriteStream(fs.openSync('/dev/tty', flags)); + return {columns, rows}; + } catch {} +}; + // On macOS, this only returns correct values when stdout is not redirected. const tput = () => { try { @@ -86,7 +85,20 @@ const tput = () => { const rows = exec('tput', ['lines'], {env: {TERM: 'dumb', ...process.env}}); if (columns && rows) { - return create(columns, rows); + return createIfNotDefault(columns, rows); + } + } catch {} +}; + +// Only exists on Linux. +const resize = () => { + // `resize` is preferred as it works even when all file descriptors are redirected + // https://linux.die.net/man/1/resize + try { + const size = exec('resize', ['-u']).match(/\d+/g); + + if (size.length === 2) { + return createIfNotDefault(size[0], size[1]); } } catch {} }; diff --git a/vendor/macos/term-size b/vendor/macos/term-size deleted file mode 100755 index a18b59a50ec77ca2de3a4115ccb456acfb62c2c5..0000000000000000000000000000000000000000 GIT binary patch literal 0 HcmV?d00001 literal 27264 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 diff --git a/vendor/windows/term-size.exe b/vendor/windows/term-size.exe deleted file mode 100644 index c7a170c96442547c1465f031f9017f4374110829..0000000000000000000000000000000000000000 GIT binary patch literal 0 HcmV?d00001 literal 17408 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