Skip to content
Merged
Show file tree
Hide file tree
Changes from all commits
Commits
File filter

Filter by extension

Filter by extension


Conversations
Failed to load comments.
Loading
Jump to
Jump to file
Failed to load files.
Loading
Diff view
Diff view
4 changes: 4 additions & 0 deletions CHANGELOG.md
Original file line number Diff line number Diff line change
Expand Up @@ -12,6 +12,10 @@ and its status can be checked out using `dfx canister migration-status`.
The optimization functionality provided by `ic_wasm::optimize" cannot handle Wasm modules that contains 64-bit table.
Instead of blocking the build, such optimization failure will issue a warning.

### fix: prevent panic on terminals with limited color support

Fixed a panic that could occur when running `dfx` on terminals lacking color support. The `term` crate has been replaced with raw ANSI escape codes, and colors are now only emitted when stderr is a TTY and the `NO_COLOR` environment variable is not set.

## Dependencies

### Motoko
Expand Down
1 change: 0 additions & 1 deletion Cargo.lock

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

1 change: 0 additions & 1 deletion src/dfx/Cargo.toml
Original file line number Diff line number Diff line change
Expand Up @@ -107,7 +107,6 @@ supports-color = "2.1.0"
sysinfo = "0.28.4"
tar.workspace = true
tempfile.workspace = true
term = "0.7.0"
thiserror.workspace = true
time = { workspace = true, features = ["macros", "serde", "serde-human-readable"] }
tokio = { workspace = true, features = ["full"] }
Expand Down
56 changes: 30 additions & 26 deletions src/dfx/src/main.rs
Original file line number Diff line number Diff line change
Expand Up @@ -15,6 +15,7 @@ use dfx_core::extension::manager::ExtensionManager;
use indicatif::MultiProgress;
use std::collections::HashMap;
use std::ffi::OsString;
use std::io::{IsTerminal, Write, stderr};
use std::path::PathBuf;
use std::time::Instant;
use util::default_allowlisted_canisters;
Expand Down Expand Up @@ -72,8 +73,19 @@ fn setup_logging(opts: &CliOpts) -> (i64, slog::Logger, MultiProgress) {
(verbose_level, logger, spinners)
}

/// Returns true if colored output should be used on stderr.
/// Respects the NO_COLOR environment variable (https://no-color.org/).
fn use_color() -> bool {
std::env::var_os("NO_COLOR").is_none() && stderr().is_terminal()
}

fn print_error_and_diagnosis(log_level: Option<i64>, err: Error, error_diagnosis: DiagnosedError) {
let mut stderr = util::stderr_wrapper::stderr_wrapper();
let mut stderr = stderr().lock();
let use_color = use_color();

const RED: &str = "\x1b[31m";
const YELLOW: &str = "\x1b[33m";
const RESET: &str = "\x1b[0m";

// print error chain stack
if log_level.unwrap_or_default() > 0 // DEBUG or more verbose
Expand All @@ -85,43 +97,35 @@ fn print_error_and_diagnosis(log_level: Option<i64>, err: Error, error_diagnosis
}

let (color, prefix) = if level == 0 {
(term::color::RED, "Error")
(RED, "Error")
} else {
(term::color::YELLOW, "Caused by")
(YELLOW, "Caused by")
};
stderr
.fg(color)
.expect("Failed to set stderr output color.");
write!(stderr, "{prefix}: ").expect("Failed to write to stderr.");
stderr
.reset()
.expect("Failed to reset stderr output color.");
if use_color {
write!(stderr, "{color}{prefix}: {RESET}").expect("Failed to write to stderr.");
} else {
write!(stderr, "{prefix}: ").expect("Failed to write to stderr.");
}

writeln!(stderr, "{cause}").expect("Failed to write to stderr.");
}
}

// print diagnosis
if let Some(explanation) = error_diagnosis.explanation {
stderr
.fg(term::color::RED)
.expect("Failed to set stderr output color.");
write!(stderr, "Error: ").expect("Failed to write to stderr.");
stderr
.reset()
.expect("Failed to reset stderr output color.");

if use_color {
write!(stderr, "{RED}Error: {RESET}").expect("Failed to write to stderr.");
} else {
write!(stderr, "Error: ").expect("Failed to write to stderr.");
}
writeln!(stderr, "{explanation}").expect("Failed to write to stderr.");
}
if let Some(action_suggestion) = error_diagnosis.action_suggestion {
stderr
.fg(term::color::YELLOW)
.expect("Failed to set stderr output color.");
write!(stderr, "To fix: ").expect("Failed to write to stderr.");
stderr
.reset()
.expect("Failed to reset stderr output color.");

if use_color {
write!(stderr, "{YELLOW}To fix: {RESET}").expect("Failed to write to stderr.");
} else {
write!(stderr, "To fix: ").expect("Failed to write to stderr.");
}
writeln!(stderr, "{action_suggestion}").expect("Failed to write to stderr.");
}
}
Expand Down
1 change: 0 additions & 1 deletion src/dfx/src/util/mod.rs
Original file line number Diff line number Diff line change
Expand Up @@ -31,7 +31,6 @@ pub mod assets;
pub mod clap;
pub mod command;
pub mod currency_conversion;
pub mod stderr_wrapper;
pub mod url;

const DECIMAL_POINT: char = '.';
Expand Down
83 changes: 0 additions & 83 deletions src/dfx/src/util/stderr_wrapper.rs

This file was deleted.