tracevault_cli/commands/
sync.rs1use crate::api_client::{resolve_credentials, ApiClient};
2use crate::commands::init::git_remote_url;
3use crate::config::TracevaultConfig;
4use std::path::Path;
5
6pub async fn sync_repo(project_root: &Path) -> Result<(), Box<dyn std::error::Error>> {
7 let (server_url, token) = resolve_credentials(project_root);
8
9 let server_url = match server_url {
10 Some(url) => url,
11 None => {
12 eprintln!("No server_url configured. Skipping sync.");
13 return Ok(());
14 }
15 };
16
17 if token.is_none() {
18 eprintln!("Not logged in. Run 'tracevault login' to sync.");
19 return Ok(());
20 }
21
22 let org_slug = TracevaultConfig::load(project_root)
23 .and_then(|c| c.org_slug)
24 .ok_or("No org_slug in config. Run 'tracevault init' first.")?;
25
26 let remote = match git_remote_url(project_root) {
27 Some(url) => url,
28 None => {
29 eprintln!("No git remote 'origin' configured. Skipping sync.");
30 return Ok(());
31 }
32 };
33
34 let client = ApiClient::new(&server_url, token.as_deref());
35
36 let repo_name = std::process::Command::new("git")
37 .args(["rev-parse", "--show-toplevel"])
38 .current_dir(project_root)
39 .output()
40 .ok()
41 .filter(|o| o.status.success())
42 .map(|o| String::from_utf8_lossy(&o.stdout).trim().to_string())
43 .as_deref()
44 .and_then(|p| p.rsplit('/').next())
45 .map(String::from)
46 .unwrap_or_else(|| "unknown".into());
47
48 match client
49 .register_repo(
50 &org_slug,
51 crate::api_client::RegisterRepoRequest {
52 repo_name,
53 github_url: Some(remote.clone()),
54 },
55 )
56 .await
57 {
58 Ok(resp) => {
59 println!(
60 "Repo synced with server (id: {}, remote: {})",
61 resp.repo_id, remote
62 );
63 }
64 Err(e) => {
65 eprintln!("Warning: could not sync repo with server: {e}");
66 }
67 }
68
69 Ok(())
70}