gitscope
← rgit / main / src/methods/repo/summary.rs
https://dev.kronoz.win/r/rgit.git
src/methods/repo/summary.rs · Rust
Blame Raw
 1use std::{collections::BTreeMap, sync::Arc};
 2
 3use anyhow::Context;
 4use askama::Template;
 5use axum::{Extension, response::IntoResponse};
 6use axum_extra::extract::Host;
 7use rkyv::string::ArchivedString;
 8
 9use crate::{
10    database::schema::{commit::YokedCommit, repository::YokedRepository},
11    into_response,
12    methods::{
13        filters,
14        repo::{DEFAULT_BRANCHES, Refs, Repository, Result},
15    },
16};
17
18#[derive(Template)]
19#[template(path = "repo/summary.html")]
20pub struct View {
21    repo: Repository,
22    refs: Refs,
23    commit_list: Vec<YokedCommit>,
24    branch: Option<Arc<str>>,
25    exported: bool,
26    host: String,
27}
28
29pub async fn handle(
30    Extension(repo): Extension<Repository>,
31    Extension(db): Extension<Arc<rocksdb::DB>>,
32    Host(host): Host,
33) -> Result<impl IntoResponse> {
34    tokio::task::spawn_blocking(move || {
35        let repository = crate::database::schema::repository::Repository::open(&db, &*repo)?
36            .context("Repository does not exist")?;
37        let commits = get_default_branch_commits(&repository, &db)?;
38
39        let mut heads = BTreeMap::new();
40        if let Some(heads_db) = repository.get().heads(&db)? {
41            for head in heads_db
42                .get()
43                .0
44                .as_slice()
45                .iter()
46                .map(ArchivedString::as_str)
47            {
48                let commit_tree = repository.get().commit_tree(db.clone(), head);
49                let name = head.strip_prefix("refs/heads/");
50
51                if let (Some(name), Some(commit)) = (name, commit_tree.fetch_latest_one()?) {
52                    heads.insert(name.to_string(), commit);
53                }
54            }
55        }
56
57        let tags = repository.get().tag_tree(db).fetch_all()?;
58
59        Ok(into_response(View {
60            repo,
61            refs: Refs { heads, tags },
62            commit_list: commits,
63            branch: None,
64            exported: repository.get().exported,
65            host,
66        }))
67    })
68    .await
69    .context("Failed to attach to tokio task")?
70}
71
72pub fn get_default_branch_commits(
73    repository: &YokedRepository,
74    database: &Arc<rocksdb::DB>,
75) -> Result<Vec<YokedCommit>> {
76    for branch in repository
77        .get()
78        .default_branch
79        .as_deref()
80        .into_iter()
81        .chain(DEFAULT_BRANCHES.into_iter())
82    {
83        let commit_tree = repository.get().commit_tree(database.clone(), branch);
84        let commits = commit_tree.fetch_latest(11, 0)?;
85
86        if !commits.is_empty() {
87            return Ok(commits);
88        }
89    }
90
91    Ok(vec![])
92}