From mboxrd@z Thu Jan 1 00:00:00 1970 From: zwinkau at kit.edu (zwinkau at kit.edu) Date: Tue, 1 Jul 2014 09:40:26 +0200 Subject: [PATCH 1/8] Can add diffs to Atom feed entries Message-ID: <1404200433-30081-1-git-send-email-zwinkau@kit.edu> From: Andreas Zwinkau 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 "^" tmp' + +test_expect_success 'find title' 'grep -e "^foo" tmp' + +test_expect_success 'find entry title' 'grep -e "^<title>commit 5" tmp' + +test_expect_success 'find entry diffstat' 'grep -e "^
" tmp' + +test_expect_success 'find entry diff' 'grep -e "" 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("\n"); html(""); 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