use crate::config::config_file::{AuthData, ConfigFile};
use rpassword::read_password;
use std::{fs, io::BufRead, path::Path};
pub struct ConfigCmdRunner {
cfg_file: String,
}
impl ConfigCmdRunner {
pub fn new(cfg_file: String) -> ConfigCmdRunner {
ConfigCmdRunner { cfg_file }
}
fn ensure_cfg_writable(&self) -> Result<(), std::io::Error> {
let path = Path::new(&self.cfg_file);
if let Some(parent) = path.parent() {
if !parent.as_os_str().is_empty() && !parent.exists() {
fs::create_dir_all(parent)?;
}
}
fs::OpenOptions::new()
.write(true)
.create(true)
.truncate(false)
.open(path)
.map(|_| ())
}
pub fn init_file(&self) -> Result<(), std::io::Error> {
let path = Path::new(&self.cfg_file);
fs::create_dir_all(path.parent().unwrap())?;
fs::File::create(path)?;
Ok(())
}
pub fn set_cfg_auth(&self, cfg: ConfigFile) -> Result<ConfigFile, std::io::Error> {
self.ensure_cfg_writable()?;
println!("Your username: ");
let stdin = std::io::stdin();
let mut reader = stdin.lock();
self.read_auth_from_sources(cfg, &mut reader, read_password)
}
fn read_auth_from_sources<R, P>(
&self,
mut cfg: ConfigFile,
reader: &mut R,
mut password_reader: P,
) -> Result<ConfigFile, std::io::Error>
where
R: BufRead,
P: FnMut() -> Result<String, std::io::Error>,
{
let mut user = String::new();
reader.read_line(&mut user)?;
println!("Your apikey: ");
let apikey = password_reader()?;
let config_data = AuthData::new(user, apikey);
cfg.set_auth_key(config_data.to_base64());
cfg.write_to_file(self.cfg_file.as_str())?;
Ok(cfg)
}
pub fn set_cfg_jira(&self, cfg: ConfigFile) -> Result<ConfigFile, std::io::Error> {
self.ensure_cfg_writable()?;
println!("Your Jira instance URL: ");
let stdin = std::io::stdin();
let mut reader = stdin.lock();
self.read_jira_from_reader(cfg, &mut reader)
}
fn read_jira_from_reader<R>(
&self,
mut cfg: ConfigFile,
reader: &mut R,
) -> Result<ConfigFile, std::io::Error>
where
R: BufRead,
{
let mut read_data = String::new();
reader.read_line(&mut read_data)?;
cfg.set_jira_url(read_data.clone());
read_data.clear();
println!("Default Jira issue resolution JSON Value: ");
reader.read_line(&mut read_data)?;
cfg.set_standard_resolution(read_data.clone());
read_data.clear();
println!("Default Jira issue resolution comment JSON: ");
reader.read_line(&mut read_data)?;
cfg.set_standard_resolution_comment(read_data);
cfg.write_to_file(self.cfg_file.as_str())?;
Ok(cfg)
}
pub fn setup_cfg(&self, mut cfg: ConfigFile) -> Result<(), std::io::Error> {
self.init_file()?;
cfg = self.set_cfg_jira(cfg)?;
self.set_cfg_auth(cfg)?;
Ok(())
}
pub fn show_cfg(&self, cfg: ConfigFile) {
println!("Auth token: {}", cfg.get_auth_key());
println!("Jira URL: {}", cfg.get_jira_url());
println!(
"Jira default resolution: {:?}",
cfg.get_standard_resolution()
);
println!(
"Jira default resolution comment: {:?}",
cfg.get_standard_resolution_comment()
);
}
#[cfg(test)]
pub(crate) fn set_cfg_auth_with_reader<R, P>(
&self,
cfg: ConfigFile,
reader: &mut R,
password_reader: P,
) -> Result<ConfigFile, std::io::Error>
where
R: BufRead,
P: FnMut() -> Result<String, std::io::Error>,
{
self.ensure_cfg_writable()?;
self.read_auth_from_sources(cfg, reader, password_reader)
}
#[cfg(test)]
pub(crate) fn set_cfg_jira_with_reader<R>(
&self,
cfg: ConfigFile,
reader: &mut R,
) -> Result<ConfigFile, std::io::Error>
where
R: BufRead,
{
self.ensure_cfg_writable()?;
self.read_jira_from_reader(cfg, reader)
}
}