🏡 index : ~doyle/rgit.git

author Jordan Doyle <jordan@doyle.la> 2022-07-06 2:59:26.0 +01:00:00
committer Jordan Doyle <jordan@doyle.la> 2022-07-06 2:59:31.0 +01:00:00
commit
576eb8deffcf4f69201d51a325c17f1e8d2d30ee [patch]
tree
162ab68bf329324809db949b4aead730c9a93a7e
parent
33361110ce8808aa0911346b013f63a684cd4e34
download
576eb8deffcf4f69201d51a325c17f1e8d2d30ee.tar.gz

Implement repository log page



Diff

 src/git.rs              | 85 ++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++--------------------
 src/methods/repo.rs     | 13 +++++++++++--
 templates/repo/log.html | 22 ++++++++++++++++++++++
 3 files changed, 87 insertions(+), 33 deletions(-)

diff --git a/src/git.rs b/src/git.rs
index 090277e..a29fe9d 100644
--- a/src/git.rs
+++ a/src/git.rs
@@ -7,7 +7,7 @@
};

use arc_swap::ArcSwapOption;
use git2::{Oid, Repository, Signature};
use git2::{Oid, Repository, Signature, Sort};
use time::OffsetDateTime;

pub type RepositoryMetadataList = BTreeMap<Option<String>, Vec<RepositoryMetadata>>;
@@ -52,38 +52,38 @@
    pub async fn get_refs<'a>(&'a self, repo: PathBuf) -> Arc<Refs> {
        self.refs
            .get_with(repo.clone(), async {
            tokio::task::spawn_blocking(move || {
                let repo = git2::Repository::open_bare(repo).unwrap();
                let refs = repo.references().unwrap();

                let mut built_refs = Refs::default();

                for ref_ in refs {
                    let ref_ = ref_.unwrap();

                    if ref_.is_branch() {
                        let commit = ref_.peel_to_commit().unwrap();

                        built_refs.branch.push(Branch {
                            name: ref_.shorthand().unwrap().to_string(),
                            commit: commit.into(),
                        });
                    } else if ref_.is_tag() {
                        let commit = ref_.peel_to_commit().unwrap();

                        built_refs.tag.push(Tag {
                            name: ref_.shorthand().unwrap().to_string(),
                            commit: commit.into(),
                        });
                tokio::task::spawn_blocking(move || {
                    let repo = git2::Repository::open_bare(repo).unwrap();
                    let refs = repo.references().unwrap();

                    let mut built_refs = Refs::default();

                    for ref_ in refs {
                        let ref_ = ref_.unwrap();

                        if ref_.is_branch() {
                            let commit = ref_.peel_to_commit().unwrap();

                            built_refs.branch.push(Branch {
                                name: ref_.shorthand().unwrap().to_string(),
                                commit: commit.into(),
                            });
                        } else if ref_.is_tag() {
                            let commit = ref_.peel_to_commit().unwrap();

                            built_refs.tag.push(Tag {
                                name: ref_.shorthand().unwrap().to_string(),
                                commit: commit.into(),
                            });
                        }
                    }
                }

                Arc::new(built_refs)
                    Arc::new(built_refs)
                })
                .await
                .unwrap()
            })
            .await
            .unwrap()
        })
        .await
    }

    pub async fn get_readme(&self, repo: PathBuf) -> Arc<str> {
@@ -95,7 +95,11 @@
                    let commit = head.peel_to_commit().unwrap();
                    let tree = commit.tree().unwrap();

                    let object = tree.get_name("README.md").unwrap().to_object(&repo).unwrap();
                    let object = tree
                        .get_name("README.md")
                        .unwrap()
                        .to_object(&repo)
                        .unwrap();
                    let blob = object.into_blob().unwrap();

                    Arc::from(String::from_utf8(blob.content().to_vec()).unwrap())
@@ -137,6 +141,27 @@
        self.repository_metadata.store(Some(repos.clone()));

        repos
    }

    pub async fn get_commits(&self, repo: PathBuf) -> Vec<Commit> {
        tokio::task::spawn_blocking(move || {
            let repo = Repository::open_bare(repo).unwrap();
            let mut revs = repo.revwalk().unwrap();
            revs.set_sorting(Sort::TIME).unwrap();
            revs.push_head().unwrap();

            let mut commits = Vec::with_capacity(200);

            for rev in revs.skip(0).take(200) {
                let rev = rev.unwrap();
                let commit = repo.find_commit(rev).unwrap();
                commits.push(commit.into());
            }

            commits
        })
        .await
        .unwrap()
    }
}

diff --git a/src/methods/repo.rs b/src/methods/repo.rs
index 7c9fe50..6431dba 100644
--- a/src/methods/repo.rs
+++ a/src/methods/repo.rs
@@ -16,8 +16,8 @@
use serde::Deserialize;
use tower::{util::BoxCloneService, Service};

use crate::{git::Commit, layers::UnwrapInfallible, Git};
use crate::git::Refs;
use crate::{git::Commit, layers::UnwrapInfallible, Git};

#[derive(Clone)]
pub struct Repository(pub PathBuf);
@@ -90,14 +90,21 @@
}

#[allow(clippy::unused_async)]
pub async fn handle_log(Extension(repo): Extension<Repository>) -> Html<String> {
pub async fn handle_log(
    Extension(repo): Extension<Repository>,
    Extension(RepositoryPath(repository_path)): Extension<RepositoryPath>,
    Extension(git): Extension<Git>,
) -> Html<String> {
    #[derive(Template)]
    #[template(path = "repo/log.html")]
    pub struct View {
        repo: Repository,
        commits: Vec<Commit>,
    }

    Html(View { repo }.render().unwrap())
    let commits = git.get_commits(repository_path).await;

    Html(View { repo, commits }.render().unwrap())
}

#[allow(clippy::unused_async)]
diff --git a/templates/repo/log.html b/templates/repo/log.html
index a50ecab..47e73f4 100644
--- a/templates/repo/log.html
+++ a/templates/repo/log.html
@@ -1,6 +1,28 @@
{% extends "repo/base.html" %}

{% block log_nav_class %}active{% endblock %}

{% block content %}
<table class="repositories">
    <thead>
    <tr>
        <th>Age</th>
        <th>Commit message</th>
        <th>Author</th>
    </tr>
    </thead>

    <tbody>
    {% for commit in commits %}
    <tr>
        <td>{{ commit.committer().time() }}</td>
        <td><a href="/{{ repo.display() }}/commit/?id={{ commit.oid() }}">{{ commit.summary() }}</a></td>
        <td>
            <img src="https://www.gravatar.com/avatar/{{ commit.author().email_md5() }}?s=13&d=retro" width="13" height="13">
            {{ commit.author().name() }}
        </td>
    </tr>
    {% endfor %}
    </tbody>
</table>
{% endblock %}