git_worktree_manager/
messages.rs1pub fn worktree_not_found(branch: &str) -> String {
5 format!(
6 "No worktree found for branch '{}'. Use 'gw list' to see available worktrees.",
7 branch
8 )
9}
10
11pub fn target_not_found(target: &str) -> String {
12 format!(
13 "No worktree matches '{}' (tried name, branch, path). Use 'gw list' to see available worktrees.",
14 target
15 )
16}
17
18pub fn branch_not_found(branch: &str) -> String {
19 format!("Branch '{}' not found", branch)
20}
21
22pub fn invalid_branch_name(error_msg: &str) -> String {
23 format!(
24 "Invalid branch name: {}\nHint: Use alphanumeric characters, hyphens, and slashes. \
25 Avoid special characters like emojis, backslashes, or control characters.",
26 error_msg
27 )
28}
29
30pub fn cannot_determine_branch() -> String {
31 "Cannot determine current branch".to_string()
32}
33
34pub fn cannot_determine_base_branch() -> String {
35 "Cannot determine base branch. Specify with --base or checkout a branch first.".to_string()
36}
37
38pub fn missing_metadata(branch: &str) -> String {
39 format!(
40 "Missing metadata for branch '{}'. Was this worktree created with 'gw new'?",
41 branch
42 )
43}
44
45pub fn worktree_dir_not_found(path: &str) -> String {
46 format!("Worktree directory does not exist: {}", path)
47}
48
49pub fn cannot_delete_main_worktree() -> String {
50 "Cannot delete main repository worktree".to_string()
51}
52
53pub fn detached_head_warning() -> String {
54 "Worktree is detached or branch not found. Specify branch with --branch or skip with --force."
55 .to_string()
56}
57
58pub fn deleting_local_branch(branch: &str) -> String {
63 format!("Deleting local branch: {}", branch)
64}
65
66pub fn deleting_remote_branch(branch: &str) -> String {
67 format!("Deleting remote branch: origin/{}", branch)
68}
69
70pub fn removing_worktree(path: &std::path::Path) -> String {
71 format!("Removing worktree: {}", path.display())
72}
73
74pub fn starting_ai_tool_foreground(tool_name: &str) -> String {
75 format!("Starting {} (Ctrl+C to exit)...", tool_name)
76}
77
78pub fn starting_ai_tool_in(tool_name: &str) -> String {
79 format!("Starting {} in:", tool_name)
80}
81
82pub fn resuming_ai_tool_in(tool_name: &str) -> String {
83 format!("Resuming {} in:", tool_name)
84}
85
86pub fn switched_to_worktree(path: &std::path::Path) -> String {
87 format!("Switched to worktree: {}", path.display())
88}
89
90#[cfg(test)]
91mod tests {
92 use super::*;
93
94 #[test]
95 fn test_worktree_not_found() {
96 let msg = worktree_not_found("feature-x");
97 assert!(msg.contains("feature-x"));
98 assert!(msg.contains("gw list"));
99 assert!(msg.contains("No worktree found"));
100 }
101
102 #[test]
103 fn test_target_not_found() {
104 let msg = target_not_found("my-target");
105 assert!(msg.contains("my-target"));
106 assert!(msg.contains("name, branch, path"));
107 assert!(msg.contains("gw list"));
108 }
109
110 #[test]
111 fn test_branch_not_found() {
112 let msg = branch_not_found("my-branch");
113 assert!(msg.contains("my-branch"));
114 assert!(msg.contains("not found"));
115 }
116
117 #[test]
118 fn test_invalid_branch_name() {
119 let msg = invalid_branch_name("contains spaces");
120 assert!(msg.contains("contains spaces"));
121 assert!(msg.contains("Invalid branch name"));
122 assert!(msg.contains("Hint"));
123 assert!(msg.contains("alphanumeric"));
124 }
125
126 #[test]
127 fn test_cannot_determine_branch() {
128 let msg = cannot_determine_branch();
129 assert!(msg.contains("Cannot determine current branch"));
130 }
131
132 #[test]
133 fn test_cannot_determine_base_branch() {
134 let msg = cannot_determine_base_branch();
135 assert!(msg.contains("Cannot determine base branch"));
136 assert!(msg.contains("--base"));
137 }
138
139 #[test]
140 fn test_missing_metadata() {
141 let msg = missing_metadata("feat-login");
142 assert!(msg.contains("feat-login"));
143 assert!(msg.contains("Missing metadata"));
144 assert!(msg.contains("gw new"));
145 }
146
147 #[test]
148 fn test_worktree_dir_not_found() {
149 let msg = worktree_dir_not_found("/tmp/worktree");
150 assert!(msg.contains("/tmp/worktree"));
151 assert!(msg.contains("does not exist"));
152 }
153
154 #[test]
155 fn test_cannot_delete_main_worktree() {
156 let msg = cannot_delete_main_worktree();
157 assert!(msg.contains("Cannot delete main repository worktree"));
158 }
159
160 #[test]
161 fn test_detached_head_warning() {
162 let msg = detached_head_warning();
163 assert!(msg.contains("detached"));
164 assert!(msg.contains("--branch"));
165 assert!(msg.contains("--force"));
166 }
167
168 #[test]
169 fn test_deleting_local_branch() {
170 let msg = deleting_local_branch("feat-x");
171 assert!(msg.contains("Deleting local branch: feat-x"));
172 }
173
174 #[test]
175 fn test_deleting_remote_branch() {
176 let msg = deleting_remote_branch("feat-x");
177 assert!(msg.contains("origin/feat-x"));
178 }
179
180 #[test]
181 fn test_removing_worktree() {
182 let msg = removing_worktree(std::path::Path::new("/tmp/wt"));
183 assert!(msg.contains("Removing worktree:"));
184 assert!(msg.contains("/tmp/wt"));
185 }
186
187 #[test]
188 fn test_starting_ai_tool_foreground() {
189 let msg = starting_ai_tool_foreground("claude");
190 assert!(msg.contains("Starting claude"));
191 assert!(msg.contains("Ctrl+C"));
192 }
193
194 #[test]
195 fn test_starting_ai_tool_in() {
196 let msg = starting_ai_tool_in("claude");
197 assert_eq!(msg, "Starting claude in:");
198 }
199
200 #[test]
201 fn test_resuming_ai_tool_in() {
202 let msg = resuming_ai_tool_in("claude");
203 assert_eq!(msg, "Resuming claude in:");
204 }
205
206 #[test]
207 fn test_switched_to_worktree() {
208 let msg = switched_to_worktree(std::path::Path::new("/tmp/wt"));
209 assert!(msg.contains("Switched to worktree:"));
210 assert!(msg.contains("/tmp/wt"));
211 }
212}