mirror of https://github.com/aminya/setup-cpp
Merge pull request #168 from aminya/notifier [skip ci]
This commit is contained in:
commit
b706650c81
|
@ -7,4 +7,3 @@ stats.html
|
|||
src/python/setup-python/
|
||||
src/msvc/msvc-dev-cmd/
|
||||
dev/cpp_vcpkg_project
|
||||
package.json
|
||||
|
|
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
|
@ -1,12 +1,26 @@
|
|||
module.exports = {
|
||||
/** @typedef {import("jest")} jestConfig */
|
||||
const jestConfig = {
|
||||
preset: "ts-jest/presets/js-with-ts-esm",
|
||||
extensionsToTreatAsEsm: [".ts"],
|
||||
transformIgnorePatterns: [], // transform everything
|
||||
testEnvironment: "node",
|
||||
testMatch: ["**/*.test.ts"],
|
||||
testPathIgnorePatterns: ["<rootDir>/src/python/setup-python/"],
|
||||
// tsconfig
|
||||
transform: {
|
||||
"^.+\\.tsx?$": [
|
||||
"ts-jest",
|
||||
/** @type {import("ts-jest")} */
|
||||
{
|
||||
importHelpers: true,
|
||||
useESM: true,
|
||||
},
|
||||
],
|
||||
},
|
||||
// coverage
|
||||
collectCoverageFrom: ["src/**/*.{ts,tsx}"],
|
||||
coveragePathIgnorePatterns: ["assets", ".css.d.ts"],
|
||||
verbose: true,
|
||||
}
|
||||
|
||||
export default jestConfig
|
|
@ -0,0 +1,4 @@
|
|||
{
|
||||
"name": "setup-cpp",
|
||||
"version": "0.27.1"
|
||||
}
|
17
package.json
17
package.json
|
@ -31,7 +31,7 @@
|
|||
"build.docker.arch": "pnpm build && docker build -f ./dev/docker/arch_node.dockerfile -t setup-cpp:arch .",
|
||||
"build.docker.fedora": "pnpm build && docker build -f ./dev/docker/fedora_node.dockerfile -t setup-cpp:fedora .",
|
||||
"build.docker.ubuntu": "pnpm build && docker build -f ./dev/docker/ubuntu_node.dockerfile -t setup-cpp:ubuntu .",
|
||||
"build.parcel": "cross-env NODE_ENV=production parcel build && babel ./dist --out-dir dist --plugins @upleveled/babel-plugin-remove-node-prefix --compact --no-babelrc --source-maps true",
|
||||
"build.parcel": "cross-env NODE_ENV=production parcel build --detailed-report 10 && babel ./dist --out-dir dist --plugins @upleveled/babel-plugin-remove-node-prefix --compact --no-babelrc --source-maps true",
|
||||
"bump": "ncu -u -x numerous && pnpm update",
|
||||
"clean": "shx rm -rf .parcel-cache dist exe",
|
||||
"copy.matchers": "shx cp ./src/gcc/gcc_matcher.json ./dist/node12/ && shx cp ./src/msvc/msvc_matcher.json ./dist/node12/ && shx cp ./src/python/python_matcher.json ./dist/node12/ && shx cp ./src/llvm/llvm_matcher.json ./dist/node12/ && shx cp ./dist/node12/*.json ./dist/node16/",
|
||||
|
@ -43,7 +43,7 @@
|
|||
"lint.eslint": "eslint **/*.{ts,tsx,js,jsx,cjs,mjs,json,yaml} --no-error-on-unmatched-pattern --cache --cache-location ./.cache/eslint/ --fix",
|
||||
"lint.prettier": "prettier --list-different --write .",
|
||||
"lint.tsc": "tsc --noEmit",
|
||||
"pack.exe": "shx rm -rf ./dist/tsconfig.tsbuildinfo && ts-node --esm ./dev/scripts/pack-exe.ts",
|
||||
"pack.exe": "shx rm -rf ./dist/tsconfig.tsbuildinfo && node ./dev/scripts/pack-exe.mjs",
|
||||
"prepare": "pnpm run -r build && pnpm run -w build",
|
||||
"start.docker": "docker run -t setup-cpp .",
|
||||
"start.docker.arch": "docker run -t setup-cpp:arch .",
|
||||
|
@ -59,6 +59,9 @@
|
|||
"test.unit": "jest --runInBand"
|
||||
},
|
||||
"prettier": "prettier-config-atomic",
|
||||
"dependencies": {
|
||||
"update-notifier": "^5.1.0"
|
||||
},
|
||||
"devDependencies": {
|
||||
"@actions/core": "^1.10.0",
|
||||
"@actions/exec": "^1.1.1",
|
||||
|
@ -90,6 +93,7 @@
|
|||
"exec-powershell": "workspace:*",
|
||||
"execa": "^7.1.1",
|
||||
"fast-glob": "^3.2.12",
|
||||
"find-up": "^6.3.0",
|
||||
"gen-readme": "^1.6.0",
|
||||
"is-url-online": "^1.5.0",
|
||||
"jest": "^29.5.0",
|
||||
|
@ -109,6 +113,7 @@
|
|||
"semver": "7.5.1",
|
||||
"setup-python": "github:actions/setup-python#v4.6.1",
|
||||
"shx": "0.3.4",
|
||||
"simple-update-notifier": "^1.1.0",
|
||||
"terser-config-atomic": "^0.1.1",
|
||||
"time-delta": "github:aminya/time-delta#69d91a41cef28e569be9a2991129f5f7d1f0d00e",
|
||||
"ts-jest": "^29.1.0",
|
||||
|
@ -153,7 +158,9 @@
|
|||
"engines": {
|
||||
"node": ">=12.x"
|
||||
},
|
||||
"includeNodeModules": true,
|
||||
"includeNodeModules": {
|
||||
"update-notifier": false
|
||||
},
|
||||
"optimize": true,
|
||||
"outputFormat": "commonjs"
|
||||
},
|
||||
|
@ -162,7 +169,9 @@
|
|||
"engines": {
|
||||
"node": ">=16.x"
|
||||
},
|
||||
"includeNodeModules": true,
|
||||
"includeNodeModules": {
|
||||
"update-notifier": false
|
||||
},
|
||||
"optimize": true,
|
||||
"outputFormat": "commonjs"
|
||||
}
|
||||
|
|
863
pnpm-lock.yaml
863
pnpm-lock.yaml
File diff suppressed because it is too large
Load Diff
|
@ -1,5 +1,7 @@
|
|||
import { syncVersions, getVersion } from "../versions/versions"
|
||||
import { getCompilerInfo, Inputs, parseArgs } from "../main"
|
||||
import { parseArgs } from "../cli-options"
|
||||
import { Inputs } from "../tool"
|
||||
import { getCompilerInfo } from "../compilers"
|
||||
|
||||
jest.setTimeout(300000)
|
||||
describe("getCompilerInfo", () => {
|
||||
|
|
|
@ -0,0 +1,12 @@
|
|||
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}`)
|
||||
}
|
||||
}
|
|
@ -0,0 +1,86 @@
|
|||
import { getInput } from "@actions/core"
|
||||
import { info } from "ci-log"
|
||||
import mri from "mri"
|
||||
import { InstallationInfo } from "./utils/setup/setupBin"
|
||||
import { Inputs, inputs } from "./tool"
|
||||
|
||||
export function parseArgs(args: string[]): Opts {
|
||||
return mri<Record<Inputs, string | undefined> & { help: boolean }>(args, {
|
||||
string: inputs,
|
||||
default: Object.fromEntries(inputs.map((inp) => [inp, maybeGetInput(inp)])),
|
||||
alias: { h: "help" },
|
||||
boolean: "help",
|
||||
})
|
||||
}
|
||||
|
||||
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.
|
||||
--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"
|
||||
|
||||
All the available tools:
|
||||
--llvm
|
||||
--gcc
|
||||
--vcvarsall
|
||||
--cmake
|
||||
--ninja
|
||||
--vcpkg
|
||||
--bazel
|
||||
--meson
|
||||
--conan
|
||||
--make
|
||||
--task
|
||||
--ccache
|
||||
--sccache
|
||||
--cppcheck
|
||||
--clangformat
|
||||
--clangtidy
|
||||
--doxygen
|
||||
--gcovr
|
||||
--opencppcoverage
|
||||
--kcov
|
||||
--python
|
||||
--choco
|
||||
--brew
|
||||
--nala
|
||||
--sevenzip
|
||||
--graphviz
|
||||
--powershell
|
||||
`)
|
||||
}
|
||||
/** Get an object from github actions */
|
||||
|
||||
export function maybeGetInput(key: string) {
|
||||
const value = getInput(key.toLowerCase())
|
||||
if (value !== "false" && value !== "") {
|
||||
return value
|
||||
}
|
||||
return undefined // skip installation
|
||||
}
|
||||
export type Opts = mri.Argv<
|
||||
Record<Inputs, string | undefined> & {
|
||||
help: boolean
|
||||
}
|
||||
>
|
||||
|
||||
export function getSuccessMessage(tool: string, installationInfo: InstallationInfo | undefined | void) {
|
||||
let msg = `✅ ${tool} was installed successfully:`
|
||||
if (installationInfo === undefined) {
|
||||
return msg
|
||||
}
|
||||
if ("installDir" in installationInfo) {
|
||||
msg += `\n- The installation directory is ${installationInfo.installDir}`
|
||||
}
|
||||
if (installationInfo.binDir !== "") {
|
||||
msg += `\n- The binary directory is ${installationInfo.binDir}`
|
||||
}
|
||||
return msg
|
||||
}
|
|
@ -0,0 +1,114 @@
|
|||
import { endGroup, notice, startGroup } from "@actions/core"
|
||||
import { error, info } from "ci-log"
|
||||
import { join } from "path"
|
||||
import semverValid from "semver/functions/valid"
|
||||
import { getSuccessMessage } from "./cli-options"
|
||||
import { setupGcc } from "./gcc/gcc"
|
||||
import { activateGcovGCC, activateGcovLLVM } from "./gcovr/gcovr"
|
||||
import { setupLLVM } from "./llvm/llvm"
|
||||
import { setupMSVC } from "./msvc/msvc"
|
||||
import { addEnv } from "./utils/env/addEnv"
|
||||
import { getVersion } from "./versions/versions"
|
||||
|
||||
/** Detecting the compiler version. Divide the given string by `-` and use the second element as the version */
|
||||
export function getCompilerInfo(compilerAndVersion: string) {
|
||||
const compilerAndMaybeVersion = compilerAndVersion.split("-")
|
||||
const compiler = compilerAndMaybeVersion[0]
|
||||
if (1 in compilerAndMaybeVersion) {
|
||||
const maybeVersion = compilerAndMaybeVersion[1]
|
||||
if (semverValid(maybeVersion) !== null) {
|
||||
return { compiler, version: maybeVersion }
|
||||
} else {
|
||||
info(`Invalid semver version ${maybeVersion} used for the compiler.`)
|
||||
return { compiler, version: maybeVersion }
|
||||
}
|
||||
}
|
||||
return { compiler, version: undefined }
|
||||
}
|
||||
|
||||
/** Installing the specified compiler */
|
||||
export async function installCompiler(
|
||||
compilerAndVersion: string,
|
||||
osVersion: number[] | null,
|
||||
setupCppDir: string,
|
||||
arch: string,
|
||||
successMessages: string[],
|
||||
hasLLVM: boolean,
|
||||
errorMessages: string[]
|
||||
) {
|
||||
try {
|
||||
const { compiler, version } = getCompilerInfo(compilerAndVersion)
|
||||
|
||||
// install the compiler. We allow some aliases for the compiler name
|
||||
startGroup(`Installing ${compiler} ${version ?? ""}`)
|
||||
switch (compiler) {
|
||||
case "llvm":
|
||||
case "clang":
|
||||
case "clang++": {
|
||||
const installationInfo = await setupLLVM(
|
||||
getVersion("llvm", version, osVersion),
|
||||
join(setupCppDir, "llvm"),
|
||||
arch
|
||||
)
|
||||
|
||||
await activateGcovLLVM()
|
||||
|
||||
successMessages.push(getSuccessMessage("llvm", installationInfo))
|
||||
break
|
||||
}
|
||||
case "gcc":
|
||||
case "mingw":
|
||||
case "cygwin":
|
||||
case "msys": {
|
||||
const gccVersion = getVersion("gcc", version, osVersion)
|
||||
const installationInfo = await setupGcc(gccVersion, join(setupCppDir, "gcc"), arch)
|
||||
|
||||
if (hasLLVM) {
|
||||
// remove back the added CPPFLAGS of LLVM that include the LLVM headers
|
||||
await addEnv("CPPFLAGS", "")
|
||||
}
|
||||
|
||||
await activateGcovGCC(gccVersion)
|
||||
|
||||
successMessages.push(getSuccessMessage("gcc", installationInfo))
|
||||
break
|
||||
}
|
||||
case "cl":
|
||||
case "msvc":
|
||||
case "msbuild":
|
||||
case "vs":
|
||||
case "visualstudio":
|
||||
case "visualcpp":
|
||||
case "visualc++": {
|
||||
const installationInfo = await setupMSVC(
|
||||
getVersion("msvc", version, osVersion),
|
||||
join(setupCppDir, "msvc"),
|
||||
arch
|
||||
)
|
||||
|
||||
if (hasLLVM) {
|
||||
// remove the CPPFLAGS of LLVM that include the LLVM headers
|
||||
await addEnv("CPPFLAGS", "")
|
||||
}
|
||||
|
||||
successMessages.push(getSuccessMessage("msvc", installationInfo))
|
||||
break
|
||||
}
|
||||
case "appleclang":
|
||||
case "applellvm": {
|
||||
notice("Assuming apple-clang is already installed")
|
||||
await Promise.all([addEnv("CC", "clang"), addEnv("CXX", "clang++")])
|
||||
successMessages.push(getSuccessMessage("apple-clang", undefined))
|
||||
break
|
||||
}
|
||||
default: {
|
||||
errorMessages.push(`Unsupported compiler ${compiler}`)
|
||||
}
|
||||
}
|
||||
} catch (err) {
|
||||
error(err as string | Error)
|
||||
errorMessages.push(`Failed to install the ${compilerAndVersion}`)
|
||||
}
|
||||
|
||||
endGroup()
|
||||
}
|
309
src/main.ts
309
src/main.ts
|
@ -1,95 +1,28 @@
|
|||
#!/usr/bin/env node
|
||||
/* eslint-disable node/shebang */
|
||||
|
||||
import { endGroup, getInput, notice, startGroup } from "@actions/core"
|
||||
import { GITHUB_ACTIONS } from "ci-info"
|
||||
import { error, info, success, warning } from "ci-log"
|
||||
import mri from "mri"
|
||||
import * as numerous from "numerous"
|
||||
import numerousLocale from "numerous/locales/en.js"
|
||||
import { join } from "patha"
|
||||
import semverValid from "semver/functions/valid"
|
||||
import * as timeDelta from "time-delta"
|
||||
import timeDeltaLocale from "time-delta/locales/en.js"
|
||||
import { untildifyUser } from "untildify-user"
|
||||
|
||||
import { setupBazel } from "./bazel/bazel"
|
||||
import { setupBrew } from "./brew/brew"
|
||||
import { setupCcache } from "./ccache/ccache"
|
||||
import { setupChocolatey } from "./chocolatey/chocolatey"
|
||||
import { setupCmake } from "./cmake/cmake"
|
||||
import { setupConan } from "./conan/conan"
|
||||
import { setupCppcheck } from "./cppcheck/cppcheck"
|
||||
import { setupDoxygen } from "./doxygen/doxygen"
|
||||
import { setupGcc } from "./gcc/gcc"
|
||||
import { activateGcovGCC, activateGcovLLVM, setupGcovr } from "./gcovr/gcovr"
|
||||
import { setupGraphviz } from "./graphviz/graphviz"
|
||||
import { setupKcov } from "./kcov/kcov"
|
||||
import { setupClangTools, setupLLVM } from "./llvm/llvm"
|
||||
import { setupMake } from "./make/make"
|
||||
import { setupMeson } from "./meson/meson"
|
||||
import { setupMSVC } from "./msvc/msvc"
|
||||
import { setupNala } from "./nala/nala"
|
||||
import { setupNinja } from "./ninja/ninja"
|
||||
import { setupOpencppcoverage } from "./opencppcoverage/opencppcoverage"
|
||||
import { setupPowershell } from "./powershell/powershell"
|
||||
import { setupPython } from "./python/python"
|
||||
import { setupSccache } from "./sccache/sccache"
|
||||
import { setupSevenZip } from "./sevenzip/sevenzip"
|
||||
import { setupTask } from "./task/task"
|
||||
import { addEnv, finalizeCpprc } from "./utils/env/addEnv"
|
||||
import { checkUpdates } from "./check-updates"
|
||||
import { parseArgs, printHelp } from "./cli-options"
|
||||
import { installCompiler } from "./compilers"
|
||||
import { installTool, tools } from "./tool"
|
||||
import { finalizeCpprc } from "./utils/env/addEnv"
|
||||
import { isArch } from "./utils/env/isArch"
|
||||
import { ubuntuVersion } from "./utils/env/ubuntu_version"
|
||||
import { InstallationInfo } from "./utils/setup/setupBin"
|
||||
import { setupPacmanPack } from "./utils/setup/setupPacmanPack"
|
||||
import { setupVcpkg } from "./vcpkg/vcpkg"
|
||||
import { setupVCVarsall } from "./vcvarsall/vcvarsall"
|
||||
import { getVersion, syncVersions } from "./versions/versions"
|
||||
|
||||
/** The setup functions */
|
||||
const setups = {
|
||||
nala: setupNala,
|
||||
cmake: setupCmake,
|
||||
ninja: setupNinja,
|
||||
python: setupPython,
|
||||
vcpkg: setupVcpkg,
|
||||
bazel: setupBazel,
|
||||
conan: setupConan,
|
||||
meson: setupMeson,
|
||||
gcovr: setupGcovr,
|
||||
opencppcoverage: setupOpencppcoverage,
|
||||
llvm: setupLLVM,
|
||||
gcc: setupGcc,
|
||||
choco: setupChocolatey,
|
||||
brew: setupBrew,
|
||||
powershell: setupPowershell,
|
||||
ccache: setupCcache,
|
||||
sccache: setupSccache,
|
||||
doxygen: setupDoxygen,
|
||||
graphviz: setupGraphviz,
|
||||
cppcheck: setupCppcheck,
|
||||
clangtidy: setupClangTools,
|
||||
clangformat: setupClangTools,
|
||||
msvc: setupMSVC,
|
||||
vcvarsall: setupVCVarsall,
|
||||
kcov: setupKcov,
|
||||
make: setupMake,
|
||||
task: setupTask,
|
||||
sevenzip: setupSevenZip,
|
||||
}
|
||||
|
||||
/** The tools that can be installed */
|
||||
const tools = Object.keys(setups) as Array<keyof typeof setups>
|
||||
|
||||
/** The possible inputs to the program */
|
||||
export type Inputs = keyof typeof setups | "compiler" | "architecture"
|
||||
|
||||
// an array of possible inputs
|
||||
const inputs: Array<Inputs> = ["compiler", "architecture", ...tools]
|
||||
import { syncVersions } from "./versions/versions"
|
||||
|
||||
/** The main entry function */
|
||||
export async function main(args: string[]): Promise<number> {
|
||||
async function main(args: string[]): Promise<number> {
|
||||
let checkUpdatePromise = Promise.resolve()
|
||||
if (!GITHUB_ACTIONS) {
|
||||
checkUpdatePromise = checkUpdates()
|
||||
process.env.ACTIONS_ALLOW_UNSECURE_COMMANDS = "true"
|
||||
}
|
||||
|
||||
|
@ -127,13 +60,14 @@ export async function main(args: string[]): Promise<number> {
|
|||
return 1
|
||||
}
|
||||
|
||||
let hasLLVM = false // used to unset CPPFLAGS of LLVM when other compilers are used as the main compiler
|
||||
|
||||
if (isArch() && typeof opts.cppcheck === "string" && typeof opts.gcovr === "string") {
|
||||
info("installing python-pygments to avoid conflicts with cppcheck and gcovr on Arch linux")
|
||||
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
|
||||
for (const tool of tools) {
|
||||
// get the version or "true" or undefined for this tool from the options
|
||||
|
@ -143,40 +77,8 @@ export async function main(args: string[]): Promise<number> {
|
|||
if (version !== undefined) {
|
||||
// running the setup function for this tool
|
||||
time1 = Date.now()
|
||||
startGroup(`Installing ${tool} ${version}`)
|
||||
try {
|
||||
let installationInfo: InstallationInfo | undefined | void
|
||||
if (tool === "vcvarsall") {
|
||||
// eslint-disable-next-line no-await-in-loop
|
||||
await setupVCVarsall(
|
||||
getVersion(tool, version, osVersion),
|
||||
undefined,
|
||||
arch,
|
||||
undefined,
|
||||
undefined,
|
||||
false,
|
||||
false
|
||||
)
|
||||
} else {
|
||||
// get the setup function
|
||||
const setupFunction = setups[tool]
|
||||
|
||||
hasLLVM = ["llvm", "clangformat", "clangtidy"].includes(tool)
|
||||
|
||||
// the tool installation directory (for the functions that ue it)
|
||||
const setupDir = join(setupCppDir, hasLLVM ? "llvm" : tool)
|
||||
|
||||
// eslint-disable-next-line no-await-in-loop
|
||||
installationInfo = await setupFunction(getVersion(tool, version, osVersion), setupDir, arch)
|
||||
}
|
||||
// preparing a report string
|
||||
successMessages.push(getSuccessMessage(tool, installationInfo))
|
||||
} catch (e) {
|
||||
// push error message to the logger
|
||||
error(e as string | Error)
|
||||
errorMessages.push(`${tool} failed to install`)
|
||||
}
|
||||
endGroup()
|
||||
hasLLVM = await installTool(tool, version, osVersion, arch, setupCppDir, successMessages, errorMessages)
|
||||
time2 = Date.now()
|
||||
info(`took ${timeFormatter.format(time1, time2) || "0 seconds"}`)
|
||||
}
|
||||
|
@ -184,87 +86,11 @@ export async function main(args: string[]): Promise<number> {
|
|||
|
||||
// installing the specified compiler
|
||||
const maybeCompiler = opts.compiler
|
||||
time1 = Date.now()
|
||||
try {
|
||||
if (maybeCompiler !== undefined) {
|
||||
const { compiler, version } = getCompilerInfo(maybeCompiler)
|
||||
|
||||
// install the compiler. We allow some aliases for the compiler name
|
||||
startGroup(`Installing ${compiler} ${version ?? ""}`)
|
||||
switch (compiler) {
|
||||
case "llvm":
|
||||
case "clang":
|
||||
case "clang++": {
|
||||
const installationInfo = await setupLLVM(
|
||||
getVersion("llvm", version, osVersion),
|
||||
join(setupCppDir, "llvm"),
|
||||
arch
|
||||
)
|
||||
|
||||
await activateGcovLLVM()
|
||||
|
||||
successMessages.push(getSuccessMessage("llvm", installationInfo))
|
||||
break
|
||||
}
|
||||
case "gcc":
|
||||
case "mingw":
|
||||
case "cygwin":
|
||||
case "msys": {
|
||||
const gccVersion = getVersion("gcc", version, osVersion)
|
||||
const installationInfo = await setupGcc(gccVersion, join(setupCppDir, "gcc"), arch)
|
||||
|
||||
if (hasLLVM) {
|
||||
// remove back the added CPPFLAGS of LLVM that include the LLVM headers
|
||||
await addEnv("CPPFLAGS", "")
|
||||
}
|
||||
|
||||
await activateGcovGCC(gccVersion)
|
||||
|
||||
successMessages.push(getSuccessMessage("gcc", installationInfo))
|
||||
break
|
||||
}
|
||||
case "cl":
|
||||
case "msvc":
|
||||
case "msbuild":
|
||||
case "vs":
|
||||
case "visualstudio":
|
||||
case "visualcpp":
|
||||
case "visualc++": {
|
||||
const installationInfo = await setupMSVC(
|
||||
getVersion("msvc", version, osVersion),
|
||||
join(setupCppDir, "msvc"),
|
||||
arch
|
||||
)
|
||||
|
||||
if (hasLLVM) {
|
||||
// remove the CPPFLAGS of LLVM that include the LLVM headers
|
||||
await addEnv("CPPFLAGS", "")
|
||||
}
|
||||
|
||||
successMessages.push(getSuccessMessage("msvc", installationInfo))
|
||||
break
|
||||
}
|
||||
case "appleclang":
|
||||
case "applellvm": {
|
||||
notice("Assuming apple-clang is already installed")
|
||||
await Promise.all([addEnv("CC", "clang"), addEnv("CXX", "clang++")])
|
||||
successMessages.push(getSuccessMessage("apple-clang", undefined))
|
||||
break
|
||||
}
|
||||
default: {
|
||||
errorMessages.push(`Unsupported compiler ${compiler}`)
|
||||
}
|
||||
}
|
||||
endGroup()
|
||||
time2 = Date.now()
|
||||
info(`took ${timeFormatter.format(time1, time2) || "0 seconds"}`)
|
||||
}
|
||||
} catch (e) {
|
||||
error(e as string | Error)
|
||||
errorMessages.push(`Failed to install the ${maybeCompiler}`)
|
||||
endGroup()
|
||||
time2 = Date.now()
|
||||
info(`took ${timeFormatter.format(time1, time2) || "0 seconds"}`)
|
||||
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"}`)
|
||||
}
|
||||
|
||||
await finalizeCpprc()
|
||||
|
@ -297,8 +123,11 @@ export async function main(args: string[]): Promise<number> {
|
|||
}
|
||||
}
|
||||
|
||||
await checkUpdatePromise
|
||||
|
||||
return errorMessages.length === 0 ? 0 : 1 // exit with non-zero if any error message
|
||||
}
|
||||
|
||||
// Run main
|
||||
main(process.argv)
|
||||
.then((ret) => {
|
||||
|
@ -309,101 +138,3 @@ main(process.argv)
|
|||
error(err as string | Error)
|
||||
process.exitCode = 1
|
||||
})
|
||||
|
||||
export type Opts = mri.Argv<
|
||||
Record<Inputs, string | undefined> & {
|
||||
help: boolean
|
||||
}
|
||||
>
|
||||
|
||||
export function parseArgs(args: string[]): Opts {
|
||||
return mri<Record<Inputs, string | undefined> & { help: boolean }>(args, {
|
||||
string: inputs,
|
||||
default: Object.fromEntries(inputs.map((inp) => [inp, maybeGetInput(inp)])),
|
||||
alias: { h: "help" },
|
||||
boolean: "help",
|
||||
})
|
||||
}
|
||||
|
||||
/** Detecting the compiler version. Divide the given string by `-` and use the second element as the version */
|
||||
export function getCompilerInfo(maybeCompiler: string) {
|
||||
const compilerAndMaybeVersion = maybeCompiler.split("-")
|
||||
const compiler = compilerAndMaybeVersion[0]
|
||||
if (1 in compilerAndMaybeVersion) {
|
||||
const maybeVersion = compilerAndMaybeVersion[1]
|
||||
if (semverValid(maybeVersion) !== null) {
|
||||
return { compiler, version: maybeVersion }
|
||||
} else {
|
||||
info(`Invalid semver version ${maybeVersion} used for the compiler.`)
|
||||
return { compiler, version: maybeVersion }
|
||||
}
|
||||
}
|
||||
return { compiler, version: undefined }
|
||||
}
|
||||
|
||||
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.
|
||||
--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"
|
||||
|
||||
All the available tools:
|
||||
--llvm
|
||||
--gcc
|
||||
--vcvarsall
|
||||
--cmake
|
||||
--ninja
|
||||
--vcpkg
|
||||
--bazel
|
||||
--meson
|
||||
--conan
|
||||
--make
|
||||
--task
|
||||
--ccache
|
||||
--sccache
|
||||
--cppcheck
|
||||
--clangformat
|
||||
--clangtidy
|
||||
--doxygen
|
||||
--gcovr
|
||||
--opencppcoverage
|
||||
--kcov
|
||||
--python
|
||||
--choco
|
||||
--brew
|
||||
--nala
|
||||
--sevenzip
|
||||
--graphviz
|
||||
--powershell
|
||||
`)
|
||||
}
|
||||
|
||||
/** Get an object from github actions */
|
||||
function maybeGetInput(key: string) {
|
||||
const value = getInput(key.toLowerCase())
|
||||
if (value !== "false" && value !== "") {
|
||||
return value
|
||||
}
|
||||
return undefined // skip installation
|
||||
}
|
||||
|
||||
function getSuccessMessage(tool: string, installationInfo: InstallationInfo | undefined | void) {
|
||||
let msg = `✅ ${tool} was installed successfully:`
|
||||
if (installationInfo === undefined) {
|
||||
return msg
|
||||
}
|
||||
if ("installDir" in installationInfo) {
|
||||
msg += `\n- The installation directory is ${installationInfo.installDir}`
|
||||
}
|
||||
if (installationInfo.binDir !== "") {
|
||||
msg += `\n- The binary directory is ${installationInfo.binDir}`
|
||||
}
|
||||
return msg
|
||||
}
|
||||
|
|
|
@ -0,0 +1,113 @@
|
|||
import { endGroup, startGroup } from "@actions/core"
|
||||
import { error } from "ci-log"
|
||||
import { join } from "patha"
|
||||
import { setupBazel } from "./bazel/bazel"
|
||||
import { setupBrew } from "./brew/brew"
|
||||
import { setupCcache } from "./ccache/ccache"
|
||||
import { setupChocolatey } from "./chocolatey/chocolatey"
|
||||
import { getSuccessMessage } from "./cli-options"
|
||||
import { setupCmake } from "./cmake/cmake"
|
||||
import { setupConan } from "./conan/conan"
|
||||
import { setupCppcheck } from "./cppcheck/cppcheck"
|
||||
import { setupDoxygen } from "./doxygen/doxygen"
|
||||
import { setupGcc } from "./gcc/gcc"
|
||||
import { setupGcovr } from "./gcovr/gcovr"
|
||||
import { setupGraphviz } from "./graphviz/graphviz"
|
||||
import { setupKcov } from "./kcov/kcov"
|
||||
import { setupClangTools, setupLLVM } from "./llvm/llvm"
|
||||
import { setupMake } from "./make/make"
|
||||
import { setupMeson } from "./meson/meson"
|
||||
import { setupMSVC } from "./msvc/msvc"
|
||||
import { setupNala } from "./nala/nala"
|
||||
import { setupNinja } from "./ninja/ninja"
|
||||
import { setupOpencppcoverage } from "./opencppcoverage/opencppcoverage"
|
||||
import { setupPowershell } from "./powershell/powershell"
|
||||
import { setupPython } from "./python/python"
|
||||
import { setupSccache } from "./sccache/sccache"
|
||||
import { setupSevenZip } from "./sevenzip/sevenzip"
|
||||
import { setupTask } from "./task/task"
|
||||
import { InstallationInfo } from "./utils/setup/setupBin"
|
||||
import { setupVcpkg } from "./vcpkg/vcpkg"
|
||||
import { setupVCVarsall } from "./vcvarsall/vcvarsall"
|
||||
import { getVersion } from "./versions/versions"
|
||||
|
||||
export async function installTool(
|
||||
tool: ToolName,
|
||||
version: string,
|
||||
osVersion: number[] | null,
|
||||
arch: string,
|
||||
setupCppDir: string,
|
||||
successMessages: string[],
|
||||
errorMessages: string[]
|
||||
) {
|
||||
startGroup(`Installing ${tool} ${version}`)
|
||||
let hasLLVM = false
|
||||
try {
|
||||
let installationInfo: InstallationInfo | undefined | void
|
||||
if (tool === "vcvarsall") {
|
||||
// eslint-disable-next-line no-await-in-loop
|
||||
await setupVCVarsall(getVersion(tool, version, osVersion), undefined, arch, undefined, undefined, false, false)
|
||||
} else {
|
||||
// get the setup function
|
||||
const setupFunction = setups[tool]
|
||||
|
||||
hasLLVM = ["llvm", "clangformat", "clangtidy"].includes(tool)
|
||||
|
||||
// the tool installation directory (for the functions that ue it)
|
||||
const setupDir = join(setupCppDir, hasLLVM ? "llvm" : tool)
|
||||
|
||||
// eslint-disable-next-line no-await-in-loop
|
||||
installationInfo = await setupFunction(getVersion(tool, version, osVersion), setupDir, arch)
|
||||
}
|
||||
// preparing a report string
|
||||
successMessages.push(getSuccessMessage(tool, installationInfo))
|
||||
} catch (e) {
|
||||
// push error message to the logger
|
||||
error(e as string | Error)
|
||||
errorMessages.push(`${tool} failed to install`)
|
||||
}
|
||||
endGroup()
|
||||
return hasLLVM
|
||||
} /** The setup functions */
|
||||
|
||||
export const setups = {
|
||||
nala: setupNala,
|
||||
cmake: setupCmake,
|
||||
ninja: setupNinja,
|
||||
python: setupPython,
|
||||
vcpkg: setupVcpkg,
|
||||
bazel: setupBazel,
|
||||
conan: setupConan,
|
||||
meson: setupMeson,
|
||||
gcovr: setupGcovr,
|
||||
opencppcoverage: setupOpencppcoverage,
|
||||
llvm: setupLLVM,
|
||||
gcc: setupGcc,
|
||||
choco: setupChocolatey,
|
||||
brew: setupBrew,
|
||||
powershell: setupPowershell,
|
||||
ccache: setupCcache,
|
||||
sccache: setupSccache,
|
||||
doxygen: setupDoxygen,
|
||||
graphviz: setupGraphviz,
|
||||
cppcheck: setupCppcheck,
|
||||
clangtidy: setupClangTools,
|
||||
clangformat: setupClangTools,
|
||||
msvc: setupMSVC,
|
||||
vcvarsall: setupVCVarsall,
|
||||
kcov: setupKcov,
|
||||
make: setupMake,
|
||||
task: setupTask,
|
||||
sevenzip: setupSevenZip,
|
||||
}
|
||||
|
||||
export type ToolName = keyof typeof setups
|
||||
/** The tools that can be installed */
|
||||
|
||||
export const tools = Object.keys(setups) as Array<ToolName>
|
||||
/** The possible inputs to the program */
|
||||
|
||||
export type Inputs = keyof typeof setups | "compiler" | "architecture"
|
||||
/** an array of possible inputs */
|
||||
|
||||
export const inputs: Array<Inputs> = ["compiler", "architecture", ...tools]
|
|
@ -1,4 +1,5 @@
|
|||
import { Inputs, Opts } from "../main"
|
||||
import { Opts } from "../cli-options"
|
||||
import { Inputs } from "../tool"
|
||||
import { DefaultLinuxVersion, DefaultVersions } from "./default_versions"
|
||||
|
||||
/** Get the default version if passed true or undefined, otherwise return the version itself */
|
||||
|
|
|
@ -18,11 +18,11 @@
|
|||
"removeComments": false,
|
||||
"skipLibCheck": true,
|
||||
"lib": ["ES2020", "dom"],
|
||||
"target": "ES2020",
|
||||
"target": "ESNext",
|
||||
"allowJs": true,
|
||||
"esModuleInterop": true,
|
||||
"resolveJsonModule": true,
|
||||
"module": "esnext",
|
||||
"module": "ESNext",
|
||||
"moduleResolution": "node",
|
||||
"importHelpers": false,
|
||||
"outDir": "./dist"
|
||||
|
|
Loading…
Reference in New Issue