154 lines
4.1 KiB
CoffeeScript
154 lines
4.1 KiB
CoffeeScript
# TODO: revisit those patterns
|
||
FOLDS = [
|
||
Em.Object.create(name: 'schema', startPattern: /^\$ (?:bundle exec )?rake( db:create)? db:schema:load/, endPattern: /^(<\/span>)?\$/)
|
||
Em.Object.create(name: 'migrate', startPattern: /^\$ (?:bundle exec )?rake( db:create)? db:migrate/, endPattern: /^(<\/span>)?\$/)
|
||
Em.Object.create(name: 'bundle', startPattern: /^\$ bundle install/, endPattern: /^(<\/span>)?\$/)
|
||
]
|
||
|
||
@Travis.OrderedLog = Em.Object.extend
|
||
linesLimit: 5000
|
||
init: ->
|
||
@set 'folds', []
|
||
@set 'line', 1
|
||
@set 'lineNumber', 1
|
||
@initial = true
|
||
|
||
for fold in FOLDS
|
||
@addFold fold
|
||
|
||
append: (lines) ->
|
||
return unless lines
|
||
return if @get('lineNumber') > @get('linesLimit')
|
||
|
||
log = @join lines
|
||
log = @escape log
|
||
log = @deansi log
|
||
lines = @split log
|
||
|
||
target = @get 'target'
|
||
index = 0
|
||
currentFold = @currentFold
|
||
|
||
result = []
|
||
|
||
for line in lines
|
||
if line == '\r'
|
||
@set 'replace', true
|
||
else if line == '\n'
|
||
@set 'newline', true
|
||
index += 1
|
||
else
|
||
if currentFold && ( @isFoldEnding(currentFold, line) )
|
||
# end of the fold, send fold to target
|
||
if result.length > 0
|
||
result.slice(-1)[0].foldEnd = true
|
||
target.appendLog result
|
||
|
||
@currentFold = currentFold = null
|
||
@set 'foldContinuation', false
|
||
result = []
|
||
|
||
if !currentFold && ( currentFold = @foldByStart(line) )
|
||
# beginning new fold, send current lines to target
|
||
if result.length > 0
|
||
target.appendLog result
|
||
|
||
result = []
|
||
start = index
|
||
|
||
payload = { content: line }
|
||
|
||
if currentFold
|
||
payload.fold = currentFold.get('name')
|
||
|
||
if @get 'foldContinuation'
|
||
payload.foldContinuation = true
|
||
|
||
payload.number = @get('lineNumber') + index
|
||
|
||
if @get 'replace'
|
||
@set 'replace', false
|
||
payload.replace = true
|
||
else if @get 'newline'
|
||
@set 'newline', false
|
||
else if !@initial
|
||
payload.append = true
|
||
|
||
@initial = false
|
||
|
||
if payload.foldContinuation && payload.content.match(/Done. Build script exited|Your build has been stopped/)
|
||
# script ended, but fold is still closed, which most probably means
|
||
# error, end the fold and open it.
|
||
# TODO: we need log marks to make it easier
|
||
payload.foldContinuation = null
|
||
payload.openFold = payload.fold
|
||
payload.fold = null
|
||
|
||
result.pushObject payload
|
||
|
||
if currentFold
|
||
@set 'foldContinuation', true
|
||
|
||
if @get('lineNumber') + index >= @get('linesLimit')
|
||
result.pushObject logWasCut: true
|
||
break
|
||
|
||
if result.length > 0
|
||
if currentFold
|
||
@currentFold = currentFold
|
||
|
||
target.appendLog result
|
||
|
||
nextLineNumber = @get('lineNumber') + index
|
||
@set 'lineNumber', nextLineNumber
|
||
|
||
join: (lines) ->
|
||
if typeof lines == 'string'
|
||
lines
|
||
else
|
||
lines.toArray().join ''
|
||
|
||
split: (log) ->
|
||
log = log.replace /\r\n/g, '\n'
|
||
lines = log.split(/(\n)/)
|
||
|
||
if lines.slice(-1)[0] == ''
|
||
lines.popObject()
|
||
|
||
result = []
|
||
for line in lines
|
||
result.pushObjects line.split(/(\r)/)
|
||
|
||
result
|
||
|
||
escape: (log) ->
|
||
Handlebars.Utils.escapeExpression log
|
||
|
||
deansi: (log) ->
|
||
log = log.replace(/\r\r/g, '\r')
|
||
.replace(/\033\[K\r/g, '\r')
|
||
.replace(/\[2K/g, '')
|
||
.replace(/\033\(B/g, '')
|
||
.replace(/\033\[\d+G/g, '')
|
||
|
||
ansi = ansiparse(log)
|
||
|
||
text = ''
|
||
ansi.forEach (part) ->
|
||
classes = []
|
||
part.foreground and classes.push(part.foreground)
|
||
part.background and classes.push('bg-' + part.background)
|
||
part.bold and classes.push('bold')
|
||
part.italic and classes.push('italic')
|
||
text += (if classes.length then ('<span class=\'' + classes.join(' ') + '\'>' + part.text + '</span>') else part.text)
|
||
text.replace /\033/g, ''
|
||
|
||
addFold: (fold) ->
|
||
@get('folds').pushObject fold
|
||
|
||
foldByStart: (line) ->
|
||
@get('folds').find (fold) -> line.match(fold.get('startPattern'))
|
||
|
||
isFoldEnding: (fold, line) ->
|
||
line.match(fold.get('endPattern'))
|