git_helpe_rs/
branch.rs

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    // Had to figure out around closure that couldn't move value
120    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}