setup-cpp/packages/root-tools/src/index.ts

61 lines
1.9 KiB
TypeScript
Raw Normal View History

2022-08-08 08:18:49 +08:00
import which from "which"
import execa from "execa"
2022-08-08 08:31:14 +08:00
/** Detect if sudo is available and the user has root privileges */
export function isSudo(): boolean {
return (Boolean(process.env.CI) || isRoot()) && which.sync("sudo", { nothrow: true }) !== null
2022-08-08 08:18:49 +08:00
}
/** Detect if the process has root privileges */
export function isRoot(): boolean {
return process.getuid?.() === 0
}
2022-08-08 08:18:49 +08:00
/** Prepend `sudo` to the command if sudo is available */
export function prependSudo(command: string) {
if (isSudo()) {
2022-08-08 08:18:49 +08:00
return `sudo ${command}`
}
return command
}
/**
* Execute a command as root if sudo is available. Otherwise executes the command normally without sudo.
2022-08-08 08:18:49 +08:00
*
2022-08-08 08:24:44 +08:00
* @param program The program to spawn
2022-08-08 08:18:49 +08:00
* @param args The command arguments
2022-08-08 09:52:03 +08:00
* @param execOptions The options passed to `execa`. Defaults to `{ stdio: "inherit", shell: true }`
* @returns The execution result
2022-08-08 08:18:49 +08:00
*/
2022-08-08 08:33:11 +08:00
export function execRootSync(
program: string,
args: string[] = [],
2022-08-08 09:52:03 +08:00
execOptions: execa.SyncOptions = { stdio: "inherit", shell: true }
): execa.ExecaSyncReturnValue<string> {
if (isSudo()) {
2022-08-08 08:24:44 +08:00
return execa.commandSync(`sudo ${[program, ...args].map((arg) => `'${arg}'`).join(" ")}`, execOptions)
2022-08-08 08:18:49 +08:00
} else {
2022-08-08 08:24:44 +08:00
return execa.sync(program, args, execOptions)
2022-08-08 08:18:49 +08:00
}
}
2022-08-08 08:34:40 +08:00
/**
* Asynchronously execute a command as root if sudo is available. Otherwise executes the command normally without sudo.
*
* @param program The program to spawn
* @param args The command arguments
2022-08-08 09:52:03 +08:00
* @param execOptions The options passed to `execa`. Defaults to `{ stdio: "inherit", shell: true }`
* @returns A promise to the execution result
2022-08-08 08:34:40 +08:00
*/
export function execRoot(
program: string,
args: string[] = [],
2022-08-08 09:52:03 +08:00
execOptions: execa.Options = { stdio: "inherit", shell: true }
): execa.ExecaChildProcess<string> {
2022-08-08 08:34:40 +08:00
if (isSudo()) {
return execa.command(`sudo ${[program, ...args].map((arg) => `'${arg}'`).join(" ")}`, execOptions)
} else {
return execa(program, args, execOptions)
}
}