1use super::script;
2use std::{fs, io, path::Path};
3
4pub struct TomeIgnorer {
5 gitignore: ignore::gitignore::Gitignore,
6}
7
8impl TomeIgnorer {
9 pub fn new(root: &Path) -> Self {
10 let mut builder = ignore::gitignore::GitignoreBuilder::new(root);
11 let tomeignore_path = root.join(".tomeignore");
12 if tomeignore_path.exists() {
13 if let Ok(metadata) = fs::metadata(&tomeignore_path) {
14 if metadata.len() > 0 {
15 builder.add(tomeignore_path);
16 }
17 }
18 }
19 let gitignore = builder.build().unwrap_or(ignore::gitignore::Gitignore::empty());
20 Self { gitignore }
21 }
22
23 pub fn is_ignored(&self, path: &Path) -> bool {
24 if path.file_name()
26 .unwrap_or_default()
27 .to_str()
28 .unwrap_or_default()
29 .starts_with('.') {
30 return true;
31 }
32
33 if path.is_dir() {
35 let tomeignore_path = path.join(".tomeignore");
36 if tomeignore_path.exists() {
37 if let Ok(metadata) = fs::metadata(&tomeignore_path) {
38 if metadata.len() == 0 {
39 return true;
40 }
41 }
42 }
43 }
44
45 self.gitignore.matched_path_or_any_parents(path, path.is_dir()).is_ignore()
46 }
47}
48
49pub fn scan_directory(
52 root: &str,
53 previous_commands: &mut Vec<String>,
54 ignorer: &TomeIgnorer,
55) -> io::Result<Vec<(String, script::Script)>> {
56 let mut result = vec![];
57 let paths_raw = fs::read_dir(root);
58 if paths_raw.is_err() {
59 return Ok(vec![]);
60 }
61 let paths: Vec<_> = paths_raw.unwrap().map(|r| r.unwrap()).collect();
62 for entry in paths {
63 let path = entry.path();
64
65 if ignorer.is_ignored(&path) {
66 continue;
67 }
68
69 let file_name = path.file_name().unwrap_or_default().to_str().unwrap_or_default();
70 let command_name = script::strip_source_suffix(file_name).to_string();
71 previous_commands.push(command_name);
72 if path.is_dir() {
73 result.extend(scan_directory(
74 path.as_path().to_str().unwrap_or_default(),
75 previous_commands,
76 ignorer,
77 )?);
78 } else if script::is_tome_script(&path) {
79 result.push((
80 previous_commands.join(" "),
81 script::Script::load(path.as_path().to_str().unwrap_or_default())?,
82 ));
83 }
84 previous_commands.pop();
85 }
86 Ok(result)
87}
88