From ce6258d1b85f9a4624a430cc2aac2a510aabb08a Mon Sep 17 00:00:00 2001 From: Dan Davison Date: Wed, 17 Nov 2021 21:48:32 -0500 Subject: Obtain parent git grep command line options --- src/utils/process.rs | 84 ++++++++++++++++++++++++++++++++++++++++++++++++++++ 1 file changed, 84 insertions(+) diff --git a/src/utils/process.rs b/src/utils/process.rs index 5455ca3c..5e7a457e 100644 --- a/src/utils/process.rs +++ b/src/utils/process.rs @@ -17,6 +17,10 @@ pub fn git_blame_filename_extension() -> Option { calling_process_cmdline(ProcInfo::new(), blame::guess_git_blame_filename_extension) } +pub fn git_grep_command_options() -> Option<(HashSet, HashSet)> { + calling_process_cmdline(ProcInfo::new(), grep::get_grep_options) +} + mod blame { use super::*; @@ -75,6 +79,34 @@ mod blame { } } // mod blame +mod grep { + use super::*; + + // Given `... grep --aa val -bc -d val e f -- ...` return + // ({"--aa"}, {"-b", "-c", "-d"}) + pub fn get_grep_options(args: &[String]) -> ProcessArgs<(HashSet, HashSet)> { + let mut args = args.iter().map(|s| s.as_str()).skip_while(|s| *s != "grep"); + match args.next() { + None => ProcessArgs::OtherProcess, + _ => { + let mut longs = HashSet::new(); + let mut shorts = HashSet::new(); + + for s in args { + if s == "--" { + break; + } else if s.starts_with("--") { + longs.insert(s.split('=').next().unwrap().to_owned()); + } else if let Some(suffix) = s.strip_prefix('-') { + shorts.extend(suffix.chars().map(|c| format!("-{}", c))); + } + } + ProcessArgs::Args((longs, shorts)) + } + } + } +} + struct ProcInfo { info: sysinfo::System, } @@ -555,6 +587,58 @@ pub mod tests { ); } + #[test] + fn test_get_grep_options() { + let no_processes = MockProcInfo::with(&[]); + assert_eq!( + calling_process_cmdline(no_processes, grep::get_grep_options), + None + ); + + let parent = MockProcInfo::with(&[ + (2, 100, "-shell", None), + (3, 100, "git grep pattern hello.txt", Some(2)), + (4, 100, "delta", Some(3)), + ]); + assert_eq!( + calling_process_cmdline(parent, grep::get_grep_options), + Some(([].into(), [].into())) + ); + + fn set(arg1: &[&str]) -> HashSet { + arg1.iter().map(|&s| s.to_owned()).collect() + } + + let git_grep_command = + "git grep -ab --function-context -n --show-function -W --foo=val pattern hello.txt"; + + let expected_result = Some(( + set(&["--function-context", "--show-function", "--foo"]), + set(&["-a", "-b", "-n", "-W"]), + )); + + let parent = MockProcInfo::with(&[ + (2, 100, "-shell", None), + (3, 100, git_grep_command, Some(2)), + (4, 100, "delta", Some(3)), + ]); + assert_eq!( + calling_process_cmdline(parent, grep::get_grep_options), + expected_result + ); + + let grandparent = MockProcInfo::with(&[ + (2, 100, "-shell", None), + (3, 100, git_grep_command, Some(2)), + (4, 100, "call_delta.sh", Some(3)), + (5, 100, "delta", Some(4)), + ]); + assert_eq!( + calling_process_cmdline(grandparent, grep::get_grep_options), + expected_result + ); + } + #[test] fn test_process_calling_cmdline() { // Github runs CI tests for arm under qemu where where sysinfo can not find the parent processr. -- cgit v1.2.3