Mountain/IPC/WindServiceHandlers/Git/Shared/
RunGit.rs1use std::time::Duration;
5
6use tokio::process::Command;
7
8use crate::dev_log;
9
10const GIT_EXEC_TIMEOUT:Duration = Duration::from_secs(30);
18
19pub async fn Fn(OperationId:&str, Args:&[String], Cwd:Option<&str>) -> Result<(i32, String, String), String> {
20 dev_log!(
21 "git",
22 "[Git] exec-begin op={} cwd={} Arguments=[{}]",
23 OperationId,
24 Cwd.unwrap_or("<inherit>"),
25 Args.join(" ")
26 );
27
28 let WorkingDir = Cwd
29 .map(super::ResolveCwd::Fn)
30 .unwrap_or_else(|| std::env::current_dir().unwrap_or_default());
31
32 let mut Spawn = Command::new("git");
33
34 Spawn.args(Args).current_dir(&WorkingDir).kill_on_drop(true);
35
36 let Child = Spawn.spawn().map_err(|Error| {
37 dev_log!(
38 "git",
39 "[Git] exec-spawn-fail op={} Arguments=[{}] error={}",
40 OperationId,
41 Args.join(" "),
42 Error
43 );
44
45 format!("git spawn failed: {}", Error)
46 })?;
47
48 if let Some(Pid) = Child.id() {
49 super::RegisterPid::Fn(OperationId, Pid);
50 }
51
52 let WaitFuture = Child.wait_with_output();
53
54 let Output = match tokio::time::timeout(GIT_EXEC_TIMEOUT, WaitFuture).await {
55 Ok(WaitResult) => {
56 WaitResult.map_err(|Error| {
57 super::ClearPid::Fn(OperationId);
58
59 format!("git wait failed: {}", Error)
60 })?
61 },
62
63 Err(_) => {
64 let _ = super::TakePid::Fn(OperationId);
69
70 dev_log!(
71 "git",
72 "warn: [Git] exec-timeout op={} Arguments=[{}] after {}s - subprocess killed",
73 OperationId,
74 Args.join(" "),
75 GIT_EXEC_TIMEOUT.as_secs()
76 );
77
78 return Err(format!(
79 "git exec timed out after {}s: git {}",
80 GIT_EXEC_TIMEOUT.as_secs(),
81 Args.join(" ")
82 ));
83 },
84 };
85
86 super::ClearPid::Fn(OperationId);
87
88 let ExitCode = Output.status.code().unwrap_or(-1);
89
90 let Stdout = String::from_utf8_lossy(&Output.stdout).into_owned();
91
92 let Stderr = String::from_utf8_lossy(&Output.stderr).into_owned();
93
94 dev_log!(
95 "git",
96 "[Git] exec-done op={} Arguments=[{}] exit={} stdout={}B stderr={}B",
97 OperationId,
98 Args.join(" "),
99 ExitCode,
100 Stdout.len(),
101 Stderr.len()
102 );
103
104 Ok((ExitCode, Stdout, Stderr))
105}