rustywatch/watch/
reload.rs1use crate::{
2 config::schema::CommandType,
3 watch::{binary, command, command::buf_reader},
4};
5use binary::{exists, remove, restart};
6use command::exec;
7use log::{error, info};
8use std::process::Child;
9
10pub async fn reload(
11 running_binary: &mut Option<Child>,
12 cmd: &CommandType,
13 bin_path: Option<&String>,
14 bin_arg: Option<&Vec<String>>,
15) {
16 match running_binary {
19 Some(ref mut child) => match child.kill() {
20 Ok(_) => info!("Restarting..."),
21 Err(e) => error!("Failed to restart binary: {:?}", e.to_string()),
22 },
23 None => (),
24 }
25
26 match bin_path {
31 Some(bin_path) => {
32 if remove(bin_path) {
33 if !exists(bin_path) {
34 match cmd {
35 CommandType::Single(cmd) => match exec(cmd.clone()).await {
36 Ok(child) => buf_reader(child),
37 Err(e) => {
38 error!("Failed to run command: {}", e.to_string())
39 }
40 },
41 CommandType::Multiple(cmds) => {
42 for cmd in cmds {
43 match exec(cmd.clone()).await {
44 Ok(child) => buf_reader(child),
45 Err(e) => {
46 error!("Failed to run command: {}", e.to_string())
47 }
48 }
49 }
50 }
51 };
52 }
53
54 if cfg!(test) {
57 return;
58 }
59
60 match restart(bin_path, bin_arg) {
63 Ok(child) => *running_binary = Some(child),
64 Err(e) => {
65 error!("Failed to restart binary: {:?}", e.to_string());
66 error!("Please check your <bin_path>: {}", bin_path);
67 *running_binary = None
68 }
69 }
70 }
71 }
72
73 None => match cmd {
76 CommandType::Single(cmd) => match exec(cmd.clone()).await {
77 Ok(child) => buf_reader(child),
78 Err(e) => {
79 error!("Failed to run command: {}", e.to_string())
80 }
81 },
82 CommandType::Multiple(cmds) => {
83 for cmd in cmds {
84 match exec(cmd.clone()).await {
85 Ok(child) => buf_reader(child),
86 Err(e) => {
87 error!("Failed to run command: {}", e.to_string())
88 }
89 }
90 }
91 }
92 },
93 }
94}
95
96#[cfg(test)]
97mod tests {
98 use super::*;
99 use std::process::Command;
100
101 #[tokio::test]
102 async fn test_reload_with_no_binary() {
103 let mut running_binary = None;
104 let cmd = CommandType::Single("echo test".to_string());
105 let bin_path = None;
106 let bin_arg = None;
107
108 reload(&mut running_binary, &cmd, bin_path, bin_arg).await;
109 assert!(running_binary.is_none());
110 }
111
112 #[tokio::test]
113 async fn test_reload_with_binary() {
114 let mut running_binary = Some(Command::new("sleep").arg("1000").spawn().unwrap());
115 let cmd = CommandType::Single("echo test".to_string());
116 let bin_path = Some("test_binary".to_string());
117 let bin_arg = Some(vec!["arg1".to_string(), "arg2".to_string()]);
118
119 reload(
120 &mut running_binary,
121 &cmd,
122 bin_path.as_ref(),
123 bin_arg.as_ref(),
124 )
125 .await;
126 assert!(running_binary.is_some());
127 }
128}