Skip to content

Progress tracking

Shell operations yield progress bars by default when they take too long. Progress operations are represented as ProgressReport objects and passed to a Progress.Consumer, which can be set with trackProgress or accessed via progressTracker.

There are utilities to help you work with and generate these events.

Tracking progress through a list

1
2
3
4
for (file in ls("/").withProgress(progressTracker)) {
    echo(file)
    Thread.sleep(1000)
}

asciicast

Customize the output

1
2
3
4
for (file in ls("/").withProgress(progressTracker, ProgressReport("Iterating over files"))) {
    echo(file)
    Thread.sleep(1000)
}

Send progress events manually

1
2
3
4
5
6
7
8
// Expect 500 units of work
var report = ProgressReport("My operation", 500).immutableReport()

while (!report.complete) {
    progressTracker.accept(report)
    Thread.sleep(100)
    report = report.withIncremented(1)
}

Spinner

For indefinite tasks where no progress can be measured:

1
2
3
progressTracker.indeterminate("My message") {
  Thread.sleep(5000)
}

Process a file

 1
 2
 3
 4
 5
 6
 7
 8
 9
10
11
12
13
14
// Write a million lines of text.
write("bigfile.txt", buildString { for (i in 1..1_000_000) appendLine("Line $i") })

// Process lines whilst tracking progress.
path("bigfile.txt").inputStreamWithProgress(progressTracker).bufferedReader().use { reader ->
    reader.lineSequence().forEachIndexed { lineNumber, line ->
        if ("Line 12345" in line)
            echo(line)

        // Slow down a bit so the progress tracker is visible.
        if (lineNumber.mod(1000) == 0)
            Thread.sleep(10)
    }
}

asciicast