1use std::process::Command;
2
3use anyhow::{anyhow, Error, Result};
4use regex::Regex;
5
6use crate::{
7 cli::{CheckoutToPrefix, DryRunAndCopyFlag, UseTemplate},
8 git_config::GitConfig,
9 run_mode::{get_run_mode_from_options, run_copy, RunMode},
10 template::{interpolate, validate_interpolation_places_count},
11};
12
13pub fn checkout_to_branch_with_prefix(options: CheckoutToPrefix, config: GitConfig) -> Result<()> {
14 let checkout_regex = Regex::new(r"^git checkout -b [a-zA-Z0-9_.-]+$").unwrap();
15 let paste_command = &config.data.clipboard_commands.paste;
16
17 let clipboard_value = Command::new(paste_command)
18 .output()
19 .expect("Couldn't run paste_command");
20
21 let output_as_string = String::from_utf8(clipboard_value.stdout).unwrap();
22
23 if !checkout_regex.is_match(&output_as_string) {
24 return Err(anyhow!(
25 "What you have in your clipboard is not a valid git checkout command \n
26 valid one looks like this: \n
27 git checkout -b name-of-your-branch
28 "
29 ));
30 }
31 let prefix_found = match config.data.branch_prefix_variants.get(&options.prefix_key) {
32 None => {
33 return Err(anyhow!(
34 "There was no prefix for key {} \n You should add it prior to trying to use",
35 options.prefix_key
36 ))
37 }
38 Some(prefix) => prefix,
39 };
40
41 let split_on_space: Vec<String> = output_as_string.split(" ").map(|s| s.to_string()).collect();
42
43 let after_prefix = &split_on_space[3..].join("");
44
45 let full_branch_name = prefix_found.to_owned() + after_prefix;
46
47 let run_mode = get_run_mode_from_options(DryRunAndCopyFlag {
48 dry_run: options.dry_run,
49 copy: options.copy,
50 });
51
52 return match run_mode {
53 RunMode::Normal => {
54 let result = Command::new("git")
55 .arg("checkout")
56 .arg("-b")
57 .arg(full_branch_name)
58 .output()
59 .unwrap();
60
61 println!("git output: \n {:?}", String::from_utf8(result.stdout));
62 Ok(())
63 }
64 RunMode::DryRun => {
65 println!(
66 "Going to run: \n \
67 git checkout -b {}",
68 full_branch_name
69 );
70 Ok(())
71 }
72 RunMode::Copy => run_copy(&config, format!("git checkout -b {}", full_branch_name)),
73 RunMode::DryRunAndCopy => {
74 let copy_command = config.data.clipboard_commands.copy;
75
76 println!(
77 "Going to run: \n \
78 echo 'git checkout -b {}' > {}",
79 full_branch_name, copy_command
80 );
81 Ok(())
82 }
83 };
84}
85
86pub fn checkout_to_branch_with_template(
87 options: UseTemplate,
88 config: GitConfig,
89) -> Result<(), Error> {
90 let selected_branch_format = options.key;
91
92 let picked_branch_format = config
93 .data
94 .branch_template_variants
95 .get(&selected_branch_format)
96 .unwrap_or_else(|| {
97 panic!(
98 "No branch template under given key {} \n \
99 You should add it prior to trying to use
100 ",
101 selected_branch_format
102 )
103 });
104
105 let is_valid =
106 validate_interpolation_places_count(picked_branch_format, options.interpolate_values.len());
107
108 if is_valid.is_err() {
109 let err: Error = is_valid.err().unwrap();
110 return Err(err);
111 };
112
113 let interpolate_values = options
114 .interpolate_values
115 .iter()
116 .map(|val| val.replace(" ", "-"))
117 .collect();
118
119 let interpolate_values_for_debugging = format!("{:?}", interpolate_values);
121 let interpolated_branch =
122 interpolate(picked_branch_format, interpolate_values).unwrap_or_else(|_err| {
123 panic!(
124 "Couldn't interpolate branch format \n \
125 Trying to interpolate template: \n \
126 {} \n \
127 with: \n \
128 {:?}
129 ",
130 picked_branch_format, interpolate_values_for_debugging
131 )
132 });
133
134 let run_mode = get_run_mode_from_options(DryRunAndCopyFlag {
135 dry_run: options.dry_run,
136 copy: options.copy,
137 });
138
139 match run_mode {
140 RunMode::Normal => {
141 let output = Command::new("git")
142 .arg("checkout")
143 .arg("-b")
144 .arg(interpolated_branch)
145 .output()
146 .unwrap()
147 .stdout;
148
149 println!("{}", String::from_utf8_lossy(&output));
150 Ok(())
151 }
152 RunMode::DryRun => {
153 let command_to_print = format!("git checkout -b {}", interpolated_branch);
154 println!("Command to be executed: \n {}", command_to_print);
155 Ok(())
156 }
157 RunMode::DryRunAndCopy => {
158 let copy_command = config.data.clipboard_commands.copy;
159
160 let command_to_print = format!(
161 "echo 'git checkout -b {}' > {}",
162 interpolated_branch, copy_command
163 );
164 let message_to_print =
165 format!("command that's going to be run: \n {}", command_to_print);
166 println!("{}", message_to_print);
167 Ok(())
168 }
169 RunMode::Copy => {
170 let value_to_copy = format!("git checkout -b {}", interpolated_branch);
171 run_copy(&config, value_to_copy)
172 }
173 }
174}