wayver's git archive


a simple self-hosted git server
git clone https://git.wayver.dev/bile

src/handlers/repo_log_feed.rs@7e0330303eec590c92eb6194f83f04d0e8fb2ea0

raw
Date Commit Message Author Files + -
2026-02-19 17:51 large refactoring wayverd 53 2153 1683
...

1use axum::{
2    extract::{Path, State},
3    http::StatusCode,
4    response::{IntoResponse as _, Response},
5};
6
7use crate::{
8    BileState,
9    error::Context as _,
10    git::Repository,
11    http::{
12        extractor::{Ref, RepoName},
13        response::{ErrorPage, Result, Xml},
14    },
15    utils::filters,
16};
17
18#[derive(askama::Template)]
19#[template(path = "log.xml")]
20struct RepoLogFeedTemplate<'a> {
21    repo: &'a Repository,
22    commits: Vec<git2::Commit<'a>>,
23    branch: String,
24    base_url: &'a str,
25}
26
27#[tracing::instrument(skip_all)]
28pub(crate) async fn get_1(state: State<BileState>, Path(repo_name): Path<RepoName>) -> Response {
29    state
30        .spawn(move |state| inner(&state, &repo_name, None))
31        .await
32}
33
34#[tracing::instrument(skip_all)]
35pub(crate) async fn get_2(
36    state: State<BileState>,
37    Path((repo_name, r#ref)): Path<(RepoName, Ref)>,
38) -> Response {
39    state
40        .spawn(move |state| inner(&state, &repo_name, Some(&r#ref)))
41        .await
42}
43
44fn inner(state: &BileState, repo_name: &RepoName, r#ref: Option<&Ref>) -> Result<Response> {
45    let Some(repo) = Repository::open(&state.config, repo_name).context("opening repository")?
46    else {
47        return Ok(ErrorPage::new(&state.config)
48            .with_status(StatusCode::NOT_FOUND)
49            .into_response());
50    };
51
52    if repo.is_empty()? {
53        // show a server error
54        return Ok(ErrorPage::new(&state.config)
55            .with_status(StatusCode::SERVICE_UNAVAILABLE)
56            .into_response());
57    }
58
59    let r = r#ref.map_or("HEAD", |r| r.0.as_str());
60
61    let Some(commits) = repo.commits(r, state.config.log_per_page)? else {
62        return Ok(ErrorPage::new(&state.config)
63            .with_status(StatusCode::NOT_FOUND)
64            .into_response());
65    };
66
67    let branch = repo.ref_or_head_shorthand(r#ref)?;
68
69    Ok(Xml(RepoLogFeedTemplate {
70        repo: &repo,
71        commits,
72        branch,
73        base_url: &format!("/{repo_name}"),
74    })
75    .into_response())
76}
77