Skip to content

Commit

Permalink
Use correct default branch on log & summary pages
Browse files Browse the repository at this point in the history
  • Loading branch information
w4 committed Dec 31, 2023
1 parent d964566 commit 7d804b9
Show file tree
Hide file tree
Showing 7 changed files with 115 additions and 15 deletions.
49 changes: 45 additions & 4 deletions src/database/indexer.rs
Original file line number Diff line number Diff line change
Expand Up @@ -4,10 +4,10 @@ use std::{
path::{Path, PathBuf},
};

use git2::Sort;
use git2::{ErrorCode, Sort};
use ini::Ini;
use time::OffsetDateTime;
use tracing::{error, info, info_span};
use tracing::{error, info, info_span, instrument, warn};

use crate::database::schema::{
commit::Commit,
Expand Down Expand Up @@ -56,11 +56,19 @@ fn update_repository_metadata(scan_path: &Path, db: &sled::Db) {
owner: find_gitweb_owner(repository_path.as_path()),
last_modified: find_last_committed_time(&git_repository)
.unwrap_or(OffsetDateTime::UNIX_EPOCH),
default_branch: find_default_branch(&git_repository)
.ok()
.flatten()
.map(Cow::Owned),
}
.insert(db, relative);
}
}

fn find_default_branch(repo: &git2::Repository) -> Result<Option<String>, git2::Error> {
Ok(repo.head()?.name().map(ToString::to_string))
}

fn find_last_committed_time(repo: &git2::Repository) -> Result<OffsetDateTime, git2::Error> {
let mut timestamp = OffsetDateTime::UNIX_EPOCH;

Expand All @@ -81,9 +89,13 @@ fn find_last_committed_time(repo: &git2::Repository) -> Result<OffsetDateTime, g
Ok(timestamp)
}

#[instrument(skip(db))]
fn update_repository_reflog(scan_path: &Path, db: &sled::Db) {
for (relative_path, db_repository) in Repository::fetch_all(db).unwrap() {
let git_repository = git2::Repository::open(scan_path.join(&relative_path)).unwrap();
let Some(git_repository) = open_repo(scan_path, &relative_path, db_repository.get(), db)
else {
continue;
};

for reference in git_repository.references().unwrap() {
let reference = reference.unwrap();
Expand Down Expand Up @@ -145,9 +157,13 @@ fn update_repository_reflog(scan_path: &Path, db: &sled::Db) {
}
}

#[instrument(skip(db))]
fn update_repository_tags(scan_path: &Path, db: &sled::Db) {
for (relative_path, db_repository) in Repository::fetch_all(db).unwrap() {
let git_repository = git2::Repository::open(scan_path.join(&relative_path)).unwrap();
let Some(git_repository) = open_repo(scan_path, &relative_path, db_repository.get(), db)
else {
continue;
};

let tag_tree = db_repository.get().tag_tree(db).unwrap();

Expand Down Expand Up @@ -195,6 +211,31 @@ fn update_repository_tags(scan_path: &Path, db: &sled::Db) {
}
}

#[instrument(skip(scan_path, db_repository, db))]
fn open_repo(
scan_path: &Path,
relative_path: &str,
db_repository: &Repository<'_>,
db: &sled::Db,
) -> Option<git2::Repository> {
match git2::Repository::open(scan_path.join(relative_path)) {
Ok(v) => Some(v),
Err(e) if e.code() == ErrorCode::NotFound => {
warn!("Repository gone from disk, removing from db");

if let Err(error) = db_repository.delete(db, relative_path) {
warn!(%error, "Failed to delete dangling index");
}

None
}
Err(error) => {
warn!(%error, "Failed to reindex {relative_path}, skipping");
None
}
}
}

fn get_relative_path<'a>(relative_to: &Path, full_path: &'a Path) -> &'a Path {
full_path.strip_prefix(relative_to).unwrap()
}
Expand Down
2 changes: 2 additions & 0 deletions src/database/schema/mod.rs
Original file line number Diff line number Diff line change
Expand Up @@ -9,3 +9,5 @@ pub mod repository;
pub mod tag;

pub type Yoked<T> = Yoke<T, Box<IVec>>;

pub const SCHEMA_VERSION: &str = "1";
5 changes: 5 additions & 0 deletions src/database/schema/prefixes.rs
Original file line number Diff line number Diff line change
Expand Up @@ -5,6 +5,7 @@ use crate::database::schema::repository::RepositoryId;
#[repr(u8)]
pub enum TreePrefix {
Repository = 0,
SchemaVersion = 1,
Commit = 100,
Tag = 101,
}
Expand Down Expand Up @@ -45,4 +46,8 @@ impl TreePrefix {

prefixed
}

pub fn schema_version() -> &'static [u8] {
&[TreePrefix::SchemaVersion as u8]
}
}
14 changes: 14 additions & 0 deletions src/database/schema/repository.rs
Original file line number Diff line number Diff line change
Expand Up @@ -25,6 +25,9 @@ pub struct Repository<'a> {
pub owner: Option<Cow<'a, str>>,
/// The last time this repository was updated, currently read from the directory mtime
pub last_modified: OffsetDateTime,
/// The default branch for Git operations
#[serde(borrow)]
pub default_branch: Option<Cow<'a, str>>,
}

pub type YokedRepository = Yoked<Repository<'static>>;
Expand Down Expand Up @@ -60,6 +63,17 @@ impl Repository<'_> {
.unwrap();
}

pub fn delete<P: AsRef<Path>>(&self, database: &sled::Db, path: P) -> Result<()> {
for reference in self.heads(database) {
database.drop_tree(TreePrefix::commit_id(self.id, &reference))?;
}

database.drop_tree(TreePrefix::tag_id(self.id))?;
database.remove(TreePrefix::repository_id(path))?;

Ok(())
}

pub fn open<P: AsRef<Path>>(database: &sled::Db, path: P) -> Result<Option<YokedRepository>> {
database
.get(TreePrefix::repository_id(path))
Expand Down
44 changes: 35 additions & 9 deletions src/main.rs
Original file line number Diff line number Diff line change
@@ -1,6 +1,7 @@
#![deny(clippy::pedantic)]

use std::{
borrow::Cow,
fmt::{Display, Formatter},
net::SocketAddr,
path::PathBuf,
Expand All @@ -9,6 +10,7 @@ use std::{
time::Duration,
};

use anyhow::Context;
use askama::Template;
use axum::{
body::Body,
Expand All @@ -20,6 +22,7 @@ use axum::{
};
use bat::assets::HighlightingAssets;
use clap::Parser;
use database::schema::{prefixes::TreePrefix, SCHEMA_VERSION};
use once_cell::sync::{Lazy, OnceCell};
use sha2::{digest::FixedOutput, Digest};
use sled::Db;
Expand All @@ -30,7 +33,7 @@ use tokio::{
};
use tower_http::cors::CorsLayer;
use tower_layer::layer_fn;
use tracing::{error, info, instrument};
use tracing::{error, info, instrument, warn};

use crate::{git::Git, layers::logger::LoggingMiddleware};

Expand Down Expand Up @@ -95,19 +98,15 @@ impl FromStr for RefreshInterval {
}

#[tokio::main]
async fn main() -> Result<(), Box<dyn std::error::Error>> {
async fn main() -> Result<(), anyhow::Error> {
let args: Args = Args::parse();

let subscriber = tracing_subscriber::fmt();
#[cfg(debug_assertions)]
let subscriber = subscriber.pretty();
subscriber.init();

let db = sled::Config::default()
.use_compression(true)
.path(&args.db_store)
.open()
.unwrap();
let db = open_db(&args)?;

let indexer_wakeup_task =
run_indexer(db.clone(), args.scan_path.clone(), args.refresh_interval);
Expand Down Expand Up @@ -190,15 +189,42 @@ async fn main() -> Result<(), Box<dyn std::error::Error>> {
.serve(app.into_make_service_with_connect_info::<SocketAddr>());

tokio::select! {
res = server => res.map_err(Box::from),
res = indexer_wakeup_task => res.map_err(Box::from),
res = server => res.context("failed to run server"),
res = indexer_wakeup_task => res.context("failed to run indexer"),
_ = tokio::signal::ctrl_c() => {
info!("Received ctrl-c, shutting down");
Ok(())
}
}
}

fn open_db(args: &Args) -> Result<Db, anyhow::Error> {
let db = sled::Config::default()
.use_compression(true)
.path(&args.db_store)
.open()
.context("Failed to open database")?;

let needs_schema_regen = match db.get(TreePrefix::schema_version())? {
Some(v) if v != SCHEMA_VERSION.as_bytes() => Some(Some(v)),
Some(_) => None,
None => Some(None),
};

if let Some(version) = needs_schema_regen {
let old_version = version
.as_deref()
.map_or(Cow::Borrowed("unknown"), String::from_utf8_lossy);

warn!("Clearing outdated database ({old_version} != {SCHEMA_VERSION})");

db.clear()?;
db.insert(TreePrefix::schema_version(), SCHEMA_VERSION)?;
}

Ok(db)
}

async fn run_indexer(
db: Db,
scan_path: PathBuf,
Expand Down
8 changes: 7 additions & 1 deletion src/methods/repo/log.rs
Original file line number Diff line number Diff line change
Expand Up @@ -84,7 +84,13 @@ pub async fn get_branch_commits(
return Ok(tag_tree);
}

for branch in DEFAULT_BRANCHES {
for branch in repository
.get()
.default_branch
.as_deref()
.into_iter()
.chain(DEFAULT_BRANCHES.into_iter())
{
let commit_tree = repository.get().commit_tree(database, branch)?;
let commits = commit_tree.fetch_latest(amount, offset).await;

Expand Down
8 changes: 7 additions & 1 deletion src/methods/repo/summary.rs
Original file line number Diff line number Diff line change
Expand Up @@ -60,7 +60,13 @@ pub async fn get_default_branch_commits(
repository: &YokedRepository,
database: &sled::Db,
) -> Result<Vec<YokedCommit>> {
for branch in DEFAULT_BRANCHES {
for branch in repository
.get()
.default_branch
.as_deref()
.into_iter()
.chain(DEFAULT_BRANCHES.into_iter())
{
let commit_tree = repository.get().commit_tree(database, branch)?;
let commits = commit_tree.fetch_latest(11, 0).await;

Expand Down

0 comments on commit 7d804b9

Please sign in to comment.