Skip to main content

Mountain/RPC/CocoonService/SCM/
GitExec.rs

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