[PATCH 1/8] Can add diffs to Atom feed entries
zwinkau at kit.edu
zwinkau at kit.edu
Tue Jul 1 09:40:26 CEST 2014
From: Andreas Zwinkau <zwinkau at kit.edu>
Off by default. Set enable-atom-diff flag for repos to enable.
Uses HTML5's "scoped CSS" feature to colorize diff deletes and inserts.
Mainstream pre-HTML5 engines either ignore this or apply the style
document-wide, which should not break anything.
As cgit was not prepared to produce multiple diffs per run,
so this also reset some counters during the diff. Additionally,
the cgit_self_link had to be extended, as it is called during
the diffing.
---
cgit.c | 7 +++++++
cgit.h | 2 ++
cgitrc.5.txt | 4 ++++
cmd.c | 2 +-
shared.c | 1 +
tests/t0112-atom.sh | 24 ++++++++++++++++++++++++
ui-atom.c | 22 +++++++++++++++++++---
ui-atom.h | 2 +-
ui-diff.c | 4 ++++
ui-shared.c | 4 ++++
10 files changed, 67 insertions(+), 5 deletions(-)
create mode 100755 tests/t0112-atom.sh
diff --git a/cgit.c b/cgit.c
index f488ebf..0b5d9e1 100644
--- a/cgit.c
+++ b/cgit.c
@@ -45,6 +45,8 @@ static void repo_config(struct cgit_repo *repo, const char *name, const char *va
repo->defbranch = xstrdup(value);
else if (!strcmp(name, "snapshots"))
repo->snapshots = ctx.cfg.snapshots & cgit_parse_snapshots_mask(value);
+ else if (!strcmp(name, "enable-atom-diff"))
+ repo->enable_atom_diff = atoi(value);
else if (!strcmp(name, "enable-commit-graph"))
repo->enable_commit_graph = atoi(value);
else if (!strcmp(name, "enable-log-filecount"))
@@ -144,6 +146,8 @@ static void config_cb(const char *name, const char *value)
ctx.cfg.noheader = atoi(value);
else if (!strcmp(name, "snapshots"))
ctx.cfg.snapshots = cgit_parse_snapshots_mask(value);
+ else if (!strcmp(name, "enable-atom-diff"))
+ ctx.cfg.enable_atom_diff = atoi(value);
else if (!strcmp(name, "enable-filter-overrides"))
ctx.cfg.enable_filter_overrides = atoi(value);
else if (!strcmp(name, "enable-http-clone"))
@@ -346,6 +350,7 @@ static void prepare_context(void)
ctx.cfg.logo = "/cgit.png";
ctx.cfg.favicon = "/favicon.ico";
ctx.cfg.local_time = 0;
+ ctx.cfg.enable_atom_diff = 0;
ctx.cfg.enable_http_clone = 1;
ctx.cfg.enable_index_owner = 1;
ctx.cfg.enable_tree_linenumbers = 1;
@@ -788,6 +793,8 @@ static void print_repo(FILE *f, struct cgit_repo *repo)
fprintf(f, "repo.section=%s\n", repo->section);
if (repo->clone_url)
fprintf(f, "repo.clone-url=%s\n", repo->clone_url);
+ fprintf(f, "repo.enable-atom-diff=%d\n",
+ repo->enable_atom_diff);
fprintf(f, "repo.enable-commit-graph=%d\n",
repo->enable_commit_graph);
fprintf(f, "repo.enable-log-filecount=%d\n",
diff --git a/cgit.h b/cgit.h
index 0badc64..3db220e 100644
--- a/cgit.h
+++ b/cgit.h
@@ -87,6 +87,7 @@ struct cgit_repo {
char *logo;
char *logo_link;
int snapshots;
+ int enable_atom_diff;
int enable_commit_graph;
int enable_log_filecount;
int enable_log_linecount;
@@ -213,6 +214,7 @@ struct cgit_config {
int cache_snapshot_ttl;
int case_sensitive_sort;
int embedded;
+ int enable_atom_diff;
int enable_filter_overrides;
int enable_http_clone;
int enable_index_links;
diff --git a/cgitrc.5.txt b/cgitrc.5.txt
index b7570db..b729294 100644
--- a/cgitrc.5.txt
+++ b/cgitrc.5.txt
@@ -141,6 +141,10 @@ embedded::
suitable for embedding in other html pages. Default value: none. See
also: "noheader".
+enable-atom-diff::
+ Flag which, when set to "1", will make cgit include a html-escaped diff
+ within the atom feed commit entries. Default value: "0".
+
enable-commit-graph::
Flag which, when set to "1", will make cgit print an ASCII-art commit
history graph to the left of the commit messages in the repository
diff --git a/cmd.c b/cmd.c
index 188cd56..3d9f245 100644
--- a/cmd.c
+++ b/cmd.c
@@ -33,7 +33,7 @@ static void HEAD_fn(void)
static void atom_fn(void)
{
- cgit_print_atom(ctx.qry.head, ctx.qry.path, ctx.cfg.max_atom_items);
+ cgit_print_atom(ctx.qry.head, ctx.qry.path, ctx.cfg.max_atom_items, ctx.repo->enable_atom_diff);
}
static void about_fn(void)
diff --git a/shared.c b/shared.c
index 8ed14c0..6bd82f9 100644
--- a/shared.c
+++ b/shared.c
@@ -57,6 +57,7 @@ struct cgit_repo *cgit_add_repo(const char *url)
ret->owner = NULL;
ret->section = ctx.cfg.section;
ret->snapshots = ctx.cfg.snapshots;
+ ret->enable_atom_diff = ctx.cfg.enable_atom_diff;
ret->enable_commit_graph = ctx.cfg.enable_commit_graph;
ret->enable_log_filecount = ctx.cfg.enable_log_filecount;
ret->enable_log_linecount = ctx.cfg.enable_log_linecount;
diff --git a/tests/t0112-atom.sh b/tests/t0112-atom.sh
new file mode 100755
index 0000000..8b5bbce
--- /dev/null
+++ b/tests/t0112-atom.sh
@@ -0,0 +1,24 @@
+#!/bin/sh
+
+test_description='Check content on atom feed'
+. ./setup.sh
+
+test_expect_success 'fetch feed' 'cgit_url "foo/atom/" >tmp'
+
+test_expect_success 'find feed open tag' 'grep -e "^<feed xmlns=.http://www\.w3\.org/2005/Atom.>" tmp'
+
+test_expect_success 'find title' 'grep -e "^<title>foo" tmp'
+
+test_expect_success 'find entry title' 'grep -e "^<title>commit 5</title>" tmp'
+
+test_expect_success 'find entry diffstat' 'grep -e "^<div class=.diffstat-header.>" tmp'
+
+test_expect_success 'find entry diff' 'grep -e "<table summary=.diff. class=.diff.>" tmp'
+
+test_expect_success 'find diff content 1' 'grep -e "diff --git a/file-1 b/file-1" tmp'
+
+test_expect_success 'find diff content 2' 'grep -e "@@ -0,0 +1 @@" tmp'
+
+test_expect_success 'find diff content 3' 'grep -e "+1<" tmp'
+
+test_done
diff --git a/ui-atom.c b/ui-atom.c
index b22d745..6a6a98b 100644
--- a/ui-atom.c
+++ b/ui-atom.c
@@ -10,16 +10,23 @@
#include "ui-atom.h"
#include "html.h"
#include "ui-shared.h"
+#include "ui-diff.h"
-static void add_entry(struct commit *commit, const char *host)
+static void add_entry(struct commit *commit, const char *host, int enable_atom_diff)
{
char delim = '&';
char *hex;
+ char *hex_parent;
char *mail, *t, *t2;
struct commitinfo *info;
info = cgit_parse_commit(commit);
hex = sha1_to_hex(commit->object.sha1);
+ if (commit->parents) {
+ hex_parent = sha1_to_hex(commit->parents->item->object.sha1);
+ } else {
+ hex_parent = NULL; /* means before initial commit */
+ }
html("<entry>\n");
html("<title>");
html_txt(info->subject);
@@ -71,6 +78,15 @@ static void add_entry(struct commit *commit, const char *host)
html("<pre>\n");
html_txt(info->msg);
html("</pre>\n");
+ if (enable_atom_diff) {
+ html("<pre class='diff'>\n");
+ html("<style scoped=\"scoped\">\n"); /* HTML5 with graceful degradation */
+ html("table.diff .add, span.add { background-color: #afa; }");
+ html("table.diff .del, span.remove { background-color: #faa; }");
+ html("</style>\n");
+ cgit_print_diff(hex, hex_parent, NULL, 0, 0);
+ html("</pre>");
+ }
html("</div>\n");
html("</content>\n");
html("</entry>\n");
@@ -78,7 +94,7 @@ static void add_entry(struct commit *commit, const char *host)
}
-void cgit_print_atom(char *tip, char *path, int max_count)
+void cgit_print_atom(char *tip, char *path, int max_count, int enable_atom_diff)
{
const char *host;
const char *argv[] = {NULL, tip, NULL, NULL, NULL};
@@ -132,7 +148,7 @@ void cgit_print_atom(char *tip, char *path, int max_count)
html("'/>\n");
}
while ((commit = get_revision(&rev)) != NULL) {
- add_entry(commit, host);
+ add_entry(commit, host, enable_atom_diff);
free(commit->buffer);
commit->buffer = NULL;
free_commit_list(commit->parents);
diff --git a/ui-atom.h b/ui-atom.h
index 749ffd3..e0043f1 100644
--- a/ui-atom.h
+++ b/ui-atom.h
@@ -1,6 +1,6 @@
#ifndef UI_ATOM_H
#define UI_ATOM_H
-extern void cgit_print_atom(char *tip, char *path, int max_count);
+extern void cgit_print_atom(char *tip, char *path, int max_count, int enable_atom_diff);
#endif
diff --git a/ui-diff.c b/ui-diff.c
index 71273aa..eeeeb80 100644
--- a/ui-diff.c
+++ b/ui-diff.c
@@ -363,6 +363,10 @@ void cgit_print_diff(const char *new_rev, const char *old_rev,
struct commit *commit, *commit2;
const unsigned char *old_tree_sha1, *new_tree_sha1;
+ /* reset global data */
+ files = 0;
+ slots = total_adds = total_rems = 0;
+
if (!new_rev)
new_rev = ctx.qry.head;
if (get_sha1(new_rev, new_rev_sha1)) {
diff --git a/ui-shared.c b/ui-shared.c
index 1ede2b0..6bdb52e 100644
--- a/ui-shared.c
+++ b/ui-shared.c
@@ -483,6 +483,10 @@ static void cgit_self_link(char *name, const char *title, const char *class)
else if (!strcmp(ctx.qry.page, "stats"))
cgit_stats_link(name, title, class, ctx.qry.head,
ctx.qry.path);
+ else if (!strcmp(ctx.qry.page, "atom"))
+ return cgit_diff_link(name, title, class, ctx.qry.head,
+ ctx.qry.sha1, ctx.qry.sha2,
+ ctx.qry.path, 0);
else {
/* Don't known how to make link for this page */
repolink(title, class, ctx.qry.page, ctx.qry.head, ctx.qry.path);
--
1.9.1
More information about the CGit
mailing list