jirust_cli/runners/
cfg_cmd_runner.rs

1use crate::config::config_file::{AuthData, ConfigFile};
2
3use rpassword::read_password;
4use std::{fs, io::BufRead, path::Path};
5
6/// ConfigCmdRunner is a struct that holds the configuration file path
7/// and provides methods to initialize, set, and show the configuration file.
8pub struct ConfigCmdRunner {
9    cfg_file: String,
10}
11
12/// Implementation of ConfigCmdRunner
13///
14/// # Methods
15///
16/// * `new(cfg_file: String) -> ConfigCmdRunner` - creates a new instance of ConfigCmdRunner
17/// * `init_file() -> Result<(), std::io::Error>` - initializes the configuration file
18/// * `set_cfg_auth(cfg: ConfigFile) -> Result<ConfigFile, std::io::Error>` - sets the authentication data in the configuration file
19/// * `set_cfg_jira(cfg: ConfigFile) -> Result<ConfigFile, std::io::Error>` - sets the Jira URL in the configuration file
20/// * `setup_cfg(cfg: ConfigFile) -> Result<(), std::io::Error>` - sets up the configuration file
21/// * `show_cfg(cfg: ConfigFile)` - shows the configuration file
22impl ConfigCmdRunner {
23    /// Creates a new instance of ConfigCmdRunner
24    ///
25    /// # Arguments
26    ///
27    /// * `cfg_file` - a String that holds the path to the configuration file
28    ///
29    /// # Returns
30    ///
31    /// * `ConfigCmdRunner` - a new instance of ConfigCmdRunner
32    ///
33    /// # Examples
34    ///
35    /// ```
36    /// use jirust_cli::runners::cfg_cmd_runner::ConfigCmdRunner;
37    ///
38    /// let cfg_runner = ConfigCmdRunner::new("test_path/to/config/file".to_string());
39    /// ```
40    pub fn new(cfg_file: String) -> ConfigCmdRunner {
41        ConfigCmdRunner { cfg_file }
42    }
43
44    /// Initializes the configuration file
45    ///
46    /// # Returns
47    ///
48    /// * `Result<(), std::io::Error>` - a Result that returns an empty tuple or an error
49    ///
50    /// # Examples
51    ///
52    /// ```
53    /// use jirust_cli::runners::cfg_cmd_runner::ConfigCmdRunner;
54    ///
55    /// let cfg_runner = ConfigCmdRunner::new("test_path/to/config/file".to_string());
56    /// cfg_runner.init_file();
57    /// ```
58    pub fn init_file(&self) -> Result<(), std::io::Error> {
59        let path = Path::new(&self.cfg_file);
60        fs::create_dir_all(path.parent().unwrap())?;
61        fs::File::create(path)?;
62        Ok(())
63    }
64
65    /// Sets the authentication data in the configuration file
66    ///
67    /// # Arguments
68    ///
69    /// * `cfg` - a ConfigFile that holds the configuration data
70    ///
71    /// # Returns
72    ///
73    /// * `Result<ConfigFile, std::io::Error>` - a Result that returns the updated ConfigFile or an error
74    ///
75    /// # Examples
76    ///
77    /// ```no_run
78    /// use jirust_cli::config::config_file::ConfigFile;
79    /// use jirust_cli::runners::cfg_cmd_runner::ConfigCmdRunner;
80    ///
81    /// let cfg_runner = ConfigCmdRunner::new("test_path/to/config/file".to_string());
82    /// let cfg = ConfigFile::default();
83    ///
84    /// cfg_runner.set_cfg_auth(cfg);
85    /// ```
86    pub fn set_cfg_auth(&self, cfg: ConfigFile) -> Result<ConfigFile, std::io::Error> {
87        println!("Your username: ");
88        let stdin = std::io::stdin();
89        let mut reader = stdin.lock();
90        self.read_auth_from_sources(cfg, &mut reader, read_password)
91    }
92
93    fn read_auth_from_sources<R, P>(
94        &self,
95        mut cfg: ConfigFile,
96        reader: &mut R,
97        mut password_reader: P,
98    ) -> Result<ConfigFile, std::io::Error>
99    where
100        R: BufRead,
101        P: FnMut() -> Result<String, std::io::Error>,
102    {
103        let mut user = String::new();
104        reader.read_line(&mut user)?;
105        println!("Your apikey: ");
106        let apikey = password_reader()?;
107        let config_data = AuthData::new(user, apikey);
108        cfg.set_auth_key(config_data.to_base64());
109        cfg.write_to_file(self.cfg_file.as_str())?;
110        Ok(cfg)
111    }
112
113    /// Sets the Jira URL in the configuration file
114    ///
115    /// # Arguments
116    ///
117    /// * `cfg` - a ConfigFile that holds the configuration data
118    ///
119    /// # Returns
120    ///
121    /// * `Result<ConfigFile, std::io::Error>` - a Result that returns the updated ConfigFile or an error
122    ///
123    /// # Examples
124    ///
125    /// ```no_run
126    /// use jirust_cli::config::config_file::ConfigFile;
127    /// use jirust_cli::runners::cfg_cmd_runner::ConfigCmdRunner;
128    ///
129    /// let cfg_runner = ConfigCmdRunner::new("test_path/to/config/file".to_string());
130    /// let cfg = ConfigFile::default();
131    /// cfg_runner.set_cfg_jira(cfg);
132    /// ```
133    pub fn set_cfg_jira(&self, cfg: ConfigFile) -> Result<ConfigFile, std::io::Error> {
134        println!("Your Jira instance URL: ");
135        let stdin = std::io::stdin();
136        let mut reader = stdin.lock();
137        self.read_jira_from_reader(cfg, &mut reader)
138    }
139
140    fn read_jira_from_reader<R>(
141        &self,
142        mut cfg: ConfigFile,
143        reader: &mut R,
144    ) -> Result<ConfigFile, std::io::Error>
145    where
146        R: BufRead,
147    {
148        let mut read_data = String::new();
149        reader.read_line(&mut read_data)?;
150        cfg.set_jira_url(read_data.clone());
151        read_data.clear();
152        println!("Default Jira issue resolution JSON Value: ");
153        reader.read_line(&mut read_data)?;
154        cfg.set_standard_resolution(read_data.clone());
155        read_data.clear();
156        println!("Default Jira issue resolution comment JSON: ");
157        reader.read_line(&mut read_data)?;
158        cfg.set_standard_resolution_comment(read_data);
159        cfg.write_to_file(self.cfg_file.as_str())?;
160        Ok(cfg)
161    }
162
163    /// Sets up the configuration file
164    ///
165    /// # Arguments
166    ///
167    /// * `cfg` - a ConfigFile that holds the configuration data
168    ///
169    /// # Returns
170    ///
171    /// * `Result<(), std::io::Error>` - a Result that returns an empty tuple or an error
172    ///
173    /// # Examples
174    ///
175    /// ```no_run
176    /// use jirust_cli::config::config_file::ConfigFile;
177    /// use jirust_cli::runners::cfg_cmd_runner::ConfigCmdRunner;
178    ///
179    /// let cfg_runner = ConfigCmdRunner::new("test_path/to/config/file".to_string());
180    /// let cfg = ConfigFile::default();
181    /// cfg_runner.setup_cfg(cfg);
182    /// ```
183    pub fn setup_cfg(&self, mut cfg: ConfigFile) -> Result<(), std::io::Error> {
184        self.init_file()?;
185        cfg = self.set_cfg_jira(cfg)?;
186        self.set_cfg_auth(cfg)?;
187        Ok(())
188    }
189
190    /// Shows the configuration file data
191    ///
192    /// # Arguments
193    ///
194    /// * `cfg` - a ConfigFile that holds the configuration data
195    ///
196    /// # Examples
197    ///
198    /// ```
199    /// use jirust_cli::config::config_file::ConfigFile;
200    /// use jirust_cli::runners::cfg_cmd_runner::ConfigCmdRunner;
201    ///
202    /// let cfg = ConfigFile::default();
203    ///
204    /// let cfg_runner = ConfigCmdRunner::new("test_path/to/config/file".to_string());
205    /// cfg_runner.show_cfg(cfg);
206    /// ```
207    pub fn show_cfg(&self, cfg: ConfigFile) {
208        println!("Auth token: {}", cfg.get_auth_key());
209        println!("Jira URL: {}", cfg.get_jira_url());
210        println!(
211            "Jira default resolution: {:?}",
212            cfg.get_standard_resolution()
213        );
214        println!(
215            "Jira default resolution comment: {:?}",
216            cfg.get_standard_resolution_comment()
217        );
218    }
219
220    #[cfg(test)]
221    pub(crate) fn set_cfg_auth_with_reader<R, P>(
222        &self,
223        cfg: ConfigFile,
224        reader: &mut R,
225        password_reader: P,
226    ) -> Result<ConfigFile, std::io::Error>
227    where
228        R: BufRead,
229        P: FnMut() -> Result<String, std::io::Error>,
230    {
231        self.read_auth_from_sources(cfg, reader, password_reader)
232    }
233
234    #[cfg(test)]
235    pub(crate) fn set_cfg_jira_with_reader<R>(
236        &self,
237        cfg: ConfigFile,
238        reader: &mut R,
239    ) -> Result<ConfigFile, std::io::Error>
240    where
241        R: BufRead,
242    {
243        self.read_jira_from_reader(cfg, reader)
244    }
245}