Skip to content

Commit

Permalink
Avoid flickering of table output (#423)
Browse files Browse the repository at this point in the history
* Avoid flickering of table output

Before this change, a table output created by ank apply was sometimes
flickering. This was caused by printing cleanup strings that had been
overwritten by the new message in the same println statement. This
change uses a mechanism as described in
https://stackoverflow.com/a/71453783

* Replace atty by std lib

* Update tabled crate

* Update hashbrown due to vulnerability

* Check advisories for PRs
  • Loading branch information
windsource authored Dec 17, 2024
1 parent cf73e93 commit d4bfdd3
Show file tree
Hide file tree
Showing 5 changed files with 89 additions and 53 deletions.
5 changes: 5 additions & 0 deletions .github/workflows/build.yml
Original file line number Diff line number Diff line change
Expand Up @@ -77,6 +77,11 @@ jobs:
with:
name: licenses
path: build/licenses.html
# We check advisories only for PRs in order to have stable builds on main.
# Remember that new advisories can pop up every time without changing the code.
- name: Check advisories for pull requests
if: ${{ github.event_name == 'pull_request' }}
run: just check-advisories

code_coverage_linux_amd64:
name: Create code coverage report
Expand Down
43 changes: 20 additions & 23 deletions Cargo.lock

Some generated files are not rendered by default. Learn more about how customized files appear on GitHub.

2 changes: 1 addition & 1 deletion ank/Cargo.toml
Original file line number Diff line number Diff line change
Expand Up @@ -34,7 +34,7 @@ tokio = { version = "1.41", features = [
serde = { version = "1.0", features = ["derive"] }
serde_json = "1.0"
serde_yaml = "0.9"
tabled = "0.12"
tabled = "0.17"
uuid = { version = "1.7.0", features = ["v4"] }
crossterm = "0.27.0"
clap_complete = { version = "<=4.5.24", features = ["unstable-dynamic", "unstable-command"] }
Expand Down
88 changes: 59 additions & 29 deletions ank/src/log.rs
Original file line number Diff line number Diff line change
Expand Up @@ -12,14 +12,23 @@
//
// SPDX-License-Identifier: Apache-2.0

use std::{env, fmt, process::exit, sync::Mutex};

use crossterm::{cursor, style::Stylize, terminal};
use std::{
env, fmt,
io::{self, IsTerminal},
process::exit,
sync::Mutex,
};

use crossterm::{
cursor,
style::Stylize,
terminal::{self, ClearType},
};

pub const VERBOSITY_KEY: &str = "VERBOSE";
pub const QUIET_KEY: &str = "SILENT";

static CLEANUP_STRING: Mutex<String> = Mutex::new(String::new());
static ROWS_PREV_MSG: Mutex<u16> = Mutex::new(0);

/// Prints the message, if the CLI command is not called with `--quiet` flag
#[macro_export]
Expand Down Expand Up @@ -74,25 +83,33 @@ pub(crate) fn output_and_exit_fn(args: fmt::Arguments<'_>) -> ! {

pub(crate) fn output_debug_fn(args: fmt::Arguments<'_>) {
if is_verbose() {
std::println!("{} {}{}", "debug:".blue(), args, cursor::SavePosition);
*CLEANUP_STRING.lock().unwrap() = "".into();
std::println!("{} {}", "debug:".blue(), args);
*ROWS_PREV_MSG.lock().unwrap() = 0;
}
}

pub(crate) fn output_warn_fn(args: fmt::Arguments<'_>) {
std::println!("{} {}{}", "warn:".yellow(), args, cursor::SavePosition);
*CLEANUP_STRING.lock().unwrap() = "".into();
std::println!("{} {}", "warn:".yellow(), args);
*ROWS_PREV_MSG.lock().unwrap() = 0;
}

pub(crate) fn output_fn(args: fmt::Arguments<'_>) {
if !is_quiet() {
std::println!("{}{}", args, cursor::SavePosition);
*CLEANUP_STRING.lock().unwrap() = "".into();
std::println!("{}", args);
*ROWS_PREV_MSG.lock().unwrap() = 0;
}
}

pub fn interactive() -> bool {
io::stdout().is_terminal()
}

pub fn terminal_width() -> usize {
let terminal_width = terminal::size().unwrap_or((80, 0)).0 as usize;
let terminal_width = if interactive() {
terminal::size().unwrap_or((80, 0)).0 as usize
} else {
u16::MAX as usize
};

// This is a workaround for terminals that return a wrong width of 0 instead of None
if 0 == terminal_width {
Expand All @@ -105,8 +122,15 @@ pub(crate) fn output_update_fn(args: fmt::Arguments<'_>) {
if !is_quiet() {
let args = args.to_string();

if !interactive() {
println!("{}\n", args);
return;
}

let lf = format!("{}\n", terminal::Clear(ClearType::UntilNewLine));

// limit line length to terminal_width by introducing newline characters
let args = args
let mut args = args
.split('\n')
.flat_map(|line| {
line.chars()
Expand All @@ -116,31 +140,37 @@ pub(crate) fn output_update_fn(args: fmt::Arguments<'_>) {
.collect::<Vec<_>>()
})
.collect::<Vec<String>>()
.join("\n");
.join(&lf);
args.push_str(&lf);

let mut cleanup_string = CLEANUP_STRING.lock().unwrap();
let up = cleanup_string.chars().filter(|c| *c == '\n').count() as u16;
let up_string = if up > 0 {
cursor::MoveUp(up).to_string()
let rows = args.chars().filter(|c| *c == '\n').count() as u16;
let mut prev_rows = ROWS_PREV_MSG.lock().unwrap();
let pre_up_string = if *prev_rows > 0 {
cursor::MoveUp(*prev_rows).to_string()
} else {
"".to_string()
};
std::println!(
"{}{}{}{}{}{}",
let cleanup_string = if rows < *prev_rows {
str::repeat(&lf, (*prev_rows - rows).into())
} else {
"".to_string()
};
let post_up_string = if rows < *prev_rows {
cursor::MoveUp(*prev_rows - rows).to_string()
} else {
"".to_string()
};

std::print!(
"{}{}{}{}{}",
cursor::MoveToColumn(0),
up_string,
pre_up_string,
args,
cleanup_string,
cursor::MoveToColumn(0),
up_string,
args
post_up_string
);

let mut new_cleanup_string: String = args
.chars()
.map(|x| if x == '\n' { '\n' } else { ' ' })
.collect();
new_cleanup_string.push('\n');
*cleanup_string = new_cleanup_string;
*prev_rows = rows;
}
}

Expand Down
4 changes: 4 additions & 0 deletions justfile
Original file line number Diff line number Diff line change
Expand Up @@ -31,6 +31,10 @@ clean:
check-licenses:
cargo deny check licenses

# Check advisories as part of https://rustsec.org/advisories/
check-advisories:
cargo deny check advisories

# Prevent non ghcr.io images to be used in test due to rate limit problem
check-test-images:
test -z "$(find tests/resources/configs -type f -exec grep -H -P 'image: (?!ghcr\.io/|image_typo:latest)' {} \;)"
Expand Down

0 comments on commit d4bfdd3

Please sign in to comment.