diff options
author | Wilfred Hughes <me@wilfred.me.uk> | 2023-12-30 11:19:49 -0800 |
---|---|---|
committer | Wilfred Hughes <me@wilfred.me.uk> | 2023-12-30 11:20:00 -0800 |
commit | db0c150f61ce6f0923d65f74471bfee7ddf4e0e5 (patch) | |
tree | 84ba10b843db2135a008781b1b7afcf35c970292 | |
parent | 68f28a808506f6e1929e569c7c410b554a4d40dd (diff) |
Report permission changes
Fixes #605
-rw-r--r-- | CHANGELOG.md | 4 | ||||
-rw-r--r-- | sample_files/compare.expected | 2 | ||||
-rw-r--r-- | src/main.rs | 69 |
3 files changed, 73 insertions, 2 deletions
diff --git a/CHANGELOG.md b/CHANGELOG.md index c406a4934..14007e1cd 100644 --- a/CHANGELOG.md +++ b/CHANGELOG.md @@ -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 diff --git a/sample_files/compare.expected b/sample_files/compare.expected index 61ce95301..c8b7cb46a 100644 --- a/sample_files/compare.expected +++ b/sample_files/compare.expected @@ -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 - diff --git a/src/main.rs b/src/main.rs index 76e45d98f..ba0e028be 100644 --- a/src/main.rs +++ b/src/main.rs @@ -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, |