diff --git a/package.json b/package.json index bb2576a67b9..2a4d9e7778f 100644 --- a/package.json +++ b/package.json @@ -69,7 +69,6 @@ "@rollup/plugin-replace": "5.0.4", "@swc/core": "^1.6.5", "@types/hash-sum": "^1.0.2", - "@types/minimist": "^1.2.5", "@types/node": "^20.14.8", "@types/semver": "^7.5.8", "@vitest/coverage-istanbul": "^1.6.0", @@ -82,14 +81,12 @@ "eslint-plugin-import-x": "^0.5.1", "eslint-plugin-vitest": "^0.5.4", "estree-walker": "^2.0.2", - "execa": "^9.3.0", "jsdom": "^24.1.0", "lint-staged": "^15.2.7", "lodash": "^4.17.21", "magic-string": "^0.30.10", "markdown-table": "^3.0.3", "marked": "^12.0.2", - "minimist": "^1.2.8", "npm-run-all2": "^6.2.0", "picocolors": "^1.0.1", "prettier": "^3.3.2", diff --git a/packages/sfc-playground/vite.config.ts b/packages/sfc-playground/vite.config.ts index e30078f4b79..ee9bbd4abf4 100644 --- a/packages/sfc-playground/vite.config.ts +++ b/packages/sfc-playground/vite.config.ts @@ -2,9 +2,11 @@ import fs from 'node:fs' import path from 'node:path' import { type Plugin, defineConfig } from 'vite' import vue from '@vitejs/plugin-vue' -import { execaSync } from 'execa' +import { spawnSync } from 'node:child_process' -const commit = execaSync('git', ['rev-parse', '--short=7', 'HEAD']).stdout +const commit = spawnSync('git', ['rev-parse', '--short=7', 'HEAD']) + .stdout.toString() + .trim() export default defineConfig({ plugins: [ diff --git a/pnpm-lock.yaml b/pnpm-lock.yaml index 47389dd7e5f..fab1b94bf97 100644 --- a/pnpm-lock.yaml +++ b/pnpm-lock.yaml @@ -38,9 +38,6 @@ importers: '@types/hash-sum': specifier: ^1.0.2 version: 1.0.2 - '@types/minimist': - specifier: ^1.2.5 - version: 1.2.5 '@types/node': specifier: ^20.14.8 version: 20.14.8 @@ -77,9 +74,6 @@ importers: estree-walker: specifier: ^2.0.2 version: 2.0.2 - execa: - specifier: ^9.3.0 - version: 9.3.0 jsdom: specifier: ^24.1.0 version: 24.1.0 @@ -98,9 +92,6 @@ importers: marked: specifier: ^12.0.2 version: 12.0.2 - minimist: - specifier: ^1.2.8 - version: 1.2.8 npm-run-all2: specifier: ^6.2.0 version: 6.2.0 @@ -896,16 +887,9 @@ packages: cpu: [x64] os: [win32] - '@sec-ant/readable-stream@0.4.1': - resolution: {integrity: sha512-831qok9r2t8AlxLko40y2ebgSDhenenCatLVeW/uBtnHPyhHOvG0C7TvfgecV+wHzIm5KUICgzmVpWS+IMEAeg==} - '@sinclair/typebox@0.27.8': resolution: {integrity: sha512-+Fj43pSMwJs4KRrH/938Uf+uAELIgVBmQzg/q1YG10djyfA3TnrU8N8XzqCh/okZdszqBQTZf96idMfE5lnwTA==} - '@sindresorhus/merge-streams@4.0.0': - resolution: {integrity: sha512-tlqY9xq5ukxTUZBmoOp+m61cqwQD5pHJtFY3Mn8CA8ps6yghLH/Hw8UPdqg4OLmFW3IFlcXnQNmo/dh8HzXYIQ==} - engines: {node: '>=18'} - '@swc/core-darwin-arm64@1.6.5': resolution: {integrity: sha512-RGQhMdni2v1/ANQ/2K+F+QYdzaucekYBewZcX1ogqJ8G5sbPaBdYdDN1qQ4kHLCIkPtGP6qC7c71qPEqL2RidQ==} engines: {node: '>=10'} @@ -993,9 +977,6 @@ packages: '@types/json-schema@7.0.15': resolution: {integrity: sha512-5+fP8P8MFNC+AyZCDxrB2pkZFPGzqQWUzpSeuuVLvm8VMcorNYavBqoFcxK8bQz4Qsbn4oUEEem4wDLfcysGHA==} - '@types/minimist@1.2.5': - resolution: {integrity: sha512-hov8bUuiLiyFPGyFPE1lwWhmzYbirOXQNNo40+y3zow8aFVTeyn3VWL0VFFfdNddA8S4Vf0Tc062rzyNr7Paag==} - '@types/node@20.14.8': resolution: {integrity: sha512-DO+2/jZinXfROG7j7WKFn/3C6nFwxy2lLpgLjEXJz+0XKphZlTLJ14mo8Vfg8X5BWN6XjyESXq+LcYdT7tR3bA==} @@ -1793,10 +1774,6 @@ packages: resolution: {integrity: sha512-VyhnebXciFV2DESc+p6B+y0LjSm0krU4OgJN44qFAhBY0TJ+1V61tYD2+wHusZ6F9n5K+vl8k0sTy7PEfV4qpg==} engines: {node: '>=16.17'} - execa@9.3.0: - resolution: {integrity: sha512-l6JFbqnHEadBoVAVpN5dl2yCyfX28WoBAGaoQcNmLLSedOxTxcn2Qa83s8I/PA5i56vWru2OHOtrwF7Om2vqlg==} - engines: {node: ^18.19.0 || >=20.5.0} - extract-zip@2.0.1: resolution: {integrity: sha512-GDhU9ntwuKyGXdZBUgTIe+vXnWj0fppUEtMDL0+idd5Sta8TGpHssn/eusA9mrPr9qNDym6SxAYZjNvCn/9RBg==} engines: {node: '>= 10.17.0'} @@ -1827,10 +1804,6 @@ packages: fd-slicer@1.1.0: resolution: {integrity: sha512-cE1qsB/VwyQozZ+q1dGxR8LBYNZeofhEdUNGSMbQD3Gw2lAzX9Zb3uIU6Ebc/Fmyjo9AWWfnn0AUCHqtevs/8g==} - figures@6.1.0: - resolution: {integrity: sha512-d+l3qxjSesT4V7v2fh+QnmFnUWv9lSpjarhShNTgBOfA0ttejbQUAlHLitbjkoRiDulW0OPoQPYIGhIC8ohejg==} - engines: {node: '>=18'} - file-entry-cache@8.0.0: resolution: {integrity: sha512-XXTUwCvisa5oacNGRP9SfNtYBNAMi+RPwBFmblZEF7N7swHYQS6/Zfk7SRwx4D5j3CH211YNRco1DEMNVfZCnQ==} engines: {node: '>=16.0.0'} @@ -1923,10 +1896,6 @@ packages: resolution: {integrity: sha512-VaUJspBffn/LMCJVoMvSAdmscJyS1auj5Zulnn5UoYcY531UWmdwhRWkcGKnGU93m5HSXP9LP2usOryrBtQowA==} engines: {node: '>=16'} - get-stream@9.0.1: - resolution: {integrity: sha512-kVCxPF3vQM/N0B1PmoqVUqgHP+EeVjmZSQn+1oCRPxd2P21P2F19lIgbR3HBosbB1PUhOAoctJnfEn2GbN2eZA==} - engines: {node: '>=18'} - get-tsconfig@4.7.5: resolution: {integrity: sha512-ZCuZCnlqNzjb4QprAzXKdpp/gh6KTxSJuw3IBsPnV/7fV4NxC9ckB+vPTt8w7fJA0TaSD7c55BR47JD6MEDyDw==} @@ -2049,10 +2018,6 @@ packages: resolution: {integrity: sha512-AXcZb6vzzrFAUE61HnN4mpLqd/cSIwNQjtNWR0euPm6y0iqx3G4gOXaIDdtdDwZmhwe82LA6+zinmW4UBWVePQ==} engines: {node: '>=16.17.0'} - human-signals@7.0.0: - resolution: {integrity: sha512-74kytxOUSvNbjrT9KisAbaTZ/eJwD/LrbM/kh5j0IhPuJzwuA19dWvniFGwBzN9rVjg+O/e+F310PjObDXS+9Q==} - engines: {node: '>=18.18.0'} - iconv-lite@0.6.3: resolution: {integrity: sha512-4fCk79wshMdzMp2rH06qWrJE4iolqLhCUH+OiuIgU++RB0+94NlDL81atO7GX55uUKueo0txHNtvEyI6D7WdMw==} engines: {node: '>=0.10.0'} @@ -2158,10 +2123,6 @@ packages: resolution: {integrity: sha512-Fd4gABb+ycGAmKou8eMftCupSir5lRxqf4aD/vd0cD2qc4HL07OjCeuHMr8Ro4CoMaeCKDB0/ECBOVWjTwUvPQ==} engines: {node: '>=8'} - is-plain-obj@4.1.0: - resolution: {integrity: sha512-+Pgi+vMuUNkJyExiMBt5IlFoMyKnr5zhJ4Uspz58WOhBF5QoIZkFyNHIbBAtHwzVAgk5RtndVNsDRN61/mmDqg==} - engines: {node: '>=12'} - is-port-reachable@4.0.0: resolution: {integrity: sha512-9UoipoxYmSk6Xy7QFgRv2HDyaysmgSG75TFQs6S+3pDM7ZhKTF/bskZV+0UlABHzKjNVhPjYCLfeZUEg1wXxig==} engines: {node: ^12.20.0 || ^14.13.1 || >=16.0.0} @@ -2187,18 +2148,10 @@ packages: resolution: {integrity: sha512-LnQR4bZ9IADDRSkvpqMGvt/tEJWclzklNgSw48V5EAaAeDd6qGvN8ei6k5p0tvxSR171VmGyHuTiAOfxAbr8kA==} engines: {node: ^12.20.0 || ^14.13.1 || >=16.0.0} - is-stream@4.0.1: - resolution: {integrity: sha512-Dnz92NInDqYckGEUJv689RbRiTSEHCQ7wOVeALbkOz999YpqT46yMRIGtSNl2iCL1waAZSx40+h59NV/EwzV/A==} - engines: {node: '>=18'} - is-text-path@2.0.0: resolution: {integrity: sha512-+oDTluR6WEjdXEJMnC2z6A4FRwFoYuvShVVEGsS7ewc0UTi2QtAKMDJuL4BDEVt+5T7MjFo12RP8ghOM75oKJw==} engines: {node: '>=8'} - is-unicode-supported@2.0.0: - resolution: {integrity: sha512-FRdAyx5lusK1iHG0TWpVtk9+1i+GjrzRffhDg4ovQ7mcidMQ6mj+MhKPmvh7Xwyv5gIS06ns49CA7Sqg7lC22Q==} - engines: {node: '>=18'} - is-wsl@2.2.0: resolution: {integrity: sha512-fKzAra0rGJUUBwGBgNkHZuToZcn+TtXHpeCgmkMJMMYx1sQDYaCSyjJBSCa2nH1DGm7s3n1oBnohoVTBaN7Lww==} engines: {node: '>=8'} @@ -2607,10 +2560,6 @@ packages: resolution: {integrity: sha512-SgOTCX/EZXtZxBE5eJ97P4yGM5n37BwRU+YMsH4vNzFqJV/oWFXXCmwFlgWUM4PrakybVOueJJ6pwHqSVhTFDw==} engines: {node: '>=16'} - parse-ms@4.0.0: - resolution: {integrity: sha512-TXfryirbmq34y8QBwgqCVLi+8oA3oWx2eAnSn62ITyEhEYaWRlVZ2DvMM9eZbMs/RfxPu/PK/aBLyGj4IrqMHw==} - engines: {node: '>=18'} - parse5@7.1.2: resolution: {integrity: sha512-Czj1WaSVpaoj0wbhMzLmWD69anp2WH7FXMB9n1Sy8/ZFF9jolSQVMu1Ij5WIyGmcBmhk7EOndpO4mIpihVqAXw==} @@ -2732,10 +2681,6 @@ packages: resolution: {integrity: sha512-Pdlw/oPxN+aXdmM9R00JVC9WVFoCLTKJvDVLgmJ+qAffBMxsV85l/Lu7sNx4zSzPyoL2euImuEwHhOXdEgNFZQ==} engines: {node: ^14.15.0 || ^16.10.0 || >=18.0.0} - pretty-ms@9.0.0: - resolution: {integrity: sha512-E9e9HJ9R9NasGOgPaPE8VMeiPKAyWR5jcFpNnwIejslIhWqdqOrb2wShBsncMPUb+BcCd2OPYfh7p2W6oemTng==} - engines: {node: '>=18'} - process-nextick-args@2.0.1: resolution: {integrity: sha512-3ouUOpQhtgrbOa17J7+uxOTpITYWaGP7/AhoR3+A+/1e9skrzelGi/dXzEYyvbxubEF6Wn2ypscTKiKJFFn1ag==} @@ -3108,10 +3053,6 @@ packages: resolution: {integrity: sha512-dOESqjYr96iWYylGObzd39EuNTa5VJxyvVAEm5Jnh7KGo75V43Hk1odPQkNDyXNmUR6k+gEiDVXnjB8HJ3crXw==} engines: {node: '>=12'} - strip-final-newline@4.0.0: - resolution: {integrity: sha512-aulFJcD6YK8V1G7iRB5tigAP4TsHBZZrOV8pjV++zdUwmeV8uzbY7yn6h9MswN62adStNZFuCIx4haBnRuMDaw==} - engines: {node: '>=18'} - strip-json-comments@2.0.1: resolution: {integrity: sha512-4gB8na07fecVVkOI6Rs4e7T6NOTki5EmL7TUduTs6bu3EdnSycntVJ4re8kgZA+wx9IueI2Y11bfbgwtzuE0KQ==} engines: {node: '>=0.10.0'} @@ -3475,10 +3416,6 @@ packages: resolution: {integrity: sha512-9bnSc/HEW2uRy67wc+T8UwauLuPJVn28jb+GtJY16iiKWyvmYJRXVT4UamsAEGQfPohgr2q4Tq0sQbQlxTfi1g==} engines: {node: '>=12.20'} - yoctocolors@2.0.2: - resolution: {integrity: sha512-Ct97huExsu7cWeEjmrXlofevF8CvzUglJ4iGUet5B8xn1oumtAZBpHU4GzYuoE6PVqcZ5hghtBrSlhwHuR1Jmw==} - engines: {node: '>=18'} - zod@3.23.8: resolution: {integrity: sha512-XBx9AXhXktjUqnepgTiE5flcKIYWi/rme0Eaj+5Y0lftuGBq+jyRu/md4WnuxqgP1ubdpNCsYEYPxrzVHD8d6g==} @@ -3916,12 +3853,8 @@ snapshots: '@rollup/rollup-win32-x64-msvc@4.18.0': optional: true - '@sec-ant/readable-stream@0.4.1': {} - '@sinclair/typebox@0.27.8': {} - '@sindresorhus/merge-streams@4.0.0': {} - '@swc/core-darwin-arm64@1.6.5': optional: true @@ -3982,8 +3915,6 @@ snapshots: '@types/json-schema@7.0.15': {} - '@types/minimist@1.2.5': {} - '@types/node@20.14.8': dependencies: undici-types: 5.26.5 @@ -4891,21 +4822,6 @@ snapshots: signal-exit: 4.1.0 strip-final-newline: 3.0.0 - execa@9.3.0: - dependencies: - '@sindresorhus/merge-streams': 4.0.0 - cross-spawn: 7.0.3 - figures: 6.1.0 - get-stream: 9.0.1 - human-signals: 7.0.0 - is-plain-obj: 4.1.0 - is-stream: 4.0.1 - npm-run-path: 5.3.0 - pretty-ms: 9.0.0 - signal-exit: 4.1.0 - strip-final-newline: 4.0.0 - yoctocolors: 2.0.2 - extract-zip@2.0.1: dependencies: debug: 4.3.5 @@ -4944,10 +4860,6 @@ snapshots: dependencies: pend: 1.2.0 - figures@6.1.0: - dependencies: - is-unicode-supported: 2.0.0 - file-entry-cache@8.0.0: dependencies: flat-cache: 4.0.1 @@ -5029,11 +4941,6 @@ snapshots: get-stream@8.0.1: {} - get-stream@9.0.1: - dependencies: - '@sec-ant/readable-stream': 0.4.1 - is-stream: 4.0.1 - get-tsconfig@4.7.5: dependencies: resolve-pkg-maps: 1.0.0 @@ -5171,8 +5078,6 @@ snapshots: human-signals@5.0.0: {} - human-signals@7.0.0: {} - iconv-lite@0.6.3: dependencies: safer-buffer: 2.1.2 @@ -5255,8 +5160,6 @@ snapshots: is-path-inside@3.0.3: {} - is-plain-obj@4.1.0: {} - is-port-reachable@4.0.0: {} is-potential-custom-element-name@1.0.1: {} @@ -5276,14 +5179,10 @@ snapshots: is-stream@3.0.0: {} - is-stream@4.0.1: {} - is-text-path@2.0.0: dependencies: text-extensions: 2.4.0 - is-unicode-supported@2.0.0: {} - is-wsl@2.2.0: dependencies: is-docker: 2.2.1 @@ -5712,8 +5611,6 @@ snapshots: lines-and-columns: 2.0.4 type-fest: 3.13.1 - parse-ms@4.0.0: {} - parse5@7.1.2: dependencies: entities: 4.5.0 @@ -5817,10 +5714,6 @@ snapshots: ansi-styles: 5.2.0 react-is: 18.2.0 - pretty-ms@9.0.0: - dependencies: - parse-ms: 4.0.0 - process-nextick-args@2.0.1: {} progress@2.0.3: {} @@ -6272,8 +6165,6 @@ snapshots: strip-final-newline@3.0.0: {} - strip-final-newline@4.0.0: {} - strip-json-comments@2.0.1: {} strip-json-comments@3.1.1: {} @@ -6603,6 +6494,4 @@ snapshots: yocto-queue@1.0.0: {} - yoctocolors@2.0.2: {} - zod@3.23.8: {} diff --git a/scripts/build.js b/scripts/build.js index eacabe0dee4..ec111a0387e 100644 --- a/scripts/build.js +++ b/scripts/build.js @@ -17,31 +17,67 @@ nr build core --formats cjs */ import fs from 'node:fs/promises' -import { existsSync } from 'node:fs' +import { parseArgs } from 'node:util' +import { existsSync, readFileSync } from 'node:fs' import path from 'node:path' -import minimist from 'minimist' import { brotliCompressSync, gzipSync } from 'node:zlib' import pico from 'picocolors' -import { execa, execaSync } from 'execa' import { cpus } from 'node:os' -import { createRequire } from 'node:module' -import { targets as allTargets, fuzzyMatchTarget } from './utils.js' +import { targets as allTargets, exec, fuzzyMatchTarget } from './utils.js' import { scanEnums } from './inline-enums.js' import prettyBytes from 'pretty-bytes' +import { spawnSync } from 'node:child_process' -const require = createRequire(import.meta.url) -const args = minimist(process.argv.slice(2)) -const targets = args._ -const formats = args.formats || args.f -const devOnly = args.devOnly || args.d -const prodOnly = !devOnly && (args.prodOnly || args.p) -const buildTypes = args.withTypes || args.t -const sourceMap = args.sourcemap || args.s -const isRelease = args.release -/** @type {boolean | undefined} */ -const buildAllMatching = args.all || args.a -const writeSize = args.size -const commit = execaSync('git', ['rev-parse', '--short=7', 'HEAD']).stdout +const commit = spawnSync('git', ['rev-parse', '--short=7', 'HEAD']) + .stdout.toString() + .trim() + +const { values, positionals: targets } = parseArgs({ + allowPositionals: true, + options: { + formats: { + type: 'string', + short: 'f', + }, + devOnly: { + type: 'boolean', + short: 'd', + }, + prodOnly: { + type: 'boolean', + short: 'p', + }, + withTypes: { + type: 'boolean', + short: 't', + }, + sourceMap: { + type: 'boolean', + short: 's', + }, + release: { + type: 'boolean', + }, + all: { + type: 'boolean', + short: 'a', + }, + size: { + type: 'boolean', + }, + }, +}) + +const { + formats, + all: buildAllMatching, + devOnly, + prodOnly, + withTypes: buildTypes, + sourceMap, + release: isRelease, + size: writeSize, +} = values const sizeDir = path.resolve('temp/size') @@ -57,7 +93,7 @@ async function run() { await buildAll(resolvedTargets) await checkAllSizes(resolvedTargets) if (buildTypes) { - await execa( + await exec( 'pnpm', [ 'run', @@ -114,6 +150,7 @@ async function runParallel(maxConcurrency, source, iteratorFn) { } return Promise.all(ret) } + /** * Builds the target. * @param {string} target - The target to build. @@ -121,7 +158,7 @@ async function runParallel(maxConcurrency, source, iteratorFn) { */ async function build(target) { const pkgDir = path.resolve(`packages/${target}`) - const pkg = require(`${pkgDir}/package.json`) + const pkg = JSON.parse(readFileSync(`${pkgDir}/package.json`, 'utf-8')) // if this is a full build (no specific targets), ignore private packages if ((isRelease || !targets.length) && pkg.private) { @@ -136,7 +173,8 @@ async function build(target) { const env = (pkg.buildOptions && pkg.buildOptions.env) || (devOnly ? 'development' : 'production') - await execa( + + await exec( 'rollup', [ '-c', diff --git a/scripts/dev.js b/scripts/dev.js index 7db79442ee9..4041e61bbfe 100644 --- a/scripts/dev.js +++ b/scripts/dev.js @@ -8,16 +8,38 @@ import esbuild from 'esbuild' import { dirname, relative, resolve } from 'node:path' import { fileURLToPath } from 'node:url' import { createRequire } from 'node:module' -import minimist from 'minimist' +import { parseArgs } from 'node:util' import { polyfillNode } from 'esbuild-plugin-polyfill-node' const require = createRequire(import.meta.url) const __dirname = dirname(fileURLToPath(import.meta.url)) -const args = minimist(process.argv.slice(2)) -const targets = args._.length ? args._ : ['vue'] -const format = args.f || 'global' -const prod = args.p || false -const inlineDeps = args.i || args.inline + +const { + values: { format: rawFormat, prod, inline: inlineDeps }, + positionals, +} = parseArgs({ + allowPositionals: true, + options: { + format: { + type: 'string', + short: 'f', + default: 'global', + }, + prod: { + type: 'boolean', + short: 'p', + default: false, + }, + inline: { + type: 'boolean', + short: 'i', + default: false, + }, + }, +}) + +const format = rawFormat || 'global' +const targets = positionals.length ? positionals : ['vue'] // resolve output const outputFormat = format.startsWith('global') diff --git a/scripts/inline-enums.js b/scripts/inline-enums.js index 40bd31bfd8a..b1baaa6c5c3 100644 --- a/scripts/inline-enums.js +++ b/scripts/inline-enums.js @@ -21,7 +21,7 @@ import { } from 'node:fs' import * as path from 'node:path' import { parse } from '@babel/parser' -import { execaSync } from 'execa' +import { spawnSync } from 'node:child_process' import MagicString from 'magic-string' /** @@ -49,8 +49,16 @@ export function scanEnums() { const defines = Object.create(null) // 1. grep for files with exported enum - const { stdout } = execaSync('git', ['grep', `export enum`]) - const files = [...new Set(stdout.split('\n').map(line => line.split(':')[0]))] + const { stdout } = spawnSync('git', ['grep', `export enum`]) + const files = [ + ...new Set( + stdout + .toString() + .trim() + .split('\n') + .map(line => line.split(':')[0]), + ), + ] // 2. parse matched files to collect enum info for (const relativeFile of files) { diff --git a/scripts/release.js b/scripts/release.js index 4a0c968e286..eed71c2fd19 100644 --- a/scripts/release.js +++ b/scripts/release.js @@ -1,13 +1,13 @@ // @ts-check -import minimist from 'minimist' import fs from 'node:fs' import path from 'node:path' import pico from 'picocolors' import semver from 'semver' import enquirer from 'enquirer' -import { execa } from 'execa' import { createRequire } from 'node:module' import { fileURLToPath } from 'node:url' +import { exec } from './utils.js' +import { parseArgs } from 'node:util' /** * @typedef {{ @@ -23,12 +23,34 @@ let versionUpdated = false const { prompt } = enquirer const currentVersion = createRequire(import.meta.url)('../package.json').version const __dirname = path.dirname(fileURLToPath(import.meta.url)) -const args = minimist(process.argv.slice(2), { - alias: { - skipBuild: 'skip-build', - skipTests: 'skip-tests', - skipGit: 'skip-git', - skipPrompts: 'skip-prompts', + +const { values: args, positionals } = parseArgs({ + allowPositionals: true, + options: { + preid: { + type: 'string', + }, + dry: { + type: 'boolean', + }, + tag: { + type: 'string', + }, + canary: { + type: 'boolean', + }, + skipBuild: { + type: 'boolean', + }, + skipTests: { + type: 'boolean', + }, + skipGit: { + type: 'boolean', + }, + skipPrompts: { + type: 'boolean', + }, }, }) @@ -94,16 +116,16 @@ const versionIncrements = [ ] const inc = (/** @type {import('semver').ReleaseType} */ i) => - semver.inc(currentVersion, i, preId) + semver.inc(currentVersion, i, typeof preId === 'string' ? preId : undefined) const run = async ( /** @type {string} */ bin, /** @type {ReadonlyArray} */ args, - /** @type {import('execa').Options} */ opts = {}, -) => execa(bin, args, { stdio: 'inherit', ...opts }) + /** @type {import('node:child_process').SpawnOptions} */ opts = {}, +) => exec(bin, args, { stdio: 'inherit', ...opts }) const dryRun = async ( /** @type {string} */ bin, /** @type {ReadonlyArray} */ args, - /** @type {import('execa').Options} */ opts = {}, + /** @type {import('node:child_process').SpawnOptions} */ opts = {}, ) => console.log(pico.blue(`[dryrun] ${bin} ${args.join(' ')}`), opts) const runIfNotDry = isDryRun ? dryRun : run const getPkgRoot = (/** @type {string} */ pkg) => @@ -117,7 +139,7 @@ async function main() { console.log(`${pico.green(`✓`)} commit is up-to-date with remote.\n`) } - let targetVersion = args._[0] + let targetVersion = positionals[0] if (isCanary) { // The canary version string format is `3.yyyyMMdd.0` (or `3.yyyyMMdd.0-minor.0` for minor) @@ -392,11 +414,11 @@ async function isInSyncWithRemote() { } async function getSha() { - return (await execa('git', ['rev-parse', 'HEAD'])).stdout + return (await exec('git', ['rev-parse', 'HEAD'])).stdout } async function getBranch() { - return (await execa('git', ['rev-parse', '--abbrev-ref', 'HEAD'])).stdout + return (await exec('git', ['rev-parse', '--abbrev-ref', 'HEAD'])).stdout } /** diff --git a/scripts/utils.js b/scripts/utils.js index 6c3844dd12c..7eec806531d 100644 --- a/scripts/utils.js +++ b/scripts/utils.js @@ -2,6 +2,7 @@ import fs from 'node:fs' import pico from 'picocolors' import { createRequire } from 'node:module' +import { spawn } from 'node:child_process' const require = createRequire(import.meta.url) @@ -51,3 +52,50 @@ export function fuzzyMatchTarget(partialTargets, includeAllMatching) { process.exit(1) } } + +/** + * @param {string} command + * @param {ReadonlyArray} args + * @param {object} [options] + */ +export async function exec(command, args, options) { + return new Promise((resolve, reject) => { + const process = spawn(command, args, { + stdio: [ + 'ignore', // stdin + 'pipe', // stdout + 'pipe', // stderr + ], + ...options, + }) + + /** + * @type {Buffer[]} + */ + const stderrChunks = [] + /** + * @type {Buffer[]} + */ + const stdoutChunks = [] + + process.stderr?.on('data', chunk => { + stderrChunks.push(chunk) + }) + + process.stdout?.on('data', chunk => { + stdoutChunks.push(chunk) + }) + + process.on('error', error => { + reject(error) + }) + + process.on('exit', code => { + const ok = code === 0 + const stderr = Buffer.concat(stderrChunks).toString().trim() + const stdout = Buffer.concat(stdoutChunks).toString().trim() + const result = { ok, code, stderr, stdout } + resolve(result) + }) + }) +} diff --git a/scripts/verify-treeshaking.js b/scripts/verify-treeshaking.js index f19fea92d24..7cb76cdac81 100644 --- a/scripts/verify-treeshaking.js +++ b/scripts/verify-treeshaking.js @@ -1,8 +1,8 @@ // @ts-check import fs from 'node:fs' -import { execa } from 'execa' +import { exec } from './utils.js' -execa('pnpm', ['build', 'vue', '-f', 'global-runtime']).then(() => { +exec('pnpm', ['build', 'vue', '-f', 'global-runtime']).then(() => { const errors = [] const devBuild = fs.readFileSync(