Skip to main content

Mountain/IPC/WindServiceHandlers/Git/Shared/
RunGit.rs

1
2//! Spawns `git`, registers the PID, awaits output, returns
3//! `(exit_code, stdout, stderr)`.
4
5use tokio::process::Command;
6
7use crate::dev_log;
8
9pub async fn Fn(OperationId:&str, Args:&[String], Cwd:Option<&str>) -> Result<(i32, String, String), String> {
10	dev_log!(
11		"git",
12		"[Git] exec-begin op={} cwd={} Arguments=[{}]",
13		OperationId,
14		Cwd.unwrap_or("<inherit>"),
15		Args.join(" ")
16	);
17
18	let WorkingDir = Cwd
19		.map(super::ResolveCwd::Fn)
20		.unwrap_or_else(|| std::env::current_dir().unwrap_or_default());
21
22	let mut Spawn = Command::new("git");
23
24	Spawn.args(Args).current_dir(&WorkingDir).kill_on_drop(true);
25
26	let Child = Spawn.spawn().map_err(|Error| {
27		dev_log!(
28			"git",
29			"[Git] exec-spawn-fail op={} Arguments=[{}] error={}",
30			OperationId,
31			Args.join(" "),
32			Error
33		);
34		format!("git spawn failed: {}", Error)
35	})?;
36
37	if let Some(Pid) = Child.id() {
38		super::RegisterPid::Fn(OperationId, Pid);
39	}
40
41	let Output = Child.wait_with_output().await.map_err(|Error| {
42		super::ClearPid::Fn(OperationId);
43		format!("git wait failed: {}", Error)
44	})?;
45
46	super::ClearPid::Fn(OperationId);
47
48	let ExitCode = Output.status.code().unwrap_or(-1);
49
50	let Stdout = String::from_utf8_lossy(&Output.stdout).into_owned();
51
52	let Stderr = String::from_utf8_lossy(&Output.stderr).into_owned();
53
54	dev_log!(
55		"git",
56		"[Git] exec-done op={} Arguments=[{}] exit={} stdout={}B stderr={}B",
57		OperationId,
58		Args.join(" "),
59		ExitCode,
60		Stdout.len(),
61		Stderr.len()
62	);
63
64	Ok((ExitCode, Stdout, Stderr))
65}