1use crate::settings::{BranchSettingsDef, RepoSettings};
10use git2::Repository;
11use std::ffi::OsStr;
12use std::path::{Path, PathBuf};
13
14pub fn create_config<P: AsRef<Path> + AsRef<OsStr>>(app_model_path: &P) -> Result<(), String> {
17 let path: &Path = app_model_path.as_ref();
18 if !path.exists() {
19 std::fs::create_dir_all(app_model_path).map_err(|err| err.to_string())?;
20
21 let models = [
22 (BranchSettingsDef::git_flow(), "git-flow.toml"),
23 (BranchSettingsDef::simple(), "simple.toml"),
24 (BranchSettingsDef::none(), "none.toml"),
25 ];
26 for (model, file) in &models {
27 let mut path = PathBuf::from(&app_model_path);
28 path.push(file);
29 let str = toml::to_string_pretty(&model).map_err(|err| err.to_string())?;
30 std::fs::write(&path, str).map_err(|err| err.to_string())?;
31 }
32 }
33
34 Ok(())
35}
36
37pub fn get_available_models<P: AsRef<Path>>(app_model_path: &P) -> Result<Vec<String>, String> {
39 let models = std::fs::read_dir(app_model_path)
40 .map_err(|err| err.to_string())?
41 .filter_map(|e| match e {
42 Ok(e) => {
43 if let (Some(name), Some(ext)) = (e.path().file_name(), e.path().extension()) {
44 if ext == "toml" {
45 name.to_str()
46 .map(|name| (name[..(name.len() - 5)]).to_string())
47 } else {
48 None
49 }
50 } else {
51 None
52 }
53 }
54 Err(_) => None,
55 })
56 .collect::<Vec<_>>();
57
58 Ok(models)
59}
60
61pub fn get_model_name(repository: &Repository, file_name: &str) -> Result<Option<String>, String> {
63 let mut config_path = PathBuf::from(repository.path());
64 config_path.push(file_name);
65
66 if config_path.exists() {
67 let repo_config: RepoSettings =
68 toml::from_str(&std::fs::read_to_string(config_path).map_err(|err| err.to_string())?)
69 .map_err(|err| err.to_string())?;
70
71 Ok(Some(repo_config.model))
72 } else {
73 Ok(None)
74 }
75}
76
77pub fn get_model<P: AsRef<Path> + AsRef<OsStr>>(
80 repository: &Repository,
81 model: Option<&str>,
82 repo_config_file: &str,
83 app_model_path: &P,
84) -> Result<BranchSettingsDef, String> {
85 match model {
86 Some(model) => read_model(model, app_model_path),
87 None => {
88 let mut config_path = PathBuf::from(repository.path());
89 config_path.push(repo_config_file);
90
91 if config_path.exists() {
92 let repo_config: RepoSettings = toml::from_str(
93 &std::fs::read_to_string(config_path).map_err(|err| err.to_string())?,
94 )
95 .map_err(|err| err.to_string())?;
96
97 read_model(&repo_config.model, app_model_path)
98 } else {
99 Ok(read_model("git-flow", app_model_path)
100 .unwrap_or_else(|_| BranchSettingsDef::git_flow()))
101 }
102 }
103 }
104}
105
106fn read_model<P: AsRef<Path> + AsRef<OsStr>>(
108 model: &str,
109 app_model_path: &P,
110) -> Result<BranchSettingsDef, String> {
111 let mut model_file = PathBuf::from(&app_model_path);
112 model_file.push(format!("{}.toml", model));
113
114 if model_file.exists() {
115 toml::from_str::<BranchSettingsDef>(
116 &std::fs::read_to_string(model_file).map_err(|err| err.to_string())?,
117 )
118 .map_err(|err| err.to_string())
119 } else {
120 let models = get_available_models(&app_model_path)?;
121 let path: &Path = app_model_path.as_ref();
122 Err(format!(
123 "ERROR: No branching model named '{}' found in {}\n Available models are: {}",
124 model,
125 path.display(),
126 itertools::join(models, ", ")
127 ))
128 }
129}
130pub fn set_model<P: AsRef<Path>>(
132 repository: &Repository,
133 model: &str,
134 repo_config_file: &str,
135 app_model_path: &P,
136) -> Result<(), String> {
137 let models = get_available_models(&app_model_path)?;
138
139 if !models.contains(&model.to_string()) {
140 return Err(format!(
141 "ERROR: No branching model named '{}' found in {}\n Available models are: {}",
142 model,
143 app_model_path.as_ref().display(),
144 itertools::join(models, ", ")
145 ));
146 }
147
148 let mut config_path = PathBuf::from(repository.path());
149 config_path.push(repo_config_file);
150
151 let config = RepoSettings {
152 model: model.to_string(),
153 };
154
155 let str = toml::to_string_pretty(&config).map_err(|err| err.to_string())?;
156 std::fs::write(&config_path, str).map_err(|err| err.to_string())?;
157
158 Ok(())
159}