gitdataai/libs/service/git_tools/ctx.rs
ZhenYi 5579e6c58e feat(backend): add git_tools service module
Add git_tools module with Git operations: branch, commit, diff, tag, tree, types, ctx
2026-04-18 19:08:06 +08:00

54 lines
1.8 KiB
Rust

//! Context wrapper for git tool handlers.
//!
//! Provides `GitToolCtx` which wraps `ToolContext` and adds git-domain operations.
use agent::ToolContext;
use git::GitDomain;
use models::projects::project;
use models::repos::repo;
use sea_orm::{ColumnTrait, EntityTrait, QueryFilter};
/// Wrapper around `ToolContext` providing git-domain operations for tool handlers.
#[derive(Clone)]
pub struct GitToolCtx {
pub ctx: ToolContext,
}
impl GitToolCtx {
pub fn new(ctx: ToolContext) -> Self {
Self { ctx }
}
/// Opens a git repository by project name and repo name.
pub async fn open_repo(&self, project_name: &str, repo_name: &str) -> Result<GitDomain, String> {
let db = self.ctx.db();
resolve_project_and_repo(db, project_name, repo_name)
.await
.and_then(|(_, path)| GitDomain::open(&path).map_err(|e| e.to_string()))
}
}
/// Free helper to resolve project_id + storage_path from names. Used by registry.
async fn resolve_project_and_repo(
db: &db::database::AppDatabase,
project_name: &str,
repo_name: &str,
) -> Result<(uuid::Uuid, String), String> {
let project = project::Entity::find()
.filter(project::Column::Name.eq(project_name))
.one(db)
.await
.map_err(|e| format!("DB error looking up project '{}': {}", project_name, e))?
.ok_or_else(|| format!("project '{}' not found", project_name))?;
let repo_model = repo::Entity::find()
.filter(repo::Column::Project.eq(project.id))
.filter(repo::Column::RepoName.eq(repo_name))
.one(db)
.await
.map_err(|e| format!("DB error looking up repo '{}/{}': {}", project_name, repo_name, e))?
.ok_or_else(|| format!("repo '{}/{}' not found", project_name, repo_name))?;
Ok((project.id, repo_model.storage_path))
}