Report permission changes

Fixes #605
pull/614/head
Wilfred Hughes 2023-12-30 11:19:49 +07:00
parent 68f28a8085
commit db0c150f61
3 changed files with 73 additions and 2 deletions

@ -7,6 +7,10 @@ Added support for Salesforce Apex.
Improved parsing of regex literals in Clojure and strictness
annotations in Haskell.
### Diffing
Difftastic will now also report file permission changes.
### Display
Fixed a rare crash when the last non-blank line had changes for

@ -23,7 +23,7 @@ sample_files/change_outer_before.el sample_files/change_outer_after.el
8ed3308b9eabd486bdbe9aa2e7dc9be6 -
sample_files/chinese_before.po sample_files/chinese_after.po
b5cf768305ee724d456aedfc20095226 -
097250024d46c75a159b8a8efe9a1e51 -
sample_files/clojure_before.clj sample_files/clojure_after.clj
34a723cb5ec5a81f3ae5c01a64bca6c2 -

@ -73,6 +73,7 @@ use crate::parse::syntax;
#[global_allocator]
static GLOBAL: MiMalloc = MiMalloc;
use std::fs::Permissions;
use std::path::Path;
use std::{env, thread};
@ -330,6 +331,62 @@ fn main() {
};
}
#[cfg(unix)]
fn compare_permissions(lhs: &Permissions, rhs: &Permissions) -> Option<String> {
use std::os::unix::fs::PermissionsExt;
let lhs_mode = lhs.mode();
let rhs_mode = rhs.mode();
if lhs_mode != rhs_mode {
let lhs_mode = format!("{:o}", lhs_mode);
let rhs_mode = format!("{:o}", rhs_mode);
Some(format!(
"File permissions changed from {} to {}.",
lhs_mode, rhs_mode
))
} else {
None
}
}
#[cfg(windows)]
fn compare_permissions(lhs: &Permissions, rhs: &Permissions) -> Option<String> {
if lhs.readonly() != rhs.readonly() {
Some(format!(
"File permissions changed from {} to {}.",
if lhs.readonly() {
"readonly"
} else {
"read-write"
},
if rhs.readonly() {
"readonly"
} else {
"read-write"
},
))
} else {
None
}
}
#[cfg(not(any(unix, windows)))]
fn compare_permissions(_lhs: &Permissions, _rhs: &Permissions) -> Option<String> {
None
}
fn describe_permissions_change(lhs_path: &FileArgument, rhs_path: &FileArgument) -> Option<String> {
match (lhs_path, rhs_path) {
(FileArgument::NamedPath(lhs_path), FileArgument::NamedPath(rhs_path)) => {
let lhs_metadata = std::fs::metadata(lhs_path).ok()?;
let rhs_metadata = std::fs::metadata(rhs_path).ok()?;
compare_permissions(&lhs_metadata.permissions(), &rhs_metadata.permissions())
}
_ => None,
}
}
/// Print a diff between two files.
fn diff_file(
display_path: &str,
@ -365,9 +422,19 @@ fn diff_file(
rhs_src.retain(|c| c != '\r');
}
let mut extra_info = renamed;
if let Some(permissions_change) = describe_permissions_change(lhs_path, rhs_path) {
if let Some(extra_info) = &mut extra_info {
extra_info.push('\n');
extra_info.push_str(&permissions_change);
} else {
extra_info = Some(permissions_change);
}
}
diff_file_content(
display_path,
renamed,
extra_info,
lhs_path,
rhs_path,
&lhs_src,