run.rs 9.7 KB

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