mirror of https://github.com/atom/atom.git
122 lines
2.8 KiB
JavaScript
122 lines
2.8 KiB
JavaScript
const fs = require('fs')
|
|
const childProcess = require('child_process')
|
|
|
|
const ENVIRONMENT_VARIABLES_TO_PRESERVE = new Set([
|
|
'NODE_ENV',
|
|
'NODE_PATH',
|
|
'ATOM_HOME',
|
|
'ATOM_DISABLE_SHELLING_OUT_FOR_ENVIRONMENT'
|
|
])
|
|
|
|
const PLATFORMS_KNOWN_TO_WORK = new Set([
|
|
'darwin',
|
|
'linux'
|
|
])
|
|
|
|
async function updateProcessEnv (launchEnv) {
|
|
let envToAssign
|
|
if (launchEnv) {
|
|
if (shouldGetEnvFromShell(launchEnv)) {
|
|
envToAssign = await getEnvFromShell(launchEnv)
|
|
} else if (launchEnv.PWD) {
|
|
envToAssign = launchEnv
|
|
}
|
|
}
|
|
|
|
if (envToAssign) {
|
|
for (let key in process.env) {
|
|
if (!ENVIRONMENT_VARIABLES_TO_PRESERVE.has(key)) {
|
|
delete process.env[key]
|
|
}
|
|
}
|
|
|
|
for (let key in envToAssign) {
|
|
if (!ENVIRONMENT_VARIABLES_TO_PRESERVE.has(key) || (!process.env[key] && envToAssign[key])) {
|
|
process.env[key] = envToAssign[key]
|
|
}
|
|
}
|
|
|
|
if (envToAssign.ATOM_HOME && fs.existsSync(envToAssign.ATOM_HOME)) {
|
|
process.env.ATOM_HOME = envToAssign.ATOM_HOME
|
|
}
|
|
}
|
|
}
|
|
|
|
function shouldGetEnvFromShell (env) {
|
|
if (!PLATFORMS_KNOWN_TO_WORK.has(process.platform)) {
|
|
return false
|
|
}
|
|
|
|
if (!env || !env.SHELL || env.SHELL.trim() === '') {
|
|
return false
|
|
}
|
|
|
|
if (env.ATOM_DISABLE_SHELLING_OUT_FOR_ENVIRONMENT || process.env.ATOM_DISABLE_SHELLING_OUT_FOR_ENVIRONMENT) {
|
|
return false
|
|
}
|
|
|
|
return true
|
|
}
|
|
|
|
async function getEnvFromShell (env) {
|
|
let {stdout, error} = await new Promise((resolve) => {
|
|
let child
|
|
let error
|
|
let stdout = ''
|
|
let done = false
|
|
const cleanup = () => {
|
|
if (!done && child) {
|
|
child.kill()
|
|
done = true
|
|
}
|
|
}
|
|
process.once('exit', cleanup)
|
|
setTimeout(() => {
|
|
cleanup()
|
|
}, 5000)
|
|
child = childProcess.spawn(env.SHELL, ['-ilc', 'command env'], {encoding: 'utf8', detached: true, stdio: ['ignore', 'pipe', process.stderr]})
|
|
const buffers = []
|
|
child.on('error', (e) => {
|
|
done = true
|
|
error = e
|
|
})
|
|
child.stdout.on('data', (data) => {
|
|
buffers.push(data)
|
|
})
|
|
child.on('close', (code, signal) => {
|
|
done = true
|
|
process.removeListener('exit', cleanup)
|
|
if (buffers.length) {
|
|
stdout = Buffer.concat(buffers).toString('utf8')
|
|
}
|
|
|
|
resolve({stdout, error})
|
|
})
|
|
})
|
|
|
|
if (error) {
|
|
if (error.handle) {
|
|
error.handle()
|
|
}
|
|
console.log('warning: ' + env.SHELL + ' -ilc "command env" failed with signal (' + error.signal + ')')
|
|
console.log(error)
|
|
}
|
|
|
|
if (!stdout || stdout.trim() === '') {
|
|
return null
|
|
}
|
|
|
|
let result = {}
|
|
for (let line of stdout.split('\n')) {
|
|
if (line.includes('=')) {
|
|
let components = line.split('=')
|
|
let key = components.shift()
|
|
let value = components.join('=')
|
|
result[key] = value
|
|
}
|
|
}
|
|
return result
|
|
}
|
|
|
|
module.exports = {updateProcessEnv, shouldGetEnvFromShell}
|