Skip to content

Commit

Permalink
feat: make diffs look nicer
Browse files Browse the repository at this point in the history
  • Loading branch information
Kyle Clemens committed Jul 2, 2018
1 parent 31929fc commit 36cb6d7
Show file tree
Hide file tree
Showing 8 changed files with 118 additions and 23 deletions.
80 changes: 67 additions & 13 deletions webserver/src/routes/web/pastes/revisions.rs
Original file line number Diff line number Diff line change
Expand Up @@ -42,13 +42,18 @@ fn get(username: String, id: PasteId, config: State<Config>, user: OptionalWebUs
return Ok(Rst::Status(status));
}

let files: Vec<OutputFile> = id.files(&conn)?
.iter()
.map(|x| x.as_output_file(false, &paste))
.collect::<result::Result<_, _>>()?;

let repo = Repository::open(paste.files_directory())?;
let head = repo.refname_to_id("HEAD")?;
let head_commit = repo.find_commit(head)?;

let mut count = 1;

let mut diffs = Vec::new();
let mut all_revisions: Vec<Vec<Revision>> = Vec::default();
let mut commit = head_commit;
loop {
let parent = match commit.parent(0) {
Expand All @@ -69,29 +74,65 @@ fn get(username: String, id: PasteId, config: State<Config>, user: OptionalWebUs
};

let diff = repo.diff_tree_to_tree(Some(&parent_tree), Some(&commit.tree()?), None)?;
let mut diff_str = String::new();
diff.print(DiffFormat::Patch, |_delta, _hunk, line| {

let mut revisions = Vec::default();

let mut revision = Revision::default();
let mut hunk = Hunk::default();

diff.print(DiffFormat::Patch, |delta, _hunk, line| {
let line_str = ::std::str::from_utf8(line.content()).unwrap();
match line.origin() {
'+' | '-' | ' ' => diff_str.push(line.origin()),
_ => {}
'+' | '-' | ' ' => hunk.diff.push(line.origin()),
'F' => {
let name = delta.new_file().path()
.or_else(|| delta.old_file().path())
.unwrap()
.to_string_lossy()
.to_string();

if revision.id.is_some() && revision.id.as_ref() != Some(&name) {
revision.hunks.push(hunk.clone());
hunk = Hunk::default();
revisions.push(revision.clone());
revision = Revision::default();
}

revision.id = Some(name.clone());

let name = files
.iter()
.find(|x| x.id.simple().to_string() == name)
.and_then(|x| x.name.as_ref())
.cloned();
revision.file_name = name;
return true;
},
'H' => {
if hunk.header.is_some() {
revision.hunks.push(hunk.clone());
hunk = Hunk::default();
}
hunk.header = Some(line_str.to_string());
return true;
},
_ => return true,
}
diff_str += ::std::str::from_utf8(line.content()).unwrap();
hunk.diff += line_str;
true
})?;

diffs.push(diff_str);
revision.hunks.push(hunk);
revisions.push(revision);

all_revisions.push(revisions);

match parent {
DiffArg::Commit(c) => commit = c,
DiffArg::Tree(_) => break,
}
}

let files: Vec<OutputFile> = id.files(&conn)?
.iter()
.map(|x| x.as_output_file(false, &paste))
.collect::<result::Result<_, _>>()?;

let output = Output::new(
id,
author,
Expand All @@ -109,7 +150,7 @@ fn get(username: String, id: PasteId, config: State<Config>, user: OptionalWebUs
ctx["paste"] = json!(output);
ctx["num_commits"] = json!(count);
ctx["author_name"] = json!(author_name);
ctx["diffs"] = json!(diffs);
ctx["revisions"] = json!(all_revisions);

Ok(Rst::Template(Template::render("paste/revisions", ctx)))
}
Expand All @@ -118,3 +159,16 @@ enum DiffArg<'repo> {
Commit(Commit<'repo>),
Tree(Tree<'repo>),
}

#[derive(Debug, Serialize, Default, Clone)]
struct Revision {
id: Option<String>,
file_name: Option<String>,
hunks: Vec<Hunk>,
}

#[derive(Debug, Serialize, Default, Clone)]
struct Hunk {
header: Option<String>,
diff: String,
}
16 changes: 16 additions & 0 deletions webserver/web/src/css/custom.scss
Original file line number Diff line number Diff line change
Expand Up @@ -270,3 +270,19 @@ th, td {
color: $grey-light;
}
}

.diffs .subtitle.hunk > * {
flex-grow: 1;
}

.diffs .subtitle.hunk {
margin: 0 -1.25rem;
padding: 0;
display: flex;
border-bottom: 2px solid $grey;
margin-top: .5rem;

&:first-child {
margin-top: -1.5rem;
}
}
2 changes: 1 addition & 1 deletion webserver/web/static/css/dark-style.css

Large diffs are not rendered by default.

2 changes: 1 addition & 1 deletion webserver/web/static/css/dark-style.css.map

Large diffs are not rendered by default.

2 changes: 1 addition & 1 deletion webserver/web/static/css/style.css

Large diffs are not rendered by default.

2 changes: 1 addition & 1 deletion webserver/web/static/css/style.css.map

Large diffs are not rendered by default.

4 changes: 2 additions & 2 deletions webserver/web/templates/base.html.tera
Original file line number Diff line number Diff line change
Expand Up @@ -6,12 +6,12 @@
title="dark"
rel="stylesheet alternate"
href="/static/css/dark-style.css?v={{ resources_version }}"
integrity="sha384-7U/cOOMq67dv6quJFfFcApW+aqxfK7g3qqgtC2F/z9w4JJbpkI917282RCEVYuqj"/>
integrity="sha384-fGUdfbAR1t3NQZ3ptRhR4shXifmfj5pthsu0wA/QMUzApbHHhClqkOxhlx9l4huv"/>
<link
title="light"
rel="stylesheet"
href="/static/css/style.css?v={{ resources_version }}"
integrity="sha384-9NGZnEBFY22H03ZaxOVZW4xMV37WS9IMeP9TG0wWN2e6NHprKgtEWNnTLPL5LvBD"/>
integrity="sha384-FRpm86IE8UIyaBUKF8lM6w/j/FQvVtI1wFdYikT91fNx6wjAK/IVs06y52O0B2xg"/>
<script
src="/static/js/style.js?v={{ resources_version }}"
integrity="sha384-Jkt7YLun9UdrUCzwOTcLZcmUpkLflmI9Y/ksdoxa8m7HmpxkETujPoYB/av7Hy5E"></script>
Expand Down
33 changes: 29 additions & 4 deletions webserver/web/templates/paste/revisions.html.tera
Original file line number Diff line number Diff line change
Expand Up @@ -112,10 +112,35 @@ untitled paste

{% block main %}

{% for diff in diffs %}
<div class="box">
<pre class="language-diff"><code>{{ diff }}</code></pre>
</div>
<div class="diffs">
{% for revisions in revisions %}
{% if not loop.first %}
<hr/>
{% endif %}
{% for revision in revisions %}
<div class="box">
<div class="box-title">
<div>
<h2 class="title is-marginless">
{% if revision.file_name %}
<span class="keeps-spaces">{{ revision.file_name }}</span>
{% else %}
<em>unknown file</em>
{% endif %}
</h2>
</div>
</div>
<div>
{% for hunk in revision.hunks %}
<p class="subtitle hunk">
<code>{{ hunk.header }}</code>
</p>
<pre class="language-diff"><code>{{ hunk.diff }}</code></pre>
{% endfor %}
</div>
</div>
{% endfor %}
{% endfor %}
</div>

{% endblock main %}

0 comments on commit 36cb6d7

Please sign in to comment.