diff --git a/package.json b/package.json index 4941854dd..5f619e54c 100644 --- a/package.json +++ b/package.json @@ -132,7 +132,6 @@ "eslint-plugin-simple-import-sort": "12.1.1", "eslint-plugin-unicorn": "57.0.0", "esm-utils": "4.3.0", - "execa": "7.2.0", "globals": "16.0.0", "jest": "30.0.0-alpha.7", "jest-light-runner": "0.6.0", @@ -141,6 +140,7 @@ "jest-watch-typeahead": "2.2.2", "knip": "5.44.4", "magic-string": "0.30.17", + "nano-spawn": "0.2.0", "node-style-text": "0.0.7", "npm-run-all2": "7.0.2", "prettier": "3.5.2", diff --git a/scripts/build-website.js b/scripts/build-website.js index b859e4e77..b026a7a07 100644 --- a/scripts/build-website.js +++ b/scripts/build-website.js @@ -4,8 +4,8 @@ import fs from "node:fs/promises"; import path from "node:path"; import url from "node:url"; import esbuild from "esbuild"; -import { execa } from "execa"; import fastGlob from "fast-glob"; +import spawn from "nano-spawn"; import serialize from "serialize-javascript"; import { copyFile, @@ -17,11 +17,7 @@ import { } from "./utils/index.js"; const runYarn = (command, args, options) => - execa("yarn", [command, ...args], { - stdout: "inherit", - stderr: "inherit", - ...options, - }); + spawn("yarn", [command, ...args], { stdio: "inherit", ...options }); const IS_PULL_REQUEST = process.env.PULL_REQUEST === "true"; const PRETTIER_DIR = IS_PULL_REQUEST ? DIST_DIR diff --git a/scripts/clean-cspell.js b/scripts/clean-cspell.js index 24752b357..72bdae0d5 100644 --- a/scripts/clean-cspell.js +++ b/scripts/clean-cspell.js @@ -1,19 +1,13 @@ #!/usr/bin/env node import fs from "node:fs/promises"; -import { execa } from "execa"; +import spawn from "nano-spawn"; const CSPELL_CONFIG_FILE = new URL("../cspell.json", import.meta.url); const updateConfig = (config) => fs.writeFile(CSPELL_CONFIG_FILE, JSON.stringify(config, undefined, 4) + "\n"); -const runSpellcheck = (options) => { - const { yarnArgs, args, execaOptions } = { - yarnArgs: [], - args: [], - ...options, - }; - return execa("yarn", [...yarnArgs, "lint:spellcheck", ...args], execaOptions); -}; +const runSpellcheck = (args, options) => + spawn("yarn", ["lint:spellcheck", ...args], options); console.log("Empty words ..."); const config = JSON.parse(await fs.readFile(CSPELL_CONFIG_FILE)); @@ -21,20 +15,24 @@ const original = config.words; await updateConfig({ ...config, words: [] }); console.log("Running spellcheck with empty words ..."); -const { stdout } = await runSpellcheck({ - args: ["--words-only", "--unique"], - execaOptions: { reject: false }, -}); +let stdout = ""; +try { + await runSpellcheck(["--words-only", "--unique"]); +} catch (error) { + ({ stdout } = error); +} const words = stdout - .split("\n") - // Remove upper case word, if lower case one already exists - .filter((word, _, words) => { - const lowerCased = word.toLowerCase(); - return lowerCased === word || !words.includes(lowerCased); - }) - // Compare function from https://github.com/streetsidesoftware/vscode-spell-checker/blob/2fde3bc5c658ee51da5a56580aa1370bf8174070/packages/client/src/settings/CSpellSettings.ts#L78 - .sort((a, b) => a.toLowerCase().localeCompare(b.toLowerCase())); + ? stdout + .split("\n") + // Remove upper case word, if lower case one already exists + .filter((word, _, words) => { + const lowerCased = word.toLowerCase(); + return lowerCased === word || !words.includes(lowerCased); + }) + // Compare function from https://github.com/streetsidesoftware/vscode-spell-checker/blob/2fde3bc5c658ee51da5a56580aa1370bf8174070/packages/client/src/settings/CSpellSettings.ts#L78 + .sort((a, b) => a.toLowerCase().localeCompare(b.toLowerCase())) + : []; config.words = words; const removed = original.filter((word) => !words.includes(word)); @@ -58,6 +56,6 @@ console.log("Updating words ..."); await updateConfig(config); console.log("Running spellcheck with new words ..."); -await runSpellcheck({ execaOptions: { stdout: "inherit" } }); +await runSpellcheck([], { stdio: "inherit" }); console.log("CSpell config file updated."); diff --git a/scripts/clean-git-blame-ignore-revs-file.js b/scripts/clean-git-blame-ignore-revs-file.js index dcc5f9d9d..357c5683d 100644 --- a/scripts/clean-git-blame-ignore-revs-file.js +++ b/scripts/clean-git-blame-ignore-revs-file.js @@ -7,7 +7,7 @@ Remove revs without actual file change */ import fs from "node:fs/promises"; -import { execa } from "execa"; +import spawn from "nano-spawn"; const FILE = new URL("../.git-blame-ignore-revs", import.meta.url); const content = await fs.readFile(FILE, "utf8"); @@ -17,7 +17,7 @@ const revsToRemove = new Set(); const IGNORED_FILES = new Set(["package.json", "yarn.lock"]); async function getChangedFiles(rev) { - const { stdout } = await execa("git", [ + const { stdout } = await spawn("git", [ "show", "--name-only", "--pretty=", diff --git a/tests/config/install-prettier.js b/tests/config/install-prettier.js index fb91dd26b..5f41ebb88 100644 --- a/tests/config/install-prettier.js +++ b/tests/config/install-prettier.js @@ -1,14 +1,17 @@ +import { spawnSync } from "node:child_process"; import crypto from "node:crypto"; import fs from "node:fs"; import os from "node:os"; import path from "node:path"; import chalk from "chalk"; -import { execaSync } from "execa"; import { outdent } from "outdent"; const createTemporaryDirectory = () => { const directory = path.join( - os.tmpdir(), + // The following quoted from https://github.com/es-tooling/module-replacements/blob/27d1acd38f19741e31d2eae561a5c8a914373fc5/docs/modules/tempy.md?plain=1#L20-L21, not sure if it's true + // MacOS and possibly some other platforms return a symlink from `os.tmpdir`. + // For some applications, this can cause problems; thus, we use `realpath`. + fs.realpathSync(os.tmpdir()), crypto.randomBytes(16).toString("hex"), ); fs.mkdirSync(directory); @@ -51,8 +54,10 @@ function cleanUp() { function installPrettier(packageDirectory) { const temporaryDirectory = createTemporaryDirectory(); directoriesToClean.add(temporaryDirectory); - const fileName = execaSync("npm", ["pack"], { + const fileName = spawnSync("npm", ["pack"], { cwd: packageDirectory, + shell: true, + encoding: "utf8", }).stdout.trim(); const file = path.join(packageDirectory, fileName); const packed = path.join(temporaryDirectory, fileName); @@ -60,7 +65,7 @@ function installPrettier(packageDirectory) { fs.unlinkSync(file); const runNpmClient = (args) => - execaSync(client, args, { cwd: temporaryDirectory }); + spawnSync(client, args, { cwd: temporaryDirectory, shell: true }); runNpmClient(client === "pnpm" ? ["init"] : ["init", "-y"]); diff --git a/yarn.lock b/yarn.lock index 19e985523..7ebbd045f 100644 --- a/yarn.lock +++ b/yarn.lock @@ -4177,23 +4177,6 @@ __metadata: languageName: node linkType: hard -"execa@npm:7.2.0": - version: 7.2.0 - resolution: "execa@npm:7.2.0" - dependencies: - cross-spawn: "npm:^7.0.3" - get-stream: "npm:^6.0.1" - human-signals: "npm:^4.3.0" - is-stream: "npm:^3.0.0" - merge-stream: "npm:^2.0.0" - npm-run-path: "npm:^5.1.0" - onetime: "npm:^6.0.0" - signal-exit: "npm:^3.0.7" - strip-final-newline: "npm:^3.0.0" - checksum: 10/473feff60f9d4dbe799225948de48b5158c1723021d19c4b982afe37bcd111ae84e1b4c9dfe967fae5101b0894b1a62e4dd564a286dfa3e46d7b0cfdbf7fe62b - languageName: node - linkType: hard - "execa@npm:^5.0.0": version: 5.1.1 resolution: "execa@npm:5.1.1" @@ -4626,7 +4609,7 @@ __metadata: languageName: node linkType: hard -"get-stream@npm:^6.0.0, get-stream@npm:^6.0.1": +"get-stream@npm:^6.0.0": version: 6.0.1 resolution: "get-stream@npm:6.0.1" checksum: 10/781266d29725f35c59f1d214aedc92b0ae855800a980800e2923b3fbc4e56b3cb6e462c42e09a1cf1a00c64e056a78fa407cbe06c7c92b7e5cd49b4b85c2a497 @@ -4950,13 +4933,6 @@ __metadata: languageName: node linkType: hard -"human-signals@npm:^4.3.0": - version: 4.3.1 - resolution: "human-signals@npm:4.3.1" - checksum: 10/fa59894c358fe9f2b5549be2fb083661d5e1dff618d3ac70a49ca73495a72e873fbf6c0878561478e521e17d498292746ee391791db95ffe5747bfb5aef8765b - languageName: node - linkType: hard - "iconv-lite@npm:^0.6.2": version: 0.6.3 resolution: "iconv-lite@npm:0.6.3" @@ -6636,13 +6612,6 @@ __metadata: languageName: node linkType: hard -"mimic-fn@npm:^4.0.0": - version: 4.0.0 - resolution: "mimic-fn@npm:4.0.0" - checksum: 10/995dcece15ee29aa16e188de6633d43a3db4611bcf93620e7e62109ec41c79c0f34277165b8ce5e361205049766e371851264c21ac64ca35499acb5421c2ba56 - languageName: node - linkType: hard - "min-indent@npm:^1.0.1": version: 1.0.1 resolution: "min-indent@npm:1.0.1" @@ -6801,6 +6770,13 @@ __metadata: languageName: node linkType: hard +"nano-spawn@npm:0.2.0": + version: 0.2.0 + resolution: "nano-spawn@npm:0.2.0" + checksum: 10/efc75810590f9a15ffde05f03ab6408727524040fe13db1a34e8d09512803269f976a294b4facf51ba30bfb32568dcc8a723fee36e45a5748cd045bf566b6790 + languageName: node + linkType: hard + "nanoid@npm:^3.3.8": version: 3.3.8 resolution: "nanoid@npm:3.3.8" @@ -6931,15 +6907,6 @@ __metadata: languageName: node linkType: hard -"npm-run-path@npm:^5.1.0": - version: 5.3.0 - resolution: "npm-run-path@npm:5.3.0" - dependencies: - path-key: "npm:^4.0.0" - checksum: 10/ae8e7a89da9594fb9c308f6555c73f618152340dcaae423e5fb3620026fefbec463618a8b761920382d666fa7a2d8d240b6fe320e8a6cdd54dc3687e2b659d25 - languageName: node - linkType: hard - "object-assign@npm:^4.1.1": version: 4.1.1 resolution: "object-assign@npm:4.1.1" @@ -7028,15 +6995,6 @@ __metadata: languageName: node linkType: hard -"onetime@npm:^6.0.0": - version: 6.0.0 - resolution: "onetime@npm:6.0.0" - dependencies: - mimic-fn: "npm:^4.0.0" - checksum: 10/0846ce78e440841335d4e9182ef69d5762e9f38aa7499b19f42ea1c4cd40f0b4446094c455c713f9adac3f4ae86f613bb5e30c99e52652764d06a89f709b3788 - languageName: node - linkType: hard - "open@npm:^8.4.0": version: 8.4.2 resolution: "open@npm:8.4.2" @@ -7254,13 +7212,6 @@ __metadata: languageName: node linkType: hard -"path-key@npm:^4.0.0": - version: 4.0.0 - resolution: "path-key@npm:4.0.0" - checksum: 10/8e6c314ae6d16b83e93032c61020129f6f4484590a777eed709c4a01b50e498822b00f76ceaf94bc64dbd90b327df56ceadce27da3d83393790f1219e07721d7 - languageName: node - linkType: hard - "path-parse@npm:^1.0.7": version: 1.0.7 resolution: "path-parse@npm:1.0.7" @@ -7510,7 +7461,6 @@ __metadata: eslint-plugin-unicorn: "npm:57.0.0" esm-utils: "npm:4.3.0" espree: "npm:10.3.0" - execa: "npm:7.2.0" fast-glob: "npm:3.3.3" fast-json-stable-stringify: "npm:2.1.0" file-entry-cache: "npm:10.0.6" @@ -7544,6 +7494,7 @@ __metadata: micromatch: "npm:4.0.8" minimist: "npm:1.2.8" n-readlines: "npm:1.0.1" + nano-spawn: "npm:0.2.0" node-style-text: "npm:0.0.7" npm-run-all2: "npm:7.0.2" outdent: "npm:0.8.0" @@ -8586,13 +8537,6 @@ __metadata: languageName: node linkType: hard -"strip-final-newline@npm:^3.0.0": - version: 3.0.0 - resolution: "strip-final-newline@npm:3.0.0" - checksum: 10/23ee263adfa2070cd0f23d1ac14e2ed2f000c9b44229aec9c799f1367ec001478469560abefd00c5c99ee6f0b31c137d53ec6029c53e9f32a93804e18c201050 - languageName: node - linkType: hard - "strip-indent@npm:^4.0.0": version: 4.0.0 resolution: "strip-indent@npm:4.0.0"