Skip to content

Commit

Permalink
Render last tag along with the process name #1144
Browse files Browse the repository at this point in the history
  • Loading branch information
pditommaso committed May 11, 2019
1 parent 622d97d commit 8cf8cc4
Show file tree
Hide file tree
Showing 2 changed files with 85 additions and 9 deletions.
Original file line number Diff line number Diff line change
Expand Up @@ -20,6 +20,7 @@ package nextflow.trace
import groovy.transform.CompileStatic
import groovy.transform.EqualsAndHashCode
import groovy.util.logging.Slf4j
import jline.TerminalFactory
import nextflow.Session
import nextflow.processor.TaskHandler
import nextflow.processor.TaskProcessor
Expand Down Expand Up @@ -54,6 +55,7 @@ class AnsiLogObserver implements TraceObserver {
boolean terminated
String hash
boolean error
String name
}

static class Event {
Expand Down Expand Up @@ -93,7 +95,9 @@ class AnsiLogObserver implements TraceObserver {

private int printedLines

private int maxNameLength
private int labelWidth

private int cols = 80

private long startTimestamp

Expand Down Expand Up @@ -195,8 +199,17 @@ class AnsiLogObserver implements TraceObserver {
return
}

cols = TerminalFactory.get().getWidth()

// calc max width
labelWidth = 0
for( Map.Entry<String,ProcessStats> entry : processes ) {
labelWidth = Math.max(labelWidth, entry.value.name.size())
}

// render line
for( Map.Entry<String,ProcessStats> entry : processes ) {
term.a(line(entry.key,entry.value))
term.a(line(entry.value))
term.newline()
}
rendered = true
Expand Down Expand Up @@ -270,10 +283,26 @@ class AnsiLogObserver implements TraceObserver {
AnsiConsole.out.print(text)
}

protected String line(String name, ProcessStats stats) {
protected String fmtWidth(String name, int width, int cols) {
assert name.size() <= width
// chop the name string if larger than max cols
if( name.size() > cols ) {
return fmtChop(name,cols)
}
// otherwise pad with blanks to the expected width
return name.padRight(Math.min(width,cols))
}

protected String fmtChop(String str, int cols) {
if( str.size() <= cols )
return str
return cols>3 ? str[0..(cols-3-1)] + '...' : str[0..cols-1]
}

protected String line(ProcessStats stats) {
final float tot = stats.submitted +stats.cached +stats.stored
final float com = stats.completed +stats.cached +stats.stored
final label = name.padRight(maxNameLength)
final label = fmtWidth(stats.name, labelWidth, Math.max(cols-50, 5))
final hh = (stats.hash && tot>0 ? stats.hash : '-').padRight(9)

if( tot == 0 )
Expand All @@ -292,16 +321,16 @@ class AnsiLogObserver implements TraceObserver {
result += ", failed: $stats.failed"
if( stats.terminated && tot )
result += stats.error ? ' \u2718' : ' \u2714'
return result
return fmtChop(result, cols)
}


private ProcessStats proc0(String name) {
def result = processes.get(name)
if( !result ) {
result = new ProcessStats()
result.name = name
processes.put(name, result)
maxNameLength = Math.max(maxNameLength, name.size())
}
return result
}
Expand Down Expand Up @@ -341,6 +370,7 @@ class AnsiLogObserver implements TraceObserver {
final process = proc0(handler)
process.submitted++
process.hash = handler.task.hashLog
process.name = handler.task.name
// executor counter
final exec = handler.task.processor.executor.name
Integer count = executors[exec] ?: 0
Expand All @@ -353,6 +383,7 @@ class AnsiLogObserver implements TraceObserver {
final process = proc0(handler)
process.completed++
process.hash = handler.task.hashLog
process.name = handler.task.name
if( handler.task.aborted || handler.task.failed ) {
process.failed++
process.error |= !handler.task.errorAction?.soft
Expand All @@ -372,6 +403,7 @@ class AnsiLogObserver implements TraceObserver {
@Override
synchronized void onProcessCached(TaskHandler handler, TraceRecord trace){
final process = proc0(handler)
process.name = handler.task.name
if( trace ) {
process.cached++
process.hash = handler.task.hashLog
Expand Down
Original file line number Diff line number Diff line change
Expand Up @@ -29,7 +29,7 @@ class AnsiLogObserverTest extends Specification {
def 'should render a process line' () {

given:
def o = new AnsiLogObserver()
def observer = new AnsiLogObserver()
def stats = new AnsiLogObserver.ProcessStats()
stats.submitted = SUBMIT
stats.completed = COMPLETED
Expand All @@ -38,9 +38,12 @@ class AnsiLogObserverTest extends Specification {
stats.terminated = DONE
stats.error = ERR
stats.hash = HASH
stats.name = 'foo'

expect:
o.line('foo', stats) == EXPECTED
when:
observer.@labelWidth = stats.name.size()
then:
observer.line(stats) == EXPECTED

where:
HASH | SUBMIT | COMPLETED | CACHE | STORE | DONE | ERR | EXPECTED
Expand All @@ -57,4 +60,45 @@ class AnsiLogObserverTest extends Specification {

}

def 'should format name' () {
given:
def ansi = new AnsiLogObserver()

expect:
ansi.fmtWidth(NAME, WIDTH, MAX) == EXPECTED

where:
NAME | WIDTH | MAX | EXPECTED

'foo' | 3 | 80 | 'foo'
'foo' | 5 | 80 | 'foo '

'long_name' | 9 | 5 | 'lo...'
'long_name' | 9 | 2 | 'lo'
'long_name' | 9 | 3 | 'lon'
'xx' | 9 | 1 | 'x'
'xx' | 9 | 5 | 'xx '
'abcd' | 9 | 5 | 'abcd '
'12345678' | 9 | 5 | '12...'
}

def 'should chop a string' () {
given:
def ansi = new AnsiLogObserver()

expect:
ansi.fmtChop(NAME, COLS) == EXPECTED

where:
NAME | COLS | EXPECTED
'long_name' | 5 | 'lo...'
'long_name' | 2 | 'lo'
'long_name' | 3 | 'lon'
'xx' | 1 | 'x'
'xx' | 5 | 'xx'
'abcd' | 5 | 'abcd'
'12345678' | 5 | '12...'

}

}

0 comments on commit 8cf8cc4

Please sign in to comment.