Can't spawn `gcloud app deploy` from a Node.js script on Windows
Asked Answered
F

1

8

I'm building an Electron application (Node.js) which needs to spawn gcloud app deploy from the application with realtime feedback (stdin/stdout/stderr).

I rapidly switched from child_process to execa because I had some issues on Mac OS X with the child_process buffer which is limited to 200kb (and gcloud app deploy sends some big chunk of string > 200kb which crash the command).

Now, with execa everything seems to work normally on OSX but not on Windows.

The code looks something like this:

let bin = `gcloud${/^win/.test(process.platform) ? '.cmd' : ''}`

//which: https://github.com/npm/node-which
which(bin, (err, fullpath) => {
  let proc = execa(fullpath, ['app', 'deploy'], {
    cwd: appPath
  })
  proc.stdout.on('data', data => {
    parseDeploy(data.toString())
  })
  proc.stderr.on('data', data => {
    parseDeploy(data.toString())
  })
  proc.then(() => {
    ...
  }).catch(e => {
    ...
  })
})

This code works perfectly on Mac OS X while I haven't the same result on Windows

I have tried lots of thing:

  • execa()
  • execa.shell()
  • options shell:true
  • I tried maxBuffer to 1GB (just in case)
  • It works with detached:true BUT I can't read stdout / stderr in realtime in the application as it prompts a new cmd.exe without interaction with the Node.js application
  • Lots of child_process variant.

I have made a GIST to show the responses I get for some tests I have done on Windows with basic Child Process scripts: https://gist.github.com/thyb/9b53b65c25cd964bbe962d8a9754e31f

I also opened an issue on execa repository: https://github.com/sindresorhus/execa/issues/97

Does someone already got this issue ? I've searched around and found nothing promising except this reddit thread which doesn't solve this issue.

Fluky answered 29/6, 2017 at 8:42 Comment(0)
F
1

Behind the scene, gcloud.cmd is running a python script. After reading tons of Node.js issue with ChildProcess / Python and Windows, I fell on this thread: https://github.com/nodejs/node-v0.x-archive/issues/8298

There is some known issue about running Python scripts from a Node.js Child Process. They talk in this comment about an unbuffered option for python. After updating the shell script in gcloud.cmd by adding the -u option, I noticed everything was working as expected

This comment explains how to set this option as an environment variable (to not modify the windows shell script directly): https://docs.python.org/2/using/cmdline.html#envvar-PYTHONUNBUFFERED

So adding PYTHONUNBUFFERED to the environment variable fix this issue !

execa(fullpath, ['app', 'deploy'], {
  cwd: appPath,
  env: Object.assign({}, process.env, {
    PYTHONUNBUFFERED: true
  })
})
Fluky answered 8/7, 2017 at 2:33 Comment(0)

© 2022 - 2024 — McMap. All rights reserved.