summaryrefslogtreecommitdiffabout
authorLars Hjemli <hjemli@gmail.com>2006-12-15 23:19:56 (UTC)
committer Lars Hjemli <hjemli@gmail.com>2006-12-15 23:19:56 (UTC)
commit9a8f88658d51aeb86a79ac1121de13562ad2601f (patch) (unidiff)
tree8724d9477efe887e0b851b567e74554e75761cc7
parent2101e26fd68f816e77de62b93df4c32fd1110d0c (diff)
downloadcgit-9a8f88658d51aeb86a79ac1121de13562ad2601f.zip
cgit-9a8f88658d51aeb86a79ac1121de13562ad2601f.tar.gz
cgit-9a8f88658d51aeb86a79ac1121de13562ad2601f.tar.bz2
Add ui-commit.c + misc ui cleanups
Signed-off-by: Lars Hjemli <hjemli@gmail.com>
Diffstat (more/less context) (ignore whitespace changes)
-rw-r--r--Makefile2
-rw-r--r--cgit.c2
-rw-r--r--cgit.css50
-rw-r--r--cgit.h5
-rw-r--r--parsing.c1
-rw-r--r--ui-commit.c80
-rw-r--r--ui-log.c11
-rw-r--r--ui-tree.c6
-rw-r--r--ui-view.c2
9 files changed, 140 insertions, 19 deletions
diff --git a/Makefile b/Makefile
index 2a4d62a..58a583b 100644
--- a/Makefile
+++ b/Makefile
@@ -1,25 +1,25 @@
1CGIT_VERSION = 0.1-pre 1CGIT_VERSION = 0.1-pre
2 2
3INSTALL_BIN = /var/www/htdocs/cgit.cgi 3INSTALL_BIN = /var/www/htdocs/cgit.cgi
4INSTALL_CSS = /var/www/htdocs/cgit.css 4INSTALL_CSS = /var/www/htdocs/cgit.css
5CACHE_ROOT = /var/cache/cgit 5CACHE_ROOT = /var/cache/cgit
6 6
7EXTLIBS = ../git/libgit.a ../git/xdiff/lib.a -lz -lcrypto 7EXTLIBS = ../git/libgit.a ../git/xdiff/lib.a -lz -lcrypto
8OBJECTS = shared.o cache.o parsing.o html.o ui-shared.o ui-repolist.o \ 8OBJECTS = shared.o cache.o parsing.o html.o ui-shared.o ui-repolist.o \
9 ui-summary.o ui-log.o ui-view.c ui-tree.c 9 ui-summary.o ui-log.o ui-view.c ui-tree.c ui-commit.c
10 10
11CFLAGS += -Wall 11CFLAGS += -Wall
12 12
13all: cgit 13all: cgit
14 14
15install: all clean-cache 15install: all clean-cache
16 install cgit $(INSTALL_BIN) 16 install cgit $(INSTALL_BIN)
17 install cgit.css $(INSTALL_CSS) 17 install cgit.css $(INSTALL_CSS)
18 18
19cgit: cgit.c cgit.h git.h $(OBJECTS) 19cgit: cgit.c cgit.h git.h $(OBJECTS)
20 $(CC) $(CFLAGS) -DCGIT_VERSION='"$(CGIT_VERSION)"' cgit.c -o cgit \ 20 $(CC) $(CFLAGS) -DCGIT_VERSION='"$(CGIT_VERSION)"' cgit.c -o cgit \
21 $(OBJECTS) $(EXTLIBS) 21 $(OBJECTS) $(EXTLIBS)
22 22
23$(OBJECTS): cgit.h git.h 23$(OBJECTS): cgit.h git.h
24 24
25.PHONY: clean 25.PHONY: clean
diff --git a/cgit.c b/cgit.c
index d7e586d..37cdb83 100644
--- a/cgit.c
+++ b/cgit.c
@@ -19,32 +19,34 @@ static void cgit_print_repo_page(struct cacheitem *item)
19 cgit_print_pageheader(title); 19 cgit_print_pageheader(title);
20 cgit_print_error(fmt("Unable to scan repository: %s", 20 cgit_print_error(fmt("Unable to scan repository: %s",
21 strerror(errno))); 21 strerror(errno)));
22 cgit_print_docend(); 22 cgit_print_docend();
23 return; 23 return;
24 } 24 }
25 setenv("GIT_DIR", fmt("%s/%s", cgit_root, cgit_query_repo), 1); 25 setenv("GIT_DIR", fmt("%s/%s", cgit_root, cgit_query_repo), 1);
26 char *title = fmt("%s - %s", cgit_repo_name, cgit_repo_desc); 26 char *title = fmt("%s - %s", cgit_repo_name, cgit_repo_desc);
27 cgit_print_docstart(title, item); 27 cgit_print_docstart(title, item);
28 cgit_print_pageheader(title); 28 cgit_print_pageheader(title);
29 if (!cgit_query_page) { 29 if (!cgit_query_page) {
30 cgit_print_summary(); 30 cgit_print_summary();
31 } else if (!strcmp(cgit_query_page, "log")) { 31 } else if (!strcmp(cgit_query_page, "log")) {
32 cgit_print_log(cgit_query_head, cgit_query_ofs, 100); 32 cgit_print_log(cgit_query_head, cgit_query_ofs, 100);
33 } else if (!strcmp(cgit_query_page, "tree")) { 33 } else if (!strcmp(cgit_query_page, "tree")) {
34 cgit_print_tree(cgit_query_sha1); 34 cgit_print_tree(cgit_query_sha1);
35 } else if (!strcmp(cgit_query_page, "commit")) {
36 cgit_print_commit(cgit_query_sha1);
35 } else if (!strcmp(cgit_query_page, "view")) { 37 } else if (!strcmp(cgit_query_page, "view")) {
36 cgit_print_view(cgit_query_sha1); 38 cgit_print_view(cgit_query_sha1);
37 } 39 }
38 cgit_print_docend(); 40 cgit_print_docend();
39} 41}
40 42
41static void cgit_fill_cache(struct cacheitem *item) 43static void cgit_fill_cache(struct cacheitem *item)
42{ 44{
43 htmlfd = item->fd; 45 htmlfd = item->fd;
44 item->st.st_mtime = time(NULL); 46 item->st.st_mtime = time(NULL);
45 if (cgit_query_repo) 47 if (cgit_query_repo)
46 cgit_print_repo_page(item); 48 cgit_print_repo_page(item);
47 else 49 else
48 cgit_print_repolist(item); 50 cgit_print_repolist(item);
49} 51}
50 52
diff --git a/cgit.css b/cgit.css
index 97b4e27..3579598 100644
--- a/cgit.css
+++ b/cgit.css
@@ -8,71 +8,113 @@ body {
8 8
9 9
10h2 { 10h2 {
11 font-size: normal; 11 font-size: normal;
12 font-weight: bold; 12 font-weight: bold;
13 margin-bottom: 0.1em; 13 margin-bottom: 0.1em;
14} 14}
15 15
16 16
17table.list { 17table.list {
18 border: solid 1px black; 18 border: solid 1px black;
19 border-collapse: collapse; 19 border-collapse: collapse;
20 border: solid 1px #aaa; 20 border: solid 1px #aaa;
21} 21}
22 22
23table.list th { 23table.list th {
24 text-align: left;
25 font-weight: bold; 24 font-weight: bold;
26 background: #ddd; 25 background: #ddd;
27 border-bottom: solid 1px #aaa; 26 border-bottom: solid 1px #aaa;
28 padding: 0.1em 0.5em 0.1em; 27 padding: 0.1em 0.5em 0.1em 0.5em;
29 vertical-align: baseline; 28 vertical-align: baseline;
30} 29}
31table.list td { 30table.list td {
32 border: none; 31 border: none;
33 padding: 0.1em 1em 0.1em 0.5em; 32 padding: 0.1em 0.5em 0.1em 0.5em;
34 background: white; 33 background: white;
35} 34}
36 35
37img { 36img {
38 border: none; 37 border: none;
39} 38}
40 39
41 40
42div#header { 41div#header {
43 background-color: #ddd; 42 background-color: #ddd;
44 padding: 0.25em 0.25em 0.25em 0.5em; 43 padding: 0.25em 0.25em 0.25em 0.5em;
45 font-size: 150%; 44 font-size: 150%;
46 font-weight: bold; 45 font-weight: bold;
47 border: solid 1px #aaa; 46 border: solid 1px #aaa;
48 vertical-align: middle; 47 vertical-align: middle;
49} 48}
50 49
51div#header img#logo { 50div#header img#logo {
52 float: right; 51 float: right;
53} 52}
54 53
55div#content { 54div#content {
56 margin: 0.5em 0.5em; 55 margin: 0.5em 0.5em;
57} 56}
58 57
58div#blob {
59 border: solid 1px black;
60}
61
59div.error { 62div.error {
60 color: red; 63 color: red;
61 font-weight: bold; 64 font-weight: bold;
62 margin: 1em 2em; 65 margin: 1em 2em;
63} 66}
64div.ls-dir a { 67div.ls-dir a {
65 font-weight: bold; 68 font-weight: bold;
66} 69}
67th.filesize, td.filesize { 70th.filesize, td.filesize {
68 text-align: right; 71 text-align: right;
69} 72}
70th.filemode, td.filemode { 73th.filemode, td.filemode {
71 text-align: center; 74 text-align: center;
72} 75}
73 76
74td.blob { 77td.blob {
75 white-space: pre; 78 white-space: pre;
76 font-family: courier; 79 font-family: courier;
77 font-size: 100%; 80 font-size: 100%;
78} \ No newline at end of file 81}
82
83table.log td {
84 white-space: nowrap;
85}
86
87table.commit-info {
88 border-collapse: collapse;
89 margin-top: 1em;
90
91}
92table.commit-info th {
93 text-align: left;
94 font-weight: normal;
95 padding: 0.1em 1em 0.1em 0.1em;
96}
97table.commit-info td {
98 font-weight: normal;
99 padding: 0.1em 1em 0.1em 0.1em;
100}
101div.commit-subject {
102 font-weight: bold;
103 font-size: 110%;
104 margin: 1em 0em 1em;
105}
106div.commit-msg {
107 white-space: pre;
108 font-family: courier;
109 font-size: 100%;
110}
111.sha1 {
112 font-family: courier;
113 font-size: 90%;
114}
115.left {
116 text-align: left;
117}
118.right {
119 text-align: right;
120}
diff --git a/cgit.h b/cgit.h
index 268db53..a905e47 100644
--- a/cgit.h
+++ b/cgit.h
@@ -79,20 +79,21 @@ extern int cache_unlock(struct cacheitem *item);
79extern int cache_cancel_lock(struct cacheitem *item); 79extern int cache_cancel_lock(struct cacheitem *item);
80extern int cache_exist(struct cacheitem *item); 80extern int cache_exist(struct cacheitem *item);
81extern int cache_expired(struct cacheitem *item); 81extern int cache_expired(struct cacheitem *item);
82 82
83extern char *cgit_repourl(const char *reponame); 83extern char *cgit_repourl(const char *reponame);
84extern char *cgit_pageurl(const char *reponame, const char *pagename, 84extern char *cgit_pageurl(const char *reponame, const char *pagename,
85 const char *query); 85 const char *query);
86 86
87extern void cgit_print_error(char *msg); 87extern void cgit_print_error(char *msg);
88extern void cgit_print_docstart(char *title, struct cacheitem *item); 88extern void cgit_print_docstart(char *title, struct cacheitem *item);
89extern void cgit_print_docend(); 89extern void cgit_print_docend();
90extern void cgit_print_pageheader(char *title); 90extern void cgit_print_pageheader(char *title);
91 91
92extern void cgit_print_repolist(struct cacheitem *item); 92extern void cgit_print_repolist(struct cacheitem *item);
93extern void cgit_print_summary(); 93extern void cgit_print_summary();
94extern void cgit_print_log(const char *tip, int ofs, int cnt); 94extern void cgit_print_log(const char *tip, int ofs, int cnt);
95extern void cgit_print_view(char *hex); 95extern void cgit_print_view(const char *hex);
96extern void cgit_print_tree(const char *sha1); 96extern void cgit_print_tree(const char *hex);
97extern void cgit_print_commit(const char *hex);
97 98
98#endif /* CGIT_H */ 99#endif /* CGIT_H */
diff --git a/parsing.c b/parsing.c
index 6cab0e9..be471b5 100644
--- a/parsing.c
+++ b/parsing.c
@@ -137,23 +137,24 @@ struct commitinfo *cgit_parse_commit(struct commit *commit)
137 ret->author = substr(p, t); 137 ret->author = substr(p, t);
138 p = strchr(p, '\n') + 1; 138 p = strchr(p, '\n') + 1;
139 } 139 }
140 140
141 if (!strncmp(p, "committer ", 9)) { 141 if (!strncmp(p, "committer ", 9)) {
142 p += 9; 142 p += 9;
143 t = strchr(p, '<') - 1; 143 t = strchr(p, '<') - 1;
144 ret->committer = substr(p, t); 144 ret->committer = substr(p, t);
145 p = strchr(p, '\n') + 1; 145 p = strchr(p, '\n') + 1;
146 } 146 }
147 147
148 while (*p == '\n') 148 while (*p == '\n')
149 p = strchr(p, '\n') + 1; 149 p = strchr(p, '\n') + 1;
150 150
151 t = strchr(p, '\n'); 151 t = strchr(p, '\n');
152 ret->subject = substr(p, t); 152 ret->subject = substr(p, t);
153 p = t + 1;
153 154
154 while (*p == '\n') 155 while (*p == '\n')
155 p = strchr(p, '\n') + 1; 156 p = strchr(p, '\n') + 1;
156 ret->msg = p; 157 ret->msg = p;
157 158
158 return ret; 159 return ret;
159} 160}
diff --git a/ui-commit.c b/ui-commit.c
new file mode 100644
index 0000000..1c0e7e5
--- a/dev/null
+++ b/ui-commit.c
@@ -0,0 +1,80 @@
1#include "cgit.h"
2
3void cgit_print_date(unsigned long secs)
4{
5 char buf[32];
6 struct tm *time;
7
8 time = gmtime(&secs);
9 strftime(buf, sizeof(buf), "%Y-%m-%d %H:%M:%S", time);
10 html_txt(buf);
11
12}
13
14void cgit_print_commit(const char *hex)
15{
16 struct commit *commit;
17 struct commitinfo *info;
18 struct commit_list *p;
19 unsigned long size;
20 char type[20];
21 char *buf;
22
23 unsigned char sha1[20];
24
25 if (get_sha1(hex, sha1)) {
26 cgit_print_error(fmt("Bad object id: %s", hex));
27 return;
28 }
29
30 buf = read_sha1_file(sha1, type, &size);
31 if (!buf) {
32 cgit_print_error(fmt("Bad object reference: %s", hex));
33 return;
34 }
35
36 commit = lookup_commit(sha1);
37 if (!commit) {
38 cgit_print_error(fmt("Bad commit reference: %s", hex));
39 return;
40 }
41
42 commit->buffer = buf;
43 if (parse_commit_buffer(commit, buf, size)) {
44 cgit_print_error(fmt("Malformed commit buffer: %s", hex));
45 return;
46 }
47
48 info = cgit_parse_commit(commit);
49
50 html("<table class='commit-info'>\n");
51 html("<tr><th>author</th><td colspan='2'>");
52 html_txt(info->author);
53 html("</td></tr>\n");
54 html("<tr><th>committer</th><td>");
55 html_txt(info->committer);
56 html("</td><td class='right'>");
57 cgit_print_date(commit->date);
58 html("</td></tr>\n");
59 html("<tr><th>tree</th><td colspan='2' class='sha1'><a href='");
60 html_attr(cgit_pageurl(cgit_query_repo, "tree", fmt("id=%s", sha1_to_hex(commit->tree->object.sha1))));
61 htmlf("'>%s</a></td></tr>\n", sha1_to_hex(commit->tree->object.sha1));
62
63 for (p = commit->parents; p ; p = p->next) {
64 html("<tr><th>parent</th><td colspan='2' class='sha1'><a href='");
65 html_attr(cgit_pageurl(cgit_query_repo, "commit", fmt("id=%s", sha1_to_hex(p->item->object.sha1))));
66 htmlf("'>%s</a></td></tr>\n",
67 sha1_to_hex(p->item->object.sha1));
68 }
69 html("</table>\n");
70 html("<div class='commit-subject'>");
71 html_txt(info->subject);
72 html("</div>");
73 html("<div class='commit-msg'>");
74 html_txt(info->msg);
75 html("</div>");
76 free(info->author);
77 free(info->committer);
78 free(info->subject);
79 free(info);
80}
diff --git a/ui-log.c b/ui-log.c
index 31331ef..c52af79 100644
--- a/ui-log.c
+++ b/ui-log.c
@@ -8,69 +8,64 @@
8 8
9#include "cgit.h" 9#include "cgit.h"
10 10
11void print_commit(struct commit *commit) 11void print_commit(struct commit *commit)
12{ 12{
13 char buf[32]; 13 char buf[32];
14 struct commitinfo *info; 14 struct commitinfo *info;
15 struct tm *time; 15 struct tm *time;
16 16
17 info = cgit_parse_commit(commit); 17 info = cgit_parse_commit(commit);
18 time = gmtime(&commit->date); 18 time = gmtime(&commit->date);
19 html("<tr><td>"); 19 html("<tr><td>");
20 strftime(buf, sizeof(buf), "%Y-%m-%d %H:%M:%S", time); 20 strftime(buf, sizeof(buf), "%Y-%m-%d %H:%M:%S", time);
21 html_txt(buf); 21 html_txt(buf);
22 html("</td><td>"); 22 html("</td><td>");
23 char *qry = fmt("id=%s", sha1_to_hex(commit->object.sha1)); 23 char *qry = fmt("id=%s", sha1_to_hex(commit->object.sha1));
24 char *url = cgit_pageurl(cgit_query_repo, "view", qry); 24 char *url = cgit_pageurl(cgit_query_repo, "commit", qry);
25 html_link_open(url, NULL, NULL); 25 html_link_open(url, NULL, NULL);
26 html_txt(info->subject); 26 html_txt(info->subject);
27 html_link_close(); 27 html_link_close();
28 html("</td><td>"); 28 html("</td><td>");
29 html_txt(info->author); 29 html_txt(info->author);
30 html("</td><td><a href='");
31 html_attr(cgit_pageurl(cgit_query_repo, "tree",
32 fmt("id=%s",
33 sha1_to_hex(commit->tree->object.sha1))));
34 html("'>tree</a>");
35 html("</td></tr>\n"); 30 html("</td></tr>\n");
36 free(info->author); 31 free(info->author);
37 free(info->committer); 32 free(info->committer);
38 free(info->subject); 33 free(info->subject);
39 free(info); 34 free(info);
40} 35}
41 36
42 37
43void cgit_print_log(const char *tip, int ofs, int cnt) 38void cgit_print_log(const char *tip, int ofs, int cnt)
44{ 39{
45 struct rev_info rev; 40 struct rev_info rev;
46 struct commit *commit; 41 struct commit *commit;
47 const char *argv[2] = {NULL, tip}; 42 const char *argv[2] = {NULL, tip};
48 int i; 43 int i;
49 44
50 init_revisions(&rev, NULL); 45 init_revisions(&rev, NULL);
51 rev.abbrev = DEFAULT_ABBREV; 46 rev.abbrev = DEFAULT_ABBREV;
52 rev.commit_format = CMIT_FMT_DEFAULT; 47 rev.commit_format = CMIT_FMT_DEFAULT;
53 rev.verbose_header = 1; 48 rev.verbose_header = 1;
54 rev.show_root_diff = 0; 49 rev.show_root_diff = 0;
55 setup_revisions(2, argv, &rev, NULL); 50 setup_revisions(2, argv, &rev, NULL);
56 prepare_revision_walk(&rev); 51 prepare_revision_walk(&rev);
57 52
58 html("<h2>Log</h2>"); 53 html("<h2>Log</h2>");
59 html("<table class='list'>"); 54 html("<table class='list log'>");
60 html("<tr><th>Date</th><th>Message</th><th>Author</th><th>Link</th></tr>\n"); 55 html("<tr><th class='left'>Date</th><th class='left'>Message</th><th class='left'>Author</th></tr>\n");
61 56
62 if (ofs<0) 57 if (ofs<0)
63 ofs = 0; 58 ofs = 0;
64 59
65 for (i = 0; i < ofs && (commit = get_revision(&rev)) != NULL; i++) { 60 for (i = 0; i < ofs && (commit = get_revision(&rev)) != NULL; i++) {
66 free(commit->buffer); 61 free(commit->buffer);
67 commit->buffer = NULL; 62 commit->buffer = NULL;
68 free_commit_list(commit->parents); 63 free_commit_list(commit->parents);
69 commit->parents = NULL; 64 commit->parents = NULL;
70 } 65 }
71 66
72 for (i = 0; i < cnt && (commit = get_revision(&rev)) != NULL; i++) { 67 for (i = 0; i < cnt && (commit = get_revision(&rev)) != NULL; i++) {
73 print_commit(commit); 68 print_commit(commit);
74 free(commit->buffer); 69 free(commit->buffer);
75 commit->buffer = NULL; 70 commit->buffer = NULL;
76 free_commit_list(commit->parents); 71 free_commit_list(commit->parents);
diff --git a/ui-tree.c b/ui-tree.c
index 84930cb..c4d75ab 100644
--- a/ui-tree.c
+++ b/ui-tree.c
@@ -49,22 +49,22 @@ void cgit_print_tree(const char *hex)
49{ 49{
50 struct tree *tree; 50 struct tree *tree;
51 unsigned char sha1[20]; 51 unsigned char sha1[20];
52 52
53 if (get_sha1_hex(hex, sha1)) { 53 if (get_sha1_hex(hex, sha1)) {
54 cgit_print_error(fmt("Invalid object id: %s", hex)); 54 cgit_print_error(fmt("Invalid object id: %s", hex));
55 return; 55 return;
56 } 56 }
57 tree = parse_tree_indirect(sha1); 57 tree = parse_tree_indirect(sha1);
58 if (!tree) { 58 if (!tree) {
59 cgit_print_error(fmt("Not a tree object: %s", hex)); 59 cgit_print_error(fmt("Not a tree object: %s", hex));
60 return; 60 return;
61 } 61 }
62 62
63 html("<h2>Tree content</h2>\n"); 63 html("<h2>Tree content</h2>\n");
64 html("<table class='list'>\n"); 64 html("<table class='list'>\n");
65 html("<tr><th>Name</th>"); 65 html("<tr><th class='left'>Name</th>");
66 html("<th class='filesize'>Size</th>"); 66 html("<th class='right'>Size</th>");
67 html("<th class='filemode'>Mode</th></tr>\n"); 67 html("<th class='right'>Mode</th></tr>\n");
68 read_tree_recursive(tree, "", 0, 1, NULL, print_entry); 68 read_tree_recursive(tree, "", 0, 1, NULL, print_entry);
69 html("</table>\n"); 69 html("</table>\n");
70} 70}
diff --git a/ui-view.c b/ui-view.c
index 9d13be1..b75ce9a 100644
--- a/ui-view.c
+++ b/ui-view.c
@@ -1,27 +1,27 @@
1/* ui-view.c: functions to output _any_ object, given it's sha1 1/* ui-view.c: functions to output _any_ object, given it's sha1
2 * 2 *
3 * Copyright (C) 2006 Lars Hjemli 3 * Copyright (C) 2006 Lars Hjemli
4 * 4 *
5 * Licensed under GNU General Public License v2 5 * Licensed under GNU General Public License v2
6 * (see COPYING for full license text) 6 * (see COPYING for full license text)
7 */ 7 */
8 8
9#include "cgit.h" 9#include "cgit.h"
10 10
11void cgit_print_view(char *hex) 11void cgit_print_view(const char *hex)
12{ 12{
13 unsigned char sha1[20]; 13 unsigned char sha1[20];
14 char type[20]; 14 char type[20];
15 unsigned char *buf; 15 unsigned char *buf;
16 unsigned long size; 16 unsigned long size;
17 17
18 if (get_sha1_hex(hex, sha1)){ 18 if (get_sha1_hex(hex, sha1)){
19 cgit_print_error(fmt("Bad hex value: %s", hex)); 19 cgit_print_error(fmt("Bad hex value: %s", hex));
20 return; 20 return;
21 } 21 }
22 22
23 if (sha1_object_info(sha1, type, &size)){ 23 if (sha1_object_info(sha1, type, &size)){
24 cgit_print_error("Bad object name"); 24 cgit_print_error("Bad object name");
25 return; 25 return;
26 } 26 }
27 27