use super::{Finding, Scanner};
use crate::git::Repo;
pub struct StashScanner;
impl Scanner for StashScanner {
fn name(&self) -> &'static str {
"Stashes"
}
fn scan(&self, repo: &Repo) -> Vec<Finding> {
let out = match repo.run(&["stash", "list", "--format=%gd%x09%H%x09%ct%x09%s"]) {
Ok(o) => o,
Err(_) => return Vec::new(),
};
let mut results = Vec::new();
for line in out.lines() {
let parts: Vec<&str> = line.splitn(4, '\t').collect();
if parts.len() < 4 {
continue;
}
let index = parts[0].to_string();
let sha = parts[1].to_string();
let ts: u64 = parts[2].parse().unwrap_or(0);
let msg = parts[3].to_string();
let (files_changed, insertions, deletions) = stash_stats(repo, &index);
results.push(Finding::Stash {
index,
sha,
ts,
message: msg,
files_changed,
insertions,
deletions,
});
}
results.sort_by_key(|f| f.timestamp());
results
}
}
fn stash_stats(repo: &Repo, index: &str) -> (usize, usize, usize) {
let out = match repo.run(&["stash", "show", "--numstat", index]) {
Ok(o) => o,
Err(_) => return (0, 0, 0),
};
let mut files = 0usize;
let mut ins = 0usize;
let mut dels = 0usize;
for line in out.lines() {
let parts: Vec<&str> = line.split_whitespace().collect();
if parts.len() >= 3 {
files += 1;
ins += parts[0].parse::<usize>().unwrap_or(0);
dels += parts[1].parse::<usize>().unwrap_or(0);
}
}
(files, ins, dels)
}