From 4bc06b3a3ed65c68e32f3d3914b32027618f2cc6 Mon Sep 17 00:00:00 2001 From: HouXiaoxuan Date: Fri, 13 Dec 2024 16:29:03 +0800 Subject: [PATCH 1/2] feat(libra): display file type in diff results Signed-off-by: HouXiaoxuan --- libra/Cargo.toml | 1 + libra/src/command/diff.rs | 30 +++++++++++++++++++++--------- 2 files changed, 22 insertions(+), 9 deletions(-) diff --git a/libra/Cargo.toml b/libra/Cargo.toml index ce6348bf1..6e04b6c80 100644 --- a/libra/Cargo.toml +++ b/libra/Cargo.toml @@ -25,6 +25,7 @@ gemini = { workspace = true, optional = true } hex = { workspace = true } imara-diff = "0.1.7" indicatif = "0.17.8" +infer = "0.16.0" lazy_static = { workspace = true } lru-mem = "0.3.0" mercury = { workspace = true } diff --git a/libra/src/command/diff.rs b/libra/src/command/diff.rs index 3518a9382..d6076a74a 100644 --- a/libra/src/command/diff.rs +++ b/libra/src/command/diff.rs @@ -2,7 +2,7 @@ use std::{ collections::{HashMap, HashSet}, fmt, io::{self, Write}, - path::PathBuf, + path::{Path, PathBuf}, }; use clap::Parser; @@ -216,15 +216,13 @@ pub async fn diff( writeln!(w, "deleted file mode 100644").unwrap(); } - let old_index = old_hash.map_or("0000000".to_string(), |h| { - h.to_string()[0..8].to_string() - }); - let new_index = new_hash.map_or("0000000".to_string(), |h| { - h.to_string()[0..8].to_string() - }); + let old_index = old_hash.map_or("0000000".to_string(), |h| h.to_string()[0..8].to_string()); + let new_index = new_hash.map_or("0000000".to_string(), |h| h.to_string()[0..8].to_string()); writeln!(w, "index {}..{}", old_index, new_index).unwrap(); // check is the content is valid utf-8 or maybe binary + let old_type = infer::get(&old_content); + let new_type = infer::get(&new_content); match ( String::from_utf8(old_content), String::from_utf8(new_content), @@ -237,8 +235,8 @@ pub async fn diff( writeln!( w, "Binary files a/{} and b/{} differ", - file.display(), - file.display() + file_display(&file, old_type), + file_display(&file, new_type) ) .unwrap(); } @@ -264,6 +262,20 @@ fn get_files_blobs(files: &[PathBuf]) -> Vec<(PathBuf, SHA1)> { .collect() } +// display file with type +fn file_display(file: &Path, file_type: Option) -> String { + if let Some(file_type) = file_type { + // Check if the file type is displayable in browser, like image, audio, video, etc. + if matches!( + file_type.matcher_type(), + infer::MatcherType::Audio | infer::MatcherType::Video | infer::MatcherType::Image + ) { + return format!("{} ({})", file.display(), file_type.mime_type()).to_string(); + } + } + file.display().to_string() +} + struct Line(Option); impl fmt::Display for Line { From 7ac49af745f7d6db59944c2bc9e017cded2f7602 Mon Sep 17 00:00:00 2001 From: HouXiaoxuan Date: Fri, 13 Dec 2024 17:13:31 +0800 Subject: [PATCH 2/2] fix(libra): redirect error path to `/dev/null` when blob is missing Signed-off-by: HouXiaoxuan --- libra/src/command/diff.rs | 16 ++++++++++------ 1 file changed, 10 insertions(+), 6 deletions(-) diff --git a/libra/src/command/diff.rs b/libra/src/command/diff.rs index d6076a74a..7f44af601 100644 --- a/libra/src/command/diff.rs +++ b/libra/src/command/diff.rs @@ -219,7 +219,6 @@ pub async fn diff( let old_index = old_hash.map_or("0000000".to_string(), |h| h.to_string()[0..8].to_string()); let new_index = new_hash.map_or("0000000".to_string(), |h| h.to_string()[0..8].to_string()); writeln!(w, "index {}..{}", old_index, new_index).unwrap(); - // check is the content is valid utf-8 or maybe binary let old_type = infer::get(&old_content); let new_type = infer::get(&new_content); @@ -235,8 +234,8 @@ pub async fn diff( writeln!( w, "Binary files a/{} and b/{} differ", - file_display(&file, old_type), - file_display(&file, new_type) + file_display(&file, old_hash, old_type), + file_display(&file, new_hash, new_type) ) .unwrap(); } @@ -263,17 +262,22 @@ fn get_files_blobs(files: &[PathBuf]) -> Vec<(PathBuf, SHA1)> { } // display file with type -fn file_display(file: &Path, file_type: Option) -> String { +fn file_display(file: &Path, hash: Option<&SHA1>, file_type: Option) -> String { + let file_name = match hash { + Some(_) => file.display().to_string(), + None => "dev/null".to_string(), + }; + if let Some(file_type) = file_type { // Check if the file type is displayable in browser, like image, audio, video, etc. if matches!( file_type.matcher_type(), infer::MatcherType::Audio | infer::MatcherType::Video | infer::MatcherType::Image ) { - return format!("{} ({})", file.display(), file_type.mime_type()).to_string(); + return format!("{} ({})", file_name, file_type.mime_type()).to_string(); } } - file.display().to_string() + file_name } struct Line(Option);