Add color to just --fmt --check diff (#1015)

This commit is contained in:
Casey Rodarmor 2021-10-31 23:18:11 -07:00 committed by GitHub
parent 1cf8a714e2
commit f3abb95c78
No known key found for this signature in database
GPG key ID: 4AEE18F83AFDEB23
6 changed files with 87 additions and 32 deletions

21
Cargo.lock generated
View file

@ -52,6 +52,17 @@ version = "1.3.2"
source = "registry+https://github.com/rust-lang/crates.io-index"
checksum = "bef38d45163c2f1dde094a7dfd33ccf595c92905c8f8f4fdc18d06fb1037718a"
[[package]]
name = "bstr"
version = "0.2.17"
source = "registry+https://github.com/rust-lang/crates.io-index"
checksum = "ba3569f383e8f1598449f1a423e72e99569137b47740b1da11ef19af3d5c3223"
dependencies = [
"lazy_static",
"memchr",
"regex-automata",
]
[[package]]
name = "camino"
version = "1.0.5"
@ -443,6 +454,12 @@ dependencies = [
"regex-syntax",
]
[[package]]
name = "regex-automata"
version = "0.1.10"
source = "registry+https://github.com/rust-lang/crates.io-index"
checksum = "6c230d73fb8d8c1b9c0b3135c5142a8acee3a0558fb8db5cf1cb65f8d7862132"
[[package]]
name = "regex-syntax"
version = "0.6.25"
@ -469,6 +486,10 @@ name = "similar"
version = "2.1.0"
source = "registry+https://github.com/rust-lang/crates.io-index"
checksum = "2e24979f63a11545f5f2c60141afe249d4f19f84581ea2138065e400941d83d3"
dependencies = [
"bstr",
"unicode-segmentation",
]
[[package]]
name = "snafu"

View file

@ -28,7 +28,6 @@ lexiclean = "0.0.1"
libc = "0.2.0"
log = "0.4.4"
regex = "1.5.4"
similar = "2.1.0"
snafu = "0.6.0"
strum_macros = "0.22.0"
target = "2.0.0"
@ -44,6 +43,10 @@ features = ["wrap_help"]
version = "3.1.1"
features = ["termination"]
[dependencies.similar]
version = "2.1.0"
features = ["unicode"]
[dependencies.strum]
version = "0.22.0"
features = ["derive"]

View file

@ -95,6 +95,14 @@ impl Color {
self.restyle(Style::new().fg(Green))
}
pub(crate) fn diff_added(self) -> Self {
self.restyle(Style::new().fg(Green))
}
pub(crate) fn diff_deleted(self) -> Self {
self.restyle(Style::new().fg(Red))
}
pub(crate) fn active(&self) -> bool {
match self.use_color {
UseColor::Always => true,

View file

@ -5,7 +5,7 @@ pub(crate) use std::{
env,
ffi::{OsStr, OsString},
fmt::{self, Debug, Display, Formatter},
fs::{self, File},
fs,
io::{self, Cursor, Write},
iter::{self, FromIterator},
mem,

View file

@ -77,7 +77,7 @@ impl Subcommand {
justfile.run(config, &search, overrides, &[])?
}
Dump => Self::dump(ast),
Format => Self::format(config, ast, &src, &search)?,
Format => Self::format(config, &search, &src, ast)?,
List => Self::list(config, justfile),
Run {
arguments,
@ -255,33 +255,47 @@ impl Subcommand {
Ok(())
}
fn format(config: &Config, ast: Ast, src: &str, search: &Search) -> Result<(), Error<'static>> {
fn format(config: &Config, search: &Search, src: &str, ast: Ast) -> Result<(), Error<'static>> {
config.require_unstable("The `--fmt` command is currently unstable.")?;
let src_formatted = ast.to_string();
let formatted = ast.to_string();
if config.check {
if src == src_formatted {
Ok(())
} else {
print!(
"{}",
similar::udiff::unified_diff(similar::Algorithm::Patience, &src, &src_formatted, 2, None)
);
return if formatted != src {
use similar::{ChangeTag, TextDiff};
let diff = TextDiff::configure()
.algorithm(similar::Algorithm::Patience)
.diff_lines(src, &formatted);
for op in diff.ops() {
for change in diff.iter_changes(op) {
let (symbol, color) = match change.tag() {
ChangeTag::Delete => ("-", config.color.stderr().diff_deleted()),
ChangeTag::Equal => (" ", config.color.stderr()),
ChangeTag::Insert => ("+", config.color.stderr().diff_added()),
};
eprint!("{}{}{}{}", color.prefix(), symbol, change, color.suffix());
}
}
Err(Error::FormatCheckFoundDiff)
}
} else if let Err(io_error) =
File::create(&search.justfile).and_then(|mut file| file.write_all(&src_formatted.as_bytes()))
{
Err(Error::WriteJustfile {
justfile: search.justfile.clone(),
io_error,
})
} else {
if config.verbosity.loud() {
eprintln!("Wrote justfile to `{}`", search.justfile.display());
}
Ok(())
} else {
Ok(())
};
}
fs::write(&search.justfile, formatted).map_err(|io_error| Error::WriteJustfile {
justfile: search.justfile.clone(),
io_error,
})?;
if config.verbosity.loud() {
eprintln!("Wrote justfile to `{}`", search.justfile.display());
}
Ok(())
}
fn init(config: &Config) -> Result<(), Error<'static>> {

View file

@ -22,7 +22,7 @@ test! {
}
test! {
name: dry_run_ok,
name: check_ok,
justfile: r#"
# comment with spaces
@ -42,20 +42,29 @@ deps:
}
test! {
name: dry_run_found_diff,
name: check_found_diff,
justfile: "x:=``\n",
args: ("--unstable", "--fmt", "--check"),
stdout: "
@@ -1 +1 @@
-x:=``
+x := ``
",
stderr: "
-x:=``
+x := ``
error: Formatted justfile differs from original.
",
status: EXIT_FAILURE,
}
test! {
name: check_diff_color,
justfile: "x:=``\n",
args: ("--unstable", "--fmt", "--check", "--color", "always"),
stderr: "
\u{1b}[31m-x:=``
\u{1b}[0m\u{1b}[32m+x := ``
\u{1b}[0m\u{1b}[1;31merror\u{1b}[0m: \u{1b}[1mFormatted justfile differs from original.\u{1b}[0m
",
status: EXIT_FAILURE,
}
#[test]
fn unstable_passed() {
let tmp = tempdir();