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
18	dev_log!(
19		"git",
20		"[Git] exec-begin cwd={} args=[{}]",
21		if Request.repository_path.is_empty() {
22			"<cwd>".to_string()
23		} else {
24			Request.repository_path.clone()
25		},
26		Request.args.join(" ")
27	);
28
29	let WorkingDirectory = if Request.repository_path.is_empty() {
30		std::env::current_dir().unwrap_or_default()
31	} else {
32		std::path::PathBuf::from(&Request.repository_path)
33	};
34
35	let Output = tokio::process::Command::new("git")
36		.args(&Request.args)
37		.current_dir(&WorkingDirectory)
38		.output()
39		.await
40		.map_err(|Error| {
41			dev_log!("cocoon", "error: [CocoonService] git_exec failed to spawn: {}", Error);
42			dev_log!(
43				"git",
44				"[Git] exec-spawn-fail cwd={:?} args=[{}] error={}",
45				WorkingDirectory,
46				Request.args.join(" "),
47				Error
48			);
49			Status::internal(format!("git_exec: failed to spawn git: {}", Error))
50		})?;
51
52	let ExitCode = Output.status.code().unwrap_or(-1);
53
54	dev_log!(
55		"cocoon",
56		"[CocoonService] git_exec exit={} stdout={} bytes stderr={} bytes",
57		ExitCode,
58		Output.stdout.len(),
59		Output.stderr.len()
60	);
61
62	dev_log!(
63		"git",
64		"[Git] exec-done args=[{}] exit={} stdout={} stderr={}",
65		Request.args.join(" "),
66		ExitCode,
67		Output.stdout.len(),
68		Output.stderr.len()
69	);
70
71	let StdoutString = String::from_utf8_lossy(&Output.stdout);
72
73	let StderrString = String::from_utf8_lossy(&Output.stderr);
74
75	let mut OutputLines:Vec<String> = StdoutString.lines().map(|L| L.to_string()).collect();
76
77	for Line in StderrString.lines() {
78		OutputLines.push(format!("stderr: {}", Line));
79	}
80
81	Ok(Response::new(GitExecResponse { output:OutputLines, exit_code:ExitCode }))
82}