Skip to main content

Mountain/RPC/CocoonService/SCM/
GitExec.rs

1//! Spawn `git` with the requested args inside `repository_path` (or cwd
2//! if unset). stdout lines are returned verbatim; stderr lines are
3//! prefixed with `stderr: ` so the extension can differentiate.
4
5use tonic::{Response, Status};
6use ::Vine::Generated::{GitExecRequest, GitExecResponse};
7
8use crate::{RPC::CocoonService::CocoonServiceImpl, dev_log};
9
10pub async fn Fn(_Service:&CocoonServiceImpl, Request:GitExecRequest) -> Result<Response<GitExecResponse>, Status> {
11	dev_log!("cocoon", "[CocoonService] git_exec: {}", Request.args.join(" "));
12
13	dev_log!(
14		"git",
15		"[Git] exec-begin cwd={} args=[{}]",
16		if Request.repository_path.is_empty() {
17			"<cwd>".to_string()
18		} else {
19			Request.repository_path.clone()
20		},
21		Request.args.join(" ")
22	);
23
24	let WorkingDirectory = if Request.repository_path.is_empty() {
25		std::env::current_dir().unwrap_or_default()
26	} else {
27		std::path::PathBuf::from(&Request.repository_path)
28	};
29
30	let Output = tokio::process::Command::new("git")
31		.args(&Request.args)
32		.current_dir(&WorkingDirectory)
33		.output()
34		.await
35		.map_err(|Error| {
36			dev_log!("cocoon", "error: [CocoonService] git_exec failed to spawn: {}", Error);
37
38			dev_log!(
39				"git",
40				"[Git] exec-spawn-fail cwd={:?} args=[{}] error={}",
41				WorkingDirectory,
42				Request.args.join(" "),
43				Error
44			);
45
46			Status::internal(format!("git_exec: failed to spawn git: {}", Error))
47		})?;
48
49	let ExitCode = Output.status.code().unwrap_or(-1);
50
51	dev_log!(
52		"cocoon",
53		"[CocoonService] git_exec exit={} stdout={} bytes stderr={} bytes",
54		ExitCode,
55		Output.stdout.len(),
56		Output.stderr.len()
57	);
58
59	dev_log!(
60		"git",
61		"[Git] exec-done args=[{}] exit={} stdout={} stderr={}",
62		Request.args.join(" "),
63		ExitCode,
64		Output.stdout.len(),
65		Output.stderr.len()
66	);
67
68	let StdoutString = String::from_utf8_lossy(&Output.stdout);
69
70	let StderrString = String::from_utf8_lossy(&Output.stderr);
71
72	let mut OutputLines:Vec<String> = StdoutString.lines().map(|L| L.to_string()).collect();
73
74	for Line in StderrString.lines() {
75		OutputLines.push(format!("stderr: {}", Line));
76	}
77
78	Ok(Response::new(GitExecResponse { output:OutputLines, exit_code:ExitCode }))
79}