Skip to content
New issue

Have a question about this project? Sign up for a free GitHub account to open an issue and contact its maintainers and the community.

By clicking “Sign up for GitHub”, you agree to our terms of service and privacy statement. We’ll occasionally send you account related emails.

Already on GitHub? Sign in to your account

gyp: send spawned output to logger #1984

Open
wants to merge 1 commit into
base: main
Choose a base branch
from
Open
Show file tree
Hide file tree
Changes from all commits
Commits
File filter

Filter by extension

Filter by extension


Conversations
Failed to load comments.
Jump to
Jump to file
Failed to load files.
Diff view
Diff view
13 changes: 11 additions & 2 deletions lib/node-gyp.js
Expand Up @@ -3,6 +3,7 @@
const path = require('path')
const nopt = require('nopt')
const log = require('npmlog')
const split = require('split2')
const childProcess = require('child_process')
const EE = require('events').EventEmitter
const inherits = require('util').inherits
Expand Down Expand Up @@ -166,10 +167,18 @@ proto.spawn = function spawn (command, args, opts) {
if (!opts) {
opts = {}
}

var cp = childProcess.spawn(command, args, opts)

if (!opts.silent && !opts.stdio) {
opts.stdio = [0, 1, 2]
cp.stdout.pipe(split()).on('data', function (line) {
Copy link
Member

Choose a reason for hiding this comment

The reason will be displayed to describe this comment to others. Learn more.

This is probably OK but it's nice to make a habit of avoiding using 'data' events so you can set up proper backpressure (not really a requirement here because npmlog doesn't give us a mechanism for it), usually done by implementing a custom stream.

maybe something like this

const { Transform } = require('stream')

...

function outLogger (prefix, log) {
  return new Transform({
    transform: (chunk, enc, callback) {
      log(prefix, chunk.toString())
      callback()
    }
  })
}

cp.stdout.pipe(split()).pipe(outLogger('spawn stdout', log.notice)) // does it need to be `log.notice.bind(log)`?
cp.stderr.pipe(split()).pipe(outLogger('spawn stderr', log.error))

Copy link
Author

Choose a reason for hiding this comment

The reason will be displayed to describe this comment to others. Learn more.

Hmmm. I was wondering why you were suggesting this route in the original issue. I hadn't heard of a reason to not just use the data event. I didn't see an advantage to using a Transform stream but makes sense.

To be clear, this is the data event from split() and not from stdout/stderr.

I wonder if there are any possible improvements from using a Writable stream instead of a Transform since there is no data coming out of the logger (as far as the stream api is concerned).

Copy link
Contributor

Choose a reason for hiding this comment

The reason will be displayed to describe this comment to others. Learn more.

One problem that I see with this is that the subprocess loses the "TTY-ness" which many programs use to determine whether or not to out put output colors to the terminal.

Copy link
Author

Choose a reason for hiding this comment

The reason will be displayed to describe this comment to others. Learn more.

@TooTallNate This seems like a reason to add an "opt-in" option.

log.notice('spawn stdout', line)
})
cp.stderr.pipe(split()).on('data', function (line) {
log.error('spawn stderr', line)
})
}
var cp = childProcess.spawn(command, args, opts)

log.info('spawn', command)
log.info('spawn args', args)
return cp
Expand Down
1 change: 1 addition & 0 deletions package.json
Expand Up @@ -31,6 +31,7 @@
"request": "^2.88.0",
"rimraf": "^2.6.3",
"semver": "^5.7.1",
"split2": "^3.1.1",
"tar": "^4.4.12",
"which": "^1.3.1"
},
Expand Down