Repositories

grarr

(mirrored on github)

Modified src/handler/commits.rs

@@ -8,12 +8,11 @@ pub struct Commits;
impl Handler for Commits {
fn handle(&self, req: &mut Request) -> IronResult<Response> {
let context = itry!(req.extensions.get::<RepositoryContext>().ok_or(Error::MissingExtension), status::InternalServerError);
let commit = itry!(context.commit(), status::InternalServerError);
let reference = context.reference().ok().and_then(|r| r.shorthand().map(ToOwned::to_owned)).unwrap_or_else(|| format!("{}", commit.id()));
let commits = itry!(CommitTree::new(&context.repository, &commit), status::InternalServerError);
let referenced_commit = itry!(context.referenced_commit(), status::InternalServerError);
let commits = itry!(CommitTree::new(&context.repository, &referenced_commit.commit), status::InternalServerError);
Html {
render: RepositoryWrapper(&context, render::Commits(&("/".to_owned() + context.requested_path.to_str().unwrap()), &reference, commits)),
etag: Some(EntityTag::weak(versioned_sha1!(commit.id().as_bytes()))),
render: RepositoryWrapper(&context, render::Commits(&("/".to_owned() + context.requested_path.to_str().unwrap()), &referenced_commit, commits)),
etag: Some(EntityTag::weak(versioned_sha1!(referenced_commit.commit.id().as_bytes()))),
req: req,
}.into()
}

Modified src/handler/tree_entry.rs

@@ -10,9 +10,8 @@ impl Handler for TreeEntry {
let router = itry!(req.extensions.get::<Router>().ok_or(Error::MissingExtension), status::InternalServerError);
let context = itry!(req.extensions.get::<RepositoryContext>().ok_or(Error::MissingExtension), status::InternalServerError);
let entry_path = router.find("path").unwrap_or("");
let commit = itry!(context.commit(), status::NotFound);
let reference = itry!(context.reference(), status::NotFound);
let tree = itry!(commit.tree(), status::InternalServerError);
let referenced_commit = itry!(context.referenced_commit(), status::NotFound);
let tree = itry!(referenced_commit.commit.tree(), status::InternalServerError);
let obj;
let entry;
if entry_path == "" {
@@ -22,10 +21,13 @@ impl Handler for TreeEntry {
obj = itry!(tree_entry.to_object(&context.repository), status::InternalServerError);
entry = &obj;
}
let parent = "/".to_owned() + &context.requested_path.to_string_lossy() + "/tree/" + itry!(reference.shorthand().ok_or(Error::String("Could not get ref shorthand")), status::InternalServerError);
let id = referenced_commit.commit.id();
let idstr = format!("{}", id);
let reff = referenced_commit.reference.as_ref().and_then(|r| r.shorthand()).unwrap_or(&*idstr);
let parent = "/".to_owned() + &context.requested_path.to_string_lossy() + "/tree/" + reff;
Html {
render: RepositoryWrapper(&context, &render::TreeEntry(&parent, Path::new(entry_path), entry)),
etag: Some(EntityTag::weak(versioned_sha1!(commit.id().as_bytes()))),
render: RepositoryWrapper(&context, &render::TreeEntry(&parent, Path::new(entry_path), entry, &referenced_commit)),
etag: Some(EntityTag::weak(versioned_sha1!(&id))),
req: req,
}.into()
}

Modified src/main.rs

@@ -41,6 +41,7 @@ mod commit_tree;
mod repository_context;
mod repository_extension;
mod settings;
mod referenced_commit;
use std::env;
use std::path::Path;

Added src/referenced_commit.rs

@@ -0,0 +1,6 @@
use git2;
pub struct ReferencedCommit<'a> {
pub commit: git2::Commit<'a>,
pub reference: Option<git2::Reference<'a>>,
}

Modified src/render/commit.rs

@@ -1,14 +1,10 @@
use std::fmt;
use git2::{ self, Oid };
use git2;
use maud::{ RenderOnce, PreEscaped };
use maud_pulldown_cmark::Markdown;
use commit_tree;
use chrono::naive::datetime::NaiveDateTime;
const HEX: &'static [u8; 0x10] = b"0123456789abcdef";
fn short(oid: Oid) -> String {
oid.as_bytes().iter().take(3).flat_map(|b| vec![HEX[((b >> 4) & 0xFu8) as usize] as char, HEX[(b & 0xFu8) as usize] as char]).collect()
}
use referenced_commit::ReferencedCommit;
fn summary<'a>(commit: &'a git2::Commit<'a>) -> Option<&'a str> {
commit.message()
@@ -47,7 +43,7 @@ renderers! {
div.column {
div {
a href={ ^root "/commit/" ^commit.id() } {
span.id ^short(commit.id())
^(super::reference::Commit(commit))
" "
@match summary(commit) {
Some(summary) => ^summary,
@@ -97,14 +93,14 @@ renderers! {
}
}
pub struct Commits<'repo, 'a>(pub &'a str, pub &'a str, pub commit_tree::CommitTree<'repo>);
pub struct Commits<'repo, 'a>(pub &'a str, pub &'a ReferencedCommit<'a>, pub commit_tree::CommitTree<'repo>);
impl<'repo, 'a> RenderOnce for Commits<'repo, 'a> {
fn render_once(self, mut w: &mut fmt::Write) -> fmt::Result {
let Commits(root, reff, commits) = self;
let Commits(root, commit, commits) = self;
html!(w, {
div.block {
div.block-header {
h3 { "Commits for ref " span.ref { ^reff } }
h3 { "Commits for ref " ^super::Reference(commit) }
}
}
^CommitTree(root, commits, &mut 0)

Modified src/render/mod.rs

@@ -22,6 +22,7 @@ mod utils;
mod highlight;
mod settings;
mod about;
mod reference;
pub use self::style::Style;
pub use self::event::{ Event, Events };
@@ -43,3 +44,4 @@ pub use self::utils::MaybeLink;
pub use self::highlight::HighlightJS;
pub use self::settings::Settings;
pub use self::about::About;
pub use self::reference::Reference;

Added src/render/reference.rs

@@ -0,0 +1,20 @@
use git2;
use referenced_commit::ReferencedCommit;
const HEX: &'static [u8; 0x10] = b"0123456789abcdef";
fn short(oid: git2::Oid) -> String {
oid.as_bytes().iter().take(3).flat_map(|b| vec![HEX[((b >> 4) & 0xFu8) as usize] as char, HEX[(b & 0xFu8) as usize] as char]).collect()
}
renderers! {
Commit(commit: &'a git2::Commit<'a>) {
span.id title=^commit.id() { ^short(commit.id()) }
}
Reference(commit: &'a ReferencedCommit<'a>) {
@match commit.reference.as_ref().and_then(|r| r.shorthand()) {
Some(ref reff) => span.ref title=^commit.commit.id() { ^reff },
None => ^Commit(&commit.commit),
}
}
}

Modified src/render/tree.rs

@@ -4,6 +4,7 @@ use std::fmt;
use super::fa::{ FA, FAM };
use git2::{ self, ObjectType };
use std::path::{ self, Path, Component };
use referenced_commit::ReferencedCommit;
renderers! {
TreeEntryStub(root: &'a str, entry: &'a git2::TreeEntry<'a>) {
@@ -19,10 +20,10 @@ renderers! {
}
}
TreeEntry(root: &'a str, path: &'a Path, entry: &'a git2::Object<'a>) {
TreeEntry(root: &'a str, path: &'a Path, entry: &'a git2::Object<'a>, commit: &'a ReferencedCommit<'a>) {
div {
@match entry.kind() {
Some(ObjectType::Tree) => ^Tree(root, path, entry.as_tree().unwrap()),
Some(ObjectType::Tree) => ^Tree(root, path, entry.as_tree().unwrap(), commit),
Some(ObjectType::Blob) => ^Blob(root, path, entry.as_blob().unwrap()),
Some(ObjectType::Tag) => "Can't render ObjectType::Tag yet",
Some(ObjectType::Commit) => "Can't render ObjectType::Commit yet",
@@ -32,12 +33,14 @@ renderers! {
}
}
Tree(root: &'a str, path: &'a Path, tree: &'a git2::Tree<'a>) {
Tree(root: &'a str, path: &'a Path, tree: &'a git2::Tree<'a>, commit: &'a ReferencedCommit<'a>) {
div.block {
div.block-header {
h2.path span {
^FAM::FixedWidth(FA::Sitemap) " "
^Components(root, path.components())
" at "
^super::Reference(commit)
}
}
div.block-details {

Modified src/repository_context.rs

@@ -12,6 +12,7 @@ use iron::status;
use hyper::method::Method;
use handler::route::Route;
use error::Error;
use referenced_commit::ReferencedCommit;
pub struct RepositoryContext {
pub requested_path: PathBuf,
@@ -39,6 +40,14 @@ impl RepositoryContext {
.map(|obj| obj.id())
.and_then(|id| self.repository.find_commit(id).map_err(From::from))
}
pub fn referenced_commit(&self) -> Result<ReferencedCommit, Error> {
self.commit().map(|commit|
ReferencedCommit {
commit: commit,
reference: self.reference().ok(),
})
}
}
pub fn inject_repository_context<H: Handler>(root: &Path, handler: H) -> RepositoryContextHandler<H> {