1use std::path::Path;
4
5#[derive(Debug, Clone, Copy, PartialEq, Eq)]
6pub enum ReviewMode {
7 Comment,
9 App,
11}
12
13impl ReviewMode {
14 fn parse(value: Option<&str>) -> Option<Self> {
15 match value.map(str::trim) {
16 Some("app") => Some(Self::App),
17 Some("comment") => Some(Self::Comment),
18 Some(other) if !other.is_empty() => {
19 tracing::warn!(
20 value = other,
21 "unknown review.mode, expected comment or app"
22 );
23 None
24 }
25 _ => None,
26 }
27 }
28}
29
30pub fn resolve(project: Option<&str>, global: Option<&str>) -> ReviewMode {
32 ReviewMode::parse(project)
33 .or_else(|| ReviewMode::parse(global))
34 .unwrap_or(ReviewMode::Comment)
35}
36
37pub fn for_repo(repo: &str) -> ReviewMode {
39 let project_dir = crate::config::get_projects_with_paths()
40 .ok()
41 .and_then(|projects| projects.into_iter().find(|(r, _)| r == repo))
42 .map(|(_, dir)| dir);
43 for_project_dir(project_dir.as_deref())
44}
45
46pub fn for_project_dir(project_dir: Option<&Path>) -> ReviewMode {
47 let project =
48 project_dir.and_then(|dir| crate::config::get_project_only(dir, "review.mode").ok());
49 let global = crate::config::get_global("review.mode").ok();
50 resolve(project.as_deref(), global.as_deref())
51}
52
53#[cfg(test)]
54mod tests {
55 use super::*;
56
57 #[test]
58 fn project_beats_global_and_comment_is_the_default() {
59 assert_eq!(resolve(Some("app"), Some("comment")), ReviewMode::App);
60 assert_eq!(resolve(Some("comment"), Some("app")), ReviewMode::Comment);
61 assert_eq!(resolve(None, Some("app")), ReviewMode::App);
62 assert_eq!(resolve(None, None), ReviewMode::Comment);
63 }
64
65 #[test]
66 fn an_unknown_value_falls_through_to_the_next_source() {
67 assert_eq!(resolve(Some("bogus"), Some("app")), ReviewMode::App);
68 assert_eq!(resolve(Some(" app "), None), ReviewMode::App);
69 assert_eq!(resolve(Some(""), None), ReviewMode::Comment);
70 }
71
72 #[test]
73 fn the_project_file_is_read_without_the_global_fallback() {
74 let dir = tempfile::tempdir().unwrap();
75 std::fs::write(dir.path().join(".orch.yml"), "review:\n mode: app\n").unwrap();
76 let value = crate::config::get_project_only(dir.path(), "review.mode").unwrap();
77 assert_eq!(value, "app");
78
79 let empty = tempfile::tempdir().unwrap();
80 assert!(crate::config::get_project_only(empty.path(), "review.mode").is_err());
81 }
82}