Skip to content
Merged
Show file tree
Hide file tree
Changes from all commits
Commits
File filter

Filter by extension

Filter by extension


Conversations
Failed to load comments.
Loading
Jump to
Jump to file
Failed to load files.
Loading
Diff view
Diff view
4 changes: 2 additions & 2 deletions Cargo.lock

Some generated files are not rendered by default. Learn more about how customized files appear on GitHub.

2 changes: 1 addition & 1 deletion Cargo.toml
Original file line number Diff line number Diff line change
Expand Up @@ -53,7 +53,7 @@ default-features = false
features = ["parsing", "assets", "yaml-load", "dump-load", "regex-onig"]

[dependencies.sysinfo]
version = "0.22.4"
version = "0.23.0"
# no default features to disable the use of threads
default-features = false
features = []
Expand Down
3 changes: 1 addition & 2 deletions src/config.rs
Original file line number Diff line number Diff line change
Expand Up @@ -281,8 +281,7 @@ impl From<cli::Opt> for Config {
file_regex_replacement: opt
.file_regex_replacement
.as_deref()
.map(RegexReplacement::from_sed_command)
.flatten(),
.and_then(RegexReplacement::from_sed_command),
right_arrow,
hunk_label,
file_style: styles["file-style"],
Expand Down
3 changes: 1 addition & 2 deletions src/handlers/grep.rs
Original file line number Diff line number Diff line change
Expand Up @@ -454,8 +454,7 @@ pub fn _parse_grep_line<'b>(regex: &Regex, line: &'b str) -> Option<GrepLine<'b>
.iter()
.find_map(|(i, line_type)| {
if caps.get(*i).is_some() {
let line_number: Option<usize> =
caps.get(i + 1).map(|m| m.as_str().parse().ok()).flatten();
let line_number: Option<usize> = caps.get(i + 1).and_then(|m| m.as_str().parse().ok());
Some((*line_type, line_number))
} else {
None
Expand Down
2 changes: 1 addition & 1 deletion src/subcommands/show_config.rs
Original file line number Diff line number Diff line change
Expand Up @@ -136,7 +136,7 @@ pub fn show_config(config: &config::Config, writer: &mut dyn Write) -> std::io::
navigate = config.navigate,
navigate_regex = match &config.navigate_regex {
None => "".to_string(),
Some(s) => format_option_value(s.to_string()),
Some(s) => format_option_value(s),
},
pager = config.pager.clone().unwrap_or_else(|| "none".to_string()),
paging_mode = match config.paging_mode {
Expand Down
99 changes: 63 additions & 36 deletions src/utils/process.rs
Original file line number Diff line number Diff line change
Expand Up @@ -3,7 +3,9 @@ use std::path::Path;
use std::sync::{Arc, Condvar, Mutex, MutexGuard};

use lazy_static::lazy_static;
use sysinfo::{Pid, Process, ProcessExt, ProcessRefreshKind, SystemExt};
use sysinfo::{Pid, PidExt, Process, ProcessExt, ProcessRefreshKind, SystemExt};

pub type DeltaPid = u32;

#[derive(Clone, Debug, PartialEq)]
pub enum CallingProcess {
Expand Down Expand Up @@ -283,7 +285,7 @@ impl ProcInfo {

trait ProcActions {
fn cmd(&self) -> &[String];
fn parent(&self) -> Option<Pid>;
fn parent(&self) -> Option<DeltaPid>;
fn start_time(&self) -> u64;
}

Expand All @@ -294,8 +296,8 @@ where
fn cmd(&self) -> &[String] {
ProcessExt::cmd(self)
}
fn parent(&self) -> Option<Pid> {
ProcessExt::parent(self)
fn parent(&self) -> Option<DeltaPid> {
ProcessExt::parent(self).map(|p| p.as_u32())
}
fn start_time(&self) -> u64 {
ProcessExt::start_time(self)
Expand All @@ -305,26 +307,30 @@ where
trait ProcessInterface {
type Out: ProcActions;

fn my_pid(&self) -> Pid;
fn my_pid(&self) -> DeltaPid;

fn process(&self, pid: Pid) -> Option<&Self::Out>;
fn process(&self, pid: DeltaPid) -> Option<&Self::Out>;
fn processes(&self) -> &HashMap<Pid, Self::Out>;

fn refresh_process(&mut self, pid: Pid) -> bool;
fn refresh_process(&mut self, pid: DeltaPid) -> bool;
fn refresh_processes(&mut self);

fn parent_process(&mut self, pid: Pid) -> Option<&Self::Out> {
fn parent_process(&mut self, pid: DeltaPid) -> Option<&Self::Out> {
self.refresh_process(pid).then(|| ())?;
let parent_pid = self.process(pid)?.parent()?;
self.refresh_process(parent_pid).then(|| ())?;
self.process(parent_pid)
}
fn naive_sibling_process(&mut self, pid: Pid) -> Option<&Self::Out> {
fn naive_sibling_process(&mut self, pid: DeltaPid) -> Option<&Self::Out> {
let sibling_pid = pid - 1;
self.refresh_process(sibling_pid).then(|| ())?;
self.process(sibling_pid)
}
fn find_sibling_in_refreshed_processes<F, T>(&mut self, pid: Pid, extract_args: &F) -> Option<T>
fn find_sibling_in_refreshed_processes<F, T>(
&mut self,
pid: DeltaPid,
extract_args: &F,
) -> Option<T>
where
F: Fn(&[String]) -> ProcessArgs<T>,
Self: Sized,
Expand All @@ -349,7 +355,7 @@ trait ProcessInterface {

let this_start_time = self.process(pid)?.start_time();

let mut pid_distances = HashMap::<Pid, usize>::new();
let mut pid_distances = HashMap::<DeltaPid, usize>::new();
let mut collect_parent_pids = |pid, distance| {
pid_distances.insert(pid, distance);
};
Expand All @@ -376,7 +382,7 @@ trait ProcessInterface {
}
}
};
iter_parents(self, pid, &mut sum_distance);
iter_parents(self, pid.as_u32(), &mut sum_distance);

if length_of_process_chain == usize::MAX {
None
Expand All @@ -396,15 +402,15 @@ trait ProcessInterface {
impl ProcessInterface for ProcInfo {
type Out = Process;

fn my_pid(&self) -> Pid {
std::process::id() as Pid
fn my_pid(&self) -> DeltaPid {
std::process::id()
}
fn refresh_process(&mut self, pid: Pid) -> bool {
fn refresh_process(&mut self, pid: DeltaPid) -> bool {
self.info
.refresh_process_specifics(pid, ProcessRefreshKind::new())
.refresh_process_specifics(Pid::from_u32(pid), ProcessRefreshKind::new())
}
fn process(&self, pid: Pid) -> Option<&Self::Out> {
self.info.process(pid)
fn process(&self, pid: DeltaPid) -> Option<&Self::Out> {
self.info.process(Pid::from_u32(pid))
}
fn processes(&self) -> &HashMap<Pid, Self::Out> {
self.info.processes()
Expand Down Expand Up @@ -499,15 +505,15 @@ where

// Walk up the process tree, calling `f` with the pid and the distance to `starting_pid`.
// Prerequisite: `info.refresh_processes()` has been called.
fn iter_parents<P, F>(info: &P, starting_pid: Pid, f: F)
fn iter_parents<P, F>(info: &P, starting_pid: DeltaPid, f: F)
where
P: ProcessInterface,
F: FnMut(Pid, usize),
F: FnMut(DeltaPid, usize),
{
fn inner_iter_parents<P, F>(info: &P, pid: Pid, mut f: F, distance: usize)
fn inner_iter_parents<P, F>(info: &P, pid: DeltaPid, mut f: F, distance: usize)
where
P: ProcessInterface,
F: FnMut(Pid, usize),
F: FnMut(u32, usize),
{
// Probably bad input, not a tree:
if distance > 2000 {
Expand Down Expand Up @@ -696,16 +702,26 @@ pub mod tests {
assert_eq!(guess_git_blame_filename_extension(&args), Args("".into()));
}

#[derive(Debug, Default)]
#[derive(Debug)]
struct FakeProc {
#[allow(dead_code)]
pid: Pid,
pid: DeltaPid,
start_time: u64,
cmd: Vec<String>,
ppid: Option<Pid>,
ppid: Option<DeltaPid>,
}
impl Default for FakeProc {
fn default() -> Self {
Self {
pid: 0,
start_time: 0,
cmd: Vec::new(),
ppid: None,
}
}
}
impl FakeProc {
fn new(pid: Pid, start_time: u64, cmd: Vec<String>, ppid: Option<Pid>) -> Self {
fn new(pid: DeltaPid, start_time: u64, cmd: Vec<String>, ppid: Option<DeltaPid>) -> Self {
FakeProc {
pid,
start_time,
Expand All @@ -719,28 +735,39 @@ pub mod tests {
fn cmd(&self) -> &[String] {
&self.cmd
}
fn parent(&self) -> Option<Pid> {
fn parent(&self) -> Option<DeltaPid> {
self.ppid
}
fn start_time(&self) -> u64 {
self.start_time
}
}

#[derive(Debug, Default)]
#[derive(Debug)]
struct MockProcInfo {
delta_pid: Pid,
delta_pid: DeltaPid,
info: HashMap<Pid, FakeProc>,
}
impl Default for MockProcInfo {
fn default() -> Self {
Self {
delta_pid: 0,
info: HashMap::new(),
}
}
}
impl MockProcInfo {
fn with(processes: &[(Pid, u64, &str, Option<Pid>)]) -> Self {
fn with(processes: &[(DeltaPid, u64, &str, Option<DeltaPid>)]) -> Self {
MockProcInfo {
delta_pid: processes.last().map(|p| p.0).unwrap_or(1),
info: processes
.iter()
.map(|(pid, start_time, cmd, ppid)| {
let cmd_vec = cmd.split(' ').map(str::to_owned).collect();
(*pid, FakeProc::new(*pid, *start_time, cmd_vec, *ppid))
(
Pid::from_u32(*pid),
FakeProc::new(*pid, *start_time, cmd_vec, *ppid),
)
})
.collect(),
}
Expand All @@ -750,17 +777,17 @@ pub mod tests {
impl ProcessInterface for MockProcInfo {
type Out = FakeProc;

fn my_pid(&self) -> Pid {
fn my_pid(&self) -> DeltaPid {
self.delta_pid
}
fn process(&self, pid: Pid) -> Option<&Self::Out> {
self.info.get(&pid)
fn process(&self, pid: DeltaPid) -> Option<&Self::Out> {
self.info.get(&Pid::from_u32(pid))
}
fn processes(&self) -> &HashMap<Pid, Self::Out> {
&self.info
}
fn refresh_processes(&mut self) {}
fn refresh_process(&mut self, _pid: Pid) -> bool {
fn refresh_process(&mut self, _pid: DeltaPid) -> bool {
true
}
}
Expand Down Expand Up @@ -1105,7 +1132,7 @@ pub mod tests {
info.refresh_processes();
let mut ppid_distance = Vec::new();

iter_parents(&info, std::process::id() as Pid, |pid, distance| {
iter_parents(&info, std::process::id(), |pid, distance| {
ppid_distance.push(pid as i32);
ppid_distance.push(distance as i32)
});
Expand Down