1use clap::Parser;
2
3#[derive(Parser)]
4#[command(author, version, about)]
5pub struct Args {
6 #[arg(
7 short = 'r',
8 long = "repo-path",
9 help = "Path or URI to the repository"
10 )]
11 pub repo_path: Option<String>,
12
13 #[arg(long, help = "Email associated with the commits")]
14 pub email: Option<String>,
15
16 #[arg(short = 'n', long = "name", help = "Name associated with the commits")]
17 pub name: Option<String>,
18
19 #[arg(
20 short = 'b',
21 long = "begin",
22 help = "Start date for the commits in YYYY-MM-DD format"
23 )]
24 pub start: Option<String>,
25
26 #[arg(
27 short = 'e',
28 long = "end",
29 help = "End date for the commits in YYYY-MM-DD format"
30 )]
31 pub end: Option<String>,
32
33 #[arg(
34 short = 's',
35 long = "show-history",
36 help = "Show updated commit history after rewriting"
37 )]
38 pub show_history: bool,
39
40 #[arg(
41 short = 'p',
42 long = "pick-specific-commits",
43 help = "Pick specific commits to rewrite. Provide a comma-separated list of commit hashes."
44 )]
45 pub pic_specific_commits: bool,
46}
47
48impl Args {
49 pub fn ensure_all_args_present(&mut self) {
50 use crate::utils::prompt::prompt_for_missing_arg;
51
52 if self.repo_path.is_none() {
53 self.repo_path = Some(String::from("./"));
54 }
55
56 if self.show_history || self.pic_specific_commits {
58 return;
59 }
60
61 if self.email.is_none() {
62 self.email = Some(prompt_for_missing_arg("email"));
63 }
64
65 if self.name.is_none() {
66 self.name = Some(prompt_for_missing_arg("name"));
67 }
68
69 if self.start.is_none() {
70 self.start = Some(prompt_for_missing_arg("start date (YYYY-MM-DD HH:MM:SS)"));
71 }
72
73 if self.end.is_none() {
74 self.end = Some(prompt_for_missing_arg("end date (YYYY-MM-DD HH:MM:SS)"));
75 }
76 }
77}
78
79#[cfg(test)]
80mod tests {
81 use super::*;
82
83 #[test]
84 fn test_args_default_values() {
85 let args = Args {
86 repo_path: None,
87 email: None,
88 name: None,
89 start: None,
90 end: None,
91 show_history: false,
92 pic_specific_commits: false,
93 };
94
95 assert_eq!(args.repo_path, None);
96 assert_eq!(args.email, None);
97 assert_eq!(args.name, None);
98 assert_eq!(args.start, None);
99 assert_eq!(args.end, None);
100 assert!(!args.show_history);
101 assert!(!args.pic_specific_commits);
102 }
103
104 #[test]
105 fn test_args_with_show_history() {
106 let args = Args {
107 repo_path: Some("/test/repo".to_string()),
108 email: None,
109 name: None,
110 start: None,
111 end: None,
112 show_history: true,
113 pic_specific_commits: false,
114 };
115
116 assert_eq!(args.repo_path, Some("/test/repo".to_string()));
117 assert!(args.show_history);
118 assert!(!args.pic_specific_commits);
119 }
120
121 #[test]
122 fn test_args_with_pick_specific_commits() {
123 let args = Args {
124 repo_path: Some("/test/repo".to_string()),
125 email: None,
126 name: None,
127 start: None,
128 end: None,
129 show_history: false,
130 pic_specific_commits: true,
131 };
132
133 assert_eq!(args.repo_path, Some("/test/repo".to_string()));
134 assert!(!args.show_history);
135 assert!(args.pic_specific_commits);
136 }
137
138 #[test]
139 fn test_args_full_rewrite() {
140 let args = Args {
141 repo_path: Some("/test/repo".to_string()),
142 email: Some("test@example.com".to_string()),
143 name: Some("Test User".to_string()),
144 start: Some("2023-01-01 00:00:00".to_string()),
145 end: Some("2023-01-02 00:00:00".to_string()),
146 show_history: false,
147 pic_specific_commits: false,
148 };
149
150 assert_eq!(args.repo_path, Some("/test/repo".to_string()));
151 assert_eq!(args.email, Some("test@example.com".to_string()));
152 assert_eq!(args.name, Some("Test User".to_string()));
153 assert_eq!(args.start, Some("2023-01-01 00:00:00".to_string()));
154 assert_eq!(args.end, Some("2023-01-02 00:00:00".to_string()));
155 }
156}