feat!: add guard and source RC options for os-env

This commit is contained in:
Amin Yahyaabadi 2024-08-14 18:43:53 -07:00
parent 77e643057d
commit 771228c4ae
No known key found for this signature in database
GPG Key ID: F52AF77F636088F0
33 changed files with 244 additions and 228 deletions

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

View File

@ -3,8 +3,7 @@ import { exportVariable as ghExportVariable } from "@actions/core"
import { GITHUB_ACTIONS } from "ci-info" import { GITHUB_ACTIONS } from "ci-info"
import { error, info } from "ci-log" import { error, info } from "ci-log"
import { execPowershell } from "exec-powershell" import { execPowershell } from "exec-powershell"
import { untildifyUser } from "untildify-user" import { defaultRcPath, sourceRCInRc } from "./rc-file.js"
import { sourceRC } from "./rc-file.js"
import { escapeString } from "./utils.js" import { escapeString } from "./utils.js"
const { appendFile } = promises const { appendFile } = promises
@ -17,6 +16,8 @@ export type AddEnvOptions = {
* The path to the RC file that the env variables should be added to. * The path to the RC file that the env variables should be added to.
*/ */
rcPath: string rcPath: string
/** Provide a name (your tool) to add a variable guard for sourcing your rc file */
guard?: string
} }
/** /**
* Add an environment variable. * Add an environment variable.
@ -32,7 +33,7 @@ export async function addEnv(
const options = { const options = {
shouldEscapeSpace: false, shouldEscapeSpace: false,
shouldAddOnlyIfNotDefined: false, shouldAddOnlyIfNotDefined: false,
rcPath: untildifyUser(".bashrc"), rcPath: defaultRcPath,
...givenOptions, ...givenOptions,
} }
@ -76,7 +77,7 @@ async function addEnvSystem(name: string, valGiven: string | undefined, options:
} }
case "linux": case "linux":
case "darwin": { case "darwin": {
await sourceRC(options.rcPath) await sourceRCInRc(options)
if (options.shouldAddOnlyIfNotDefined) { if (options.shouldAddOnlyIfNotDefined) {
await appendFile(options.rcPath, `\nif [ -z "\${${name}}" ]; then export ${name}="${val}"; fi\n`) await appendFile(options.rcPath, `\nif [ -z "\${${name}}" ]; then export ${name}="${val}"; fi\n`)
info(`if not defined ${name} then ${name}="${val}" was added to "${options.rcPath}`) info(`if not defined ${name} then ${name}="${val}" was added to "${options.rcPath}`)

View File

@ -4,8 +4,7 @@ import { addPath as ghAddPath } from "@actions/core"
import { GITHUB_ACTIONS } from "ci-info" import { GITHUB_ACTIONS } from "ci-info"
import { error, info } from "ci-log" import { error, info } from "ci-log"
import { execPowershell } from "exec-powershell" import { execPowershell } from "exec-powershell"
import { untildifyUser } from "untildify-user" import { defaultRcPath, sourceRCInRc } from "./rc-file.js"
import { sourceRC } from "./rc-file.js"
const { appendFile } = promises const { appendFile } = promises
type AddPathOptions = { type AddPathOptions = {
@ -13,6 +12,8 @@ type AddPathOptions = {
* The path to the RC file that the PATH variables should be added to. * The path to the RC file that the PATH variables should be added to.
*/ */
rcPath: string rcPath: string
/** Provide a name (your tool) to add a variable guard for sourcing your rc file */
guard?: string
} }
/** /**
* Add a path to the PATH environment variable. * Add a path to the PATH environment variable.
@ -21,7 +22,7 @@ type AddPathOptions = {
*/ */
export async function addPath(path: string, givenOptions: Partial<AddPathOptions> = {}) { export async function addPath(path: string, givenOptions: Partial<AddPathOptions> = {}) {
const options = { rcPath: untildifyUser(".bashrc"), ...givenOptions } const options = { rcPath: defaultRcPath, ...givenOptions }
if (isIgnoredPath(path)) { if (isIgnoredPath(path)) {
return return
@ -34,17 +35,17 @@ export async function addPath(path: string, givenOptions: Partial<AddPathOptions
ghAddPath(path) ghAddPath(path)
} catch (err) { } catch (err) {
error(err as Error) error(err as Error)
await addPathSystem(path, options.rcPath) await addPathSystem(path, options)
} }
} else { } else {
await addPathSystem(path, options.rcPath) await addPathSystem(path, options)
} }
} catch (err) { } catch (err) {
error(`${err}\nFailed to add ${path} to the percistent PATH. You should add it manually.`) error(`${err}\nFailed to add ${path} to the percistent PATH. You should add it manually.`)
} }
} }
async function addPathSystem(path: string, rcPath: string) { async function addPathSystem(path: string, options: AddPathOptions) {
switch (process.platform) { switch (process.platform) {
case "win32": { case "win32": {
// We do not use `execaSync(`setx PATH "${path};%PATH%"`)` because of its character limit and also because %PATH% is different for user and system // We do not use `execaSync(`setx PATH "${path};%PATH%"`)` because of its character limit and also because %PATH% is different for user and system
@ -56,9 +57,9 @@ async function addPathSystem(path: string, rcPath: string) {
} }
case "linux": case "linux":
case "darwin": { case "darwin": {
await sourceRC(rcPath) await sourceRCInRc(options)
await appendFile(rcPath, `\nexport PATH="${path}:$PATH"\n`) await appendFile(options.rcPath, `\nexport PATH="${path}:$PATH"\n`)
info(`"${path}" was added to "${rcPath}"`) info(`"${path}" was added to "${options.rcPath}"`)
return return
} }
default: { default: {

View File

@ -1,3 +1,3 @@
export { addEnv } from "./add-env.js" export { addEnv } from "./add-env.js"
export { addPath } from "./add-path.js" export { addPath } from "./add-path.js"
export { finalizeRC, sourceRC } from "./rc-file.js" export { finalizeRC, sourceRCInRc as sourceRC } from "./rc-file.js"

View File

@ -6,15 +6,26 @@ import { pathExists } from "path-exists"
import { untildifyUser } from "untildify-user" import { untildifyUser } from "untildify-user"
const { appendFile, readFile, writeFile } = promises const { appendFile, readFile, writeFile } = promises
async function sourceRC_raw(rcPath: string) { export const defaultRcPath = untildifyUser("~/.bashrc")
const sourceRcString =
`\n# source .cpprc if SOURCE_CPPRC is not set to 0\nif [[ "$SOURCE_CPPRC" != 0 && -f "${rcPath}" ]]; then source "${rcPath}"; fi\n` export type RcOptions = {
/** The path to the RC file that the env variables should be added to. */
rcPath: string
/** Provide a name (your tool) to add a variable guard for sourcing your rc file */
guard?: string
}
async function sourceRCInRc_(options: RcOptions) {
const sourceRcString = options.guard === undefined
? `source "${options.rcPath}"`
: `# ${options.guard}\nif [[ "$SOURCE_${options.guard.toUpperCase()}RC" != 0 && -f "${options.rcPath}" ]]; then source "${options.rcPath}"; fi`
try { try {
await Promise.all([ await Promise.all([
addRCHeader(rcPath), addRCHeader(options),
sourceRcInProfile(sourceRcString), addSourceToTargetRc(sourceRcString, untildifyUser("~/.bashrc")),
sourceRCInBashrc(sourceRcString), addSourceToTargetRc(sourceRcString, untildifyUser("~/.profile")),
]) ])
} catch (err) { } catch (err) {
warning(`Failed to add ${sourceRcString} to .profile or .bashrc. You should add it manually: ${err}`) warning(`Failed to add ${sourceRcString} to .profile or .bashrc. You should add it manually: ${err}`)
@ -24,52 +35,42 @@ async function sourceRC_raw(rcPath: string) {
/** /**
* handles adding conditions to source rc file from .bashrc and .profile * handles adding conditions to source rc file from .bashrc and .profile
*/ */
export const sourceRC = memoize(sourceRC_raw, { isPromise: true }) export const sourceRCInRc = memoize(sourceRCInRc_, { isPromise: true })
async function addRCHeader(rcPath: string) { async function addRCHeader(options: RcOptions) {
// a variable that prevents source_cpprc from being called from .bashrc and .profile // a variable that prevents source rc from being called from .bashrc and .profile
const rcHeader = "# Automatically Generated by os-env\nexport SOURCE_CPPRC=0" const rcHeader = options.guard === undefined
? "# Automatically Generated by os-env"
: `# Automatically Generated by os-env ${options.guard}\nexport SOURCE_${options.guard.toUpperCase()}RC=0`
if (await pathExists(rcPath)) { if (await pathExists(options.rcPath)) {
const rcContent = await readFile(rcPath, "utf8") const rcContent = await readFile(options.rcPath, "utf8")
if (!rcContent.includes(rcHeader)) { if (!rcContent.includes(rcHeader)) {
// already executed setupCppInProfile // already executed setupCppInProfile
await appendFile(rcPath, `\n${rcHeader}\n`) await appendFile(options.rcPath, `\n${rcHeader}\n`)
info(`Added ${rcHeader} to ${rcPath}`) info(`Added ${rcHeader} to ${options.rcPath}`)
} }
} }
} }
async function sourceRCInBashrc(sourceRcString: string) { async function addSourceToTargetRc(sourceRcString: string, targetRcPath: string) {
const bashrcPath = untildifyUser("~/.bashrc") if (await pathExists(targetRcPath)) {
if (await pathExists(bashrcPath)) { const bashrcContent = await readFile(targetRcPath, "utf-8")
const bashrcContent = await readFile(bashrcPath, "utf-8")
if (!bashrcContent.includes(sourceRcString)) { if (!bashrcContent.includes(sourceRcString)) {
await appendFile(bashrcPath, sourceRcString) await appendFile(targetRcPath, sourceRcString)
info(`${sourceRcString} was added to ${bashrcPath}`) info(`${sourceRcString} was added to ${targetRcPath}`)
} }
} }
} }
async function sourceRcInProfile(sourceRcString: string) { export async function finalizeRC(rcOptions: RcOptions) {
const profilePath = untildifyUser("~/.profile") if (await pathExists(rcOptions.rcPath)) {
if (await pathExists(profilePath)) { const entries = (await readFile(rcOptions.rcPath, "utf-8")).split("\n")
const profileContent = await readFile(profilePath, "utf-8")
if (!profileContent.includes(sourceRcString)) {
await appendFile(profilePath, sourceRcString)
info(`${sourceRcString} was added to ${profilePath}`)
}
}
}
export async function finalizeRC(rcPath: string) {
if (await pathExists(rcPath)) {
const entries = (await readFile(rcPath, "utf-8")).split("\n")
const uniqueEntries = [...new Set(entries.reverse())].reverse() // remove duplicates, keeping the latest entry const uniqueEntries = [...new Set(entries.reverse())].reverse() // remove duplicates, keeping the latest entry
await writeFile(rcPath, uniqueEntries.join("\n")) await writeFile(rcOptions.rcPath, uniqueEntries.join("\n"))
await grantUserWriteAccess(rcPath) await grantUserWriteAccess(rcOptions.rcPath)
} }
} }

View File

@ -6,7 +6,7 @@ import { readFile } from "fs/promises"
import { addPath } from "os-env" import { addPath } from "os-env"
import { dirname } from "patha" import { dirname } from "patha"
import which from "which" import which from "which"
import { rcPath } from "../cli-options" import { rcOptions } from "../cli-options"
/* eslint-disable require-atomic-updates */ /* eslint-disable require-atomic-updates */
let binDir: string | undefined let binDir: string | undefined
@ -48,7 +48,7 @@ export async function setupBrew(_version: string, _setupDir: string, _arch: stri
}) })
binDir = getBrewPath() binDir = getBrewPath()
await addPath(binDir, { rcPath }) await addPath(binDir, rcOptions)
return { binDir } return { binDir }
} }

View File

@ -3,7 +3,7 @@ import { addPath } from "os-env"
import { pathExists } from "path-exists" import { pathExists } from "path-exists"
import { dirname } from "patha" import { dirname } from "patha"
import which from "which" import which from "which"
import { rcPath } from "../cli-options" import { rcOptions } from "../cli-options"
import type { InstallationInfo } from "../utils/setup/setupBin" import type { InstallationInfo } from "../utils/setup/setupBin"
/* eslint-disable require-atomic-updates */ /* eslint-disable require-atomic-updates */
@ -55,7 +55,7 @@ export async function setupChocolatey(
) )
const chocoPath = `${process.env.ALLUSERSPROFILE}\\chocolatey\\bin` const chocoPath = `${process.env.ALLUSERSPROFILE}\\chocolatey\\bin`
await addPath(chocoPath, { rcPath }) await addPath(chocoPath, rcOptions)
const maybeChoco = which.sync("choco", { nothrow: true }) const maybeChoco = which.sync("choco", { nothrow: true })
if (maybeChoco !== null) { if (maybeChoco !== null) {

View File

@ -73,4 +73,7 @@ export function getSuccessMessage(tool: string, installationInfo: InstallationIn
return msg return msg
} }
export const rcPath = untildifyUser("~/.cpprc") export const rcOptions = {
rcPath: untildifyUser(".cpprc"),
guard: "cpp",
}

View File

@ -3,7 +3,7 @@ import { endGroup, notice, startGroup } from "@actions/core"
import { error, info } from "ci-log" import { error, info } from "ci-log"
import { addEnv } from "os-env" import { addEnv } from "os-env"
import semverValid from "semver/functions/valid" import semverValid from "semver/functions/valid"
import { getSuccessMessage } from "./cli-options" import { getSuccessMessage, rcOptions } from "./cli-options"
import { setupGcc, setupMingw } from "./gcc/gcc" import { setupGcc, setupMingw } from "./gcc/gcc"
import { activateGcovGCC, activateGcovLLVM } from "./gcovr/gcovr" import { activateGcovGCC, activateGcovLLVM } from "./gcovr/gcovr"
import { setupLLVM } from "./llvm/llvm" import { setupLLVM } from "./llvm/llvm"
@ -69,7 +69,7 @@ export async function installCompiler(
if (hasLLVM) { if (hasLLVM) {
// remove back the added CPPFLAGS of LLVM that include the LLVM headers // remove back the added CPPFLAGS of LLVM that include the LLVM headers
await addEnv("CPPFLAGS", "") await addEnv("CPPFLAGS", "", rcOptions)
} }
await activateGcovGCC(gccVersion) await activateGcovGCC(gccVersion)
@ -92,7 +92,7 @@ export async function installCompiler(
if (hasLLVM) { if (hasLLVM) {
// remove the CPPFLAGS of LLVM that include the LLVM headers // remove the CPPFLAGS of LLVM that include the LLVM headers
await addEnv("CPPFLAGS", "") await addEnv("CPPFLAGS", "", rcOptions)
} }
successMessages.push(getSuccessMessage("msvc", installationInfo)) successMessages.push(getSuccessMessage("msvc", installationInfo))
@ -101,7 +101,7 @@ export async function installCompiler(
case "appleclang": case "appleclang":
case "applellvm": { case "applellvm": {
notice("Assuming apple-clang is already installed") notice("Assuming apple-clang is already installed")
await Promise.all([addEnv("CC", "clang"), addEnv("CXX", "clang++")]) await Promise.all([addEnv("CC", "clang", rcOptions), addEnv("CXX", "clang++", rcOptions)])
successMessages.push(getSuccessMessage("apple-clang", undefined)) successMessages.push(getSuccessMessage("apple-clang", undefined))
break break
} }

View File

@ -1,5 +1,5 @@
import { addPath } from "os-env" import { addPath } from "os-env"
import { rcPath } from "../cli-options" import { rcOptions } from "../cli-options"
import { hasDnf } from "../utils/env/hasDnf" import { hasDnf } from "../utils/env/hasDnf"
import { isArch } from "../utils/env/isArch" import { isArch } from "../utils/env/isArch"
import { isUbuntu } from "../utils/env/isUbuntu" import { isUbuntu } from "../utils/env/isUbuntu"
@ -38,6 +38,6 @@ export async function setupCppcheck(version: string | undefined, _setupDir: stri
async function activateWinCppcheck() { async function activateWinCppcheck() {
const binDir = "C:/Program Files/Cppcheck" const binDir = "C:/Program Files/Cppcheck"
await addPath(binDir, { rcPath }) await addPath(binDir, rcOptions)
return binDir return binDir
} }

View File

@ -12,7 +12,7 @@ import { getVersion } from "../versions/versions"
import { pathExists } from "path-exists" import { pathExists } from "path-exists"
import retry from "retry-as-promised" import retry from "retry-as-promised"
import { rcPath } from "../cli-options" import { rcOptions } from "../cli-options"
import { hasDnf } from "../utils/env/hasDnf" import { hasDnf } from "../utils/env/hasDnf"
import { isArch } from "../utils/env/isArch" import { isArch } from "../utils/env/isArch"
import { isUbuntu } from "../utils/env/isUbuntu" import { isUbuntu } from "../utils/env/isUbuntu"
@ -139,7 +139,7 @@ async function activateWinDoxygen() {
// eslint-disable-next-line no-await-in-loop // eslint-disable-next-line no-await-in-loop
if (await pathExists(join(binDir, "doxygen.exe"))) { if (await pathExists(join(binDir, "doxygen.exe"))) {
// eslint-disable-next-line no-await-in-loop // eslint-disable-next-line no-await-in-loop
await addPath(binDir, { rcPath }) await addPath(binDir, rcOptions)
return binDir return binDir
} }
} }

View File

@ -7,7 +7,7 @@ import { pathExists } from "path-exists"
import { addExeExt, join } from "patha" import { addExeExt, join } from "patha"
import semverCoerce from "semver/functions/coerce" import semverCoerce from "semver/functions/coerce"
import semverMajor from "semver/functions/major" import semverMajor from "semver/functions/major"
import { rcPath } from "../cli-options" import { rcOptions } from "../cli-options"
import { setupMacOSSDK } from "../macos-sdk/macos-sdk" import { setupMacOSSDK } from "../macos-sdk/macos-sdk"
import { hasDnf } from "../utils/env/hasDnf" import { hasDnf } from "../utils/env/hasDnf"
import { isArch } from "../utils/env/isArch" import { isArch } from "../utils/env/isArch"
@ -188,10 +188,10 @@ async function setupChocoMingw(version: string, arch: string): Promise<Installat
let binDir: string | undefined let binDir: string | undefined
if (arch === "x64" && (await pathExists("C:/tools/mingw64/bin"))) { if (arch === "x64" && (await pathExists("C:/tools/mingw64/bin"))) {
binDir = "C:/tools/mingw64/bin" binDir = "C:/tools/mingw64/bin"
await addPath(binDir, { rcPath }) await addPath(binDir, rcOptions)
} else if (arch === "ia32" && (await pathExists("C:/tools/mingw32/bin"))) { } else if (arch === "ia32" && (await pathExists("C:/tools/mingw32/bin"))) {
binDir = "C:/tools/mingw32/bin" binDir = "C:/tools/mingw32/bin"
await addPath(binDir, { rcPath }) await addPath(binDir, rcOptions)
} else if (await pathExists(`${process.env.ChocolateyInstall ?? "C:/ProgramData/chocolatey"}/bin/g++.exe`)) { } else if (await pathExists(`${process.env.ChocolateyInstall ?? "C:/ProgramData/chocolatey"}/bin/g++.exe`)) {
binDir = `${process.env.ChocolateyInstall ?? "C:/ProgramData/chocolatey"}/bin` binDir = `${process.env.ChocolateyInstall ?? "C:/ProgramData/chocolatey"}/bin`
} }
@ -209,37 +209,46 @@ async function activateGcc(version: string, binDir: string, priority: number = 4
// const ld = process.env.LD_LIBRARY_PATH ?? "" // const ld = process.env.LD_LIBRARY_PATH ?? ""
// const dyld = process.env.DYLD_LIBRARY_PATH ?? "" // const dyld = process.env.DYLD_LIBRARY_PATH ?? ""
// promises.push( // promises.push(
// addEnv("LD_LIBRARY_PATH", `${installDir}/lib${path.delimiter}${ld}`), // addEnv("LD_LIBRARY_PATH", `${installDir}/lib${path.delimiter}${ld}`, rcOptions),
// addEnv("DYLD_LIBRARY_PATH", `${installDir}/lib${path.delimiter}${dyld}`), // addEnv("DYLD_LIBRARY_PATH", `${installDir}/lib${path.delimiter}${dyld}`, rcOptions),
// addEnv("CPATH", `${installDir}/lib/gcc/${majorVersion}/include`), // addEnv("CPATH", `${installDir}/lib/gcc/${majorVersion}/include`, rcOptions),
// addEnv("LDFLAGS", `-L${installDir}/lib`), // addEnv("LDFLAGS", `-L${installDir}/lib`, rcOptions),
// addEnv("CPPFLAGS", `-I${installDir}/include`) // addEnv("CPPFLAGS", `-I${installDir}/include`, rcOptions),
// ) // )
if (process.platform === "win32") { if (process.platform === "win32") {
promises.push(addEnv("CC", addExeExt(`${binDir}/gcc`)), addEnv("CXX", addExeExt(`${binDir}/g++`))) promises.push(
addEnv("CC", addExeExt(`${binDir}/gcc`), rcOptions),
addEnv("CXX", addExeExt(`${binDir}/g++`), rcOptions),
)
} else { } else {
const majorVersion = semverMajor(semverCoerce(version) ?? version) const majorVersion = semverMajor(semverCoerce(version) ?? version)
if (majorVersion >= 5) { if (majorVersion >= 5) {
promises.push(addEnv("CC", `${binDir}/gcc-${majorVersion}`), addEnv("CXX", `${binDir}/g++-${majorVersion}`)) promises.push(
addEnv("CC", `${binDir}/gcc-${majorVersion}`, rcOptions),
addEnv("CXX", `${binDir}/g++-${majorVersion}`, rcOptions),
)
if (isUbuntu()) { if (isUbuntu()) {
promises.push( promises.push(
updateAptAlternatives("cc", `${binDir}/gcc-${majorVersion}`, rcPath, priority), updateAptAlternatives("cc", `${binDir}/gcc-${majorVersion}`, rcOptions.rcPath, priority),
updateAptAlternatives("cxx", `${binDir}/g++-${majorVersion}`, rcPath, priority), updateAptAlternatives("cxx", `${binDir}/g++-${majorVersion}`, rcOptions.rcPath, priority),
updateAptAlternatives("gcc", `${binDir}/gcc-${majorVersion}`, rcPath, priority), updateAptAlternatives("gcc", `${binDir}/gcc-${majorVersion}`, rcOptions.rcPath, priority),
updateAptAlternatives("g++", `${binDir}/g++-${majorVersion}`, rcPath, priority), updateAptAlternatives("g++", `${binDir}/g++-${majorVersion}`, rcOptions.rcPath, priority),
) )
} }
} else { } else {
promises.push(addEnv("CC", `${binDir}/gcc-${version}`), addEnv("CXX", `${binDir}/g++-${version}`)) promises.push(
addEnv("CC", `${binDir}/gcc-${version}`, rcOptions),
addEnv("CXX", `${binDir}/g++-${version}`, rcOptions),
)
if (isUbuntu()) { if (isUbuntu()) {
promises.push( promises.push(
updateAptAlternatives("cc", `${binDir}/gcc-${version}`, rcPath, priority), updateAptAlternatives("cc", `${binDir}/gcc-${version}`, rcOptions.rcPath, priority),
updateAptAlternatives("cxx", `${binDir}/g++-${version}`, rcPath, priority), updateAptAlternatives("cxx", `${binDir}/g++-${version}`, rcOptions.rcPath, priority),
updateAptAlternatives("gcc", `${binDir}/gcc-${version}`, rcPath, priority), updateAptAlternatives("gcc", `${binDir}/gcc-${version}`, rcOptions.rcPath, priority),
updateAptAlternatives("g++", `${binDir}/g++-${version}`, rcPath, priority), updateAptAlternatives("g++", `${binDir}/g++-${version}`, rcOptions.rcPath, priority),
) )
} }
} }

View File

@ -1,6 +1,7 @@
import { addEnv } from "os-env" import { addEnv } from "os-env"
import semverMajor from "semver/functions/major" import semverMajor from "semver/functions/major"
import semverValid from "semver/functions/valid" import semverValid from "semver/functions/valid"
import { rcOptions } from "../cli-options"
import { setupPipPack } from "../utils/setup/setupPipPack" import { setupPipPack } from "../utils/setup/setupPipPack"
// eslint-disable-next-line @typescript-eslint/no-unused-vars // eslint-disable-next-line @typescript-eslint/no-unused-vars
@ -9,7 +10,7 @@ export function setupGcovr(version: string | undefined, _setupDir: string, _arch
} }
export function activateGcovLLVM() { export function activateGcovLLVM() {
return addEnv("GCOV", "llvm-cov gcov") return addEnv("GCOV", "llvm-cov gcov", rcOptions)
} }
export function activateGcovGCC(gccVersion: string) { export function activateGcovGCC(gccVersion: string) {
@ -17,5 +18,5 @@ export function activateGcovGCC(gccVersion: string) {
const gccMajor = gccSemver !== null ? semverMajor(gccSemver) : gccVersion const gccMajor = gccSemver !== null ? semverMajor(gccSemver) : gccVersion
const gcov = gccMajor !== "" ? `gcov-${gccMajor}` : "gcov" const gcov = gccMajor !== "" ? `gcov-${gccMajor}` : "gcov"
return addEnv("GCOV", gcov) return addEnv("GCOV", gcov, rcOptions)
} }

View File

@ -1,5 +1,5 @@
import { addPath } from "os-env" import { addPath } from "os-env"
import { rcPath } from "../cli-options" import { rcOptions } from "../cli-options"
import { hasDnf } from "../utils/env/hasDnf" import { hasDnf } from "../utils/env/hasDnf"
import { isArch } from "../utils/env/isArch" import { isArch } from "../utils/env/isArch"
import { isUbuntu } from "../utils/env/isUbuntu" import { isUbuntu } from "../utils/env/isUbuntu"
@ -40,7 +40,7 @@ async function activateGraphviz(): Promise<InstallationInfo> {
switch (process.platform) { switch (process.platform) {
case "win32": { case "win32": {
const binDir = "C:/Program Files/Graphviz/bin" const binDir = "C:/Program Files/Graphviz/bin"
await addPath(binDir, { rcPath }) await addPath(binDir, rcOptions)
return { binDir } return { binDir }
} }
default: { default: {

View File

@ -5,7 +5,7 @@ import memoize from "micro-memoize"
import { addEnv } from "os-env" import { addEnv } from "os-env"
import { pathExists } from "path-exists" import { pathExists } from "path-exists"
import { addExeExt, join } from "patha" import { addExeExt, join } from "patha"
import { rcPath } from "../cli-options" import { rcOptions } from "../cli-options"
import { setupGcc } from "../gcc/gcc" import { setupGcc } from "../gcc/gcc"
import { setupMacOSSDK } from "../macos-sdk/macos-sdk" import { setupMacOSSDK } from "../macos-sdk/macos-sdk"
import { isUbuntu } from "../utils/env/isUbuntu" import { isUbuntu } from "../utils/env/isUbuntu"
@ -98,21 +98,21 @@ export async function activateLLVM(directory: string) {
const actPromises: Promise<void>[] = [ const actPromises: Promise<void>[] = [
// the output of this action // the output of this action
addEnv("LLVM_PATH", directory), addEnv("LLVM_PATH", directory, rcOptions),
// Setup LLVM as the compiler // Setup LLVM as the compiler
addEnv("LD_LIBRARY_PATH", `${directory}/lib${delimiter}${ld}`), addEnv("LD_LIBRARY_PATH", `${directory}/lib${delimiter}${ld}`, rcOptions),
addEnv("DYLD_LIBRARY_PATH", `${directory}/lib${delimiter}${dyld}`), addEnv("DYLD_LIBRARY_PATH", `${directory}/lib${delimiter}${dyld}`, rcOptions),
// compiler flags // compiler flags
addEnv("LDFLAGS", `-L"${directory}/lib"`), addEnv("LDFLAGS", `-L"${directory}/lib"`, rcOptions),
addEnv("CPPFLAGS", `-I"${directory}/include"`), addEnv("CPPFLAGS", `-I"${directory}/include"`, rcOptions),
// compiler paths // compiler paths
addEnv("CC", addExeExt(`${directory}/bin/clang`)), addEnv("CC", addExeExt(`${directory}/bin/clang`), rcOptions),
addEnv("CXX", addExeExt(`${directory}/bin/clang++`)), addEnv("CXX", addExeExt(`${directory}/bin/clang++`), rcOptions),
addEnv("LIBRARY_PATH", `${directory}/lib`), addEnv("LIBRARY_PATH", `${directory}/lib`, rcOptions),
// os sdks // os sdks
setupMacOSSDK(), setupMacOSSDK(),
@ -122,22 +122,22 @@ export async function activateLLVM(directory: string) {
// TODO Windows builds fail with llvm's CPATH // TODO Windows builds fail with llvm's CPATH
// if (process.platform !== "win32") { // if (process.platform !== "win32") {
// if (await pathExists(`${directory}/lib/clang/${version}/include`)) { // if (await pathExists(`${directory}/lib/clang/${version}/include`)) {
// promises.push(addEnv("CPATH", `${directory}/lib/clang/${version}/include`)) // promises.push(addEnv("CPATH", `${directory}/lib/clang/${version}/include`, rcOptions))
// } else if (await pathExists(`${directory}/lib/clang/${llvmMajor}/include`)) { // } else if (await pathExists(`${directory}/lib/clang/${llvmMajor}/include`)) {
// promises.push(addEnv("CPATH", `${directory}/lib/clang/${llvmMajor}/include`)) // promises.push(addEnv("CPATH", `${directory}/lib/clang/${llvmMajor}/include`, rcOptions))
// } // }
// } // }
if (isUbuntu()) { if (isUbuntu()) {
const priority = 60 const priority = 60
actPromises.push( actPromises.push(
updateAptAlternatives("cc", `${directory}/bin/clang`, rcPath, priority), updateAptAlternatives("cc", `${directory}/bin/clang`, rcOptions.rcPath, priority),
updateAptAlternatives("cxx", `${directory}/bin/clang++`, rcPath, priority), updateAptAlternatives("cxx", `${directory}/bin/clang++`, rcOptions.rcPath, priority),
updateAptAlternatives("clang", `${directory}/bin/clang`, rcPath), updateAptAlternatives("clang", `${directory}/bin/clang`, rcOptions.rcPath),
updateAptAlternatives("clang++", `${directory}/bin/clang++`, rcPath), updateAptAlternatives("clang++", `${directory}/bin/clang++`, rcOptions.rcPath),
updateAptAlternatives("lld", `${directory}/bin/lld`, rcPath), updateAptAlternatives("lld", `${directory}/bin/lld`, rcOptions.rcPath),
updateAptAlternatives("ld.lld", `${directory}/bin/ld.lld`, rcPath), updateAptAlternatives("ld.lld", `${directory}/bin/ld.lld`, rcOptions.rcPath),
updateAptAlternatives("llvm-ar", `${directory}/bin/llvm-ar`, rcPath), updateAptAlternatives("llvm-ar", `${directory}/bin/llvm-ar`, rcOptions.rcPath),
) )
} }

View File

@ -3,7 +3,7 @@ import { execRoot } from "admina"
import { execa } from "execa" import { execa } from "execa"
import { chmod, readFile, writeFile } from "fs/promises" import { chmod, readFile, writeFile } from "fs/promises"
import { addPath } from "os-env" import { addPath } from "os-env"
import { rcPath } from "../cli-options" import { rcOptions } from "../cli-options"
import { DEFAULT_TIMEOUT } from "../installTool" import { DEFAULT_TIMEOUT } from "../installTool"
import { aptTimeout, hasNala, isPackageRegexInstalled, setupAptPack } from "../utils/setup/setupAptPack" import { aptTimeout, hasNala, isPackageRegexInstalled, setupAptPack } from "../utils/setup/setupAptPack"
import type { InstallationInfo } from "../utils/setup/setupBin" import type { InstallationInfo } from "../utils/setup/setupBin"
@ -36,7 +36,7 @@ export async function setupLLVMApt(
}, },
) )
await addPath(`${installationFolder}/bin`, { rcPath }) await addPath(`${installationFolder}/bin`, rcOptions)
return { return {
installDir: `${installationFolder}`, installDir: `${installationFolder}`,

View File

@ -1,6 +1,7 @@
import { getExecOutput } from "@actions/exec" import { getExecOutput } from "@actions/exec"
import { error } from "ci-log" import { error } from "ci-log"
import { addEnv } from "os-env" import { addEnv } from "os-env"
import { rcOptions } from "../cli-options"
export async function setupMacOSSDK() { export async function setupMacOSSDK() {
if (process.platform === "darwin") { if (process.platform === "darwin") {
@ -8,7 +9,7 @@ export async function setupMacOSSDK() {
const xcrun = await getExecOutput("xcrun --sdk macosx --show-sdk-path") const xcrun = await getExecOutput("xcrun --sdk macosx --show-sdk-path")
const sdkroot = xcrun.stdout || xcrun.stderr const sdkroot = xcrun.stdout || xcrun.stderr
if (sdkroot) { if (sdkroot) {
await addEnv("SDKROOT", sdkroot.trim()) await addEnv("SDKROOT", sdkroot.trim(), rcOptions)
} else { } else {
error("SDKROOT not set") error("SDKROOT not set")
} }

View File

@ -10,7 +10,7 @@ import * as timeDelta from "time-delta"
import timeDeltaLocale from "time-delta/locales/en.js" import timeDeltaLocale from "time-delta/locales/en.js"
import { untildifyUser } from "untildify-user" import { untildifyUser } from "untildify-user"
import { checkUpdates } from "./check-updates" import { checkUpdates } from "./check-updates"
import { parseArgs, printHelp, rcPath } from "./cli-options" import { parseArgs, printHelp, rcOptions } from "./cli-options"
import { installCompiler } from "./compilers" import { installCompiler } from "./compilers"
import { installTool } from "./installTool" import { installTool } from "./installTool"
import { tools } from "./tool" import { tools } from "./tool"
@ -115,7 +115,7 @@ async function main(args: string[]): Promise<number> {
} }
} }
await finalizeRC(rcPath) await finalizeRC(rcOptions)
if (successMessages.length === 0 && errorMessages.length === 0) { if (successMessages.length === 0 && errorMessages.length === 0) {
warning("setup-cpp was called without any arguments. Nothing to do.") warning("setup-cpp was called without any arguments. Nothing to do.")

View File

@ -1,5 +1,5 @@
import { addPath } from "os-env" import { addPath } from "os-env"
import { rcPath } from "../cli-options" import { rcOptions } from "../cli-options"
import { hasDnf } from "../utils/env/hasDnf" import { hasDnf } from "../utils/env/hasDnf"
import { isArch } from "../utils/env/isArch" import { isArch } from "../utils/env/isArch"
import { isUbuntu } from "../utils/env/isUbuntu" import { isUbuntu } from "../utils/env/isUbuntu"
@ -17,7 +17,7 @@ export async function setupMake(version: string, _setupDir: string, _arch: strin
} }
case "darwin": { case "darwin": {
await setupBrewPack("make", version) await setupBrewPack("make", version)
await addPath("/usr/local/opt/make/libexec/gnubin", { rcPath }) await addPath("/usr/local/opt/make/libexec/gnubin", rcOptions)
return { binDir: "/usr/local/opt/make/libexec/gnubin" } return { binDir: "/usr/local/opt/make/libexec/gnubin" }
} }
case "linux": { case "linux": {

View File

@ -1,5 +1,5 @@
import { addPath } from "os-env" import { addPath } from "os-env"
import { rcPath } from "../cli-options" import { rcOptions } from "../cli-options"
import { setupChocoPack } from "../utils/setup/setupChocoPack" import { setupChocoPack } from "../utils/setup/setupChocoPack"
// eslint-disable-next-line @typescript-eslint/no-unused-vars // eslint-disable-next-line @typescript-eslint/no-unused-vars
@ -14,6 +14,6 @@ export async function setupOpencppcoverage(version: string | undefined, _setupDi
async function activateOpencppcoverage() { async function activateOpencppcoverage() {
const binDir = "C:/Program Files/OpenCppCoverage" const binDir = "C:/Program Files/OpenCppCoverage"
await addPath(binDir, { rcPath }) await addPath(binDir, rcOptions)
return binDir return binDir
} }

View File

@ -1,6 +1,6 @@
import { execRootSync } from "admina" import { execRootSync } from "admina"
import { addPath } from "os-env" import { addPath } from "os-env"
import { rcPath } from "../cli-options" import { rcOptions } from "../cli-options"
import { hasDnf } from "../utils/env/hasDnf" import { hasDnf } from "../utils/env/hasDnf"
import { isArch } from "../utils/env/isArch" import { isArch } from "../utils/env/isArch"
import { isUbuntu } from "../utils/env/isUbuntu" import { isUbuntu } from "../utils/env/isUbuntu"
@ -17,7 +17,7 @@ export async function setupPowershell(version: string | undefined, _setupDir: st
case "win32": { case "win32": {
await setupChocoPack("powershell-core", version) await setupChocoPack("powershell-core", version)
const binDir = "C:/Program Files/PowerShell/7" const binDir = "C:/Program Files/PowerShell/7"
await addPath(binDir, { rcPath }) await addPath(binDir, rcOptions)
return { binDir } return { binDir }
} }
case "darwin": { case "darwin": {

View File

@ -11,7 +11,7 @@ import { addPath } from "os-env"
import { pathExists } from "path-exists" import { pathExists } from "path-exists"
import { addExeExt, dirname, join } from "patha" import { addExeExt, dirname, join } from "patha"
import which from "which" import which from "which"
import { rcPath } from "../cli-options" import { rcOptions } from "../cli-options"
import { hasDnf } from "../utils/env/hasDnf" import { hasDnf } from "../utils/env/hasDnf"
import { isArch } from "../utils/env/isArch" import { isArch } from "../utils/env/isArch"
import { isUbuntu } from "../utils/env/isUbuntu" import { isUbuntu } from "../utils/env/isUbuntu"
@ -135,7 +135,7 @@ async function setupPythonSystem(setupDir: string, version: string) {
} }
const binDir = dirname(bin) const binDir = dirname(bin)
/** The directory which the tool is installed to */ /** The directory which the tool is installed to */
await addPath(binDir, { rcPath }) await addPath(binDir, rcOptions)
installInfo = { installDir: binDir, binDir, bin } installInfo = { installDir: binDir, binDir, bin }
break break
} }
@ -147,7 +147,7 @@ async function setupPythonSystem(setupDir: string, version: string) {
stderr: string stderr: string
} = await execa("brew", ["--prefix", "python"], { stdio: "pipe" }) } = await execa("brew", ["--prefix", "python"], { stdio: "pipe" })
const brewPythonBin = join(brewPythonPrefix.stdout, "libexec", "bin") const brewPythonBin = join(brewPythonPrefix.stdout, "libexec", "bin")
await addPath(brewPythonBin, { rcPath }) await addPath(brewPythonBin, rcOptions)
break break
} }

View File

@ -7,6 +7,7 @@ import { appendFile } from "fs/promises"
import { addEnv, sourceRC } from "os-env" import { addEnv, sourceRC } from "os-env"
import { pathExists } from "path-exists" import { pathExists } from "path-exists"
import which from "which" import which from "which"
import { rcOptions } from "../../cli-options"
import type { InstallationInfo } from "./setupBin" import type { InstallationInfo } from "./setupBin"
/* eslint-disable require-atomic-updates */ /* eslint-disable require-atomic-updates */
@ -223,8 +224,8 @@ async function initApt(apt: string) {
if (apt === "nala") { if (apt === "nala") {
// enable utf8 otherwise it fails because of the usage of ASCII encoding // enable utf8 otherwise it fails because of the usage of ASCII encoding
promises.push( promises.push(
addEnv("LANG", "C.UTF-8", { shouldAddOnlyIfNotDefined: true }), addEnv("LANG", "C.UTF-8", { shouldAddOnlyIfNotDefined: true, ...rcOptions }),
addEnv("LC_ALL", "C.UTF-8", { shouldAddOnlyIfNotDefined: true }), addEnv("LC_ALL", "C.UTF-8", { shouldAddOnlyIfNotDefined: true, ...rcOptions }),
) )
} }
await Promise.all(promises) await Promise.all(promises)
@ -278,7 +279,7 @@ export async function updateAptAlternatives(name: string, path: string, rcPath:
if (GITHUB_ACTIONS) { if (GITHUB_ACTIONS) {
await execRoot("update-alternatives", ["--install", `/usr/bin/${name}`, name, path, priority.toString()]) await execRoot("update-alternatives", ["--install", `/usr/bin/${name}`, name, path, priority.toString()])
} else { } else {
await sourceRC(rcPath) await sourceRC(rcOptions)
await appendFile( await appendFile(
rcPath, rcPath,
`\nif [ $UID -eq 0 ]; then update-alternatives --install /usr/bin/${name} ${name} ${path} ${priority}; fi\n`, `\nif [ $UID -eq 0 ]; then update-alternatives --install /usr/bin/${name} ${name} ${path} ${priority}; fi\n`,

View File

@ -7,7 +7,7 @@ import { tmpdir } from "os"
import { GITHUB_ACTIONS } from "ci-info" import { GITHUB_ACTIONS } from "ci-info"
import { pathExists } from "path-exists" import { pathExists } from "path-exists"
import retry from "retry-as-promised" import retry from "retry-as-promised"
import { maybeGetInput, rcPath } from "../../cli-options" import { maybeGetInput, rcOptions } from "../../cli-options"
import { hasDnf } from "../env/hasDnf" import { hasDnf } from "../env/hasDnf"
import { isArch } from "../env/isArch" import { isArch } from "../env/isArch"
import { isUbuntu } from "../env/isUbuntu" import { isUbuntu } from "../env/isUbuntu"
@ -74,7 +74,7 @@ export async function setupBin(
const binDir = join(installDir, binRelativeDir) const binDir = join(installDir, binRelativeDir)
if (await pathExists(join(binDir, binFileName))) { if (await pathExists(join(binDir, binFileName))) {
info(`${name} ${version} was found in the cache at ${binDir}.`) info(`${name} ${version} was found in the cache at ${binDir}.`)
await addPath(binDir, { rcPath }) await addPath(binDir, rcOptions)
return { installDir, binDir } return { installDir, binDir }
} }
@ -129,7 +129,7 @@ export async function setupBin(
// Adding the bin dir to the path // Adding the bin dir to the path
/** The directory which the tool is installed to */ /** The directory which the tool is installed to */
info(`Add ${binDir} to PATH`) info(`Add ${binDir} to PATH`)
await addPath(binDir, { rcPath }) await addPath(binDir, rcOptions)
// check if inside Github Actions. If so, cache the installation // check if inside Github Actions. If so, cache the installation
if (GITHUB_ACTIONS && typeof process.env.RUNNER_TOOL_CACHE === "string") { if (GITHUB_ACTIONS && typeof process.env.RUNNER_TOOL_CACHE === "string") {

View File

@ -4,7 +4,7 @@ import { execaSync } from "execa"
import { addPath } from "os-env" import { addPath } from "os-env"
import which from "which" import which from "which"
import { setupChocolatey } from "../../chocolatey/chocolatey" import { setupChocolatey } from "../../chocolatey/chocolatey"
import { rcPath } from "../../cli-options" import { rcOptions } from "../../cli-options"
import type { InstallationInfo } from "./setupBin" import type { InstallationInfo } from "./setupBin"
let hasChoco = false let hasChoco = false
@ -46,7 +46,7 @@ export async function setupChocoPack(name: string, version?: string, args: strin
} }
const binDir = `${process.env.ChocolateyInstall ?? "C:/ProgramData/chocolatey"}/bin` const binDir = `${process.env.ChocolateyInstall ?? "C:/ProgramData/chocolatey"}/bin`
await addPath(binDir, { rcPath }) await addPath(binDir, rcOptions)
return { binDir } return { binDir }
} }

View File

@ -7,7 +7,7 @@ import { pathExists } from "path-exists"
import { addExeExt, dirname, join } from "patha" import { addExeExt, dirname, join } from "patha"
import { untildifyUser } from "untildify-user" import { untildifyUser } from "untildify-user"
import which from "which" import which from "which"
import { rcPath } from "../../cli-options" import { rcOptions } from "../../cli-options"
import { addPythonBaseExecPrefix, setupPython } from "../../python/python" import { addPythonBaseExecPrefix, setupPython } from "../../python/python"
import { getVersion } from "../../versions/versions" import { getVersion } from "../../versions/versions"
import { hasDnf } from "../env/hasDnf" import { hasDnf } from "../env/hasDnf"
@ -86,7 +86,7 @@ export async function setupPipPackWithPython(
const execPaths = await addPythonBaseExecPrefix(givenPython) const execPaths = await addPythonBaseExecPrefix(givenPython)
const binDir = await findBinDir(execPaths, name) const binDir = await findBinDir(execPaths, name)
await addPath(binDir, { rcPath }) await addPath(binDir, rcOptions)
return { binDir } return { binDir }
} }
@ -136,7 +136,7 @@ async function getPipxBinDir_raw() {
} }
const pipxBinDir = untildifyUser("~/.local/bin") const pipxBinDir = untildifyUser("~/.local/bin")
await addPath(pipxBinDir, { rcPath }) await addPath(pipxBinDir, rcOptions)
await mkdirp(pipxBinDir) await mkdirp(pipxBinDir)
return pipxBinDir return pipxBinDir
} }

View File

@ -5,7 +5,7 @@ import { addPath } from "os-env"
import { pathExists } from "path-exists" import { pathExists } from "path-exists"
import { addShExt, addShRelativePrefix, dirname, join } from "patha" import { addShExt, addShRelativePrefix, dirname, join } from "patha"
import which from "which" import which from "which"
import { rcPath } from "../cli-options" import { rcOptions } from "../cli-options"
import { hasDnf } from "../utils/env/hasDnf" import { hasDnf } from "../utils/env/hasDnf"
import { isArch } from "../utils/env/isArch" import { isArch } from "../utils/env/isArch"
import { isUbuntu } from "../utils/env/isUbuntu" import { isUbuntu } from "../utils/env/isUbuntu"
@ -76,7 +76,7 @@ export async function setupVcpkg(version: string, setupDir: string, _arch: strin
await grantUserWriteAccess(setupDir) await grantUserWriteAccess(setupDir)
await addPath(setupDir, { rcPath }) await addPath(setupDir, rcOptions)
// eslint-disable-next-line require-atomic-updates // eslint-disable-next-line require-atomic-updates
hasVCPKG = true hasVCPKG = true
return { binDir: setupDir } return { binDir: setupDir }

View File

@ -4,6 +4,7 @@ import { info } from "ci-log"
import { setupMSVCDevCmd } from "msvc-dev-cmd/lib.js" import { setupMSVCDevCmd } from "msvc-dev-cmd/lib.js"
import { addEnv } from "os-env" import { addEnv } from "os-env"
import { pathExists } from "path-exists" import { pathExists } from "path-exists"
import { rcOptions } from "../cli-options"
function getArch(arch: string): string { function getArch(arch: string): string {
switch (arch) { switch (arch) {
@ -32,7 +33,7 @@ export async function setupVCVarsall(
) { ) {
if (VCTargetsPath !== undefined && (await pathExists(VCTargetsPath))) { if (VCTargetsPath !== undefined && (await pathExists(VCTargetsPath))) {
info(`Adding ${VCTargetsPath} to PATH`) info(`Adding ${VCTargetsPath} to PATH`)
await addEnv("VCTargetsPath", VCTargetsPath) await addEnv("VCTargetsPath", VCTargetsPath, rcOptions)
} }
await setupMSVCDevCmd(getArch(arch), sdk, toolset, uwp, spectre, vsversion) await setupMSVCDevCmd(getArch(arch), sdk, toolset, uwp, spectre, vsversion)