From 5d9a1047578f33e71fc721b19382858813355693 Mon Sep 17 00:00:00 2001 From: Jordan Doyle Date: Wed, 6 Jul 2022 12:54:40 +0100 Subject: [PATCH] Add tag view --- src/git.rs | 46 ++++++++++++++++++++++++++++++++++++++++++---- src/methods/repo.rs | 27 ++++++++++++++++++++++++++- statics/style.css | 6 ++++++ templates/repo/commit.html | 1 - templates/repo/tag.html | 37 +++++++++++++++++++++++++++++++++++++ 5 files changed, 111 insertions(+), 6 deletions(-) create mode 100644 templates/repo/tag.html diff --git a/src/git.rs b/src/git.rs index b20f84d..f025d13 100644 --- a/src/git.rs +++ b/src/git.rs @@ -7,7 +7,7 @@ use std::{ }; use arc_swap::ArcSwapOption; -use git2::{Oid, Repository, Signature}; +use git2::{ObjectType, Oid, Repository, Signature}; use moka::future::Cache; use time::OffsetDateTime; @@ -59,6 +59,29 @@ impl Git { .await } + pub async fn get_tag(&self, repo: PathBuf, tag_name: &str) -> DetailedTag { + let repo = Repository::open_bare(repo).unwrap(); + let tag = repo + .find_reference(&format!("refs/tags/{tag_name}")) + .unwrap() + .peel_to_tag() + .unwrap(); + let tag_target = tag.target().unwrap(); + + let tagged_object = match tag_target.kind() { + Some(ObjectType::Commit) => Some(TaggedObject::Commit(tag_target.id().to_string())), + Some(ObjectType::Tree) => Some(TaggedObject::Tree(tag_target.id().to_string())), + None | Some(_) => None, + }; + + DetailedTag { + name: tag_name.to_string(), + tagger: tag.tagger().map(Into::into), + message: tag.message().unwrap().to_string(), + tagged_object, + } + } + pub async fn get_refs(&self, repo: PathBuf) -> Arc { self.refs .get_with(repo.clone(), async { @@ -114,11 +137,12 @@ impl Git { continue; }; - let object = object.to_object(&repo) - .unwrap(); + let object = object.to_object(&repo).unwrap(); let blob = object.into_blob().unwrap(); - return Some(Arc::from(String::from_utf8(blob.content().to_vec()).unwrap())); + return Some(Arc::from( + String::from_utf8(blob.content().to_vec()).unwrap(), + )); } None @@ -219,6 +243,20 @@ pub struct Remote { } #[derive(Debug)] +pub enum TaggedObject { + Commit(String), + Tree(String), +} + +#[derive(Debug)] +pub struct DetailedTag { + pub name: String, + pub tagger: Option, + pub message: String, + pub tagged_object: Option, +} + +#[derive(Debug)] pub struct Tag { pub name: String, pub tagger: Option, diff --git a/src/methods/repo.rs b/src/methods/repo.rs index f75710c..8dd6269 100644 --- a/src/methods/repo.rs +++ b/src/methods/repo.rs @@ -16,7 +16,7 @@ use path_clean::PathClean; use serde::Deserialize; use tower::{util::BoxCloneService, Service}; -use crate::git::Refs; +use crate::git::{DetailedTag, Refs}; use crate::{git::Commit, layers::UnwrapInfallible, Git}; #[derive(Clone)] @@ -58,6 +58,7 @@ pub async fn service(mut request: Request) -> Some("commit") => BoxCloneService::new(handle_commit.into_service()), Some("diff") => BoxCloneService::new(handle_diff.into_service()), Some("stats") => BoxCloneService::new(handle_stats.into_service()), + Some("tag") => BoxCloneService::new(handle_tag.into_service()), Some(v) => { uri_parts.push(v); BoxCloneService::new(handle_summary.into_service()) @@ -90,6 +91,30 @@ pub async fn handle_summary(Extension(repo): Extension) -> Html, + Extension(RepositoryPath(repository_path)): Extension, + Extension(git): Extension, + Query(query): Query, +) -> Html { + #[derive(Template)] + #[template(path = "repo/tag.html")] + pub struct View { + repo: Repository, + tag: DetailedTag, + } + + let tag = git.get_tag(repository_path, &query.name).await; + + Html(View { repo, tag }.render().unwrap()) +} + +#[derive(Deserialize)] pub struct LogQuery { #[serde(rename = "ofs")] offset: Option, diff --git a/statics/style.css b/statics/style.css index c0e96ce..51cae2b 100644 --- a/statics/style.css +++ b/statics/style.css @@ -85,3 +85,9 @@ nav a.active { color: #000; background-color: #ccc; } + +pre.h2-first-line::first-line { + font-family: sans-serif; + font-size: 1.5em; + font-weight: bold; +} diff --git a/templates/repo/commit.html b/templates/repo/commit.html index f4e13b7..70eeee2 100644 --- a/templates/repo/commit.html +++ b/templates/repo/commit.html @@ -34,5 +34,4 @@

{{ commit.summary() }}

{{ commit.body() }}
- {% endblock %} \ No newline at end of file diff --git a/templates/repo/tag.html b/templates/repo/tag.html new file mode 100644 index 0000000..09bd4bb --- /dev/null +++ b/templates/repo/tag.html @@ -0,0 +1,37 @@ +{% extends "repo/base.html" %} + +{% block content %} + + + + + + + {% if let Some(tagger) = tag.tagger %} + + + + + + + + + {% endif %} + {% if let Some(tagged_object) = tag.tagged_object %} + + + + + {% endif %} + +
tag name{{ tag.name }}
tag date{{ tagger.time() }}
tagged by{{ tagger.name() }} <{{ tagger.email() }}>
tagged object + {% match tagged_object %} + {% when crate::git::TaggedObject::Commit with (commit) %} + commit {{ commit.as_str()[0..10] }}... + {% when crate::git::TaggedObject::Tree with (tree) %} + tree {{ tree }} + {% endmatch %} +
+ +
{{ tag.message }}
+{% endblock %} -- libgit2 1.7.2