-
Notifications
You must be signed in to change notification settings - Fork 218
Commit
This commit does not belong to any branch on this repository, and may belong to a fork outside of the repository.
Add progress tracker and message for CLI while cloning a template (#1888
) Adds a progress tracker for long running CLI tasks. The progress tracker currently supports a simple repeated dots pattern to indicate execution of a long running task. The progress tracker can be extended in the future to support progress bars and additional loading messages.
- Loading branch information
Showing
4 changed files
with
143 additions
and
6 deletions.
There are no files selected for viewing
This file contains bidirectional Unicode text that may be interpreted or compiled differently than what appears below. To review, open the file in an editor that reveals hidden Unicode characters.
Learn more about bidirectional Unicode characters
This file contains bidirectional Unicode text that may be interpreted or compiled differently than what appears below. To review, open the file in an editor that reveals hidden Unicode characters.
Learn more about bidirectional Unicode characters
58 changes: 58 additions & 0 deletions
58
smithy-cli/src/main/java/software/amazon/smithy/cli/commands/ProgressStyle.java
This file contains bidirectional Unicode text that may be interpreted or compiled differently than what appears below. To review, open the file in an editor that reveals hidden Unicode characters.
Learn more about bidirectional Unicode characters
Original file line number | Diff line number | Diff line change |
---|---|---|
@@ -0,0 +1,58 @@ | ||
/* | ||
* Copyright Amazon.com, Inc. or its affiliates. All Rights Reserved. | ||
* SPDX-License-Identifier: Apache-2.0 | ||
*/ | ||
|
||
package software.amazon.smithy.cli.commands; | ||
|
||
import java.util.concurrent.atomic.AtomicInteger; | ||
import software.amazon.smithy.cli.ColorBuffer; | ||
import software.amazon.smithy.cli.ColorTheme; | ||
import software.amazon.smithy.cli.Command; | ||
import software.amazon.smithy.utils.StringUtils; | ||
|
||
|
||
interface ProgressStyle { | ||
|
||
void updateAction(Command.Env env, AtomicInteger tracker); | ||
|
||
void closeAction(Command.Env env); | ||
|
||
static ColorBuffer getBuffer(Command.Env env) { | ||
return ColorBuffer.of(env.colors(), env.stdout()); | ||
} | ||
|
||
static ProgressStyle dots(String progressMessage, String closeMessage) { | ||
return new ProgressStyle() { | ||
private static final String PROGRESS_CHAR = "."; | ||
private static final int TICKER_LENGTH = 3; | ||
private final long startTimeMillis = System.currentTimeMillis(); | ||
|
||
@Override | ||
public void updateAction(Command.Env env, AtomicInteger tracker) { | ||
int tickCount = tracker.getAndIncrement(); | ||
int tickNumber = tickCount % (TICKER_LENGTH + 1); | ||
String loadStr = StringUtils.repeat(PROGRESS_CHAR, tickNumber) | ||
+ StringUtils.repeat(" ", TICKER_LENGTH - tickNumber); | ||
try (ColorBuffer buffer = getBuffer(env)) { | ||
buffer.print("\r") | ||
.print(progressMessage, ColorTheme.NOTE) | ||
.print(loadStr, ColorTheme.NOTE); | ||
} | ||
} | ||
|
||
@Override | ||
public void closeAction(Command.Env env) { | ||
try (ColorBuffer buffer = getBuffer(env)) { | ||
buffer.print("\r") | ||
.print(closeMessage, ColorTheme.SUCCESS) | ||
.print(" [", ColorTheme.MUTED) | ||
.print((System.currentTimeMillis() - startTimeMillis) / 1000.0 + "s", | ||
ColorTheme.NOTE) | ||
.print("]", ColorTheme.MUTED) | ||
.println(); | ||
} | ||
} | ||
}; | ||
} | ||
} |
68 changes: 68 additions & 0 deletions
68
smithy-cli/src/main/java/software/amazon/smithy/cli/commands/ProgressTracker.java
This file contains bidirectional Unicode text that may be interpreted or compiled differently than what appears below. To review, open the file in an editor that reveals hidden Unicode characters.
Learn more about bidirectional Unicode characters
Original file line number | Diff line number | Diff line change |
---|---|---|
@@ -0,0 +1,68 @@ | ||
/* | ||
* Copyright Amazon.com, Inc. or its affiliates. All Rights Reserved. | ||
* SPDX-License-Identifier: Apache-2.0 | ||
*/ | ||
|
||
package software.amazon.smithy.cli.commands; | ||
|
||
import java.util.concurrent.ExecutionException; | ||
import java.util.concurrent.Executors; | ||
import java.util.concurrent.ScheduledFuture; | ||
import java.util.concurrent.ScheduledThreadPoolExecutor; | ||
import java.util.concurrent.TimeUnit; | ||
import java.util.concurrent.atomic.AtomicInteger; | ||
import software.amazon.smithy.cli.Command; | ||
|
||
final class ProgressTracker implements AutoCloseable { | ||
private static final ScheduledThreadPoolExecutor EXECUTOR = new ScheduledThreadPoolExecutor(1, runnable -> { | ||
Thread thread = Executors.defaultThreadFactory().newThread(runnable); | ||
thread.setDaemon(true); | ||
return thread; | ||
}); | ||
private static final long INTERVAL_MILLIS = 400L; | ||
private final ScheduledFuture<?> task; | ||
private final ProgressStyle style; | ||
private final Command.Env env; | ||
private final AtomicInteger tracker; | ||
private final boolean quiet; | ||
|
||
ProgressTracker(Command.Env env, ProgressStyle style, boolean quiet) { | ||
this(env, style, quiet, new AtomicInteger()); | ||
} | ||
|
||
ProgressTracker(Command.Env env, ProgressStyle style, boolean quiet, AtomicInteger tracker) { | ||
this.env = env; | ||
this.style = style; | ||
this.quiet = quiet; | ||
this.tracker = tracker; | ||
|
||
// Do not print a progress bar if the quiet setting is enabled | ||
if (quiet) { | ||
task = null; | ||
} else { | ||
task = EXECUTOR.scheduleAtFixedRate(this::write, 0, INTERVAL_MILLIS, TimeUnit.MILLISECONDS); | ||
} | ||
} | ||
|
||
@Override | ||
public void close() { | ||
if (!quiet) { | ||
task.cancel(false); | ||
try { | ||
EXECUTOR.schedule(this::executeClose, 0, TimeUnit.NANOSECONDS).get(); | ||
} catch (ExecutionException | InterruptedException e) { /* ignored */ } | ||
} | ||
} | ||
|
||
private void write() { | ||
style.updateAction(env, tracker); | ||
// Flush so the output is written immediately | ||
env.stdout().flush(); | ||
} | ||
|
||
private void executeClose() { | ||
style.closeAction(env); | ||
// Flush so the output is written immediately | ||
env.stdout().flush(); | ||
} | ||
} |