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