gitscope
← rgit / Diff · 5d9a104 → 5d9a104
Changes 5d9a104..5d9a104
Patch commit
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<Refs> {
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
@@ -218,6 +242,20 @@ pub struct Remote {
pub name: String,
}
+#[derive(Debug)]
+pub enum TaggedObject {
+ Commit(String),
+ Tree(String),
+}
+
+#[derive(Debug)]
+pub struct DetailedTag {
+ pub name: String,
+ pub tagger: Option<CommitUser>,
+ pub message: String,
+ pub tagged_object: Option<TaggedObject>,
+}
+
#[derive(Debug)]
pub struct Tag {
pub name: String,
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<ReqBody: Send + 'static>(mut request: Request<ReqBody>) ->
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())
@@ -89,6 +90,30 @@ pub async fn handle_summary(Extension(repo): Extension<Repository>) -> Html<Stri
Html(View { repo }.render().unwrap())
}
+#[derive(Deserialize)]
+pub struct TagQuery {
+ #[serde(rename = "h")]
+ name: String,
+}
+
+pub async fn handle_tag(
+ Extension(repo): Extension<Repository>,
+ Extension(RepositoryPath(repository_path)): Extension<RepositoryPath>,
+ Extension(git): Extension<Git>,
+ Query(query): Query<TagQuery>,
+) -> Html<String> {
+ #[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")]
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 @@
<h2>{{ commit.summary() }}</h2>
<pre>{{ commit.body() }}</pre>
-
{% 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 %}
+<table class="commit-info">
+ <tbody>
+ <tr>
+ <th>tag name</th>
+ <td>{{ tag.name }}</td>
+ </tr>
+ {% if let Some(tagger) = tag.tagger %}
+ <tr>
+ <th>tag date</th>
+ <td>{{ tagger.time() }}</td>
+ </tr>
+ <tr>
+ <th>tagged by</th>
+ <td>{{ tagger.name() }} &lt;{{ tagger.email() }}&gt;</td>
+ </tr>
+ {% endif %}
+ {% if let Some(tagged_object) = tag.tagged_object %}
+ <tr>
+ <th>tagged object</th>
+ <td>
+ {% match tagged_object %}
+ {% when crate::git::TaggedObject::Commit with (commit) %}
+ <a href="/{{ repo.display() }}/commit?id={{ commit }}">commit {{ commit.as_str()[0..10] }}...</a>
+ {% when crate::git::TaggedObject::Tree with (tree) %}
+ tree {{ tree }}
+ {% endmatch %}
+ </td>
+ </tr>
+ {% endif %}
+ </tbody>
+</table>
+
+<pre class="h2-first-line">{{ tag.message }}</pre>
+{% endblock %}