fix: parallelize updating rc files

This commit is contained in:
Amin Yahyaabadi 2024-04-03 00:36:48 -07:00
parent a4e6fc40b5
commit 183707949f
9 changed files with 137 additions and 98 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,7 +5,7 @@ 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, readFile, 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"
@ -121,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
@ -150,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
} }
@ -165,48 +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
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(),
if (await pathExists(profile_path)) { sourceCpprcInProfile(source_cpprc_string),
const profileContent = readFileSync(profile_path, "utf-8") sourceCpprcInBashrc(source_cpprc_string),
if (!profileContent.includes(source_cpprc_string)) { ])
appendFileSync(profile_path, source_cpprc_string)
info(`${source_cpprc_string} was added to ${profile_path}`)
}
}
// source cpprc in .bashrc too
const bashrc_path = untildifyUser("~/.bashrc")
if (await pathExists(bashrc_path)) {
const bashrcContent = readFileSync(bashrc_path, "utf-8")
if (!bashrcContent.includes(source_cpprc_string)) {
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}`)
} }
@ -214,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`,