From 6be32501a040072d24b8fe358c82a48a38cecf20 Mon Sep 17 00:00:00 2001 From: Jordan Doyle Date: Mon, 18 Jul 2022 01:45:52 +0100 Subject: [PATCH] Expose raw patches --- 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> 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(¤t_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: &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::().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, + Extension(git): Extension>, + Query(query): Query, +) -> 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 @@ commit -
{{ commit.oid() }}
+
{{ commit.oid() }} [patch]
tree -- rgit 0.1.3