setup-cpp/src/main.ts

167 lines
4.7 KiB
TypeScript
Raw Normal View History

#!/usr/bin/env node
/* eslint-disable node/shebang */
import { GITHUB_ACTIONS, isCI } from "ci-info"
import { error, info, success, warning } from "ci-log"
import * as numerous from "numerous"
import numerousLocale from "numerous/locales/en.js"
import { finalizeRC } from "os-env"
import * as timeDelta from "time-delta"
import timeDeltaLocale from "time-delta/locales/en.js"
import { untildifyUser } from "untildify-user"
import { checkUpdates } from "./check-updates"
import { parseArgs, printHelp, rcPath } from "./cli-options"
import { installCompiler } from "./compilers"
2024-04-03 15:15:43 +08:00
import { installTool } from "./installTool"
import { tools } from "./tool"
import { isArch } from "./utils/env/isArch"
import { ubuntuVersion } from "./utils/env/ubuntu_version"
import { setupPacmanPack } from "./utils/setup/setupPacmanPack"
import { syncVersions } from "./versions/versions"
2021-09-18 01:51:59 +08:00
/** The main entry function */
async function main(args: string[]): Promise<number> {
let checkUpdatePromise = Promise.resolve()
if (!GITHUB_ACTIONS) {
checkUpdatePromise = checkUpdates()
process.env.ACTIONS_ALLOW_UNSECURE_COMMANDS = "true"
}
2021-09-18 01:51:59 +08:00
// parse options using mri or github actions
const opts = parseArgs(args)
2021-09-14 15:03:59 +08:00
2021-09-18 02:09:00 +08:00
// print help
if (opts.help) {
printHelp()
}
2021-09-18 01:51:59 +08:00
// cpu architecture
const arch = opts.architecture ?? process.arch
// the installation dir for the tools that are downloaded directly
2024-01-23 08:23:22 +08:00
const setupCppDir = process.env.SETUP_CPP_DIR ?? untildifyUser("~")
2021-09-18 01:51:59 +08:00
// report messages
const successMessages: string[] = []
const errorMessages: string[] = []
2022-04-18 20:27:28 +08:00
const timeFormatter = timeDelta.create({ autoloadLocales: true })
2022-04-18 21:16:11 +08:00
timeDelta.addLocale(timeDeltaLocale as timeDelta.Locale)
numerous.addLocale(numerousLocale as numerous.Locale)
let time1: number
let time2: number
2022-04-18 18:23:58 +08:00
// installing the specified tools
const osVersion = await ubuntuVersion()
// sync the version for the llvm tools
if (!syncVersions(opts, ["llvm", "clangtidy", "clangformat"])) {
error("The same version must be used for llvm, clangformat and clangtidy")
return 1
}
if (isArch() && typeof opts.cppcheck === "string" && typeof opts.gcovr === "string") {
info("installing python-pygments to avoid conflicts with cppcheck and gcovr on Arch linux")
2023-05-25 05:57:08 +08:00
await setupPacmanPack("python-pygments")
}
/** Used to unset CPPFLAGS of LLVM when other compilers are used as the main compiler */
let hasLLVM = false
// loop over the tools and run their setup function
let failedFast = false
for (const tool of tools) {
// fail fast inside CI when any tool fails
if (isCI) {
if (errorMessages.length !== 0) {
failedFast = true
break
}
}
// get the version or "true" or undefined for this tool from the options
const version = opts[tool]
// skip if undefined
if (version !== undefined) {
2021-11-22 04:20:51 +08:00
// running the setup function for this tool
time1 = Date.now()
// eslint-disable-next-line no-await-in-loop
hasLLVM = await installTool(
tool,
version,
osVersion,
arch,
setupCppDir,
successMessages,
errorMessages,
2024-08-07 14:44:32 +08:00
Number.parseFloat(opts.timeout ?? "20") * 60 * 1000,
)
time2 = Date.now()
info(`took ${timeFormatter.format(time1, time2) || "0 seconds"}`)
}
}
if (!failedFast) {
// installing the specified compiler
const maybeCompiler = opts.compiler
if (maybeCompiler !== undefined) {
const time1Compiler = Date.now()
await installCompiler(maybeCompiler, osVersion, setupCppDir, arch, successMessages, hasLLVM, errorMessages)
const time2Compiler = Date.now()
info(`took ${timeFormatter.format(time1Compiler, time2Compiler) || "0 seconds"}`)
}
2021-09-18 01:51:59 +08:00
}
await finalizeRC(rcPath)
2022-11-21 15:14:33 +08:00
if (successMessages.length === 0 && errorMessages.length === 0) {
warning("setup-cpp was called without any arguments. Nothing to do.")
return 0
}
2021-09-18 01:51:59 +08:00
// report the messages in the end
2024-08-07 14:44:32 +08:00
for (const tool of successMessages) {
success(tool)
}
for (const tool of errorMessages) {
error(tool)
}
2021-09-18 01:51:59 +08:00
info("setup-cpp finished")
if (!GITHUB_ACTIONS) {
switch (process.platform) {
case "win32": {
2022-03-01 19:04:33 +08:00
warning("Run `RefreshEnv.cmd` or restart your shell to update the environment.")
break
}
case "linux":
case "darwin": {
2022-03-01 19:04:33 +08:00
warning("Run `source ~/.cpprc` or restart your shell to update the environment.")
break
}
default: {
// nothing
}
}
}
await checkUpdatePromise
2021-09-18 01:51:59 +08:00
return errorMessages.length === 0 ? 0 : 1 // exit with non-zero if any error message
2021-09-14 15:03:59 +08:00
}
2021-09-18 01:51:59 +08:00
// Run main
main(process.argv)
2021-09-14 15:03:59 +08:00
.then((ret) => {
process.exitCode = ret
})
2021-09-18 21:21:22 +08:00
.catch((err) => {
error("main() panicked!")
error(err as string | Error)
2021-09-14 15:03:59 +08:00
process.exitCode = 1
})