Implement diff on commit view with syntax highlighting
Diff
Cargo.lock | 402 ++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++
Cargo.toml | 2 ++
src/git.rs | 112 ++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++
src/main.rs | 17 ++++++++++++++++-
statics/style.css | 19 +++++++++++++++++++
src/methods/repo.rs | 6 ++++--
templates/repo/commit.html | 8 ++++++++
7 files changed, 557 insertions(+), 9 deletions(-)
@@ -1,8 +1,32 @@
version = 3
[[package]]
name = "adler"
version = "1.0.2"
source = "registry+https://github.com/rust-lang/crates.io-index"
checksum = "f26201604c87b1e01bd3d98f8d5d9a8fcbb815e8cedb41ffccbeb4bf593a35fe"
[[package]]
name = "aho-corasick"
version = "0.7.18"
source = "registry+https://github.com/rust-lang/crates.io-index"
checksum = "1e37cfd5e7657ada45f742d6e99ca5788580b5c529dc78faf11ece6dc702656f"
dependencies = [
"memchr",
]
[[package]]
name = "ansi_colours"
version = "1.1.1"
source = "registry+https://github.com/rust-lang/crates.io-index"
checksum = "32678233b67f9056b0c144b39d46dc3218637e8d84ad6038ded339e08b19620d"
dependencies = [
"rgb",
]
[[package]]
name = "ansi_term"
version = "0.12.1"
source = "registry+https://github.com/rust-lang/crates.io-index"
@@ -173,13 +197,65 @@
"http",
"http-body",
"mime",
]
[[package]]
name = "base64"
version = "0.13.0"
source = "registry+https://github.com/rust-lang/crates.io-index"
checksum = "904dfeac50f3cdaba28fc6f57fdcddb75f49ed61346676a78c4ffe55877802fd"
[[package]]
name = "bat"
version = "0.21.0"
source = "registry+https://github.com/rust-lang/crates.io-index"
checksum = "fd1212d80800b3d7614b3725e0b2ee3b45b2b7484805d54b5660c8fa6f706305"
dependencies = [
"ansi_colours",
"ansi_term",
"bincode",
"bytesize",
"clircle",
"console",
"content_inspector",
"encoding",
"flate2",
"globset",
"once_cell",
"path_abs",
"regex",
"semver",
"serde",
"serde_yaml",
"syntect",
"thiserror",
"unicode-width",
"walkdir",
]
[[package]]
name = "bincode"
version = "1.3.3"
source = "registry+https://github.com/rust-lang/crates.io-index"
checksum = "b1f45e9417d87227c7a56d22e471c6206462cba514c7590c09aff4cf6d1ddcad"
dependencies = [
"serde",
]
[[package]]
name = "bitflags"
version = "1.3.2"
source = "registry+https://github.com/rust-lang/crates.io-index"
checksum = "bef38d45163c2f1dde094a7dfd33ccf595c92905c8f8f4fdc18d06fb1037718a"
[[package]]
name = "bstr"
version = "0.2.17"
source = "registry+https://github.com/rust-lang/crates.io-index"
checksum = "ba3569f383e8f1598449f1a423e72e99569137b47740b1da11ef19af3d5c3223"
dependencies = [
"memchr",
]
[[package]]
name = "bumpalo"
@@ -192,6 +268,12 @@
version = "0.6.3"
source = "registry+https://github.com/rust-lang/crates.io-index"
checksum = "2c676a478f63e9fa2dd5368a42f28bba0d6c560b775f38583c8bbaa7fcd67c9c"
[[package]]
name = "bytemuck"
version = "1.10.0"
source = "registry+https://github.com/rust-lang/crates.io-index"
checksum = "c53dfa917ec274df8ed3c572698f381a24eef2efba9492d797301b72b6db408a"
[[package]]
name = "bytes"
@@ -200,6 +282,12 @@
checksum = "c4872d67bab6358e59559027aa3b9157c53d9358c51423c17554809a8858e0f8"
[[package]]
name = "bytesize"
version = "1.1.0"
source = "registry+https://github.com/rust-lang/crates.io-index"
checksum = "6c58ec36aac5066d5ca17df51b3e70279f5670a72102f5752cb7e7c856adfc70"
[[package]]
name = "cache-padded"
version = "1.2.0"
source = "registry+https://github.com/rust-lang/crates.io-index"
@@ -293,6 +381,18 @@
checksum = "2850f2f5a82cbf437dd5af4d49848fbdfc27c157c3d010345776f952765261c5"
dependencies = [
"os_str_bytes",
]
[[package]]
name = "clircle"
version = "0.3.0"
source = "registry+https://github.com/rust-lang/crates.io-index"
checksum = "e68bbd985a63de680ab4d1ad77b6306611a8f961b282c8b5ab513e6de934e396"
dependencies = [
"cfg-if 1.0.0",
"libc",
"serde",
"winapi",
]
[[package]]
@@ -311,9 +411,42 @@
checksum = "30ed07550be01594c6026cff2a1d7fe9c8f683caa798e12b68694ac9e88286a3"
dependencies = [
"cache-padded",
]
[[package]]
name = "console"
version = "0.15.0"
source = "registry+https://github.com/rust-lang/crates.io-index"
checksum = "a28b32d32ca44b70c3e4acd7db1babf555fa026e385fb95f18028f88848b3c31"
dependencies = [
"encode_unicode",
"libc",
"once_cell",
"regex",
"terminal_size",
"unicode-width",
"winapi",
]
[[package]]
name = "content_inspector"
version = "0.2.4"
source = "registry+https://github.com/rust-lang/crates.io-index"
checksum = "b7bda66e858c683005a53a9a60c69a4aca7eeaa45d124526e389f7aec8e62f38"
dependencies = [
"memchr",
]
[[package]]
name = "crc32fast"
version = "1.3.2"
source = "registry+https://github.com/rust-lang/crates.io-index"
checksum = "b540bd8bc810d3885c6ea91e2018302f68baba2129ab3e88f32389ee9370880d"
dependencies = [
"cfg-if 1.0.0",
]
[[package]]
name = "crossbeam-channel"
version = "0.5.5"
source = "registry+https://github.com/rust-lang/crates.io-index"
@@ -357,9 +490,79 @@
dependencies = [
"cfg-if 1.0.0",
"once_cell",
]
[[package]]
name = "encode_unicode"
version = "0.3.6"
source = "registry+https://github.com/rust-lang/crates.io-index"
checksum = "a357d28ed41a50f9c765dbfe56cbc04a64e53e5fc58ba79fbc34c10ef3df831f"
[[package]]
name = "encoding"
version = "0.2.33"
source = "registry+https://github.com/rust-lang/crates.io-index"
checksum = "6b0d943856b990d12d3b55b359144ff341533e516d94098b1d3fc1ac666d36ec"
dependencies = [
"encoding-index-japanese",
"encoding-index-korean",
"encoding-index-simpchinese",
"encoding-index-singlebyte",
"encoding-index-tradchinese",
]
[[package]]
name = "encoding-index-japanese"
version = "1.20141219.5"
source = "registry+https://github.com/rust-lang/crates.io-index"
checksum = "04e8b2ff42e9a05335dbf8b5c6f7567e5591d0d916ccef4e0b1710d32a0d0c91"
dependencies = [
"encoding_index_tests",
]
[[package]]
name = "encoding-index-korean"
version = "1.20141219.5"
source = "registry+https://github.com/rust-lang/crates.io-index"
checksum = "4dc33fb8e6bcba213fe2f14275f0963fd16f0a02c878e3095ecfdf5bee529d81"
dependencies = [
"encoding_index_tests",
]
[[package]]
name = "encoding-index-simpchinese"
version = "1.20141219.5"
source = "registry+https://github.com/rust-lang/crates.io-index"
checksum = "d87a7194909b9118fc707194baa434a4e3b0fb6a5a757c73c3adb07aa25031f7"
dependencies = [
"encoding_index_tests",
]
[[package]]
name = "encoding-index-singlebyte"
version = "1.20141219.5"
source = "registry+https://github.com/rust-lang/crates.io-index"
checksum = "3351d5acffb224af9ca265f435b859c7c01537c0849754d3db3fdf2bfe2ae84a"
dependencies = [
"encoding_index_tests",
]
[[package]]
name = "encoding-index-tradchinese"
version = "1.20141219.5"
source = "registry+https://github.com/rust-lang/crates.io-index"
checksum = "fd0e20d5688ce3cab59eb3ef3a2083a5c77bf496cb798dc6fcdb75f323890c18"
dependencies = [
"encoding_index_tests",
]
[[package]]
name = "encoding_index_tests"
version = "0.1.4"
source = "registry+https://github.com/rust-lang/crates.io-index"
checksum = "a246d82be1c9d791c5dfde9a2bd045fc3cbba3fa2b11ad558f27d01712f00569"
[[package]]
name = "error-chain"
version = "0.12.4"
source = "registry+https://github.com/rust-lang/crates.io-index"
@@ -381,6 +584,16 @@
checksum = "c3fcf0cee53519c866c09b5de1f6c56ff9d647101f81c1964fa632e148896cdf"
dependencies = [
"instant",
]
[[package]]
name = "flate2"
version = "1.0.24"
source = "registry+https://github.com/rust-lang/crates.io-index"
checksum = "f82b0f4c27ad9f8bfd1f3208d882da2b09c301bc1c828fd3a00d0216d2fbbff6"
dependencies = [
"crc32fast",
"miniz_oxide",
]
[[package]]
@@ -540,6 +753,19 @@
version = "0.3.0"
source = "registry+https://github.com/rust-lang/crates.io-index"
checksum = "9b919933a397b79c37e33b77bb2aa3dc8eb6e165ad809e58ff75bc7db2e34574"
[[package]]
name = "globset"
version = "0.4.9"
source = "registry+https://github.com/rust-lang/crates.io-index"
checksum = "0a1e17342619edbc21a964c2afbeb6c820c6a2560032872f397bb97ea127bd0a"
dependencies = [
"aho-corasick",
"bstr",
"fnv",
"log",
"regex",
]
[[package]]
name = "hashbrown"
@@ -751,7 +977,22 @@
"libc",
"pkg-config",
"vcpkg",
]
[[package]]
name = "line-wrap"
version = "0.1.1"
source = "registry+https://github.com/rust-lang/crates.io-index"
checksum = "f30344350a2a51da54c1d53be93fade8a237e545dbcc4bdbe635413f2117cab9"
dependencies = [
"safemem",
]
[[package]]
name = "linked-hash-map"
version = "0.5.6"
source = "registry+https://github.com/rust-lang/crates.io-index"
checksum = "0717cef1bc8b636c6e1c1bbdefc09e6322da8a9321966e8928ef80d20f7f770f"
[[package]]
name = "lock_api"
@@ -841,6 +1082,15 @@
version = "0.2.1"
source = "registry+https://github.com/rust-lang/crates.io-index"
checksum = "68354c5c6bd36d73ff3feceb05efa59b6acb7626617f4962be322a825e61f79a"
[[package]]
name = "miniz_oxide"
version = "0.5.3"
source = "registry+https://github.com/rust-lang/crates.io-index"
checksum = "6f5c75688da582b8ffc1f1799e9db273f32133c49e048f614d22ec3256773ccc"
dependencies = [
"adler",
]
[[package]]
name = "mio"
@@ -932,6 +1182,28 @@
version = "1.13.0"
source = "registry+https://github.com/rust-lang/crates.io-index"
checksum = "18a6dbe30758c9f83eb00cbea4ac95966305f5a7772f3f42ebfc7fc7eddbd8e1"
[[package]]
name = "onig"
version = "6.3.2"
source = "registry+https://github.com/rust-lang/crates.io-index"
checksum = "1eb3502504c9c8b06634b38bfdda86a9a8cef6277f3dec4d8b17c115110dd2a3"
dependencies = [
"bitflags",
"lazy_static",
"libc",
"onig_sys",
]
[[package]]
name = "onig_sys"
version = "69.8.0"
source = "registry+https://github.com/rust-lang/crates.io-index"
checksum = "8bf3fbc9b931b6c9af85d219c7943c274a6ad26cff7488a2210215edd5f49bf8"
dependencies = [
"cc",
"pkg-config",
]
[[package]]
name = "openssl-probe"
@@ -992,6 +1264,15 @@
version = "0.1.0"
source = "registry+https://github.com/rust-lang/crates.io-index"
checksum = "ecba01bf2678719532c5e3059e0b5f0811273d94b397088b82e3bd0a78c78fdd"
[[package]]
name = "path_abs"
version = "0.5.1"
source = "registry+https://github.com/rust-lang/crates.io-index"
checksum = "05ef02f6342ac01d8a93b65f96db53fe68a92a15f41144f97fb00a9e669633c3"
dependencies = [
"std_prelude",
]
[[package]]
name = "percent-encoding"
@@ -1074,6 +1355,20 @@
version = "0.3.25"
source = "registry+https://github.com/rust-lang/crates.io-index"
checksum = "1df8c4ec4b0627e53bdf214615ad287367e482558cf84b109250b37464dc03ae"
[[package]]
name = "plist"
version = "1.3.1"
source = "registry+https://github.com/rust-lang/crates.io-index"
checksum = "bd39bc6cdc9355ad1dc5eeedefee696bb35c34caf21768741e81826c0bbd7225"
dependencies = [
"base64",
"indexmap",
"line-wrap",
"serde",
"time 0.3.11",
"xml-rs",
]
[[package]]
name = "polling"
@@ -1264,7 +1559,24 @@
checksum = "62f25bc4c7e55e0b0b7a1d43fb893f4fa1361d0abe38b9ce4f323c2adfe6ef42"
dependencies = [
"bitflags",
]
[[package]]
name = "regex"
version = "1.6.0"
source = "registry+https://github.com/rust-lang/crates.io-index"
checksum = "4c4eb3267174b8c6c2f654116623910a0fef09c4753f8dd83db29c48a0df988b"
dependencies = [
"aho-corasick",
"memchr",
"regex-syntax",
]
[[package]]
name = "regex-syntax"
version = "0.6.27"
source = "registry+https://github.com/rust-lang/crates.io-index"
checksum = "a3f87b73ce11b1619a3c6332f45341e0047173771e8b8b73f87bfeefb7b56244"
[[package]]
name = "remove_dir_all"
@@ -1273,6 +1585,15 @@
checksum = "3acd125665422973a33ac9d3dd2df85edad0f4ae9b00dafb1a05e43a9f5ef8e7"
dependencies = [
"winapi",
]
[[package]]
name = "rgb"
version = "0.8.33"
source = "registry+https://github.com/rust-lang/crates.io-index"
checksum = "c3b221de559e4a29df3b957eec92bc0de6bc8eaf6ca9cfed43e5e1d67ff65a34"
dependencies = [
"bytemuck",
]
[[package]]
@@ -1282,6 +1603,7 @@
"arc-swap",
"askama",
"axum",
"bat",
"clap",
"futures",
"git2",
@@ -1291,6 +1613,7 @@
"moka",
"path-clean",
"serde",
"syntect",
"time 0.3.11",
"timeago",
"tokio",
@@ -1307,6 +1630,12 @@
version = "1.0.10"
source = "registry+https://github.com/rust-lang/crates.io-index"
checksum = "f3f6f92acf49d1b98f7a81226834412ada05458b7364277387724a237f062695"
[[package]]
name = "safemem"
version = "0.3.3"
source = "registry+https://github.com/rust-lang/crates.io-index"
checksum = "ef703b7cb59335eae2eb93ceb664c0eb7ea6bf567079d843e09420219668e072"
[[package]]
name = "same-file"
@@ -1380,8 +1709,20 @@
dependencies = [
"form_urlencoded",
"itoa",
"ryu",
"serde",
]
[[package]]
name = "serde_yaml"
version = "0.8.24"
source = "registry+https://github.com/rust-lang/crates.io-index"
checksum = "707d15895415db6628332b737c838b88c598522e4dc70647e59b72312924aebc"
dependencies = [
"indexmap",
"ryu",
"serde",
"yaml-rust",
]
[[package]]
@@ -1444,6 +1785,12 @@
"libc",
"winapi",
]
[[package]]
name = "std_prelude"
version = "0.2.12"
source = "registry+https://github.com/rust-lang/crates.io-index"
checksum = "8207e78455ffdf55661170876f88daf85356e4edd54e0a3dbc79586ca1e50cbe"
[[package]]
name = "strsim"
@@ -1467,6 +1814,29 @@
version = "0.1.1"
source = "registry+https://github.com/rust-lang/crates.io-index"
checksum = "20518fe4a4c9acf048008599e464deb21beeae3d3578418951a189c235a7a9a8"
[[package]]
name = "syntect"
version = "5.0.0"
source = "registry+https://github.com/rust-lang/crates.io-index"
checksum = "c6c454c27d9d7d9a84c7803aaa3c50cd088d2906fe3c6e42da3209aa623576a8"
dependencies = [
"bincode",
"bitflags",
"flate2",
"fnv",
"lazy_static",
"once_cell",
"onig",
"plist",
"regex-syntax",
"serde",
"serde_derive",
"serde_json",
"thiserror",
"walkdir",
"yaml-rust",
]
[[package]]
name = "tagptr"
@@ -1495,6 +1865,16 @@
checksum = "bab24d30b911b2376f3a13cc2cd443142f0c81dda04c118693e35b3835757755"
dependencies = [
"winapi-util",
]
[[package]]
name = "terminal_size"
version = "0.1.17"
source = "registry+https://github.com/rust-lang/crates.io-index"
checksum = "633c1a546cee861a1a6d0dc69ebeca693bf4296661ba7852b9d21d159e0506df"
dependencies = [
"libc",
"winapi",
]
[[package]]
@@ -1548,6 +1928,7 @@
source = "registry+https://github.com/rust-lang/crates.io-index"
checksum = "72c91f41dcb2f096c05f0873d667dceec1087ce5bcf984ec8ffb19acddbb3217"
dependencies = [
"itoa",
"libc",
"num_threads",
]
@@ -1764,6 +2145,12 @@
dependencies = [
"tinyvec",
]
[[package]]
name = "unicode-width"
version = "0.1.9"
source = "registry+https://github.com/rust-lang/crates.io-index"
checksum = "3ed742d4ea2bd1176e236172c8429aaf54486e7ac098db29ffe6529e0ce50973"
[[package]]
name = "url"
@@ -1989,3 +2376,18 @@
version = "0.36.1"
source = "registry+https://github.com/rust-lang/crates.io-index"
checksum = "c811ca4a8c853ef420abd8592ba53ddbbac90410fab6903b3e79972a631f7680"
[[package]]
name = "xml-rs"
version = "0.8.4"
source = "registry+https://github.com/rust-lang/crates.io-index"
checksum = "d2d7d3948613f75c98fd9328cfdcc45acc4d360655289d0a7d4ec931392200a3"
[[package]]
name = "yaml-rust"
version = "0.4.5"
source = "registry+https://github.com/rust-lang/crates.io-index"
checksum = "56c1936c4cc7a1c9ab21a1ebb602eb942ba868cbd44a99cb7cdc5892335e1c85"
dependencies = [
"linked-hash-map",
]
@@ -9,6 +9,7 @@
askama = "0.11"
arc-swap = "1.5"
axum = "0.5"
bat = { version = "0.21", default-features = false, features = ["build-assets"] }
clap = { version = "3.2", features = ["cargo"] }
futures = "0.3"
git2 = "0.14"
@@ -18,6 +19,7 @@
moka = { version = "0.9", features = ["future"] }
path-clean = "0.1"
serde = { version = "1.0", features = ["derive"] }
syntect = "5"
time = "0.3"
timeago = "0.3"
tokio = { version = "1.19", features = ["full"] }
@@ -7,8 +7,12 @@
};
use arc_swap::ArcSwapOption;
use git2::{ObjectType, Oid, Repository, Signature};
use git2::{
DiffFormat, DiffLineType, DiffOptions, DiffStatsFormat, ObjectType, Oid, Repository, Signature,
};
use moka::future::Cache;
use syntect::html::{ClassStyle, ClassedHTMLGenerator};
use syntect::parsing::SyntaxSet;
use time::OffsetDateTime;
pub type RepositoryMetadataList = BTreeMap<Option<String>, Vec<RepositoryMetadata>>;
@@ -42,7 +46,12 @@
}
impl Git {
pub async fn get_commit<'a>(&'a self, repo: PathBuf, commit: &str) -> Arc<Commit> {
pub async fn get_commit<'a>(
&'a self,
repo: PathBuf,
commit: &str,
syntax_set: Arc<SyntaxSet>,
) -> Arc<Commit> {
let commit = Oid::from_str(commit).unwrap();
self.commits
@@ -50,8 +59,14 @@
tokio::task::spawn_blocking(move || {
let repo = Repository::open_bare(repo).unwrap();
let commit = repo.find_commit(commit).unwrap();
let (diff_output, diff_stats) =
fetch_diff_and_stats(&repo, &commit, &syntax_set);
let mut commit = Commit::from(commit);
commit.diff_stats = diff_stats;
commit.diff = diff_output;
Arc::new(Commit::from(commit))
Arc::new(commit)
})
.await
.unwrap()
@@ -153,13 +168,17 @@
.await
}
pub async fn get_latest_commit(&self, repo: PathBuf) -> Commit {
pub async fn get_latest_commit(&self, repo: PathBuf, syntax_set: Arc<SyntaxSet>) -> Commit {
tokio::task::spawn_blocking(move || {
let repo = Repository::open_bare(repo).unwrap();
let head = repo.head().unwrap();
let commit = head.peel_to_commit().unwrap();
Commit::from(commit)
let (diff_output, diff_stats) = fetch_diff_and_stats(&repo, &commit, &syntax_set);
let mut commit = Commit::from(commit);
commit.diff_stats = diff_stats;
commit.diff = diff_output;
commit
})
.await
.unwrap()
@@ -316,6 +335,8 @@
parents: Vec<String>,
summary: String,
body: String,
pub diff_stats: String,
pub diff: String,
}
impl From<git2::Commit<'_>> for Commit {
@@ -328,6 +349,8 @@
parents: commit.parent_ids().map(|v| v.to_string()).collect(),
summary: commit.summary().unwrap().to_string(),
body: commit.body().map(ToString::to_string).unwrap_or_default(),
diff_stats: String::with_capacity(0),
diff: String::with_capacity(0),
}
}
}
@@ -360,6 +383,83 @@
pub fn body(&self) -> &str {
&self.body
}
}
fn fetch_diff_and_stats(
repo: &git2::Repository,
commit: &git2::Commit<'_>,
syntax_set: &SyntaxSet,
) -> (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
.diff_tree_to_tree(
parent_tree.as_ref(),
Some(¤t_tree),
Some(&mut diff_opts),
)
.unwrap();
let diff_stats = diff
.stats()
.unwrap()
.to_buf(DiffStatsFormat::FULL, 80)
.unwrap()
.as_str()
.unwrap()
.to_string();
let diff_output = format_diff(&diff, &syntax_set);
(diff_output, diff_stats)
}
fn format_diff(diff: &git2::Diff<'_>, syntax_set: &SyntaxSet) -> String {
let mut diff_output = String::new();
diff.print(DiffFormat::Patch, |delta, _diff_hunk, diff_line| {
let (class, prefix, should_highlight_as_source) = match diff_line.origin_value() {
DiffLineType::Addition => (Some("add-line"), "+", true),
DiffLineType::Deletion => (Some("remove-line"), "-", true),
DiffLineType::Context => (None, " ", true),
DiffLineType::AddEOFNL => (Some("remove-line"), "", false),
DiffLineType::DeleteEOFNL => (Some("add-line"), "", false),
DiffLineType::FileHeader => (Some("file-header"), "", false),
_ => (None, "", false),
};
let line = std::str::from_utf8(diff_line.content()).unwrap();
let extension = if should_highlight_as_source {
let path = delta.new_file().path().unwrap();
path.extension()
.or(path.file_name())
.unwrap()
.to_string_lossy()
} else {
Cow::Borrowed("patch")
};
let syntax = syntax_set
.find_syntax_by_extension(&extension)
.unwrap_or(syntax_set.find_syntax_plain_text());
let mut html_generator =
ClassedHTMLGenerator::new_with_class_style(syntax, &syntax_set, ClassStyle::Spaced);
html_generator
.parse_html_for_line_which_includes_newline(line)
.unwrap();
if let Some(class) = class {
diff_output.push_str(&format!("<span class=\"diff-{class}\">"));
}
diff_output.push_str(prefix);
diff_output.push_str(&html_generator.finalize());
if class.is_some() {
diff_output.push_str("</span>");
}
true
})
.unwrap();
diff_output
}
fn fetch_repository_metadata_impl(
@@ -1,9 +1,12 @@
#![deny(clippy::pedantic)]
use axum::{
body::Body, handler::Handler, http::HeaderValue, response::Response, routing::get, Extension,
Router,
};
use bat::assets::HighlightingAssets;
use std::sync::Arc;
use syntect::html::ClassStyle;
use tower_layer::layer_fn;
use crate::{git::Git, layers::logger::LoggingMiddleware};
@@ -21,15 +24,27 @@
let subscriber = subscriber.pretty();
subscriber.init();
let bat_assets = HighlightingAssets::from_binary();
let syntax_set = bat_assets.get_syntax_set().unwrap().clone();
let theme = bat_assets.get_theme("GitHub");
let css = Box::leak(
syntect::html::css_for_theme_with_class_style(theme, ClassStyle::Spaced)
.unwrap()
.into_boxed_str()
.into_boxed_bytes(),
);
let app = Router::new()
.route("/", get(methods::index::handle))
.route(
"/style.css",
get(static_css(include_bytes!("../statics/style.css"))),
)
.route("/highlight.css", get(static_css(css)))
.fallback(methods::repo::service.into_service())
.layer(layer_fn(LoggingMiddleware))
.layer(Extension(Git::default()));
.layer(Extension(Git::default()))
.layer(Extension(Arc::new(syntax_set)));
axum::Server::bind(&"127.0.0.1:3333".parse().unwrap())
.serve(app.into_make_service_with_connect_info::<std::net::SocketAddr>())
@@ -91,3 +91,22 @@
font-size: 1.5em;
font-weight: bold;
}
.diff-file-header {
font-weight: bold;
}
.diff-file-header > span > span {
font-weight: normal;
}
.diff-add-line {
background: #e6ffec;
display: block;
}
.diff-remove-line {
background: #ffebe9;
display: block;
}
@@ -14,6 +14,7 @@
};
use path_clean::PathClean;
use serde::Deserialize;
use syntect::parsing::SyntaxSet;
use tower::{util::BoxCloneService, Service};
use super::filters;
@@ -205,6 +206,7 @@
Extension(repo): Extension<Repository>,
Extension(RepositoryPath(repository_path)): Extension<RepositoryPath>,
Extension(git): Extension<Git>,
Extension(syntax_set): Extension<Arc<SyntaxSet>>,
Query(query): Query<CommitQuery>,
) -> Html<String> {
#[derive(Template)]
@@ -218,9 +220,9 @@
View {
repo,
commit: if let Some(commit) = query.id {
git.get_commit(repository_path, &commit).await
git.get_commit(repository_path, &commit, syntax_set).await
} else {
Arc::new(git.get_latest_commit(repository_path).await)
Arc::new(git.get_latest_commit(repository_path, syntax_set).await)
},
}
.render()
@@ -1,5 +1,9 @@
{% extends "repo/base.html" %}
{% block head %}
<link rel="stylesheet" type="text/css" href="/highlight.css" />
{% endblock %}
{% block commit_nav_class %}active{% endblock %}
{% block content %}
@@ -34,4 +38,8 @@
<h2>{{ commit.summary() }}</h2>
<pre>{{ commit.body() }}</pre>
<h3>Diff</h3>
<pre>{{ commit.diff_stats|safe }}
{{ commit.diff|safe }}</pre>
{% endblock %}