wayver's git archive


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

src/handlers/repo_refs_feed.rs@71b17dd92232913d023854951d629e9876076719

raw
Date Commit Message Author Files + -
2026-02-20 20:25 remove unneeded result type alias wayverd 13 27 31
...

1use axum::{
2    extract::State,
3    http::StatusCode,
4    response::{IntoResponse as _, Response},
5};
6
7use crate::{
8    BileState,
9    error::{Context as _, Result},
10    git::{Repository, TagEntry},
11    http::{
12        extractor::RepoName,
13        path::Path,
14        response::{ErrorPage, Xml},
15    },
16    utils::filters,
17};
18
19#[derive(askama::Template)]
20#[template(path = "refs.xml")]
21struct RepoRefFeedTemplate<'a> {
22    repo: &'a Repository,
23    tags: Vec<TagEntry>,
24    base_url: &'a str,
25}
26
27#[tracing::instrument(skip_all)]
28pub(crate) async fn get(state: State<BileState>, Path(repo_name): Path<RepoName>) -> Response {
29    state.spawn(move |state| inner(&state, &repo_name)).await
30}
31
32#[tracing::instrument(skip_all)]
33fn inner(state: &BileState, repo_name: &RepoName) -> Result<Response> {
34    let Some(repo) = Repository::open(&state.config, repo_name).context("opening repository")?
35    else {
36        return Ok(ErrorPage::from(state)
37            .with_status(StatusCode::NOT_FOUND)
38            .into_response());
39    };
40
41    if repo.is_empty()? {
42        // show a server error
43        return Ok(ErrorPage::from(state)
44            .with_status(StatusCode::SERVICE_UNAVAILABLE)
45            .into_response());
46    }
47
48    let mut tags = repo.tag_entries()?;
49
50    // sort so that newest tags are at the top
51    tags.sort_unstable_by(|a, b| a.signature.when().cmp(&b.signature.when()).reverse());
52
53    Ok(Xml(RepoRefFeedTemplate {
54        repo: &repo,
55        tags,
56        base_url: &format!("/{repo_name}"),
57    })
58    .into_response())
59}
60