dev-sidecar/packages/core/src/shell/shell.js

127 lines
2.8 KiB
JavaScript

const util = require('util')
const os = require('os')
const childProcess = require('child_process')
const _exec = childProcess.exec
const exec = util.promisify(_exec)
const PowerShell = require('node-powershell')
class SystemShell {
static async exec (cmds, args) {
throw new Error('You have to implement the method exec!')
}
}
class LinuxSystemShell extends SystemShell {
static async exec (cmds) {
if (cmds instanceof String) {
cmds = [cmds]
}
for (const cmd of cmds) {
await exec(cmd)
}
}
}
class DarwinSystemShell extends SystemShell {
static async exec (cmds) {
if (cmds instanceof String) {
cmds = [cmds]
}
for (const cmd of cmds) {
await exec(cmd)
}
}
}
class WindowsSystemShell extends SystemShell {
static async exec (cmds, args = { }) {
let { type } = args
type = type || 'ps'
if (typeof cmds === 'string') {
cmds = [cmds]
}
if (type === 'ps') {
const ps = new PowerShell({
executionPolicy: 'Bypass',
noProfile: true
})
for (const cmd of cmds) {
ps.addCommand(cmd)
}
try {
const ret = await ps.invoke()
// console.log('ps complete', cmds)
return ret
} finally {
ps.dispose()
}
} else {
let compose = 'chcp 65001 '
for (const cmd of cmds) {
compose += ' && ' + cmd
}
// compose += '&& exit'
const ret = await childExec(compose)
// console.log('cmd complete:', compose)
return ret
}
}
}
function childExec (composeCmds) {
return new Promise((resolve, reject) => {
const childProcess = require('child_process')
childProcess.exec(composeCmds, function (error, stdout, stderr) {
if (error) {
console.error('cmd 命令执行错误:', composeCmds, error, stderr)
reject(error)
} else {
// console.log('cmd 命令完成:', stdout)
resolve(stdout)
}
// console.log('关闭 cmd')
// ps.kill('SIGINT')
})
})
}
function getSystemShell () {
switch (getSystemPlatform()) {
case 'mac':
return DarwinSystemShell
case 'linux':
return LinuxSystemShell
case 'windows':
return WindowsSystemShell
case 'unknown os':
default:
throw new Error(`UNKNOWN OS TYPE ${os.platform()}`)
}
}
function getSystemPlatform () {
switch (os.platform()) {
case 'darwin':
return 'mac'
case 'linux':
return 'linux'
case 'win32':
case 'win64':
return 'windows'
case 'unknown os':
default:
throw new Error(`UNKNOWN OS TYPE ${os.platform()}`)
}
}
async function execute (executor, args) {
return executor[getSystemPlatform()](getSystemShell().exec, args)
}
module.exports = {
getSystemShell,
getSystemPlatform,
execute
}