wayver's git archive


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

src/handlers/repo_tag.rs@788f4460a8c003cb5018293ae250a8d8feaa2f1b

raw
Date Commit Message Author Files + -
2026-02-17 21:07 initial mvp wayverd 74 10800 0
...

1use axum::{
2    extract::Path,
3    http::StatusCode,
4    response::{IntoResponse, Response},
5};
6use git2::Tag;
7
8use crate::utils::{
9    Error, Result,
10    error::Context as _,
11    extractor::repo_name_checks,
12    filters,
13    git::Repository,
14    response::{Html, Redirect},
15    spawn_blocking,
16};
17
18#[derive(askama::Template)]
19#[template(path = "tag.html")]
20struct Template<'a> {
21    repo: &'a Repository,
22    tag: Tag<'a>,
23}
24
25#[tracing::instrument(skip_all)]
26pub async fn get(Path((repo_name, tag)): Path<(String, String)>) -> Response {
27    spawn_blocking(move || inner(&repo_name, &tag).into_response()).await
28}
29
30#[tracing::instrument(skip_all)]
31fn inner(repo_name: &str, tag: &str) -> Result {
32    repo_name_checks(repo_name)?;
33
34    let Some(repo) = Repository::open(repo_name).context("opening repository")? else {
35        return Err(Error::new(StatusCode::NOT_FOUND, "repo does not exist"));
36    };
37
38    let Ok(repo_tag) = repo.tag(tag) else {
39        return Ok(Redirect::permanent(&format!("/{repo_name}/commit/{tag}"))
40            .unwrap_or(Redirect::PERMANENT_ROOT)
41            .into_response());
42    };
43
44    Ok(Html(Template {
45        repo: &repo,
46        tag: repo_tag,
47    })
48    .into_response())
49}
50