run.rs 9.4 KB

123456789101112131415161718192021222324252627282930313233343536373839404142434445464748495051525354555657585960616263646566676869707172737475767778798081828384858687888990919293949596979899100101102103104105106107108109110111112113114115116117118119120121122123124125126127128129130131132133134135136137138139140141142143144145146147148149150151152153154155156157158159160161162163164165166167168169170171172173174175176177178179180181182183184185186187188189190191192193194195196197198199200201202203204205206207208209210211212213214215216217218219220221222223224225226227228229230231232233234235236237238239
  1. use clap::Values;
  2. use crate::lib::config::Config;
  3. use string_template::Template;
  4. use std::process::Command;
  5. use std::path::Path;
  6. use std::collections::HashMap;
  7. pub fn run(config: &Config, names: Values<'_>) {
  8. for name in names {
  9. if config.repositories.contains_key(name) {
  10. run_repository_sync(&config, name.to_string());
  11. } else if config.groups.contains_key(name) {
  12. run_group(&config, name.to_string());
  13. } else {
  14. println!("\"{}\" is neither a group nor a repository.", name);
  15. }
  16. }
  17. }
  18. pub fn run_with_command(config: &Config, command: String, names: Values<'_>) {
  19. for name in names {
  20. if config.repositories.contains_key(name) {
  21. run_named_command(&config, name.to_string(), &command);
  22. } else if config.groups.contains_key(name) {
  23. run_group_with_command(&config, name.to_string(), &command);
  24. } else {
  25. println!("\"{}\" is neither a group nor a repository.", name);
  26. }
  27. }
  28. }
  29. fn run_command(command: String) {
  30. if !command.is_empty() {
  31. match Command::new("sh")
  32. .arg("-c")
  33. .arg(command)
  34. .spawn() {
  35. Ok(mut child) => {
  36. let mut status = child.try_wait();
  37. loop {
  38. match status {
  39. Ok(Some(_)) => break,
  40. Ok(None) => {},
  41. _ => {}
  42. }
  43. status = child.try_wait();
  44. }
  45. },
  46. _ => {}
  47. }
  48. }
  49. }
  50. fn run_command_in_directory(directory: String, command: String) {
  51. if !command.is_empty() {
  52. match Command::new("sh")
  53. .current_dir(directory)
  54. .arg("-c")
  55. .arg(command)
  56. .spawn() {
  57. Ok(mut child) => {
  58. let mut status = child.try_wait();
  59. loop {
  60. match status {
  61. Ok(Some(_)) => break,
  62. Ok(None) => {},
  63. _ => {}
  64. }
  65. status = child.try_wait();
  66. }
  67. },
  68. _ => {}
  69. }
  70. }
  71. }
  72. pub fn run_action(config: &Config, name: String) {
  73. let action = config.actions.get(&name.to_string());
  74. match action {
  75. Some(action) => {
  76. if !action.disabled {
  77. run_command(action.command.to_string());
  78. }
  79. },
  80. None => panic!("No known action named \"{}\".", name)
  81. }
  82. }
  83. pub fn run_named_command(config: &Config, repo: String, command: &String) {
  84. match config.repositories.get(&repo) {
  85. Some(repository) => {
  86. if !repository.disabled {
  87. let location = match config.is_not_default {
  88. true => {
  89. let thing = config.base_path.join(Path::new(&repository.location.to_string()));
  90. String::from(thing.to_str().unwrap())
  91. },
  92. _ => repository.location.clone()
  93. };
  94. if Path::new(&location).exists() {
  95. let mut options: HashMap<&str, &str> = HashMap::new();
  96. for (key, value) in &repository.options {
  97. options.insert(key, value);
  98. }
  99. options.insert("location", &location);
  100. match config.repo_types.get(&repository.repo_type) {
  101. Some(repo_type) => {
  102. match repo_type.commands.get(command) {
  103. Some(command_string) => {
  104. println!("\n\nRepository {} ({}):", repo, location);
  105. run_command_in_directory(location.to_string(),
  106. Template::new(&command_string).render(&options));
  107. },
  108. None => {}
  109. }
  110. },
  111. None => panic!("No repository type named \"{}\".", repository.repo_type)
  112. }
  113. }
  114. }
  115. }
  116. None => panic!("No known repository named \"{}\".", repo)
  117. }
  118. }
  119. pub fn run_repository_sync(config: &Config, name: String) {
  120. let repository = config.repositories.get(&name.to_string());
  121. match repository {
  122. Some(repository) => {
  123. if !repository.disabled {
  124. let location = match config.is_not_default {
  125. true => {
  126. let thing = config.base_path.join(Path::new(&repository.location.to_string()));
  127. String::from(thing.to_str().unwrap())
  128. },
  129. _ => repository.location.clone()
  130. };
  131. if !Path::new(&location).exists() {
  132. if repository.auto_create {
  133. run_repository_creation(config, name);
  134. }
  135. } else {
  136. let mut options: HashMap<&str, &str> = HashMap::new();
  137. for (key, value) in &repository.options {
  138. options.insert(key, value);
  139. }
  140. options.insert("location", &location);
  141. let repo_type = config.repo_types.get(&repository.repo_type);
  142. match repo_type {
  143. Some(repo_type) => {
  144. println!("\n\nRepository {} ({}):", name, location);
  145. run_command_in_directory(location.to_string(),
  146. Template::new(&repo_type.pre_inward).render(&options));
  147. run_command_in_directory(location.to_string(),
  148. Template::new(&repo_type.inward).render(&options));
  149. run_command_in_directory(location.to_string(),
  150. Template::new(&repo_type.post_inward).render(&options));
  151. run_command_in_directory(location.to_string(),
  152. Template::new(&repo_type.outward).render(&options));
  153. run_command_in_directory(location.to_string(),
  154. Template::new(&repo_type.post_outward).render(&options));
  155. },
  156. None => panic!("No known repository type named \"{}\".", &repository.repo_type)
  157. }
  158. }
  159. }
  160. },
  161. None => panic!("No known repository named \"{}\".", name)
  162. }
  163. }
  164. pub fn run_repository_creation(config: &Config, name: String) {
  165. let repository = config.repositories.get(&name.to_string());
  166. match repository {
  167. Some(repository) => {
  168. let repository_type_name = &repository.repo_type;
  169. let repository_type = config.repo_types.get(repository_type_name);
  170. match repository_type {
  171. Some(repository_type) => {
  172. if !repository.disabled {
  173. let mut options: HashMap<&str, &str> = HashMap::new();
  174. for (key, value) in &repository.options {
  175. options.insert(key, value);
  176. }
  177. options.insert("location", &repository.location);
  178. run_command(Template::new(&repository_type.create).render(&options));
  179. }
  180. },
  181. None => panic!("No known repository type named \"{}\".", repository_type_name)
  182. }
  183. },
  184. None => panic!("No known repository named \"{}\".", name)
  185. }
  186. }
  187. pub fn run_group(config: &Config, name: String) {
  188. let group = config.groups.get(&name.to_string());
  189. match group {
  190. Some(group) => {
  191. for member in &group.members {
  192. if config.repositories.contains_key(member) {
  193. run_repository_sync(&config, member.to_string());
  194. } else if config.groups.contains_key(member) {
  195. run_group(&config, member.to_string());
  196. } else {
  197. println!("\"{}\" is neither a group nor a repository.", member);
  198. }
  199. }
  200. for action in &group.actions_after {
  201. run_action(&config, action.to_string());
  202. }
  203. },
  204. None => panic!("No known group named \"{}\".", name)
  205. }
  206. }
  207. pub fn run_group_with_command(config: &Config, name: String, command: &String) {
  208. let group = config.groups.get(&name.to_string());
  209. match group {
  210. Some(group) => {
  211. for member in &group.members {
  212. if config.repositories.contains_key(member) {
  213. run_named_command(&config, member.to_string(), &command);
  214. } else if config.groups.contains_key(member) {
  215. run_group_with_command(&config, member.to_string(), &command);
  216. } else {
  217. println!("\"{}\" is neither a group nor a repository.", member);
  218. }
  219. }
  220. for action in &group.actions_after {
  221. run_action(&config, action.to_string());
  222. }
  223. },
  224. None => panic!("No known group named \"{}\".", name)
  225. }
  226. }