summaryrefslogtreecommitdiffabout
authorLars Hjemli <hjemli@gmail.com>2007-05-11 21:44:42 (UTC)
committer Lars Hjemli <hjemli@gmail.com>2007-05-11 21:44:42 (UTC)
commit9f48df63f6d8d9a8abcc02cd2f08293da7081520 (patch) (unidiff)
treed171ce9834577d3133e584c821f78806fbe0daef
parentf596d10d7391ed72b73019e037a7f7eec7a50d02 (diff)
downloadcgit-9f48df63f6d8d9a8abcc02cd2f08293da7081520.zip
cgit-9f48df63f6d8d9a8abcc02cd2f08293da7081520.tar.gz
cgit-9f48df63f6d8d9a8abcc02cd2f08293da7081520.tar.bz2
Add links to enable downloading of tagged blobs
All tags below refs/archives are shown on the repo summary page as download links. The links referes to the tagged objects, using the tag name as filename for download. This can be used to add shortcuts for release tarballs, documentation and other blobs stored in the object database, especially blobs that are not reachable during cloning. Signed-off-by: Lars Hjemli <hjemli@gmail.com>
Diffstat (more/less context) (ignore whitespace changes)
-rw-r--r--cgit.css20
-rw-r--r--ui-summary.c74
2 files changed, 85 insertions, 9 deletions
diff --git a/cgit.css b/cgit.css
index ef4bc62..49cf2d1 100644
--- a/cgit.css
+++ b/cgit.css
@@ -1,271 +1,291 @@
1body { 1body {
2 font-family: arial; 2 font-family: arial;
3 font-size: 11pt; 3 font-size: 11pt;
4 background: white; 4 background: white;
5 padding: 0em; 5 padding: 0em;
6 margin: 0em; 6 margin: 0em;
7} 7}
8 8
9 9
10h2 { 10h2 {
11 font-size: 120%; 11 font-size: 120%;
12 font-weight: bold; 12 font-weight: bold;
13 margin-top: 0em;
13 margin-bottom: 0.25em; 14 margin-bottom: 0.25em;
14} 15}
15 16
16h3 { 17h3 {
17 margin-top: 0em; 18 margin-top: 0em;
18 font-size: 100%; 19 font-size: 100%;
19 font-weight: normal; 20 font-weight: normal;
20} 21}
21 22
22a { 23a {
23 color: blue; 24 color: blue;
24 text-decoration: none; 25 text-decoration: none;
25} 26}
26 27
27a:hover { 28a:hover {
28 text-decoration: underline; 29 text-decoration: underline;
29} 30}
30 31
31table.list { 32table.list {
32 border: none; 33 border: none;
33 border-collapse: collapse; 34 border-collapse: collapse;
34} 35}
35 36
36table.list tr { 37table.list tr {
37 background: white; 38 background: white;
38} 39}
39 40
40table.list tr:hover { 41table.list tr:hover {
41 background: #eee; 42 background: #eee;
42} 43}
43 44
44table.list tr.nohover:hover { 45table.list tr.nohover:hover {
45 background: white; 46 background: white;
46} 47}
47 48
48table.list th { 49table.list th {
49 font-weight: normal; 50 font-weight: normal;
50 border-bottom: solid 1px #777; 51 border-bottom: solid 1px #777;
51 padding: 0.1em 0.5em 0.1em 0.5em; 52 padding: 0.1em 0.5em 0.1em 0.5em;
52 vertical-align: baseline; 53 vertical-align: baseline;
53} 54}
54 55
55table.list td { 56table.list td {
56 border: none; 57 border: none;
57 padding: 0.1em 0.5em 0.1em 0.5em; 58 padding: 0.1em 0.5em 0.1em 0.5em;
58} 59}
59 60
60img { 61img {
61 border: none; 62 border: none;
62} 63}
63 64
64table#layout { 65table#layout {
65 width: 100%; 66 width: 100%;
66 border-collapse: separate; 67 border-collapse: separate;
67 border-spacing: 0px; 68 border-spacing: 0px;
68 margin: 0px; 69 margin: 0px;
69} 70}
70 71
71td#header, td#logo { 72td#header, td#logo {
72 color: #666; 73 color: #666;
73 background-color: #ddd; 74 background-color: #ddd;
74 border-bottom: solid 1px #000; 75 border-bottom: solid 1px #000;
75} 76}
76 77
77td#header { 78td#header {
78 font-size: 150%; 79 font-size: 150%;
79 font-weight: bold; 80 font-weight: bold;
80 padding: 0.2em 0.5em; 81 padding: 0.2em 0.5em;
81 vertical-align: text-bottom; 82 vertical-align: text-bottom;
82} 83}
83 84
84td#logo { 85td#logo {
85 text-align: right; 86 text-align: right;
86 vertical-align: middle; 87 vertical-align: middle;
87 padding-right: 0.5em; 88 padding-right: 0.5em;
88} 89}
89 90
90td#crumb, td#search { 91td#crumb, td#search {
91 color: #ccc; 92 color: #ccc;
92 border-top: solid 3px #555; 93 border-top: solid 3px #555;
93 background-color: #666; 94 background-color: #666;
94 border-bottom: solid 1px #333; 95 border-bottom: solid 1px #333;
95 padding: 2px 1em; 96 padding: 2px 1em;
96} 97}
97 98
98td#crumb { 99td#crumb {
99 font-weight: bold; 100 font-weight: bold;
100} 101}
101 102
102td#crumb a { 103td#crumb a {
103 color: #ccc; 104 color: #ccc;
104} 105}
105 106
106td#crumb a:hover { 107td#crumb a:hover {
107 color: #eee; 108 color: #eee;
108} 109}
109 110
110td#search { 111td#search {
111 text-align: right; 112 text-align: right;
112 vertical-align: center; 113 vertical-align: center;
113 padding-right: 0.5em; 114 padding-right: 0.5em;
114} 115}
115 116
116td#search form { 117td#search form {
117 margin: 0px; 118 margin: 0px;
118 padding: 0px; 119 padding: 0px;
119} 120}
120 121
121td#search input { 122td#search input {
122 font-size: 9pt; 123 font-size: 9pt;
123 padding: 0px; 124 padding: 0px;
124 width: 10em; 125 width: 10em;
125 border: solid 1px #333; 126 border: solid 1px #333;
126 color: #333; 127 color: #333;
127 background-color: #fff; 128 background-color: #fff;
128} 129}
129 130
131td#summary {
132 vertical-align: top;
133 padding-bottom: 1em;
134}
135
136td#archivelist {
137 padding-bottom: 1em;
138}
139
140td#archivelist table {
141 float: right;
142 border-collapse: collapse;
143 border: solid 1px #777;
144}
145
146td#archivelist table th {
147 background-color: #ccc;
148}
149
130td#content { 150td#content {
131 padding: 1em 0.5em; 151 padding: 1em 0.5em;
132} 152}
133 153
134div#blob { 154div#blob {
135 border: solid 1px black; 155 border: solid 1px black;
136} 156}
137 157
138div.error { 158div.error {
139 color: red; 159 color: red;
140 font-weight: bold; 160 font-weight: bold;
141 margin: 1em 2em; 161 margin: 1em 2em;
142} 162}
143 163
144td.ls-blob, td.ls-dir, td.ls-mod { 164td.ls-blob, td.ls-dir, td.ls-mod {
145 font-family: monospace; 165 font-family: monospace;
146} 166}
147 167
148div.ls-dir a { 168div.ls-dir a {
149 font-weight: bold; 169 font-weight: bold;
150} 170}
151 171
152th.filesize, td.filesize { 172th.filesize, td.filesize {
153 text-align: right; 173 text-align: right;
154} 174}
155 175
156td.filesize { 176td.filesize {
157 font-family: monospace; 177 font-family: monospace;
158} 178}
159 179
160td.filemode { 180td.filemode {
161 font-family: monospace; 181 font-family: monospace;
162} 182}
163 183
164td.blob { 184td.blob {
165 white-space: pre; 185 white-space: pre;
166 font-family: monospace; 186 font-family: monospace;
167 background-color: white; 187 background-color: white;
168} 188}
169 189
170table.nowrap td { 190table.nowrap td {
171 white-space: nowrap; 191 white-space: nowrap;
172} 192}
173 193
174table.commit-info { 194table.commit-info {
175 border-collapse: collapse; 195 border-collapse: collapse;
176 margin-top: 1.5em; 196 margin-top: 1.5em;
177} 197}
178 198
179table.commit-info th { 199table.commit-info th {
180 text-align: left; 200 text-align: left;
181 font-weight: normal; 201 font-weight: normal;
182 padding: 0.1em 1em 0.1em 0.1em; 202 padding: 0.1em 1em 0.1em 0.1em;
183} 203}
184 204
185table.commit-info td { 205table.commit-info td {
186 font-weight: normal; 206 font-weight: normal;
187 padding: 0.1em 1em 0.1em 0.1em; 207 padding: 0.1em 1em 0.1em 0.1em;
188} 208}
189 209
190div.commit-subject { 210div.commit-subject {
191 font-weight: bold; 211 font-weight: bold;
192 font-size: 125%; 212 font-size: 125%;
193 margin: 1.5em 0em 0.5em 0em; 213 margin: 1.5em 0em 0.5em 0em;
194 padding: 0em; 214 padding: 0em;
195} 215}
196 216
197div.commit-msg { 217div.commit-msg {
198 white-space: pre; 218 white-space: pre;
199 font-family: monospace; 219 font-family: monospace;
200} 220}
201 221
202table.diffstat { 222table.diffstat {
203 border-collapse: collapse; 223 border-collapse: collapse;
204 margin-top: 1.5em; 224 margin-top: 1.5em;
205} 225}
206 226
207table.diffstat th { 227table.diffstat th {
208 font-weight: normal; 228 font-weight: normal;
209 text-align: left; 229 text-align: left;
210 text-decoration: underline; 230 text-decoration: underline;
211 padding: 0.1em 1em 0.1em 0.1em; 231 padding: 0.1em 1em 0.1em 0.1em;
212 font-size: 100%; 232 font-size: 100%;
213} 233}
214 234
215table.diffstat td { 235table.diffstat td {
216 padding: 0.1em 1em 0.1em 0.1em; 236 padding: 0.1em 1em 0.1em 0.1em;
217 font-size: 100%; 237 font-size: 100%;
218} 238}
219 239
220table.diffstat td span.modechange { 240table.diffstat td span.modechange {
221 padding-left: 1em; 241 padding-left: 1em;
222 color: red; 242 color: red;
223} 243}
224 244
225table.diffstat td.add a { 245table.diffstat td.add a {
226 color: green; 246 color: green;
227} 247}
228 248
229table.diffstat td.del a { 249table.diffstat td.del a {
230 color: red; 250 color: red;
231} 251}
232 252
233table.diffstat td.upd a { 253table.diffstat td.upd a {
234 color: blue; 254 color: blue;
235} 255}
236 256
237table.diffstat td.summary { 257table.diffstat td.summary {
238 color: #888; 258 color: #888;
239 padding-top: 0.5em; 259 padding-top: 0.5em;
240} 260}
241 261
242table.diff td { 262table.diff td {
243 border: solid 1px black; 263 border: solid 1px black;
244 font-family: monospace; 264 font-family: monospace;
245 white-space: pre; 265 white-space: pre;
246} 266}
247 267
248table.diff td div.hunk { 268table.diff td div.hunk {
249 background: #ccc; 269 background: #ccc;
250} 270}
251 271
252table.diff td div.add { 272table.diff td div.add {
253 color: green; 273 color: green;
254} 274}
255 275
256table.diff td div.del { 276table.diff td div.del {
257 color: red; 277 color: red;
258} 278}
259 279
260.sha1 { 280.sha1 {
261 font-family: courier; 281 font-family: courier;
262 font-size: 90%; 282 font-size: 90%;
263} 283}
264 284
265.left { 285.left {
266 text-align: left; 286 text-align: left;
267} 287}
268 288
269.right { 289.right {
270 text-align: right; 290 text-align: right;
271} 291}
diff --git a/ui-summary.c b/ui-summary.c
index 0a7869b..9388f5f 100644
--- a/ui-summary.c
+++ b/ui-summary.c
@@ -1,141 +1,197 @@
1/* ui-summary.c: functions for generating repo summary page 1/* ui-summary.c: functions for generating repo summary page
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
11int items = 0;
12
11static int cgit_print_branch_cb(const char *refname, const unsigned char *sha1, 13static int cgit_print_branch_cb(const char *refname, const unsigned char *sha1,
12 int flags, void *cb_data) 14 int flags, void *cb_data)
13{ 15{
14 struct commit *commit; 16 struct commit *commit;
15 struct commitinfo *info; 17 struct commitinfo *info;
16 char buf[256], *url; 18 char buf[256], *url;
17 19
18 strncpy(buf, refname, sizeof(buf)); 20 strncpy(buf, refname, sizeof(buf));
19 commit = lookup_commit(sha1); 21 commit = lookup_commit(sha1);
20 if (commit && !parse_commit(commit)){ 22 if (commit && !parse_commit(commit)){
21 info = cgit_parse_commit(commit); 23 info = cgit_parse_commit(commit);
22 html("<tr><td>"); 24 html("<tr><td>");
23 url = cgit_pageurl(cgit_query_repo, "log", 25 url = cgit_pageurl(cgit_query_repo, "log",
24 fmt("h=%s", refname)); 26 fmt("h=%s", refname));
25 html_link_open(url, NULL, NULL); 27 html_link_open(url, NULL, NULL);
26 html_txt(buf); 28 html_txt(buf);
27 html_link_close(); 29 html_link_close();
28 html("</td><td>"); 30 html("</td><td>");
29 cgit_print_date(commit->date); 31 cgit_print_date(commit->date);
30 html("</td><td>"); 32 html("</td><td>");
31 html_txt(info->author); 33 html_txt(info->author);
32 html("</td><td>"); 34 html("</td><td>");
33 url = cgit_pageurl(cgit_query_repo, "commit", 35 url = cgit_pageurl(cgit_query_repo, "commit",
34 fmt("id=%s", sha1_to_hex(sha1))); 36 fmt("id=%s", sha1_to_hex(sha1)));
35 html_link_open(url, NULL, NULL); 37 html_link_open(url, NULL, NULL);
36 html_ntxt(cgit_max_msg_len, info->subject); 38 html_ntxt(cgit_max_msg_len, info->subject);
37 html_link_close(); 39 html_link_close();
38 html("</td></tr>\n"); 40 html("</td></tr>\n");
39 cgit_free_commitinfo(info); 41 cgit_free_commitinfo(info);
40 } else { 42 } else {
41 html("<tr><td>"); 43 html("<tr><td>");
42 html_txt(buf); 44 html_txt(buf);
43 html("</td><td colspan='3'>"); 45 html("</td><td colspan='3'>");
44 htmlf("*** bad ref %s ***", sha1_to_hex(sha1)); 46 htmlf("*** bad ref %s ***", sha1_to_hex(sha1));
45 html("</td></tr>\n"); 47 html("</td></tr>\n");
46 } 48 }
47 return 0; 49 return 0;
48} 50}
49 51
50 52
51static void cgit_print_object_ref(struct object *obj) 53static void cgit_print_object_ref(struct object *obj)
52{ 54{
53 char *page, *url; 55 char *page, *url;
54 56
55 if (obj->type == OBJ_COMMIT) 57 if (obj->type == OBJ_COMMIT)
56 page = "commit"; 58 page = "commit";
57 else if (obj->type == OBJ_TREE) 59 else if (obj->type == OBJ_TREE)
58 page = "tree"; 60 page = "tree";
59 else 61 else
60 page = "view"; 62 page = "view";
61 63
62 url = cgit_pageurl(cgit_query_repo, page, 64 url = cgit_pageurl(cgit_query_repo, page,
63 fmt("id=%s", sha1_to_hex(obj->sha1))); 65 fmt("id=%s", sha1_to_hex(obj->sha1)));
64 html_link_open(url, NULL, NULL); 66 html_link_open(url, NULL, NULL);
65 htmlf("%s %s", typename(obj->type), 67 htmlf("%s %s", typename(obj->type),
66 sha1_to_hex(obj->sha1)); 68 sha1_to_hex(obj->sha1));
67 html_link_close(); 69 html_link_close();
68} 70}
69 71
70static int cgit_print_tag_cb(const char *refname, const unsigned char *sha1, 72static int cgit_print_tag_cb(const char *refname, const unsigned char *sha1,
71 int flags, void *cb_data) 73 int flags, void *cb_data)
72{ 74{
73 struct tag *tag; 75 struct tag *tag;
74 struct taginfo *info; 76 struct taginfo *info;
75 struct object *obj; 77 struct object *obj;
76 char buf[256], *url; 78 char buf[256], *url;
77 79
78 strncpy(buf, refname, sizeof(buf)); 80 strncpy(buf, refname, sizeof(buf));
79 obj = parse_object(sha1); 81 obj = parse_object(sha1);
80 if (!obj) 82 if (!obj)
81 return 1; 83 return 1;
82 if (obj->type == OBJ_TAG) { 84 if (obj->type == OBJ_TAG) {
83 tag = lookup_tag(sha1); 85 tag = lookup_tag(sha1);
84 if (!tag || parse_tag(tag) || !(info = cgit_parse_tag(tag))) 86 if (!tag || parse_tag(tag) || !(info = cgit_parse_tag(tag)))
85 return 2; 87 return 2;
88 if (!items) {
89 html("<tr class='nohover'><th class='left'>Tag</th>"
90 "<th class='left'>Created</th>"
91 "<th class='left'>Author</th>"
92 "<th class='left'>Reference</th></tr>\n");
93 }
94 items++;
86 html("<tr><td>"); 95 html("<tr><td>");
87 url = cgit_pageurl(cgit_query_repo, "view", 96 url = cgit_pageurl(cgit_query_repo, "view",
88 fmt("id=%s", sha1_to_hex(sha1))); 97 fmt("id=%s", sha1_to_hex(sha1)));
89 html_link_open(url, NULL, NULL); 98 html_link_open(url, NULL, NULL);
90 html_txt(buf); 99 html_txt(buf);
91 html_link_close(); 100 html_link_close();
92 html("</td><td>"); 101 html("</td><td>");
93 if (info->tagger_date > 0) 102 if (info->tagger_date > 0)
94 cgit_print_date(info->tagger_date); 103 cgit_print_date(info->tagger_date);
95 html("</td><td>"); 104 html("</td><td>");
96 if (info->tagger) 105 if (info->tagger)
97 html(info->tagger); 106 html(info->tagger);
98 html("</td><td>"); 107 html("</td><td>");
99 cgit_print_object_ref(tag->tagged); 108 cgit_print_object_ref(tag->tagged);
100 html("</td></tr>\n"); 109 html("</td></tr>\n");
101 } else { 110 } else {
102 html("<tr><td>"); 111 html("<tr><td>");
103 html_txt(buf); 112 html_txt(buf);
104 html("</td><td colspan='2'/><td>"); 113 html("</td><td colspan='2'/><td>");
105 cgit_print_object_ref(obj); 114 cgit_print_object_ref(obj);
106 html("</td></tr>\n"); 115 html("</td></tr>\n");
107 } 116 }
108 return 0; 117 return 0;
109} 118}
110 119
120static int cgit_print_archive_cb(const char *refname, const unsigned char *sha1,
121 int flags, void *cb_data)
122{
123 struct tag *tag;
124 struct taginfo *info;
125 struct object *obj;
126 char buf[256], *url;
127
128 if (prefixcmp(refname, "refs/archives"))
129 return 0;
130 strncpy(buf, refname+14, sizeof(buf));
131 obj = parse_object(sha1);
132 if (!obj)
133 return 1;
134 if (obj->type == OBJ_TAG) {
135 tag = lookup_tag(sha1);
136 if (!tag || parse_tag(tag) || !(info = cgit_parse_tag(tag)))
137 return 0;
138 hashcpy(sha1, tag->tagged->sha1);
139 } else if (obj->type != OBJ_BLOB) {
140 return 0;
141 }
142 if (!items) {
143 html("<table>");
144 html("<tr><th>Downloads</th></tr>");
145 }
146 items++;
147 html("<tr><td>");
148 url = cgit_pageurl(cgit_query_repo, "blob",
149 fmt("id=%s&path=%s", sha1_to_hex(sha1),
150 buf));
151 html_link_open(url, NULL, NULL);
152 html_txt(buf);
153 html_link_close();
154 html("</td><tr>");
155 return 0;
156}
157
111static void cgit_print_branches() 158static void cgit_print_branches()
112{ 159{
113 html("<tr class='nohover'><th class='left'>Branch</th>" 160 html("<tr class='nohover'><th class='left'>Branch</th>"
114 "<th class='left'>Updated</th>" 161 "<th class='left'>Updated</th>"
115 "<th class='left'>Author</th>" 162 "<th class='left'>Author</th>"
116 "<th class='left'>Head commit</th></tr>\n"); 163 "<th class='left'>Head commit</th></tr>\n");
117 for_each_branch_ref(cgit_print_branch_cb, NULL); 164 for_each_branch_ref(cgit_print_branch_cb, NULL);
118} 165}
119 166
120static void cgit_print_tags() 167static void cgit_print_tags()
121{ 168{
122 html("<tr class='nohover'><th class='left'>Tag</th>" 169 items = 0;
123 "<th class='left'>Created</th>"
124 "<th class='left'>Author</th>"
125 "<th class='left'>Reference</th></tr>\n");
126 for_each_tag_ref(cgit_print_tag_cb, NULL); 170 for_each_tag_ref(cgit_print_tag_cb, NULL);
127} 171}
128 172
173static void cgit_print_archives()
174{
175 items = 0;
176 for_each_ref(cgit_print_archive_cb, NULL);
177 if (items)
178 html("</table>");
179}
180
129void cgit_print_summary() 181void cgit_print_summary()
130{ 182{
131 html("<h2>");
132 html(cgit_repo->name);
133 html("</h2><h3>");
134 html(cgit_repo->desc);
135 html("</h3>");
136 html("<table class='list nowrap'>"); 183 html("<table class='list nowrap'>");
184 html("<tr class='nohover'><td id='summary' colspan='3'>");
185 html("<h2>");
186 html_txt(cgit_repo->name);
187 html(" - ");
188 html_txt(cgit_repo->desc);
189 html("</h2>");
190 html("</td><td id='archivelist'>");
191 cgit_print_archives();
192 html("</td></tr>");
137 cgit_print_branches(); 193 cgit_print_branches();
138 html("<tr class='nohover'><td colspan='4'>&nbsp;</td></tr>"); 194 html("<tr class='nohover'><td colspan='4'>&nbsp;</td></tr>");
139 cgit_print_tags(); 195 cgit_print_tags();
140 html("</table>"); 196 html("</table>");
141} 197}