1use std::collections::BTreeSet;
8use std::path::PathBuf;
9
10use crate::shell::XtaskShell;
11
12pub fn git_diffed(in_git_hook: bool) -> anyhow::Result<Vec<PathBuf>> {
15 let sh = XtaskShell::new()?;
16
17 let files = sh
18 .cmd("git")
19 .args(["diff", "--diff-filter", "MAR", "--name-only"])
20 .output()?
21 .stdout;
22 let files_cached = sh
23 .cmd("git")
24 .args(["diff", "--diff-filter", "MAR", "--name-only", "--cached"])
25 .output()?
26 .stdout;
27
28 let files = String::from_utf8_lossy(&files);
29 let files_cached = String::from_utf8_lossy(&files_cached);
30
31 let files: Box<dyn Iterator<Item = _>> = if in_git_hook {
33 Box::new(files_cached.lines())
34 } else {
35 Box::new(files_cached.lines().chain(files.lines()))
36 };
37
38 let mut all_files = files.map(PathBuf::from).collect::<Vec<_>>();
39
40 all_files.sort();
41 all_files.dedup();
42 Ok(all_files)
43}
44
45pub fn git_ls_files() -> anyhow::Result<Vec<PathBuf>> {
48 let sh = XtaskShell::new()?;
49
50 macro_rules! as_set {
51 ($($arg:literal),+) => {{
52 let output = sh.cmd("git").args([$($arg),+]).output()?.stdout;
53 let output = String::from_utf8_lossy(&output).to_string();
54 output
55 .split('\n')
56 .map(PathBuf::from)
57 .collect::<BTreeSet<_>>()
58 }};
59 }
60
61 let all = as_set!("ls-files");
63 let extra = as_set!("ls-files", "--others", "--exclude-standard");
64 let deleted = as_set!("ls-files", "--deleted");
65
66 let mut allow_list = all;
67 allow_list.extend(extra);
68 allow_list = allow_list.difference(&deleted).cloned().collect();
69
70 Ok(allow_list.into_iter().collect())
72}