Skip to main content

Mountain/RPC/CocoonService/SCM/
GitExec.rs

1#![allow(non_snake_case)]
2
3//! Spawn `git` with the requested args inside `repository_path` (or cwd
4//! if unset). stdout lines are returned verbatim; stderr lines are
5//! prefixed with `stderr: ` so the extension can differentiate.
6
7use tonic::{Response, Status};
8
9use crate::{
10	RPC::CocoonService::CocoonServiceImpl,
11	Vine::Generated::{GitExecRequest, GitExecResponse},
12	dev_log,
13};
14
15pub async fn Fn(_Service:&CocoonServiceImpl, Request:GitExecRequest) -> Result<Response<GitExecResponse>, Status> {
16	dev_log!("cocoon", "[CocoonService] git_exec: {}", Request.args.join(" "));
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	dev_log!(
53		"cocoon",
54		"[CocoonService] git_exec exit={} stdout={} bytes stderr={} bytes",
55		ExitCode,
56		Output.stdout.len(),
57		Output.stderr.len()
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	let StderrString = String::from_utf8_lossy(&Output.stderr);
70	let mut OutputLines:Vec<String> = StdoutString.lines().map(|L| L.to_string()).collect();
71	for Line in StderrString.lines() {
72		OutputLines.push(format!("stderr: {}", Line));
73	}
74
75	Ok(Response::new(GitExecResponse { output:OutputLines, exit_code:ExitCode }))
76}