Merge pull request #241 from aminya/bashrc-update [skip ci]

This commit is contained in:
Amin Yahyaabadi 2024-04-03 00:57:50 -07:00 committed by GitHub
commit 17a5a833c4
No known key found for this signature in database
GPG Key ID: B5690EEEBB952194
9 changed files with 142 additions and 93 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

31
src/utils/compat/fs/types.d.ts vendored Normal file
View File

@ -0,0 +1,31 @@
declare module "fs/promises" {
import * as fs from "fs"
export default fs.promises
export const {
access,
appendFile,
chmod,
chown,
copyFile,
lchmod,
lchown,
link,
lstat,
mkdir,
mkdtemp,
open,
readdir,
readFile,
readlink,
realpath,
rename,
rmdir,
stat,
symlink,
truncate,
unlink,
utimes,
writeFile,
} = fs.promises
}

View File

@ -5,16 +5,16 @@ import { error, warning } from "ci-log"
import escapeSpace from "escape-path-with-spaces" import escapeSpace from "escape-path-with-spaces"
import escapeQuote from "escape-quotes" import escapeQuote from "escape-quotes"
import { execPowershell } from "exec-powershell" import { execPowershell } from "exec-powershell"
import { appendFileSync, readFileSync, writeFileSync } from "fs" import { appendFile, readFile, writeFile } from "fs/promises"
import { delimiter } from "path" import { delimiter } from "path"
import { pathExists } from "path-exists" import { pathExists } from "path-exists"
import { untildifyUser } from "untildify-user" import { untildifyUser } from "untildify-user"
type AddEnvOptions = { type AddEnvOptions = {
/** If true, the value will be escaped with quotes and spaces will be escaped with backslash */ /** If true, the value will be escaped with quotes and spaces will be escaped with backslash */
shouldEscapeSpace?: boolean shouldEscapeSpace: boolean
/** If true, the variable will be only added if it is not defined */ /** If true, the variable will be only added if it is not defined */
shouldAddOnlyIfNotDefined?: boolean shouldAddOnlyIfNotDefined: boolean
} }
const defaultAddEnvOptions: AddEnvOptions = { const defaultAddEnvOptions: AddEnvOptions = {
@ -30,8 +30,10 @@ const defaultAddEnvOptions: AddEnvOptions = {
export async function addEnv( export async function addEnv(
name: string, name: string,
valGiven: string | undefined, valGiven: string | undefined,
options: AddEnvOptions = defaultAddEnvOptions, givenOptions: Partial<AddEnvOptions> = defaultAddEnvOptions,
) { ) {
const options = { ...defaultAddEnvOptions, ...givenOptions }
const val = escapeString(valGiven ?? "", options.shouldEscapeSpace) const val = escapeString(valGiven ?? "", options.shouldEscapeSpace)
try { try {
if (GITHUB_ACTIONS) { if (GITHUB_ACTIONS) {
@ -119,12 +121,12 @@ async function addEnvSystem(name: string, valGiven: string | undefined, options:
} }
case "linux": case "linux":
case "darwin": { case "darwin": {
await setupCppInProfile() await sourceCpprc()
if (options.shouldAddOnlyIfNotDefined) { if (options.shouldAddOnlyIfNotDefined) {
appendFileSync(cpprc_path, `\nif [ -z "\${${name}}" ]; then export ${name}="${val}"; fi\n`) await appendFile(cpprc_path, `\nif [ -z "\${${name}}" ]; then export ${name}="${val}"; fi\n`)
info(`if not defined ${name} then ${name}="${val}" was added to "${cpprc_path}`) info(`if not defined ${name} then ${name}="${val}" was added to "${cpprc_path}`)
} else { } else {
appendFileSync(cpprc_path, `\nexport ${name}="${val}"\n`) await appendFile(cpprc_path, `\nexport ${name}="${val}"\n`)
info(`${name}="${val}" was added to "${cpprc_path}`) info(`${name}="${val}" was added to "${cpprc_path}`)
} }
return return
@ -148,8 +150,8 @@ async function addPathSystem(path: string) {
} }
case "linux": case "linux":
case "darwin": { case "darwin": {
await setupCppInProfile() await sourceCpprc()
appendFileSync(cpprc_path, `\nexport PATH="${path}:$PATH"\n`) await appendFile(cpprc_path, `\nexport PATH="${path}:$PATH"\n`)
info(`"${path}" was added to "${cpprc_path}"`) info(`"${path}" was added to "${cpprc_path}"`)
return return
} }
@ -163,40 +165,20 @@ async function addPathSystem(path: string) {
let setupCppInProfile_called = false let setupCppInProfile_called = false
/// handles adding conditions to source .cpprc file from .bashrc and .profile /// handles adding conditions to source .cpprc file from .bashrc and .profile
export async function setupCppInProfile() { export async function sourceCpprc() {
if (setupCppInProfile_called) { if (setupCppInProfile_called) {
return return
} }
// a variable that prevents source_cpprc from being called from .bashrc and .profile
const source_cpprc_str = "# Automatically Generated by setup-cpp\nexport SOURCE_CPPRC=0"
if (await pathExists(cpprc_path)) {
const cpprc_content = readFileSync(cpprc_path, "utf8")
if (cpprc_content.includes(source_cpprc_str)) {
// already executed setupCppInProfile
return
}
}
appendFileSync(cpprc_path, `\n${source_cpprc_str}\n`)
info(`Added ${source_cpprc_str} to ${cpprc_path}`)
// source cpprc in bashrc/profile
const source_cpprc_string = const source_cpprc_string =
`\n# source .cpprc if SOURCE_CPPRC is not set to 0\nif [[ "$SOURCE_CPPRC" != 0 && -f "${cpprc_path}" ]]; then source "${cpprc_path}"; fi\n` `\n# source .cpprc if SOURCE_CPPRC is not set to 0\nif [[ "$SOURCE_CPPRC" != 0 && -f "${cpprc_path}" ]]; then source "${cpprc_path}"; fi\n`
try { try {
// source cpprc in .profile await Promise.all([
const profile_path = untildifyUser("~/.profile") addCpprcHeader(),
appendFileSync(profile_path, source_cpprc_string) sourceCpprcInProfile(source_cpprc_string),
info(`${source_cpprc_string} was added to ${profile_path}`) sourceCpprcInBashrc(source_cpprc_string),
])
// source cpprc in .bashrc too
const bashrc_path = untildifyUser("~/.bashrc")
appendFileSync(bashrc_path, source_cpprc_string)
info(`${source_cpprc_string} was added to ${bashrc_path}`)
} catch (err) { } catch (err) {
warning(`Failed to add ${source_cpprc_string} to .profile or .bashrc. You should add it manually: ${err}`) warning(`Failed to add ${source_cpprc_string} to .profile or .bashrc. You should add it manually: ${err}`)
} }
@ -204,13 +186,49 @@ export async function setupCppInProfile() {
setupCppInProfile_called = true setupCppInProfile_called = true
} }
async function addCpprcHeader() {
// a variable that prevents source_cpprc from being called from .bashrc and .profile
const cpprc_header = "# Automatically Generated by setup-cpp\nexport SOURCE_CPPRC=0"
if (await pathExists(cpprc_path)) {
const cpprc_content = await readFile(cpprc_path, "utf8")
if (!cpprc_content.includes(cpprc_header)) {
// already executed setupCppInProfile
await appendFile(cpprc_path, `\n${cpprc_header}\n`)
info(`Added ${cpprc_header} to ${cpprc_path}`)
}
}
}
async function sourceCpprcInBashrc(source_cpprc_string: string) {
const bashrc_path = untildifyUser("~/.bashrc")
if (await pathExists(bashrc_path)) {
const bashrcContent = await readFile(bashrc_path, "utf-8")
if (!bashrcContent.includes(source_cpprc_string)) {
await appendFile(bashrc_path, source_cpprc_string)
info(`${source_cpprc_string} was added to ${bashrc_path}`)
}
}
}
async function sourceCpprcInProfile(source_cpprc_string: string) {
const profile_path = untildifyUser("~/.profile")
if (await pathExists(profile_path)) {
const profileContent = await readFile(profile_path, "utf-8")
if (!profileContent.includes(source_cpprc_string)) {
await appendFile(profile_path, source_cpprc_string)
info(`${source_cpprc_string} was added to ${profile_path}`)
}
}
}
export async function finalizeCpprc() { export async function finalizeCpprc() {
if (await pathExists(cpprc_path)) { if (await pathExists(cpprc_path)) {
const entries = readFileSync(cpprc_path, "utf-8").split("\n") const entries = (await readFile(cpprc_path, "utf-8")).split("\n")
const unique_entries = [...new Set(entries.reverse())].reverse() // remove duplicates, keeping the latest entry const unique_entries = [...new Set(entries.reverse())].reverse() // remove duplicates, keeping the latest entry
writeFileSync(cpprc_path, unique_entries.join("\n")) await writeFile(cpprc_path, unique_entries.join("\n"))
await grantUserWriteAccess(cpprc_path) await grantUserWriteAccess(cpprc_path)
} }

View File

@ -2,7 +2,7 @@ import { execRoot, execRootSync } from "admina"
import { GITHUB_ACTIONS } from "ci-info" import { GITHUB_ACTIONS } from "ci-info"
import { promises as fsPromises } from "fs" import { promises as fsPromises } from "fs"
import { pathExists } from "path-exists" import { pathExists } from "path-exists"
import { addEnv, cpprc_path, setupCppInProfile } from "../env/addEnv" import { addEnv, cpprc_path, sourceCpprc } from "../env/addEnv"
import { InstallationInfo } from "./setupBin" import { InstallationInfo } from "./setupBin"
const { appendFile } = fsPromises const { appendFile } = fsPromises
import { info, warning } from "ci-log" import { info, warning } from "ci-log"
@ -223,7 +223,7 @@ export async function updateAptAlternatives(name: string, path: string, priority
if (GITHUB_ACTIONS) { if (GITHUB_ACTIONS) {
return execRoot("update-alternatives", ["--install", `/usr/bin/${name}`, name, path, priority.toString()]) return execRoot("update-alternatives", ["--install", `/usr/bin/${name}`, name, path, priority.toString()])
} else { } else {
await setupCppInProfile() await sourceCpprc()
return appendFile( return appendFile(
cpprc_path, cpprc_path,
`\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`,