Skip to repository content

tenant.openagents/omega

No repository description is available.

OpenAgents Git authority 2026-07-28T02:53:24.454Z Public web read
NIP-34 coordinate30617:7649603503856e5148d571eac2766b288a8ff1e9e35d380337a1d2b0015b4f92:omega
MaintainersHidden in public view
References2 branches · 1 tag
Read-only clonegit clone https://openagents.com/git/tenant.openagents/omega.git
Browse files

git.rs

130 lines · 4.0 KB · rust
1use anyhow::{Context as _, Result};
2use collections::HashMap;
3use futures::lock::{Mutex, OwnedMutexGuard};
4use std::{
5    cell::RefCell,
6    path::{Path, PathBuf},
7    sync::Arc,
8};
9
10use crate::paths::REPOS_DIR;
11
12thread_local! {
13    static REPO_LOCKS: RefCell<HashMap<PathBuf, Arc<Mutex<()>>>> = RefCell::new(HashMap::default());
14}
15
16#[must_use]
17pub async fn lock_repo(path: impl AsRef<Path>) -> OwnedMutexGuard<()> {
18    REPO_LOCKS
19        .with(|cell| {
20            cell.borrow_mut()
21                .entry(path.as_ref().to_path_buf())
22                .or_default()
23                .clone()
24        })
25        .lock_owned()
26        .await
27}
28
29pub async fn run_git(repo_path: &Path, args: &[&str]) -> Result<String> {
30    let output = smol::process::Command::new("git")
31        .current_dir(repo_path)
32        .args(args)
33        .output()
34        .await?;
35
36    anyhow::ensure!(
37        output.status.success(),
38        "`git {}` within `{}` failed with status: {}\nstderr:\n{}\nstdout:\n{}",
39        args.join(" "),
40        repo_path.display(),
41        output.status,
42        String::from_utf8_lossy(&output.stderr),
43        String::from_utf8_lossy(&output.stdout),
44    );
45    Ok(String::from_utf8(output.stdout)?.trim().to_string())
46}
47
48pub fn parse_repo_url(url: &str) -> Result<(String, String)> {
49    if url.contains('@') {
50        let (_, path) = url.split_once(':').context("expected : in git url")?;
51        let (owner, repo) = path.split_once('/').context("expected / in git url")?;
52        Ok((owner.to_string(), repo.trim_end_matches(".git").to_string()))
53    } else {
54        let parsed = http_client::Url::parse(url)?;
55        let mut segments = parsed.path_segments().context("empty http url")?;
56        let owner = segments.next().context("expected owner")?;
57        let repo = segments.next().context("expected repo")?;
58        Ok((owner.to_string(), repo.trim_end_matches(".git").to_string()))
59    }
60}
61
62pub fn repo_path_for_url(url: &str) -> Result<PathBuf> {
63    let (owner, name) = parse_repo_url(url)?;
64    Ok(REPOS_DIR.join(&owner).join(&name))
65}
66
67pub async fn ensure_repo_cloned(repo_url: &str) -> Result<PathBuf> {
68    let repo_path = repo_path_for_url(repo_url)?;
69    let _lock = lock_repo(&repo_path).await;
70
71    // Validate existing repo has correct origin, otherwise remove and re-init.
72    let mut git_repo_exists = false;
73    if repo_path.is_dir() {
74        if run_git(&repo_path, &["remote", "get-url", "origin"])
75            .await
76            .map_or(false, |origin| origin.trim() == repo_url)
77        {
78            git_repo_exists = true;
79        } else {
80            std::fs::remove_dir_all(&repo_path).ok();
81        }
82    }
83
84    if !git_repo_exists {
85        log::info!("Cloning {} into {:?}", repo_url, repo_path);
86        std::fs::create_dir_all(&repo_path)?;
87        run_git(&repo_path, &["init"]).await?;
88        run_git(&repo_path, &["remote", "add", "origin", repo_url])
89            .await
90            .ok();
91    }
92
93    // Always fetch to get latest commits
94    run_git(&repo_path, &["fetch", "--depth", "1000", "origin"]).await?;
95
96    // Check if we have a valid HEAD, if not checkout FETCH_HEAD
97    let has_head = run_git(&repo_path, &["rev-parse", "HEAD"]).await.is_ok();
98    if !has_head {
99        // Use reset to set HEAD without needing a branch
100        run_git(&repo_path, &["reset", "--hard", "FETCH_HEAD"]).await?;
101    }
102
103    Ok(repo_path)
104}
105
106pub async fn fetch_if_needed(repo_path: &Path, revision: &str) -> Result<String> {
107    let resolved = run_git(
108        repo_path,
109        &["rev-parse", &format!("{}^{{commit}}", revision)],
110    )
111    .await;
112
113    if let Ok(sha) = resolved {
114        return Ok(sha);
115    }
116
117    if run_git(repo_path, &["fetch", "--depth", "1", "origin", revision])
118        .await
119        .is_err()
120    {
121        run_git(repo_path, &["fetch", "origin"]).await?;
122    }
123
124    run_git(
125        repo_path,
126        &["rev-parse", &format!("{}^{{commit}}", revision)],
127    )
128    .await
129}
130
Served at tenant.openagents/omega Member data and write actions are omitted.