mirror of
https://github.com/balena-io/balena-cli.git
synced 2024-12-24 07:46:39 +00:00
Improve handling of build log output
This makes sure build logs don’t leak escape sequences and new lines and they don’t break the output. Also improved “inline” logs by normalising the stream before passing it to “transpose build stream”. Fixes: #808 Change-Type: patch
This commit is contained in:
parent
e5fb954645
commit
1833f6ff0a
@ -144,6 +144,7 @@ exports.buildProject = (
|
|||||||
) ->
|
) ->
|
||||||
_ = require('lodash')
|
_ = require('lodash')
|
||||||
humanize = require('humanize')
|
humanize = require('humanize')
|
||||||
|
split = require('split')
|
||||||
compose = require('resin-compose-parse')
|
compose = require('resin-compose-parse')
|
||||||
builder = require('resin-multibuild')
|
builder = require('resin-multibuild')
|
||||||
transpose = require('docker-qemu-transpose')
|
transpose = require('docker-qemu-transpose')
|
||||||
@ -225,6 +226,7 @@ exports.buildProject = (
|
|||||||
task.progressHook = pullProgressAdapter(captureStream)
|
task.progressHook = pullProgressAdapter(captureStream)
|
||||||
else
|
else
|
||||||
task.streamHook = (stream) ->
|
task.streamHook = (stream) ->
|
||||||
|
stream = createLogStream(stream)
|
||||||
if qemuPath?
|
if qemuPath?
|
||||||
buildThroughStream = transpose.getBuildThroughStream
|
buildThroughStream = transpose.getBuildThroughStream
|
||||||
hostQemuPath: toPosixPath(qemuPath)
|
hostQemuPath: toPosixPath(qemuPath)
|
||||||
@ -236,6 +238,7 @@ exports.buildProject = (
|
|||||||
# where we're given objects. capture these strings as they come
|
# where we're given objects. capture these strings as they come
|
||||||
# before we parse them.
|
# before we parse them.
|
||||||
rawStream
|
rawStream
|
||||||
|
.pipe(dropEmptyLinesStream())
|
||||||
.pipe(captureStream)
|
.pipe(captureStream)
|
||||||
.pipe(buildProgressAdapter(inlineLogs))
|
.pipe(buildProgressAdapter(inlineLogs))
|
||||||
.pipe(task.logStream)
|
.pipe(task.logStream)
|
||||||
@ -440,13 +443,22 @@ pushProgressRenderer = (tty, prefix) ->
|
|||||||
tty.clearLine()
|
tty.clearLine()
|
||||||
return fn
|
return fn
|
||||||
|
|
||||||
|
createLogStream = (input) ->
|
||||||
|
split = require('split')
|
||||||
|
stripAnsi = require('strip-ansi-stream')
|
||||||
|
return input.pipe(stripAnsi()).pipe(split())
|
||||||
|
|
||||||
|
dropEmptyLinesStream = ->
|
||||||
|
through = require('through2')
|
||||||
|
through (data, enc, cb) ->
|
||||||
|
str = data.toString('utf-8')
|
||||||
|
@push(str) if str.trim()
|
||||||
|
cb()
|
||||||
|
|
||||||
buildLogCapture = (objectMode, buffer) ->
|
buildLogCapture = (objectMode, buffer) ->
|
||||||
_ = require('lodash')
|
|
||||||
through = require('through2')
|
through = require('through2')
|
||||||
|
|
||||||
through { objectMode }, (data, enc, cb) ->
|
through { objectMode }, (data, enc, cb) ->
|
||||||
return cb(null, data) if not data?
|
|
||||||
|
|
||||||
# data from pull stream
|
# data from pull stream
|
||||||
if data.error
|
if data.error
|
||||||
buffer.push("#{data.error}")
|
buffer.push("#{data.error}")
|
||||||
@ -457,30 +469,14 @@ buildLogCapture = (objectMode, buffer) ->
|
|||||||
|
|
||||||
# data from build stream
|
# data from build stream
|
||||||
else
|
else
|
||||||
# normalise build log output here. it is somewhat ugly
|
buffer.push(data)
|
||||||
# that this supposedly "passthrough" stream mutates the
|
|
||||||
# values before forwarding them, but it's convenient
|
|
||||||
# as it allows to both forward and save normalised logs
|
|
||||||
|
|
||||||
# convert to string, split to lines, trim each one and
|
|
||||||
# filter out empty ones.
|
|
||||||
lines = _(data.toString('utf-8').split(/\r?\n$/))
|
|
||||||
.map(_.trimEnd)
|
|
||||||
.reject(_.isEmpty)
|
|
||||||
|
|
||||||
# forward each line separately
|
|
||||||
lines.forEach (line) =>
|
|
||||||
buffer.push(line)
|
|
||||||
@push(line)
|
|
||||||
|
|
||||||
return cb()
|
|
||||||
|
|
||||||
cb(null, data)
|
cb(null, data)
|
||||||
|
|
||||||
buildProgressAdapter = (inline) ->
|
buildProgressAdapter = (inline) ->
|
||||||
through = require('through2')
|
through = require('through2')
|
||||||
|
|
||||||
stepRegex = /^\s*Step\s+(\d+)\/(\d+)\s*:\s+(.+)$/
|
stepRegex = /^\s*Step\s+(\d+)\/(\d+)\s*: (.+)$/
|
||||||
|
|
||||||
[ step, numSteps, progress ] = [ null, null, undefined ]
|
[ step, numSteps, progress ] = [ null, null, undefined ]
|
||||||
|
|
||||||
@ -495,7 +491,7 @@ buildProgressAdapter = (inline) ->
|
|||||||
else
|
else
|
||||||
if (match = stepRegex.exec(str))
|
if (match = stepRegex.exec(str))
|
||||||
step = match[1]
|
step = match[1]
|
||||||
numSteps = match[2]
|
numSteps ?= match[2]
|
||||||
str = match[3]
|
str = match[3]
|
||||||
if step?
|
if step?
|
||||||
str = "Step #{step}/#{numSteps}: #{str}"
|
str = "Step #{step}/#{numSteps}: #{str}"
|
||||||
|
@ -148,8 +148,10 @@
|
|||||||
"rimraf": "^2.4.3",
|
"rimraf": "^2.4.3",
|
||||||
"rindle": "^1.0.0",
|
"rindle": "^1.0.0",
|
||||||
"semver": "^5.3.0",
|
"semver": "^5.3.0",
|
||||||
|
"split": "^1.0.1",
|
||||||
"stream-to-promise": "^2.2.0",
|
"stream-to-promise": "^2.2.0",
|
||||||
"string-width": "^2.1.1",
|
"string-width": "^2.1.1",
|
||||||
|
"strip-ansi-stream": "^1.0.0",
|
||||||
"through2": "^2.0.3",
|
"through2": "^2.0.3",
|
||||||
"tmp": "0.0.31",
|
"tmp": "0.0.31",
|
||||||
"umount": "^1.1.6",
|
"umount": "^1.1.6",
|
||||||
|
Loading…
Reference in New Issue
Block a user