aboutsummaryrefslogtreecommitdiff
diff options
context:
space:
mode:
authorTuomas Siipola2020-01-03 17:58:55 +0200
committerTuomas Siipola2020-01-03 17:58:55 +0200
commitf686ac3502e2d79d02931a50e29fac9a56196628 (patch)
treeb869e7cbf17b4ae3413032dc880a8db3168c32c2
parent3cbd74ad6161112fbd41723b48dcfa66e9caa603 (diff)
Add log page
-rw-r--r--Cargo.lock1
-rw-r--r--Cargo.toml1
-rw-r--r--src/main.rs56
-rw-r--r--templates/log.html42
-rw-r--r--templates/repo.html1
5 files changed, 97 insertions, 4 deletions
diff --git a/Cargo.lock b/Cargo.lock
index 1da2f8e..ed88f53 100644
--- a/Cargo.lock
+++ b/Cargo.lock
@@ -280,6 +280,7 @@ dependencies = [
"hyper 0.13.1 (registry+https://github.com/rust-lang/crates.io-index)",
"pulldown-cmark 0.6.1 (registry+https://github.com/rust-lang/crates.io-index)",
"tokio 0.2.6 (registry+https://github.com/rust-lang/crates.io-index)",
+ "url 2.1.0 (registry+https://github.com/rust-lang/crates.io-index)",
]
[[package]]
diff --git a/Cargo.toml b/Cargo.toml
index 24067c4..5032022 100644
--- a/Cargo.toml
+++ b/Cargo.toml
@@ -13,3 +13,4 @@ tokio = { version = "0.2.6", features = ["macros"] }
askama = "0.8.0"
git2 = { version = "0.11.0", default-features = false }
pulldown-cmark = { version = "0.6.1", default-features = false }
+url = "2.1.0"
diff --git a/src/main.rs b/src/main.rs
index 23c5a6f..6ff3cae 100644
--- a/src/main.rs
+++ b/src/main.rs
@@ -13,6 +13,7 @@ use git2::Repository;
use hyper::service::{make_service_fn, service_fn};
use hyper::{Body, Method, Request, Response, Server, StatusCode};
use pulldown_cmark::{html, Parser};
+use url::form_urlencoded;
struct Repo {
name: String,
@@ -73,7 +74,7 @@ async fn index() -> Result<Response<Body>, Infallible> {
enum Tab {
Summary,
Tree,
- Commit,
+ Log,
}
struct Commit<'a> {
@@ -125,7 +126,7 @@ fn read_readme(repo: &Repository, head: git2::Reference) -> Result<Option<String
Ok(None)
}
-async fn repo(name: &str) -> Result<Response<Body>, Infallible> {
+async fn summary(name: &str) -> Result<Response<Body>, Infallible> {
let repo = Repository::open(Path::new("..").join(name)).unwrap();
let readme = read_readme(&repo, repo.head().unwrap()).unwrap();
let mut revwalk = repo.revwalk().unwrap();
@@ -338,7 +339,7 @@ async fn commit(name: &str, id: &str) -> Result<Response<Body>, Infallible> {
.unwrap();
let tmpl = CommitTemplate {
- tab: Tab::Commit,
+ tab: Tab::Log,
repo: &read_repo(name).unwrap(),
commit,
diff: &diff_output,
@@ -349,6 +350,47 @@ async fn commit(name: &str, id: &str) -> Result<Response<Body>, Infallible> {
.unwrap())
}
+#[derive(Template)]
+#[template(path = "log.html")]
+struct LogTemplate<'a> {
+ tab: Tab,
+ repo: &'a Repo,
+ commits: &'a [Commit<'a>],
+ next_id: Option<&'a str>,
+}
+
+async fn log(name: &str, after: Option<&str>) -> Result<Response<Body>, Infallible> {
+ let repo = Repository::open(Path::new("..").join(name)).unwrap();
+
+ let mut revwalk = repo.revwalk().unwrap();
+ match after {
+ Some(id) => revwalk.push(git2::Oid::from_str(id).unwrap()).unwrap(),
+ None => revwalk.push_head().unwrap(),
+ }
+
+ let mut next_id = None;
+ let mut commits = Vec::new();
+ while let Some(id) = revwalk.next() {
+ let id = id.unwrap();
+ commits.push(Commit::new(repo.find_commit(id).unwrap()));
+ if commits.len() == 10 {
+ next_id = Some(format!("{}", id));
+ break;
+ }
+ }
+
+ let tmpl = LogTemplate {
+ tab: Tab::Log,
+ repo: &read_repo(name).unwrap(),
+ commits: commits.as_slice(),
+ next_id: next_id.as_ref().map(|x| x.as_ref()),
+ };
+ Ok(Response::builder()
+ .header("Content-Type", "text/html")
+ .body(Body::from(tmpl.render().unwrap()))
+ .unwrap())
+}
+
async fn router(req: Request<Body>) -> Result<Response<Body>, Infallible> {
if req.method() != Method::GET {
return Ok(Response::builder()
@@ -388,7 +430,13 @@ async fn router(req: Request<Body>) -> Result<Response<Body>, Infallible> {
fs::read_to_string("public/folder-solid.svg").unwrap(),
))
.unwrap()),
- [name] => repo(name).await,
+ [name] => summary(name).await,
+ [name, "log"] => {
+ let after = form_urlencoded::parse(req.uri().query().unwrap_or("").as_bytes())
+ .find(|(key, _)| key == "after")
+ .map(|(_, value)| value);
+ log(name, after.as_ref().map(|x| x.as_ref())).await
+ }
[name, "commit", id] => commit(name, id).await,
_ => Ok(Response::builder()
.status(StatusCode::NOT_FOUND)
diff --git a/templates/log.html b/templates/log.html
new file mode 100644
index 0000000..1d39fbb
--- /dev/null
+++ b/templates/log.html
@@ -0,0 +1,42 @@
+{#
+ # SPDX-FileCopyrightText: 2020 Tuomas Siipola
+ # SPDX-License-Identifier: EUPL-1.2
+ #}
+
+{% extends "repo.html" %}
+
+{% block tab %}
+ <ul class="commits">
+ {% for commit in commits %}
+ <li>
+ <a href="/{{ repo.name }}/commit/{{ commit.id }}">
+ <code>
+ {{- commit.id[..8] -}}
+ </code>
+ <span class="message">
+ {% match commit.summary() %}
+ {% when Some with (summary) %}
+ {{ summary }}
+ {% when None %}
+ no message
+ {% endmatch %}
+ </span>
+ <span class="author">
+ by
+ {% match commit.author().name() %}
+ {% when Some with (author) %}
+ {{ author }}
+ {% when None %}
+ unknown
+ {% endmatch %}
+ </span>
+ </a>
+ </li>
+ {% endfor %}
+ </ul>
+ {% match next_id %}
+ {% when Some with (id) %}
+ <a href="/{{ repo.name }}/log?after={{ id }}">Next</a>
+ {% when None %}
+ {% endmatch %}
+{% endblock %}
diff --git a/templates/repo.html b/templates/repo.html
index 8cfdc65..eac949c 100644
--- a/templates/repo.html
+++ b/templates/repo.html
@@ -22,6 +22,7 @@
<ul class="tabs">
<li><a href="/{{ repo.name }}"{% match tab %}{% when Tab::Summary %} class="current"{% else %}{% endmatch %}>summary</a></li>
<li><a href="/{{ repo.name }}/tree"{% match tab %}{% when Tab::Tree %} class="current"{% else %}{% endmatch %}>tree</a></li>
+ <li><a href="/{{ repo.name }}/log"{% match tab %}{% when Tab::Log %} class="current"{% else %}{% endmatch %}>log</a></li>
</ul>
{% block tab %}{% endblock %}
{% endblock %}