feat: add sudo-tools package

This commit is contained in:
Amin Yahyaabadi 2022-08-07 17:18:49 -07:00
parent 4c866cd807
commit fe2db9dd25
4 changed files with 98 additions and 0 deletions

View File

@ -0,0 +1,39 @@
{
"name": "sudo-tools",
"version": "1.0.0",
"description": "Tools for working with sudo: executing command as sudo if available, detecting root, etc.",
"homepage": "https://github.com/aminya/setup-cpp",
"license": "Apache-2.0",
"author": "Amin Yahyaabadi",
"main": "./dist/index.js",
"module": "./dist/index.mjs",
"source": "./src/index.ts",
"scripts": {
"build": "tsc"
},
"dependencies": {
"execa": "^5.1.1",
"which": "^2.0.2"
},
"devDependencies": {
"@types/which": "^2.0.1"
},
"keywords": [
"sudo",
"root",
"is-root",
"is-sudo",
"exec-sudo",
"exec",
"execa",
"spawn",
"system",
"unix",
"linux",
"github-actions",
"github",
"actions",
"gitlab",
"ci"
]
}

View File

@ -0,0 +1,41 @@
import which from "which"
import execa from "execa"
let isSudoCache: boolean | undefined = undefined
/**
* Detect if sudo is available and the user has root privileges
*
* @note it caches the result for the subsequent calls to this function.
*/
export function isRoot(): boolean {
if (isSudoCache !== undefined) {
return isSudoCache
}
// eslint-disable-next-line @typescript-eslint/strict-boolean-expressions, @typescript-eslint/no-unnecessary-condition
isSudoCache = (Boolean(process.env.CI) || process.getuid?.() === 0) && which.sync("sudo", { nothrow: true }) !== null
return isSudoCache
}
/** Prepend `sudo` to the command if sudo is available */
export function prependSudo(command: string) {
if (isRoot()) {
return `sudo ${command}`
}
return command
}
/**
* Execute a command as sudo if sudo is available. Otherwise executes the command without sudo.
*
* @param file The file to spawn
* @param args The command arguments
* @param execOptions The options passed to `execa`.
*/
export function execSudo(file: string, args: string[], execOptions: execa.SyncOptions = { stdio: "inherit" }) {
if (isRoot()) {
return execa.commandSync(`sudo ${[file, ...args].map((arg) => `'${arg}'`).join(" ")}`, execOptions)
} else {
return execa.sync(file, args, execOptions)
}
}

View File

@ -0,0 +1,7 @@
{
"extends": "../../tsconfig.json",
"compilerOptions": {
"outDir": "./dist"
},
"include": ["./src"]
}

View File

@ -104,6 +104,17 @@ importers:
devDependencies: devDependencies:
'@types/which': 2.0.1 '@types/which': 2.0.1
packages/sudo-tools:
specifiers:
'@types/which': ^2.0.1
execa: ^5.1.1
which: ^2.0.2
dependencies:
execa: 5.1.1
which: 2.0.2
devDependencies:
'@types/which': 2.0.1
packages: packages:
/@actions/cache/3.0.0: /@actions/cache/3.0.0: