fix: transform CLI via SWC reusing lib bundle

This commit is contained in:
Amin Yahyaabadi 2025-04-06 23:12:55 -07:00
parent d1834415a9
commit 6ef4c24024
40 changed files with 981 additions and 175 deletions

View File

@ -62,6 +62,7 @@ words:
- inja
- isci
- isroot
- jsonify
- kcov
- LDFLAGS
- lefticus

File diff suppressed because one or more lines are too long

File diff suppressed because one or more lines are too long

File diff suppressed because one or more lines are too long

File diff suppressed because one or more lines are too long

File diff suppressed because one or more lines are too long

File diff suppressed because one or more lines are too long

File diff suppressed because one or more lines are too long

File diff suppressed because one or more lines are too long

File diff suppressed because one or more lines are too long

2
dist/legacy/lib.js vendored

File diff suppressed because one or more lines are too long

File diff suppressed because one or more lines are too long

File diff suppressed because one or more lines are too long

File diff suppressed because one or more lines are too long

File diff suppressed because one or more lines are too long

File diff suppressed because one or more lines are too long

File diff suppressed because one or more lines are too long

File diff suppressed because one or more lines are too long

File diff suppressed because one or more lines are too long

File diff suppressed because one or more lines are too long

File diff suppressed because one or more lines are too long

File diff suppressed because one or more lines are too long

File diff suppressed because one or more lines are too long

File diff suppressed because one or more lines are too long

2
dist/modern/lib.mjs vendored

File diff suppressed because one or more lines are too long

File diff suppressed because one or more lines are too long

File diff suppressed because one or more lines are too long

File diff suppressed because one or more lines are too long

File diff suppressed because one or more lines are too long

View File

@ -5,9 +5,9 @@
"repository": "https://github.com/aminya/setup-cpp",
"license": "Apache-2.0",
"author": "Amin Yahyaabadi",
"main": "dist/legacy/setup-cpp.js",
"modern": "./dist/modern/setup-cpp.mjs",
"source": "./src/setup-cpp.ts",
"main": "dist/legacy/lib.js",
"modern": "./dist/modern/lib.mjs",
"source": "./src/lib.ts",
"bin": {
"setup-cpp": "dist/legacy/setup-cpp.js"
},
@ -46,9 +46,11 @@
"tsconfig.json"
],
"scripts": {
"build": "run-s clean && turbo build && run-p lint.root.tsc build.vite.modern build.vite.legacy && run-p build.json build.bash",
"build.vite.modern": "cross-env NODE_ENV=production vite build --mode cli-modern",
"build.vite.legacy": "cross-env NODE_ENV=production vite build --mode cli-legacy",
"build": "run-s clean && turbo build && run-p lint.root.tsc build.cli.modern build.cli.legacy build.library.modern build.library.legacy && run-p build.json build.bash",
"build.cli.modern": "swc ./src/setup-cpp.ts --out-file ./dist/modern/setup-cpp.mjs --config-file ./swc.modern.json && sed -i 's|./lib.ts|./lib.mjs|g' ./dist/modern/setup-cpp.mjs",
"build.cli.legacy": "swc ./src/setup-cpp.ts --out-file ./dist/legacy/setup-cpp.js --config-file ./swc.legacy.json && sed -i 's|./lib.ts|./lib.js|g' ./dist/legacy/setup-cpp.js",
"build.library.modern": "cross-env NODE_ENV=production vite build --mode library-modern",
"build.library.legacy": "cross-env NODE_ENV=production vite build --mode library-legacy",
"build.json": "shx cp ./src/*/*.json ./dist/legacy/ && shx cp ./dist/legacy/*.json ./dist/modern && minijson --file ./dist/**/*.json",
"build.bash": "shx cp ./src/*/*.bash ./dist/legacy/ && shx cp ./dist/legacy/*.bash ./dist/modern",
"bump": "ncu -u -x execa,numerous,eslint,@types/eslint,which && pnpm update && pnpx typesync && pnpm run clean",
@ -80,6 +82,10 @@
"test": "turbo test && jest --runInBand --forceExit --coverage",
"build.docker-ci": "node ./dev/docker/ci/docker-ci.mjs"
},
"dependencies": {
"mri": "^1.2.0",
"simple-update-notifier": "^2.0.0"
},
"devDependencies": {
"@actions/cache": "^4.0.2",
"@actions/core": "^1.11.1",
@ -99,6 +105,7 @@
"@octokit/rest": "^21.1.1",
"@octokit/types": "^13.8.0",
"@shockpkg/archive-files": "3.2.5",
"@swc/cli": "^0.6.0",
"@swc/jest": "^0.2.37",
"@types/babel__core": "~7.20.5",
"@types/cross-spawn": "^6.0.6",
@ -137,7 +144,6 @@
"macos-release": "^3.3.0",
"memoizee": "^0.4.17",
"mkdirp": "^3.0.1",
"mri": "^1.2.0",
"msvc-dev-cmd": "github:aminya/msvc-dev-cmd#c01f519bd995460228ed3dec4df51df92dc290fd",
"node-downloader-helper": "2.1.9",
"npm-check-updates": "^17.1.16",
@ -154,12 +160,11 @@
"rollup": "^4.34.9",
"safe-stable-stringify": "^2.5.0",
"semver": "7.7.1",
"setup-apt": "workspace:*",
"setup-alpine": "workspace:*",
"setup-apt": "workspace:*",
"setup-brew": "workspace:*",
"setup-python": "github:aminya/setup-python#9700887",
"shx": "0.4.0",
"simple-update-notifier": "^2.0.0",
"terser": "^5.39.0",
"terser-config-atomic": "^1.0.0",
"time-delta": "github:aminya/time-delta#69d91a4",

File diff suppressed because it is too large Load Diff

View File

@ -2,10 +2,6 @@ import packageJson from "../../package-version.json"
import { setupCpp } from "../lib.js"
describe("setupCpp", () => {
it("should be a function", () => {
expect(setupCpp).toBeInstanceOf(Function)
})
it("should install nothing if no tools are installed", async () => {
const opts = {
"setup-cpp": false,

View File

@ -1,5 +1,6 @@
import { parseArgs } from "../cli-options.js"
process.env.SETUP_CPP_SKIP_MAIN = "true"
import { getCompilerInfo } from "../compilers.js"
import { parseArgs } from "../setup-cpp.js"
import { type Inputs, llvmTools } from "../tool.js"
import { getVersion, syncVersions } from "../versions/versions.js"

View File

@ -1,12 +0,0 @@
import { warning } from "ci-log"
import updateNotifier from "simple-update-notifier"
import packageJson from "../package-version.json"
// auto self update notifier
export async function checkUpdates() {
try {
await updateNotifier({ pkg: packageJson })
} catch (err) {
warning(`Failed to check for updates: ${err instanceof Error ? err.message + err.stack : err}`)
}
}

View File

@ -1,63 +0,0 @@
import { info } from "ci-log"
import mri from "mri"
import { type Opts, maybeGetInput } from "./options.js"
import { type Inputs, inputs } from "./tool.js"
/**
* The options for the setup-cpp function
*/
export type CliOpts = Opts & {
help: boolean
version: boolean
}
export function parseArgs(args: string[]): CliOpts {
const defaults = Object.fromEntries(inputs.map((inp) => [inp, maybeGetInput(inp)]))
return mri<Record<Inputs, string | undefined> & { help: boolean; version: boolean; "setup-cpp": boolean }>(args, {
string: [...inputs, "timeout", "node-package-manager"],
default: defaults,
alias: { h: "help", v: "version" },
boolean: ["help", "version", "setup-cpp"],
})
}
export function printHelp() {
info(`
setup-cpp [options]
setup-cpp --compiler llvm --cmake true --ninja true --ccache true --vcpkg true
Install all the tools required for building and testing C++/C projects.
--architecture\t the cpu architecture to install the tools for. By default it uses the current CPU architecture.
--timeout\t the timeout for the installation of each tool in minutes. By default it is 10 minutes.
--compiler\t the <compiler> to install.
\t You can specify the version instead of specifying just the name e.g: --compiler 'llvm-13.0.0'
--tool_name\t pass "true" or pass the <version> you would like to install for this tool. e.g. --conan true or --conan "1.42.1"
--nodePackageManager\t the node package manager to use (npm/yarn/pnpm) when installing setup-cpp globally
--help\t show this help message
--version\t show the version of setup-cpp
All the available tools:
`)
console.table(
{
"compiler and analyzer": {
tools: "--llvm, --gcc, --msvc, --apple-clang, --vcvarsall",
},
"build system": {
tools: "--cmake, --ninja, --meson, --make, --task, --bazel",
},
"package manager": { tools: "--vcpkg, --conan, --choco, --brew, --nala, --git, --setup-cpp" },
"analyzer/linter": {
tools:
"--clang-tidy, --clang-format, --cppcheck, --cpplint, --flawfinder, --lizard, --infer, , --cmakelang, --cmake-lint, --cmake-format",
},
cache: { tools: "--ccache, --sccache" },
documentation: { tools: "--doxygen, --graphviz" },
coverage: { tools: "--gcovr, --opencppcoverage, --kcov" },
other: { tools: "--python, --powershell, --sevenzip" },
},
["tools"],
)
}

View File

@ -19,8 +19,10 @@ import { syncVersions } from "./versions/versions.js"
// re-export for the setup-cpp CLI
export { GITHUB_ACTIONS } from "ci-info"
export { error, info, success, warning } from "ci-log"
export * from "ci-log"
export { packageJson }
export { maybeGetInput, type Opts } from "./options.js"
export { type Inputs, inputs } from "./tool.js"
/**
* The result of the setup, with the success and error messages. If the setup was successful, the error messages are empty.

View File

@ -1,9 +1,18 @@
#!/usr/bin/env node
/* eslint-disable node/shebang */
import { checkUpdates } from "./check-updates.ts"
import { parseArgs, printHelp } from "./cli-options.ts"
import { GITHUB_ACTIONS, error, info, packageJson, setupCpp, success, warning } from "./lib.ts"
import mri from "mri"
import updateNotifier from "simple-update-notifier"
import {
GITHUB_ACTIONS,
type Inputs,
type Opts,
error,
info,
inputs,
maybeGetInput,
packageJson,
setupCpp,
success,
warning,
} from "./lib.ts"
/** The main entry function */
async function main(args: string[]): Promise<number> {
@ -60,13 +69,83 @@ async function main(args: string[]): Promise<number> {
return 0
}
// auto self update notifier
async function checkUpdates() {
try {
await updateNotifier({ pkg: packageJson })
} catch (err) {
warning(`Failed to check for updates: ${err instanceof Error ? err.message + err.stack : err}`)
}
}
/**
* The options for the setup-cpp function
*/
type CliOpts = Opts & {
help: boolean
version: boolean
}
export function parseArgs(args: string[]): CliOpts {
const defaults = Object.fromEntries(inputs.map((inp) => [inp, maybeGetInput(inp)]))
return mri<Record<Inputs, string | undefined> & { help: boolean; version: boolean; "setup-cpp": boolean }>(args, {
string: [...inputs, "timeout", "node-package-manager"],
default: defaults,
alias: { h: "help", v: "version" },
boolean: ["help", "version", "setup-cpp"],
})
}
function printHelp() {
info(`
setup-cpp [options]
setup-cpp --compiler llvm --cmake true --ninja true --ccache true --vcpkg true
Install all the tools required for building and testing C++/C projects.
--architecture\t the cpu architecture to install the tools for. By default it uses the current CPU architecture.
--timeout\t the timeout for the installation of each tool in minutes. By default it is 10 minutes.
--compiler\t the <compiler> to install.
\t You can specify the version instead of specifying just the name e.g: --compiler 'llvm-13.0.0'
--tool_name\t pass "true" or pass the <version> you would like to install for this tool. e.g. --conan true or --conan "1.42.1"
--nodePackageManager\t the node package manager to use (npm/yarn/pnpm) when installing setup-cpp globally
--help\t show this help message
--version\t show the version of setup-cpp
All the available tools:
`)
console.table(
{
"compiler and analyzer": {
tools: "--llvm, --gcc, --msvc, --apple-clang, --vcvarsall",
},
"build system": {
tools: "--cmake, --ninja, --meson, --make, --task, --bazel",
},
"package manager": { tools: "--vcpkg, --conan, --choco, --brew, --nala, --git, --setup-cpp" },
"analyzer/linter": {
tools:
"--clang-tidy, --clang-format, --cppcheck, --cpplint, --flawfinder, --lizard, --infer, , --cmakelang, --cmake-lint, --cmake-format",
},
cache: { tools: "--ccache, --sccache" },
documentation: { tools: "--doxygen, --graphviz" },
coverage: { tools: "--gcovr, --opencppcoverage, --kcov" },
other: { tools: "--python, --powershell, --sevenzip" },
},
["tools"],
)
}
// Run main
main(process.argv)
.then((ret) => {
process.exitCode = ret
})
.catch((err) => {
error("main() panicked!")
error(err as string | Error)
process.exitCode = 1
})
if (process.env.SETUP_CPP_SKIP_MAIN !== "true") {
main(process.argv)
.then((ret) => {
process.exitCode = ret
})
.catch((err) => {
error("main() panicked!")
error(err as string | Error)
process.exitCode = 1
})
}

24
swc.legacy.json Normal file
View File

@ -0,0 +1,24 @@
{
"$schema": "https://swc.rs/schema.json",
"sourceMaps": true,
"jsc": {
"target": "es2019",
"transform": {
"optimizer": {
"simplify": true,
"jsonify": {
"minCost": 1000
}
}
},
"parser": {
"syntax": "typescript",
"tsx": false,
"dynamicImport": true
}
},
"minify": true,
"module": {
"type": "commonjs"
}
}

29
swc.modern.json Normal file
View File

@ -0,0 +1,29 @@
{
"$schema": "https://swc.rs/schema.json",
"sourceMaps": true,
"jsc": {
"target": "esnext",
"transform": {
"optimizer": {
"simplify": true,
"jsonify": {
"minCost": 1000
}
}
},
"parser": {
"syntax": "typescript",
"tsx": false,
"dynamicImport": true
},
"baseUrl": ".",
"paths": {
"./lib.js": ["./lib.mjs"]
}
},
"minify": true,
"module": {
"type": "nodenext",
"outFileExtension": "mjs"
}
}

View File

@ -1,15 +1,39 @@
import module from "module"
import { type TerserOptions, defineConfig } from "vite"
import { type AliasOptions, type TerserOptions, defineConfig } from "vite"
import babel from "vite-plugin-babel"
import terserRc from "./.terserrc.mjs"
import babelConfig from "./babel.config.mts"
const viteConfig = defineConfig((configEnv) => {
const isLegacy = configEnv.mode.includes("legacy")
const isLibrary = configEnv.mode.includes("library")
const plugins = []
if (isLegacy) {
plugins.push(
babel({
babelConfig,
}),
)
}
let aliasOpts: AliasOptions = {}
if (isLegacy) {
aliasOpts = {
...aliasOpts,
"fs/promises": "./src/utils/compat/fs/promises.ts",
"stream/promises": "./src/utils/compat/stream/promises.ts",
"stream/web": "web-streams-polyfill/dist/ponyfill.mjs",
"util/types": "util.types/index.js",
"timers/promises": "timers-browserify",
diagnostics_channel: "diagnostics_channel/index.js",
crypto: "./src/utils/compat/crypto/index.ts",
}
}
return {
build: {
ssr: "./src/setup-cpp.ts",
ssr: isLibrary ? "./src/lib.ts" : "./src/setup-cpp.ts",
outDir: isLegacy ? "./dist/legacy" : "./dist/modern",
target: isLegacy ? "node12" : "node20",
minify: process.env.NODE_ENV === "production" ? "terser" : false,
@ -20,50 +44,19 @@ const viteConfig = defineConfig((configEnv) => {
format: isLegacy
? "cjs"
: "es",
manualChunks: {
lib: ["./src/lib.ts"],
},
chunkFileNames: (chunkInfo) => {
const moduleIds = chunkInfo.facadeModuleId
?.split("/").reverse()
.slice(1, 3)
.filter(part => !["src", "esm"].includes(part))
.join("-")
const hash = moduleIds !== undefined ? `-${moduleIds}` : ""
return `${chunkInfo.name}${hash}.${isLegacy ? "js" : "mjs"}`
},
},
},
emptyOutDir: false,
},
resolve: {
alias: {
...(isLegacy
? {
"fs/promises": "./src/utils/compat/fs/promises.ts",
"stream/promises": "./src/utils/compat/stream/promises.ts",
"stream/web": "web-streams-polyfill/dist/ponyfill.mjs",
"util/types": "util.types/index.js",
"timers/promises": "timers-browserify",
diagnostics_channel: "diagnostics_channel/index.js",
crypto: "./src/utils/compat/crypto/index.ts",
}
: {}),
},
alias: aliasOpts,
},
ssr: {
target: "node",
noExternal: true,
external: module.builtinModules as string[],
external: [...module.builtinModules],
},
plugins: isLegacy
? [
babel({
babelConfig,
}),
]
: [],
plugins,
}
})