Skip to content

Commit

Permalink
Merge pull request #142 from ctongfei/0.9.4
Browse files Browse the repository at this point in the history
0.9.4
  • Loading branch information
ctongfei authored Sep 10, 2022
2 parents 87600ec + 4adfbfe commit 493daa1
Show file tree
Hide file tree
Showing 12 changed files with 126 additions and 38 deletions.
11 changes: 11 additions & 0 deletions CHANGELOG.md
Original file line number Diff line number Diff line change
@@ -1,4 +1,15 @@
# Changelog
* `0.9.4`:
- New functionalities:
- In `ProgressBarBuilder`s, one can now switch whether to show the remaining time, or to provide a custom
function to compute the remaining time (if the progress is not linear) (#131). Thanks @MagnusErikssonAB !
- In `ProgressBarBuilder`s, one can now set `.clearDisplayOnFinish()` to clear the display on terminals when
a progress is complete (#135). Thanks @mattparkins !
- Added a method `ProgressBar::isIndefinite` to check if a progress bar's max is unknown (#140). Thanks @lt3stus3el !
- Bugfixes:
- Fixed the bug of not drawing after resetting or stepping back caused by #91 (#124). Thanks @Bricktheworld !
- Suppress exceptions thrown in `Spliterator.estimateSize` and continue as if indefinite (#141). Thanks @seanf !
- Dependency version bump.
* `0.9.3`:
- New functionalities:
- Supports for wrapping around `java.io.OutputStream`s and `java.io.Writer`s (#114). Thanks @azachar !
Expand Down
4 changes: 2 additions & 2 deletions README.md
Original file line number Diff line number Diff line change
Expand Up @@ -18,7 +18,7 @@ For Consolas or Andale Mono fonts, use `ProgressBarStyle.ASCII` because the box-

#### Documentation
- [Documentation](http://ctongfei.github.io/progressbar/)
- [Javadoc](https://javadoc.io/doc/me.tongfei/progressbar/0.9.3)
- [Javadoc](https://javadoc.io/doc/me.tongfei/progressbar/latest)


#### Installation
Expand All @@ -29,7 +29,7 @@ Maven:
<dependency>
<groupId>me.tongfei</groupId>
<artifactId>progressbar</artifactId>
<version>0.9.3</version>
<version>0.9.4</version>
</dependency>
```

Expand Down
1 change: 0 additions & 1 deletion docs/builder.md
Original file line number Diff line number Diff line change
Expand Up @@ -14,7 +14,6 @@ ProgressBarBuilder pbb = new ProgressBarBuilder()
.setMaxRenderedLength(<max rendered length in terminal>)
.showSpeed();
// or .showSpeed(new DecimalFormat("#.##")) to customize speed display

for (T x : ProgressBar.wrap(collection, pbb)) {
...
}
Expand Down
4 changes: 2 additions & 2 deletions docs/index.md
Original file line number Diff line number Diff line change
Expand Up @@ -12,14 +12,14 @@ Depending on your build tool, add the following setting.
<dependency>
<groupId>me.tongfei</groupId>
<artifactId>progressbar</artifactId>
<version>0.9.3</version>
<version>0.9.4</version>
</dependency>
```

=== "Gradle"

``` groovy
compile 'me.tongfei:progressbar:0.9.3'
compile 'me.tongfei:progressbar:0.9.4'
```

#### Getting started
Expand Down
4 changes: 2 additions & 2 deletions mkdocs.yml
Original file line number Diff line number Diff line change
@@ -1,7 +1,7 @@
site_name: 'Progressbar 0.9.3'
site_name: 'Progressbar 0.9.4'
site_description: 'A terminal progress bar for Java/JVM'
site_author: 'Tongfei Chen'
copyright: 'Copyright &copy; 2015-2021 Tongfei Chen and contributors'
copyright: 'Copyright &copy; 2015-2022 Tongfei Chen and contributors'

theme:
name: 'material'
Expand Down
10 changes: 5 additions & 5 deletions pom.xml
Original file line number Diff line number Diff line change
Expand Up @@ -6,7 +6,7 @@

<groupId>me.tongfei</groupId>
<artifactId>progressbar</artifactId>
<version>0.9.3</version>
<version>0.9.4</version>
<name>progressbar</name>
<description>A terminal-based progress bar for JVM</description>
<url>http://github.com/ctongfei/progressbar</url>
Expand Down Expand Up @@ -133,28 +133,28 @@
<dependency>
<groupId>org.junit.jupiter</groupId>
<artifactId>junit-jupiter-api</artifactId>
<version>5.8.2</version>
<version>5.9.0</version>
<scope>test</scope>
</dependency>

<dependency>
<groupId>org.junit.jupiter</groupId>
<artifactId>junit-jupiter-engine</artifactId>
<version>5.8.2</version>
<version>5.9.0</version>
<scope>test</scope>
</dependency>

<dependency>
<groupId>org.slf4j</groupId>
<artifactId>slf4j-api</artifactId>
<version>1.7.32</version>
<version>2.0.0</version>
<scope>test</scope>
</dependency>

<dependency>
<groupId>org.slf4j</groupId>
<artifactId>slf4j-simple</artifactId>
<version>1.7.32</version>
<version>2.0.0</version>
<scope>test</scope>
</dependency>
</dependencies>
Expand Down
Original file line number Diff line number Diff line change
Expand Up @@ -4,6 +4,8 @@
import java.time.Duration;
import java.time.Instant;
import java.time.temporal.ChronoUnit;
import java.util.Optional;
import java.util.function.BiFunction;

import static me.tongfei.progressbar.StringDisplayUtils.*;

Expand All @@ -21,21 +23,27 @@ public class DefaultProgressBarRenderer implements ProgressBarRenderer {
private boolean isSpeedShown;
private DecimalFormat speedFormat;
private ChronoUnit speedUnit;
private boolean isETAShown;
private BiFunction<ProgressState, Duration, Optional<Duration>> eta;

protected DefaultProgressBarRenderer(
ProgressBarStyle style,
String unitName,
long unitSize,
boolean isSpeedShown,
DecimalFormat speedFormat,
ChronoUnit speedUnit
ChronoUnit speedUnit,
boolean isETAShown,
BiFunction<ProgressState, Duration, Optional<Duration>> eta
) {
this.style = style;
this.unitName = unitName;
this.unitSize = unitSize;
this.isSpeedShown = isSpeedShown;
this.speedFormat = isSpeedShown && speedFormat == null ? new DecimalFormat() : speedFormat;
this.speedUnit = speedUnit;
this.isETAShown = isETAShown;
this.eta = eta;
}

// Number of full blocks
Expand All @@ -49,12 +57,14 @@ protected int progressFractionalPart(ProgressState progress, int length) {
return (int) Math.floor(fraction);
}

protected String eta(ProgressState progress, Duration elapsed) {
if (progress.max <= 0 || progress.indefinite) return "?";
else if (progress.current - progress.start == 0) return "?";
else return Util.formatDuration(
elapsed.dividedBy(progress.current - progress.start).multipliedBy(progress.max - progress.current)
);
protected String etaString(ProgressState progress, Duration elapsed) {
Optional<Duration> eta = this.eta.apply(progress, elapsed);
if (eta.isPresent()) {
return Util.formatDuration(eta.get());
}
else {
return "?";
}
}

protected String percentage(ProgressState progress) {
Expand Down Expand Up @@ -118,7 +128,7 @@ public String render(ProgressState progress, int maxLength) {

String speedString = isSpeedShown ? speed(progress, elapsed) : "";
String suffix = style.rightBracket + " " + ratio(progress) + " ("
+ Util.formatDuration(elapsed) + " / " + eta(progress, elapsed) + ") "
+ Util.formatDuration(elapsed) + (isETAShown ? " / " + etaString(progress, elapsed) : "") + ") "
+ speedString + progress.extraMessage;
int suffixLength = getStringDisplayLength(suffix);
// trim excessive suffix
Expand Down
48 changes: 32 additions & 16 deletions src/main/java/me/tongfei/progressbar/ProgressBar.java
Original file line number Diff line number Diff line change
Expand Up @@ -24,17 +24,22 @@
*/
public class ProgressBar implements AutoCloseable {

private ProgressState progress;
private ProgressUpdateAction action;
private ScheduledFuture<?> scheduledTask;
private final ProgressState progress;
private final ProgressUpdateAction action;
private final ScheduledFuture<?> scheduledTask;

/**
* Creates a progress bar with the specific taskName name and initial maximum value.
* @param task Task name
* @param initialMax Initial maximum value
*/
public ProgressBar(String task, long initialMax) {
this(task, initialMax, 1000, false, System.err, ProgressBarStyle.COLORFUL_UNICODE_BLOCK, "", 1, false, null, ChronoUnit.SECONDS, 0L, Duration.ZERO);
this(
task, initialMax, 1000, false, false,
System.err, ProgressBarStyle.COLORFUL_UNICODE_BLOCK,
"", 1, false, null,
ChronoUnit.SECONDS, 0L, Duration.ZERO
);
}

/**
Expand All @@ -54,6 +59,7 @@ public ProgressBar(
long initialMax,
int updateIntervalMillis,
boolean continuousUpdate,
boolean clearDisplayOnFinish,
PrintStream os,
ProgressBarStyle style,
String unitName,
Expand All @@ -64,8 +70,12 @@ public ProgressBar(
long processed,
Duration elapsed
) {
this(task, initialMax, updateIntervalMillis, continuousUpdate, processed, elapsed,
new DefaultProgressBarRenderer(style, unitName, unitSize, showSpeed, speedFormat, speedUnit),
this(task, initialMax, updateIntervalMillis, continuousUpdate, clearDisplayOnFinish, processed, elapsed,
new DefaultProgressBarRenderer(
style, unitName, unitSize,
showSpeed, speedFormat, speedUnit,
true, Util::linearETA
),
createConsoleConsumer(os)
);
}
Expand All @@ -88,13 +98,14 @@ public ProgressBar(
long initialMax,
int updateIntervalMillis,
boolean continuousUpdate,
boolean clearDisplayOnFinish,
long processed,
Duration elapsed,
ProgressBarRenderer renderer,
ProgressBarConsumer consumer
) {
this.progress = new ProgressState(task, initialMax, processed, elapsed);
this.action = new ProgressUpdateAction(progress, renderer, consumer, continuousUpdate);
this.action = new ProgressUpdateAction(progress, renderer, consumer, continuousUpdate, clearDisplayOnFinish);
scheduledTask = Util.executor.scheduleAtFixedRate(
action, 0, updateIntervalMillis, TimeUnit.MILLISECONDS
);
Expand All @@ -114,7 +125,9 @@ public ProgressBar stepBy(long n) {
* @param n New progress value
*/
public ProgressBar stepTo(long n) {
boolean back = n < progress.current;
progress.stepTo(n);
if (back) action.forceRefresh(); // fix #124
return this;
}

Expand Down Expand Up @@ -159,6 +172,7 @@ public ProgressBar resume() {
/** Resets the progress bar to its initial state (where progress equals to 0). */
public ProgressBar reset() {
progress.reset();
action.forceRefresh(); // force refresh, fixing #124
return this;
}

Expand Down Expand Up @@ -214,6 +228,11 @@ public String getExtraMessage() {
return progress.getExtraMessage();
}

/** Checks if the progress bar is indefinite, i.e., its maximum value is unknown. */
public boolean IsIndefinite() {
return progress.indefinite;
}

/**
* Prompts the progress bar to refresh. Normally a user should not call this function.
*/
Expand Down Expand Up @@ -264,9 +283,8 @@ public static <T> Iterable<T> wrap(Iterable<T> ts, String task) {
* @param pbb An instance of a {@link ProgressBarBuilder}
*/
public static <T> Iterable<T> wrap(Iterable<T> ts, ProgressBarBuilder pbb) {
long size = ts.spliterator().estimateSize();
if (size != Long.MAX_VALUE)
pbb.setInitialMax(size);
if (!pbb.initialMaxIsSet())
pbb.setInitialMax(Util.getSpliteratorSize(ts.spliterator()));
return new ProgressBarWrappedIterable<>(ts, pbb);
}

Expand All @@ -287,9 +305,8 @@ public static InputStream wrap(InputStream is, String task) {
* @param pbb An instance of a {@link ProgressBarBuilder}
*/
public static InputStream wrap(InputStream is, ProgressBarBuilder pbb) {
long size = Util.getInputStreamSize(is);
if (size != -1 && pbb.initialMaxIsSet())
pbb.setInitialMax(size);
if (!pbb.initialMaxIsSet())
pbb.setInitialMax(Util.getInputStreamSize(is));
return new ProgressBarWrappedInputStream(is, pbb.build());
}

Expand Down Expand Up @@ -370,9 +387,8 @@ public static <T> Spliterator<T> wrap(Spliterator<T> sp, String task) {
* @param pbb An instance of a {@link ProgressBarBuilder}
*/
public static <T> Spliterator<T> wrap(Spliterator<T> sp, ProgressBarBuilder pbb) {
long size = sp.estimateSize();
if (size != Long.MAX_VALUE)
pbb.setInitialMax(size);
if (!pbb.initialMaxIsSet())
pbb.setInitialMax(Util.getSpliteratorSize(sp));
return new ProgressBarWrappedSpliterator<>(sp, pbb.build());
}

Expand Down
27 changes: 26 additions & 1 deletion src/main/java/me/tongfei/progressbar/ProgressBarBuilder.java
Original file line number Diff line number Diff line change
Expand Up @@ -3,6 +3,8 @@
import java.text.DecimalFormat;
import java.time.Duration;
import java.time.temporal.ChronoUnit;
import java.util.Optional;
import java.util.function.BiFunction;

/**
* Builder class for {@link ProgressBar}s.
Expand All @@ -17,9 +19,12 @@ public class ProgressBarBuilder {
private boolean continuousUpdate = false;
private ProgressBarStyle style = ProgressBarStyle.COLORFUL_UNICODE_BLOCK;
private ProgressBarConsumer consumer = null;
private boolean clearDisplayOnFinish = false;
private String unitName = "";
private long unitSize = 1;
private boolean showSpeed = false;
private boolean hideETA = false;
private BiFunction<ProgressState, Duration, Optional<Duration>> eta = Util::linearETA;
private DecimalFormat speedFormat;
private ChronoUnit speedUnit = ChronoUnit.SECONDS;
private long processed = 0;
Expand Down Expand Up @@ -62,6 +67,11 @@ public ProgressBarBuilder setConsumer(ProgressBarConsumer consumer) {
return this;
}

public ProgressBarBuilder clearDisplayOnFinish() {
this.clearDisplayOnFinish = true;
return this;
}

public ProgressBarBuilder setUnit(String unitName, long unitSize) {
this.unitName = unitName;
this.unitSize = unitSize;
Expand All @@ -83,6 +93,17 @@ public ProgressBarBuilder showSpeed(DecimalFormat speedFormat) {
return this;
}

public ProgressBarBuilder hideETA() {
this.hideETA = true;
return this;
}

public ProgressBarBuilder setETAFunction(BiFunction<ProgressState, Duration, Optional<Duration>> eta) {
this.hideETA = false;
this.eta = eta;
return this;
}

public ProgressBarBuilder setSpeedUnit(ChronoUnit speedUnit) {
this.speedUnit = speedUnit;
return this;
Expand All @@ -105,9 +126,13 @@ public ProgressBar build() {
initialMax,
updateIntervalMillis,
continuousUpdate,
clearDisplayOnFinish,
processed,
elapsed,
new DefaultProgressBarRenderer(style, unitName, unitSize, showSpeed, speedFormat, speedUnit),
new DefaultProgressBarRenderer(
style, unitName, unitSize,
showSpeed, speedFormat, speedUnit,
!hideETA, eta),
consumer == null ? Util.createConsoleConsumer(maxRenderedLength) : consumer
);
}
Expand Down
5 changes: 5 additions & 0 deletions src/main/java/me/tongfei/progressbar/ProgressBarConsumer.java
Original file line number Diff line number Diff line change
Expand Up @@ -21,6 +21,11 @@ public interface ProgressBarConsumer extends Consumer<String>, Appendable, AutoC
*/
void accept(String rendered);

/** Clears the progress bar from the display. */
default void clear() {
accept("\r" + Util.repeat(' ', getMaxRenderedLength()) + "\r");
}

default ProgressBarConsumer append(CharSequence csq) {
accept(csq.toString());
return this;
Expand Down
Loading

0 comments on commit 493daa1

Please sign in to comment.