raw
1use std::fs;
2
3use axum::{
4 extract::State,
5 response::{IntoResponse as _, Response},
6};
7
8use crate::{
9 BileState,
10 config::Config,
11 error::Context as _,
12 git::Repository,
13 http::response::{Html, Result},
14 utils::filters,
15};
16
17#[derive(askama::Template)]
18#[template(path = "index.html")]
19struct IndexTemplate<'a> {
20 config: &'a Config,
21 repos: Vec<Repository>,
22}
23
24#[tracing::instrument(skip_all)]
25pub(crate) async fn get(state: State<BileState>) -> Response {
26 state.spawn(move |state| inner(&state)).await
27}
28
29fn inner(state: &BileState) -> Result<Response> {
30 let Ok(read) = fs::read_dir(&state.config.project_root) else {
31 return Ok(Html(IndexTemplate {
32 config: &state.config,
33 repos: Vec::new(),
34 })
35 .into_response());
36 };
37
38 let mut repos = Vec::new();
39
40 for entry in read {
41 let entry = entry.context("failed to open directory entry")?;
42
43 let Some(repo) = Repository::open_path(&state.config, &entry.path())
44 .context("failed to open repository")?
45 else {
46 continue;
47 };
48
49 if !repo.path().join(&state.config.export_ok).exists() {
52 continue;
53 }
54
55 repos.push(repo);
56 }
57
58 Ok(Html(IndexTemplate {
59 config: &state.config,
60 repos,
61 })
62 .into_response())
63}
64