mirror of
https://github.com/atom/atom.git
synced 2026-01-24 14:28:14 -05:00
This ensures the node used by the spawned process is the one bundled with Atom. This should prevent any "env: node: No such file or directory" errors when spawning a node bin script such as nak. Refs #514
72 lines
1.9 KiB
CoffeeScript
72 lines
1.9 KiB
CoffeeScript
ChildProcess = require 'child_process'
|
|
path = require 'path'
|
|
_ = require 'underscore'
|
|
|
|
module.exports =
|
|
class BufferedProcess
|
|
process: null
|
|
killed: false
|
|
|
|
constructor: ({command, args, options, stdout, stderr, exit}={}) ->
|
|
options ?= {}
|
|
@addNodeDirectoryToPath(options)
|
|
@process = ChildProcess.spawn(command, args, options)
|
|
|
|
stdoutClosed = true
|
|
stderrClosed = true
|
|
processExited = true
|
|
exitCode = 0
|
|
triggerExitCallback = ->
|
|
return if @killed
|
|
if stdoutClosed and stderrClosed and processExited
|
|
exit?(exitCode)
|
|
|
|
if stdout
|
|
stdoutClosed = false
|
|
@bufferStream @process.stdout, stdout, ->
|
|
stdoutClosed = true
|
|
triggerExitCallback()
|
|
|
|
if stderr
|
|
stderrClosed = false
|
|
@bufferStream @process.stderr, stderr, ->
|
|
stderrClosed = true
|
|
triggerExitCallback()
|
|
|
|
if exit
|
|
processExited = false
|
|
@process.on 'exit', (code) ->
|
|
exitCode = code
|
|
processExited = true
|
|
triggerExitCallback()
|
|
|
|
addNodeDirectoryToPath: (options) ->
|
|
options.env ?= process.env
|
|
pathSegments = []
|
|
nodeDirectoryPath = path.resolve(process.execPath, '..', '..', '..', '..', 'Resources')
|
|
pathSegments.push(nodeDirectoryPath)
|
|
pathSegments.push(options.env.PATH) if options.env.PATH
|
|
options.env = _.extend({}, options.env, PATH: pathSegments.join(path.delimiter))
|
|
|
|
bufferStream: (stream, onLines, onDone) ->
|
|
stream.setEncoding('utf8')
|
|
buffered = ''
|
|
|
|
stream.on 'data', (data) =>
|
|
return if @killed
|
|
buffered += data
|
|
lastNewlineIndex = buffered.lastIndexOf('\n')
|
|
if lastNewlineIndex isnt -1
|
|
onLines(buffered.substring(0, lastNewlineIndex + 1))
|
|
buffered = buffered.substring(lastNewlineIndex + 1)
|
|
|
|
stream.on 'close', =>
|
|
return if @killed
|
|
onLines(buffered) if buffered.length > 0
|
|
onDone()
|
|
|
|
kill: ->
|
|
@killed = true
|
|
@process.kill()
|
|
@process = null
|