🏡 index : ~doyle/rgit.git

author Jordan Doyle <jordan@doyle.la> 2022-07-18 1:45:52.0 +01:00:00
committer Jordan Doyle <jordan@doyle.la> 2022-07-18 1:45:52.0 +01:00:00
commit
6be32501a040072d24b8fe358c82a48a38cecf20 [patch]
tree
ba5e0a75cd1ffde396fd7b218df7a8523bfbf2b3
parent
395106596ba93d39430759f00f8f8cb191c30327
download
6be32501a040072d24b8fe358c82a48a38cecf20.tar.gz

Expose raw patches



Diff

 Cargo.lock                 |  1 +
 Cargo.toml                 |  1 +
 src/git.rs                 | 20 +++++++++++++++++++-
 src/main.rs                |  3 ++-
 src/methods/repo.rs        | 25 +++++++++++++++++++++++++
 templates/repo/commit.html |  2 +-
 6 files changed, 43 insertions(+), 9 deletions(-)

diff --git a/Cargo.lock b/Cargo.lock
index 24237ed..0101d84 100644
--- a/Cargo.lock
+++ a/Cargo.lock
@@ -1711,6 +1711,7 @@
 "axum",
 "bat",
 "bincode",
 "bytes",
 "clap",
 "futures",
 "git2",
diff --git a/Cargo.toml b/Cargo.toml
index b15e34a..5b6ad9d 100644
--- a/Cargo.toml
+++ a/Cargo.toml
@@ -9,6 +9,7 @@
askama = "0.11"
axum = "0.5"
bat = { version = "0.21", default-features = false, features = ["build-assets"] }
bytes = "1.1"
bincode = "1.3"
clap = { version = "3.2", features = ["cargo"] }
futures = "0.3"
diff --git a/src/git.rs b/src/git.rs
index fd72db9..6468db9 100644
--- a/src/git.rs
+++ a/src/git.rs
@@ -1,5 +1,6 @@
use std::{borrow::Cow, fmt::Write, path::PathBuf, sync::Arc, time::Duration};

use bytes::{Bytes, BytesMut};
use git2::{
    BranchType, DiffFormat, DiffLineType, DiffOptions, DiffStatsFormat, ObjectType, Oid, Signature,
};
@@ -270,12 +271,13 @@

            let head = repo.head().unwrap();
            let commit = head.peel_to_commit().unwrap();
            let (diff_output, diff_stats) =
            let (diff_plain, diff_output, diff_stats) =
                fetch_diff_and_stats(&repo, &commit, &self.git.syntax_set);

            let mut commit = Commit::from(commit);
            commit.diff_stats = diff_stats;
            commit.diff = diff_output;
            commit.diff_plain = diff_plain;
            commit
        })
        .await
@@ -294,12 +296,13 @@
                    let repo = self.repo.lock();

                    let commit = repo.find_commit(commit).unwrap();
                    let (diff_output, diff_stats) =
                    let (diff_plain, diff_output, diff_stats) =
                        fetch_diff_and_stats(&repo, &commit, &self.git.syntax_set);

                    let mut commit = Commit::from(commit);
                    commit.diff_stats = diff_stats;
                    commit.diff = diff_output;
                    commit.diff_plain = diff_plain;

                    Arc::new(commit)
                })
@@ -426,6 +429,7 @@
    body: String,
    pub diff_stats: String,
    pub diff: String,
    pub diff_plain: Bytes,
}

impl From<git2::Commit<'_>> for Commit {
@@ -440,6 +444,7 @@
            body: commit.body().map(ToString::to_string).unwrap_or_default(),
            diff_stats: String::with_capacity(0),
            diff: String::with_capacity(0),
            diff_plain: Bytes::new(),
        }
    }
}
@@ -479,17 +484,22 @@
    repo: &git2::Repository,
    commit: &git2::Commit<'_>,
    syntax_set: &SyntaxSet,
) -> (String, String) {
) -> (Bytes, String, String) {
    let current_tree = commit.tree().unwrap();
    let parent_tree = commit.parents().next().and_then(|v| v.tree().ok());
    let mut diff_opts = DiffOptions::new();
    let diff = repo
    let mut diff = repo
        .diff_tree_to_tree(
            parent_tree.as_ref(),
            Some(&current_tree),
            Some(&mut diff_opts),
        )
        .unwrap();

    let mut diff_plain = BytesMut::new();
    let email = diff.format_email(1, 1, commit, None).unwrap();
    diff_plain.extend_from_slice(&*email);

    let diff_stats = diff
        .stats()
        .unwrap()
@@ -500,7 +510,7 @@
        .to_string();
    let diff_output = format_diff(&diff, syntax_set);

    (diff_output, diff_stats)
    (diff_plain.freeze(), diff_output, diff_stats)
}

fn format_file(content: &[u8], extension: &str, syntax_set: &SyntaxSet) -> String {
diff --git a/src/main.rs b/src/main.rs
index 06d08b0..e5babb7 100644
--- a/src/main.rs
+++ a/src/main.rs
@@ -12,7 +12,7 @@
use std::time::Duration;
use syntect::html::ClassStyle;
use tower_layer::layer_fn;
use tracing::info;
use tracing::{info, instrument};

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

@@ -90,6 +90,7 @@
    }
}

#[instrument(skip(t))]
pub fn into_response<T: Template>(t: &T) -> Response {
    match t.render() {
        Ok(body) => {
diff --git a/src/methods/repo.rs b/src/methods/repo.rs
index 259635a..1b78848 100644
--- a/src/methods/repo.rs
+++ a/src/methods/repo.rs
@@ -6,9 +6,11 @@
};

use askama::Template;
use axum::http::HeaderValue;
use axum::{
    extract::Query,
    handler::Handler,
    http,
    http::Request,
    response::{IntoResponse, Response},
    Extension,
@@ -66,6 +68,7 @@
        Some("tree") => BoxCloneService::new(handle_tree.into_service()),
        Some("commit") => BoxCloneService::new(handle_commit.into_service()),
        Some("diff") => BoxCloneService::new(handle_diff.into_service()),
        Some("patch") => BoxCloneService::new(handle_patch.into_service()),
        Some("tag") => BoxCloneService::new(handle_tag.into_service()),
        Some(v) => {
            uri_parts.push(v);
@@ -87,8 +90,6 @@

                child_path = Some(reconstructed_path.into_iter().collect::<PathBuf>().clean());

                eprintln!("repo path: {:?}", child_path);

                BoxCloneService::new(handle_tree.into_service())
            } else {
                BoxCloneService::new(handle_summary.into_service())
@@ -353,4 +354,24 @@
    };

    into_response(&DiffView { repo, commit })
}

pub async fn handle_patch(
    Extension(RepositoryPath(repository_path)): Extension<RepositoryPath>,
    Extension(git): Extension<Arc<Git>>,
    Query(query): Query<CommitQuery>,
) -> Response {
    let open_repo = git.repo(repository_path).await;
    let commit = if let Some(commit) = query.id {
        open_repo.commit(&commit).await
    } else {
        Arc::new(open_repo.latest_commit().await)
    };

    let headers = [(
        http::header::CONTENT_TYPE,
        HeaderValue::from_static("text/plain"),
    )];

    (headers, commit.diff_plain.clone()).into_response()
}
diff --git a/templates/repo/commit.html b/templates/repo/commit.html
index 7b1e54f..b19510a 100644
--- a/templates/repo/commit.html
+++ a/templates/repo/commit.html
@@ -21,7 +21,7 @@
    </tr>
    <tr>
        <th>commit</th>
        <td colspan="2"><pre><a href="/{{ repo.display() }}/commit?id={{ commit.oid() }}" class="no-style">{{ commit.oid() }}</a></pre></td>
        <td colspan="2"><pre><a href="/{{ repo.display() }}/commit?id={{ commit.oid() }}" class="no-style">{{ commit.oid() }}</a> <a href="/{{ repo.display() }}/patch?id={{ commit.oid() }}">[patch]</a></pre></td>
    </tr>
    <tr>
        <th>tree</th>