UNPKG

@jjeem/detect-shell

Version:

detect shells available on the system

110 lines 4.23 kB
"use strict"; var __importDefault = (this && this.__importDefault) || function (mod) { return (mod && mod.__esModule) ? mod : { "default": mod }; }; Object.defineProperty(exports, "__esModule", { value: true }); exports.detectAvailableShells = exports.getWindowsBuildNumber = void 0; const os_1 = __importDefault(require("os")); const pfs_1 = require("./pfs"); const path_1 = require("path"); const powershell_1 = require("./powershell"); const platform = { isWindows: process.platform === 'win32', isMacintosh: process.platform === 'darwin', isLinux: process.platform === 'linux' }; function getWindowsBuildNumber() { const osVersion = /(\d+)\.(\d+)\.(\d+)/g.exec(os_1.default.release()); let buildNumber = 0; if (osVersion && osVersion.length === 4) { buildNumber = parseInt(osVersion[3]); } return buildNumber; } exports.getWindowsBuildNumber = getWindowsBuildNumber; function detectAvailableShells() { return platform.isWindows ? detectAvailableWindowsShells() : detectAvailableUnixShells(); } exports.detectAvailableShells = detectAvailableShells; async function detectAvailableWindowsShells() { const is32ProcessOn64Windows = process.env.hasOwnProperty('PROCESSOR_ARCHITEW6432'); const system32Path = `${process.env['windir']}\\${is32ProcessOn64Windows ? 'Sysnative' : 'System32'}`; let useWSLexe = false; if (getWindowsBuildNumber() >= 16299) { useWSLexe = true; } const expectedLocations = { 'Command Prompt': [`${system32Path}\\cmd.exe`], 'WSL Bash': [`${system32Path}\\${useWSLexe ? 'wsl.exe' : 'bash.exe'}`], 'Git Bash': [ `${process.env['ProgramW6432']}\\Git\\bin\\bash.exe`, `${process.env['ProgramW6432']}\\Git\\usr\\bin\\bash.exe`, `${process.env['ProgramFiles']}\\Git\\bin\\bash.exe`, `${process.env['ProgramFiles']}\\Git\\usr\\bin\\bash.exe`, `${process.env['LocalAppData']}\\Programs\\Git\\bin\\bash.exe` ], Cygwin: [ `${process.env['HOMEDRIVE']}\\cygwin64\\bin\\bash.exe`, `${process.env['HOMEDRIVE']}\\cygwin\\bin\\bash.exe` ], Nushell: [`${process.env['ProgramFiles']}\\nu\\bin\\nu.exe`] }; // console.table(expectedLocations); // Add all of the different kinds of PowerShells for await (const pwshExe of (0, powershell_1.enumeratePowerShellInstallations)()) { expectedLocations[pwshExe.displayName] = [pwshExe.exePath]; } const promises = []; Object.keys(expectedLocations).forEach((key) => promises.push(validateShellPaths(key, expectedLocations[key]))); const shells = await Promise.all(promises); return shells.filter((e) => !!e); } async function detectAvailableUnixShells() { const contents = await (0, pfs_1.readFile)('/etc/shells', 'utf8'); const shells = contents .split('\n') .filter((e) => e.trim().indexOf('#') !== 0 && e.trim().length > 0); return shells.map((e) => { return { label: (0, path_1.basename)(e), path: e }; }); } async function validateShellPaths(label, potentialPaths) { if (potentialPaths.length === 0) { return Promise.resolve(undefined); } const current = potentialPaths.shift(); if (current === '') { return validateShellPaths(label, potentialPaths); } try { const result = await (0, pfs_1.stat)((0, path_1.normalize)(current)); if (result.isFile() || result.isSymbolicLink()) { return { label, path: current }; } } catch (e) { // Also try using lstat as some symbolic links on Windows // throw 'permission denied' using 'stat' but don't throw // using 'lstat' try { const result = await (0, pfs_1.lstat)((0, path_1.normalize)(current)); if (result.isFile() || result.isSymbolicLink()) { return { label, path: current }; } } catch (e) { // noop } } return validateShellPaths(label, potentialPaths); } //# sourceMappingURL=index.js.map