174 lines
4.6 KiB
Rust
174 lines
4.6 KiB
Rust
use std::time::Duration;
|
|
|
|
use juniper::graphql_object;
|
|
use serde::{Deserialize, Serialize};
|
|
|
|
use crate::{
|
|
cmd::branch::{branch_list::BranchListItem, branch_summary::BranchSummary},
|
|
graphql::{
|
|
GraphqlContext,
|
|
cache_helper::{
|
|
MUTABLE_TTL, cached_json, mutable_cache_key, repo_revision,
|
|
},
|
|
},
|
|
};
|
|
|
|
const BRANCH_TTL: Duration = MUTABLE_TTL;
|
|
|
|
#[derive(Clone, Serialize, Deserialize)]
|
|
pub struct BranchGql {
|
|
pub name: String,
|
|
pub oid: String,
|
|
pub is_head: bool,
|
|
pub is_remote: bool,
|
|
pub is_current: bool,
|
|
pub upstream: Option<String>,
|
|
}
|
|
|
|
#[graphql_object(context = GraphqlContext)]
|
|
impl BranchGql {
|
|
fn name(&self) -> &str {
|
|
&self.name
|
|
}
|
|
fn oid(&self) -> &str {
|
|
&self.oid
|
|
}
|
|
fn is_head(&self) -> bool {
|
|
self.is_head
|
|
}
|
|
fn is_remote(&self) -> bool {
|
|
self.is_remote
|
|
}
|
|
fn is_current(&self) -> bool {
|
|
self.is_current
|
|
}
|
|
fn upstream(&self) -> Option<&str> {
|
|
self.upstream.as_deref()
|
|
}
|
|
}
|
|
|
|
impl From<BranchListItem> for BranchGql {
|
|
fn from(item: BranchListItem) -> Self {
|
|
BranchGql {
|
|
name: item.name,
|
|
oid: item.oid.0,
|
|
is_head: item.is_head,
|
|
is_remote: item.is_remote,
|
|
is_current: item.is_current,
|
|
upstream: item.upstream,
|
|
}
|
|
}
|
|
}
|
|
|
|
#[derive(Clone, Serialize, Deserialize)]
|
|
pub struct BranchSummaryGql {
|
|
pub local_count: i32,
|
|
pub remote_count: i32,
|
|
pub all_count: i32,
|
|
}
|
|
|
|
#[graphql_object(context = GraphqlContext)]
|
|
impl BranchSummaryGql {
|
|
fn local_count(&self) -> i32 {
|
|
self.local_count
|
|
}
|
|
fn remote_count(&self) -> i32 {
|
|
self.remote_count
|
|
}
|
|
fn all_count(&self) -> i32 {
|
|
self.all_count
|
|
}
|
|
}
|
|
|
|
impl From<BranchSummary> for BranchSummaryGql {
|
|
fn from(s: BranchSummary) -> Self {
|
|
BranchSummaryGql {
|
|
local_count: s.local_count as i32,
|
|
remote_count: s.remote_count as i32,
|
|
all_count: s.all_count as i32,
|
|
}
|
|
}
|
|
}
|
|
|
|
pub async fn resolve_branches(
|
|
ctx: &GraphqlContext,
|
|
) -> anyhow::Result<Vec<BranchGql>> {
|
|
let revision = repo_revision(ctx).await;
|
|
let key = mutable_cache_key(ctx, "query:git:branches", &[], &revision);
|
|
cached_json(&ctx.cache, &key, BRANCH_TTL, || {
|
|
let repo = ctx.repo.clone();
|
|
async move {
|
|
let items =
|
|
tokio::task::spawn_blocking(move || repo.branch_list_all())
|
|
.await?
|
|
.map_err(|e| anyhow::anyhow!(e))?;
|
|
Ok(items.into_iter().map(BranchGql::from).collect())
|
|
}
|
|
})
|
|
.await
|
|
}
|
|
|
|
pub async fn resolve_branch(
|
|
ctx: &GraphqlContext,
|
|
name: String,
|
|
) -> anyhow::Result<BranchGql> {
|
|
let revision = repo_revision(ctx).await;
|
|
let key = mutable_cache_key(ctx, "query:git:branch", &[&name], &revision);
|
|
cached_json(&ctx.cache, &key, BRANCH_TTL, || {
|
|
let repo = ctx.repo.clone();
|
|
let branch_name = name.clone();
|
|
async move {
|
|
let item = tokio::task::spawn_blocking(move || {
|
|
repo.branch_info(branch_name)
|
|
})
|
|
.await?
|
|
.map_err(|e| anyhow::anyhow!(e))?;
|
|
Ok(BranchGql::from(item))
|
|
}
|
|
})
|
|
.await
|
|
}
|
|
|
|
pub async fn resolve_head_branch(
|
|
ctx: &GraphqlContext,
|
|
) -> anyhow::Result<BranchGql> {
|
|
let revision = repo_revision(ctx).await;
|
|
let key = mutable_cache_key(ctx, "query:git:head_branch", &[], &revision);
|
|
cached_json(&ctx.cache, &key, BRANCH_TTL, || {
|
|
let repo1 = ctx.repo.clone();
|
|
let repo2 = ctx.repo.clone();
|
|
async move {
|
|
let head_name =
|
|
tokio::task::spawn_blocking(move || repo1.branch_head_name())
|
|
.await?
|
|
.map_err(|e| anyhow::anyhow!(e))?;
|
|
let branch = tokio::task::spawn_blocking(move || {
|
|
repo2.branch_info(head_name)
|
|
})
|
|
.await?
|
|
.map_err(|e| anyhow::anyhow!(e))?;
|
|
Ok(BranchGql::from(branch))
|
|
}
|
|
})
|
|
.await
|
|
}
|
|
|
|
pub async fn resolve_branch_summary(
|
|
ctx: &GraphqlContext,
|
|
) -> anyhow::Result<BranchSummaryGql> {
|
|
let revision = repo_revision(ctx).await;
|
|
let key =
|
|
mutable_cache_key(ctx, "query:git:branch_summary", &[], &revision);
|
|
cached_json(&ctx.cache, &key, BRANCH_TTL, || {
|
|
let repo = ctx.repo.clone();
|
|
async move {
|
|
let summary =
|
|
tokio::task::spawn_blocking(move || repo.branch_summary())
|
|
.await?
|
|
.map_err(|e| anyhow::anyhow!(e))?;
|
|
Ok(BranchSummaryGql::from(summary))
|
|
}
|
|
})
|
|
.await
|
|
}
|