hematite/tools/
git_onboarding.rs1use serde_json::Value;
2use std::fmt::Write as _;
3use std::process::Command;
4
5pub async fn execute(args: &Value) -> Result<String, String> {
9 let url = args
10 .get("url")
11 .and_then(|v| v.as_str())
12 .ok_or("Missing 'url' argument")?;
13 let name = args
14 .get("name")
15 .and_then(|v| v.as_str())
16 .unwrap_or("origin");
17 let do_push = args.get("push").and_then(|v| v.as_bool()).unwrap_or(false);
18
19 if !url.starts_with("https://") && !url.starts_with("git@") {
21 return Err("Invalid remote URL. Must be HTTPS or SSH.".into());
22 }
23
24 let check = Command::new("git")
26 .args(["remote", "get-url", name])
27 .output()
28 .map_err(|e| e.to_string())?;
29
30 if check.status.success() {
31 let set_url = Command::new("git")
33 .args(["remote", "set-url", name, url])
34 .output()
35 .map_err(|e| e.to_string())?;
36 if !set_url.status.success() {
37 return Err(format!(
38 "Failed to update remote: {}",
39 String::from_utf8_lossy(&set_url.stderr)
40 ));
41 }
42 } else {
43 let add = Command::new("git")
45 .args(["remote", "add", name, url])
46 .output()
47 .map_err(|e| e.to_string())?;
48 if !add.status.success() {
49 return Err(format!(
50 "Failed to add remote: {}",
51 String::from_utf8_lossy(&add.stderr)
52 ));
53 }
54 }
55
56 let mut status = format!("Successfully configured remote '{}' to {}.", name, url);
57
58 if do_push {
60 let push = Command::new("git")
61 .args(["push", "-u", name, "HEAD"])
62 .output()
63 .map_err(|e| e.to_string())?;
64
65 if push.status.success() {
66 status.push_str("\nInitial push complete. Branch tracking established.");
67 } else {
68 let _ = write!(status, "\nWarning: Push failed: {}. You may need to authenticate or handle branch conflicts manually.", String::from_utf8_lossy(&push.stderr));
69 }
70 }
71
72 Ok(status)
73}