Skip to content

Commit

Permalink
refactor: Port to anstream
Browse files Browse the repository at this point in the history
  • Loading branch information
epage committed May 29, 2024
1 parent 4b09269 commit e59e657
Show file tree
Hide file tree
Showing 6 changed files with 57 additions and 115 deletions.
67 changes: 14 additions & 53 deletions Cargo.lock

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

4 changes: 2 additions & 2 deletions Cargo.toml
Original file line number Diff line number Diff line change
Expand Up @@ -137,7 +137,6 @@ semver = "1.0"
quick-error = "2.0"
regex = "1.10"
bstr = "1.9.1"
termcolor = "1.4.1"
maplit = "1.0"
indexmap = "2.2"
time = { version = "0.3", features = ["formatting", "macros"] }
Expand All @@ -153,9 +152,10 @@ globset = { version = "0.4.14", default-features = false }
dunce = "1.0.4"
trycmd = "0.15.1"
anyhow = "1.0.82"
concolor-control = { version = "0.0.7", features = ["auto"] }
git-conventional = "0.12.6"
similar = "2.5"
anstream = "0.6.14"
anstyle = "1.0.7"

[dev-dependencies]
assert_fs = "1.1"
Expand Down
1 change: 1 addition & 0 deletions src/ops/mod.rs
Original file line number Diff line number Diff line change
Expand Up @@ -4,6 +4,7 @@ pub mod git;
pub mod index;
pub mod replace;
pub mod shell;
pub mod style;
pub mod version;

pub(crate) mod diff;
61 changes: 16 additions & 45 deletions src/ops/shell.rs
Original file line number Diff line number Diff line change
@@ -1,87 +1,63 @@
use std::io::{stdin, stdout, Write};

use anstyle::Style;
use anyhow::Context as _;
use termcolor::{ColorChoice, StandardStream, WriteColor};

pub use termcolor::Color;
pub use termcolor::ColorSpec;

use crate::error::CargoResult;
use crate::ops::style::{ERROR, HEADER, NOTE, WARN};

pub fn confirm(prompt: &str) -> bool {
let mut input = String::new();

console_println(&format!("{} [y/N] ", prompt), None, true);
console_println(&format!("{} [y/N] ", prompt), Style::new());

stdout().flush().unwrap();
stdin().read_line(&mut input).expect("y/n required");

input.trim().to_lowercase() == "y"
}

fn console_println(text: &str, color: Option<Color>, bold: bool) {
let mut stdout = StandardStream::stdout(ColorChoice::Auto);
stdout.reset().unwrap();
// unwrap the result, panic if error
stdout
.set_color(ColorSpec::new().set_fg(color).set_bold(bold))
.unwrap();
writeln!(&mut stdout, "{}", text).unwrap();
stdout.reset().unwrap();
}

/// Whether to color logged output
fn colorize_stderr() -> ColorChoice {
if concolor_control::get(concolor_control::Stream::Stderr).color() {
ColorChoice::Always
} else {
ColorChoice::Never
}
fn console_println(text: &str, style: Style) {
let _ = writeln!(anstream::stdout(), "{style}{text}{style:#}");
}

/// Print a message with a colored title in the style of Cargo shell messages.
pub fn print(
status: &str,
message: impl std::fmt::Display,
color: Color,
style: Style,
justified: bool,
) -> CargoResult<()> {
let color_choice = colorize_stderr();
let mut output = StandardStream::stderr(color_choice);

output.set_color(ColorSpec::new().set_fg(Some(color)).set_bold(true))?;
let mut stderr = anstream::stderr().lock();
if justified {
write!(output, "{status:>12}")?;
write!(stderr, "{style}{status:>12}{style:#}")?;
} else {
write!(output, "{}", status)?;
output.set_color(ColorSpec::new().set_bold(true))?;
write!(output, ":")?;
write!(stderr, "{style}{}{style:#}:", status)?;
}
output.reset()?;

writeln!(output, " {message:#}").with_context(|| "Failed to write message")?;
writeln!(stderr, " {message:#}").with_context(|| "Failed to write message")?;

Ok(())
}

/// Print a styled action message.
pub fn status(action: &str, message: impl std::fmt::Display) -> CargoResult<()> {
print(action, message, Color::Green, true)
print(action, message, HEADER, true)
}

/// Print a styled error message.
pub fn error(message: impl std::fmt::Display) -> CargoResult<()> {
print("error", message, Color::Red, false)
print("error", message, ERROR, false)
}

/// Print a styled warning message.
pub fn warn(message: impl std::fmt::Display) -> CargoResult<()> {
print("warning", message, Color::Yellow, false)
print("warning", message, WARN, false)
}

/// Print a styled warning message.
pub fn note(message: impl std::fmt::Display) -> CargoResult<()> {
print("note", message, Color::Cyan, false)
print("note", message, NOTE, false)
}

pub fn log(level: log::Level, message: impl std::fmt::Display) -> CargoResult<()> {
Expand All @@ -97,12 +73,7 @@ pub fn log(level: log::Level, message: impl std::fmt::Display) -> CargoResult<()
}

/// Print a part of a line with formatting
pub fn write_stderr(fragment: impl std::fmt::Display, spec: &ColorSpec) -> CargoResult<()> {
let color_choice = colorize_stderr();
let mut output = StandardStream::stderr(color_choice);

output.set_color(spec)?;
write!(output, "{}", fragment)?;
output.reset()?;
pub fn write_stderr(fragment: impl std::fmt::Display, style: &Style) -> CargoResult<()> {
write!(anstream::stderr(), "{style}{fragment}{style:#}")?;
Ok(())
}
13 changes: 13 additions & 0 deletions src/ops/style.rs
Original file line number Diff line number Diff line change
@@ -0,0 +1,13 @@
use anstyle::{AnsiColor, Effects, Style};

pub const NOP: Style = Style::new();
pub const HEADER: Style = AnsiColor::Green.on_default().effects(Effects::BOLD);
pub const USAGE: Style = AnsiColor::Green.on_default().effects(Effects::BOLD);
pub const LITERAL: Style = AnsiColor::Cyan.on_default().effects(Effects::BOLD);
pub const PLACEHOLDER: Style = AnsiColor::Cyan.on_default();
pub const ERROR: Style = AnsiColor::Red.on_default().effects(Effects::BOLD);
pub const WARN: Style = AnsiColor::Yellow.on_default().effects(Effects::BOLD);
pub const NOTE: Style = AnsiColor::Cyan.on_default().effects(Effects::BOLD);
pub const GOOD: Style = AnsiColor::Green.on_default().effects(Effects::BOLD);
pub const VALID: Style = AnsiColor::Cyan.on_default().effects(Effects::BOLD);
pub const INVALID: Style = AnsiColor::Yellow.on_default().effects(Effects::BOLD);
26 changes: 11 additions & 15 deletions src/steps/changes.rs
Original file line number Diff line number Diff line change
@@ -1,8 +1,7 @@
use crate::error::CargoResult;
use crate::error::CliError;
use crate::ops::git;
use crate::ops::shell::Color;
use crate::ops::shell::ColorSpec;
use crate::ops::style::{ERROR, GOOD, NOP, WARN};
use crate::ops::version::VersionExt as _;
use crate::steps::plan;

Expand Down Expand Up @@ -186,17 +185,14 @@ pub fn changes(
let mut max_status = None;
for commit in &commits {
#[allow(clippy::needless_borrow)] // False positive
let _ = crate::ops::shell::write_stderr(&prefix, &ColorSpec::new());
let _ = crate::ops::shell::write_stderr(
&commit.short_id,
ColorSpec::new().set_fg(Some(Color::Yellow)),
);
let _ = crate::ops::shell::write_stderr(" ", &ColorSpec::new());
let _ = crate::ops::shell::write_stderr(&commit.summary, &ColorSpec::new());
let _ = crate::ops::shell::write_stderr(&prefix, &NOP);
let _ = crate::ops::shell::write_stderr(&commit.short_id, &WARN);
let _ = crate::ops::shell::write_stderr(" ", &NOP);
let _ = crate::ops::shell::write_stderr(&commit.summary, &NOP);

let current_status = commit.status();
write_status(current_status);
let _ = crate::ops::shell::write_stderr("\n", &ColorSpec::new());
let _ = crate::ops::shell::write_stderr("\n", &NOP);
match (current_status, max_status) {
(Some(cur), Some(max)) => {
max_status = Some(cur.max(max));
Expand Down Expand Up @@ -272,25 +268,25 @@ pub fn changes(
fn write_status(status: Option<CommitStatus>) {
if let Some(status) = status {
let suffix;
let mut color = ColorSpec::new();
let mut style = NOP;
match status {
CommitStatus::Breaking => {
suffix = " (breaking)";
color.set_fg(Some(Color::Red));
style = ERROR;
}
CommitStatus::Feature => {
suffix = " (feature)";
color.set_fg(Some(Color::Yellow));
style = WARN;
}
CommitStatus::Fix => {
suffix = " (fix)";
color.set_fg(Some(Color::Green));
style = GOOD;
}
CommitStatus::Ignore => {
suffix = "";
}
}
let _ = crate::ops::shell::write_stderr(suffix, &color);
let _ = crate::ops::shell::write_stderr(suffix, &style);
}
}

Expand Down

0 comments on commit e59e657

Please sign in to comment.