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" source = "registry+https://github.com/rust-lang/crates.io-index"
checksum = "bef38d45163c2f1dde094a7dfd33ccf595c92905c8f8f4fdc18d06fb1037718a" 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]] [[package]]
name = "camino" name = "camino"
version = "1.0.5" version = "1.0.5"
@ -443,6 +454,12 @@ dependencies = [
"regex-syntax", "regex-syntax",
] ]
[[package]]
name = "regex-automata"
version = "0.1.10"
source = "registry+https://github.com/rust-lang/crates.io-index"
checksum = "6c230d73fb8d8c1b9c0b3135c5142a8acee3a0558fb8db5cf1cb65f8d7862132"
[[package]] [[package]]
name = "regex-syntax" name = "regex-syntax"
version = "0.6.25" version = "0.6.25"
@ -469,6 +486,10 @@ name = "similar"
version = "2.1.0" version = "2.1.0"
source = "registry+https://github.com/rust-lang/crates.io-index" source = "registry+https://github.com/rust-lang/crates.io-index"
checksum = "2e24979f63a11545f5f2c60141afe249d4f19f84581ea2138065e400941d83d3" checksum = "2e24979f63a11545f5f2c60141afe249d4f19f84581ea2138065e400941d83d3"
dependencies = [
"bstr",
"unicode-segmentation",
]
[[package]] [[package]]
name = "snafu" name = "snafu"

View File

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

View File

@ -95,6 +95,14 @@ impl Color {
self.restyle(Style::new().fg(Green)) 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 { pub(crate) fn active(&self) -> bool {
match self.use_color { match self.use_color {
UseColor::Always => true, UseColor::Always => true,

View File

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

View File

@ -77,7 +77,7 @@ impl Subcommand {
justfile.run(config, &search, overrides, &[])? justfile.run(config, &search, overrides, &[])?
} }
Dump => Self::dump(ast), Dump => Self::dump(ast),
Format => Self::format(config, ast, &src, &search)?, Format => Self::format(config, &search, &src, ast)?,
List => Self::list(config, justfile), List => Self::list(config, justfile),
Run { Run {
arguments, arguments,
@ -255,33 +255,47 @@ impl Subcommand {
Ok(()) 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.")?; config.require_unstable("The `--fmt` command is currently unstable.")?;
let src_formatted = ast.to_string(); let formatted = ast.to_string();
if config.check { if config.check {
if src == src_formatted { return if formatted != src {
Ok(()) use similar::{ChangeTag, TextDiff};
} else {
print!( let diff = TextDiff::configure()
"{}", .algorithm(similar::Algorithm::Patience)
similar::udiff::unified_diff(similar::Algorithm::Patience, &src, &src_formatted, 2, None) .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) Err(Error::FormatCheckFoundDiff)
} } else {
} else if let Err(io_error) = Ok(())
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(())
} }
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>> { fn init(config: &Config) -> Result<(), Error<'static>> {

View File

@ -22,7 +22,7 @@ test! {
} }
test! { test! {
name: dry_run_ok, name: check_ok,
justfile: r#" justfile: r#"
# comment with spaces # comment with spaces
@ -42,20 +42,29 @@ deps:
} }
test! { test! {
name: dry_run_found_diff, name: check_found_diff,
justfile: "x:=``\n", justfile: "x:=``\n",
args: ("--unstable", "--fmt", "--check"), args: ("--unstable", "--fmt", "--check"),
stdout: "
@@ -1 +1 @@
-x:=``
+x := ``
",
stderr: " stderr: "
-x:=``
+x := ``
error: Formatted justfile differs from original. error: Formatted justfile differs from original.
", ",
status: EXIT_FAILURE, 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] #[test]
fn unstable_passed() { fn unstable_passed() {
let tmp = tempdir(); let tmp = tempdir();