some pending cosmetics
[webgit] / src / object_commit.c
1 /*
2     cehtehs git web frontend
3
4   Copyright (C)
5     2007, 2008,         Christian Thaeter <ct@pipapo.org>
6
7   This program is free software: you can redistribute it and/or modify
8   it under the terms of the GNU Affero General Public License as published by
9   the Free Software Foundation, either version 3 of the License, or
10   (at your option) any later version.
11
12   This program is distributed in the hope that it will be useful,
13   but WITHOUT ANY WARRANTY; without even the implied warranty of
14   MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE.  See the
15   GNU Affero General Public License for more details.
16
17   You should have received a copy of the GNU Affero General Public License
18   along with this program.  If not, see <http://www.gnu.org/licenses/>.
19 */
20
21 #include "object.h"
22 #include "repo.h"
23 #include "date.h"
24 #include "actions.h"
25 #include "summary.h"
26
27 char*
28 webgit_object_commit_tree_parse (struct commit* commit)
29 {
30   char* tree = strstr (commit->buffer, "tree ");
31   if (!tree)
32     return NULL;
33
34   char* ret = strncpy (cwa_buffer_provide (41), tree+5, 40);
35   ret[40] = '\0';
36
37   return ret;
38 }
39
40 time_t
41 webgit_object_commit_author_date_parse (struct commit* commit, struct tm* tm)
42 {
43   struct tm tmp;
44   if (!tm)
45     tm = &tmp;
46
47   char* author = strstr (commit->buffer, "author ");
48   if (!author)
49     return (time_t)-1;
50
51   char* beg = strchr (author, '>');
52   if (!beg)
53     return (time_t)-1;
54
55   if (!strptime (beg + 2, "%s %Z", tm))
56     return (time_t)-1;
57
58   return mktime (tm);
59 }
60
61
62 Html
63 webgit_object_commit_parents_parse (struct commit* commit, struct webgit_repo_info* repo)
64 {
65   Html parents = html_list ();
66
67   struct commit* parent;
68   while ((parent = pop_commit (&commit->parents)))
69     {
70       char* sha1 = sha1_to_hex (parent->object.sha1);
71
72       html_list_append (parents,
73                         html (
74                             "Parent: ",
75                             webgit_object_link (repo->query, html_fmt ("%.40s", sha1),
76                                                 "repo", repo->query->repo,
77                                                 "ref", repo->query->head,
78                                                 "commit", sha1)
79                             )
80                       );
81     }
82
83   return parents;
84 }
85
86
87 Html
88 webgit_object_commit_author_name_parse (struct commit* commit)
89 {
90   char* author = strstr (commit->buffer, "author ");
91   if (!author)
92     return NULL;
93
94   char* end = strchr (author, '<');
95   if (!end)
96     return NULL;
97
98   return html_fmt ("%.*s", end-author-8, author+7);
99 }
100
101
102 Html
103 webgit_object_commit_author_email_parse (struct commit* commit)
104 {
105   char* author = strstr (commit->buffer, "author ");
106   if (!author)
107     return NULL;
108
109   char* beg = strchr (author, '<');
110   if (!beg)
111     return NULL;
112
113   char* end = strchr (beg, '>');
114   if (!end)
115     return NULL;
116
117
118   return html_fmt ("%.*s", end-beg-1, beg+1);
119 }
120
121
122 time_t
123 webgit_object_commit_committer_date_parse (struct commit* commit, struct tm* tm)
124 {
125   struct tm tmp;
126   if (!tm)
127     tm = &tmp;
128
129   char* committer = strstr (commit->buffer, "committer ");
130   if (!committer)
131     return (time_t)-1;
132
133   char* beg = strchr (committer, '>');
134   if (!beg)
135     return (time_t)-1;
136
137   if (!strptime (beg + 2, "%s %Z", tm))
138     return (time_t)-1;
139
140   return mktime (tm);
141 }
142
143
144 Html
145 webgit_object_commit_committer_name_parse (struct commit* commit)
146 {
147   char* committer = strstr (commit->buffer, "committer ");
148   if (!committer)
149     return NULL;
150
151   char* end = strchr (committer, '<');
152   if (!end)
153     return NULL;
154
155   return html_fmt ("%.*s", end-committer-11, committer+10);
156 }
157
158
159 Html
160 webgit_object_commit_committer_email_parse (struct commit* commit)
161 {
162   char* committer = strstr (commit->buffer, "committer ");
163   if (!committer)
164     return NULL;
165
166   char* beg = strchr (committer, '<');
167   if (!beg)
168     return NULL;
169
170   char* end = strchr (beg, '>');
171   if (!end)
172     return NULL;
173
174
175   return html_fmt ("%.*s", end-beg-1, beg+1);
176 }
177
178
179 Html
180 webgit_object_commit_header_parse (struct commit* commit)
181 {
182   char* header = strstr (commit->buffer, "\n\n");
183   if (!header)
184     return NULL;
185
186   char* end = strchr (header+2, '\n');
187   if (!end)
188     end = header + strlen (header+2);
189   else
190     --end;
191
192   return html_fmt ("%.*s", end-header, header+2);
193 }
194
195
196 Html
197 webgit_object_commit_message_parse (struct commit* commit)
198 {
199   char* header = strstr (commit->buffer, "\n\n");
200   if (!header)
201     return NULL;
202
203   header = strchr (header+2, '\n');
204   if (!header)
205     return html ();
206   else
207     ++header;
208
209   return html_fmt ("%.*s", strlen (header), header);
210 }
211
212
213 /*
214   Display commits
215 */
216 static Html
217 webgit_object_commit_menu_action (struct webgit_repo_info* repo, unsigned char* sha1, struct commit* commit)
218 {
219   (void) repo;
220   (void) sha1;
221   return html (html_tag ("div"),
222                webgit_repo_logo (repo), "<br />",
223                // TODO: "diff against.. <br />",
224                // TODO: "log <br />",
225                // TODO: "create branch <br />",
226                // TODO: "cherry pick? <br />",
227                // TODO: "log <br />",
228                webgit_summary_link (repo->query, repo, html("Summary")), "<br />",
229                webgit_main_link (repo->query, html ("Main"))
230                );
231 }
232
233
234 static Html
235 webgit_object_commit_content_action (struct webgit_repo_info* repo, unsigned char* sha1, struct commit* commit)
236 {
237   char* tree = webgit_object_commit_tree_parse (commit);
238
239   return html (
240                html (html_tag ("h3"), webgit_object_commit_header_parse (commit)),
241                html (html_tag ("div"),
242                      "Tree: ",
243                      webgit_object_link (repo->query, html_strndup (tree, 40),
244                                          "repo", repo->query->repo,
245                                          "ref", repo->query->head,
246                                          "commit", sha1_to_hex (commit->object.sha1),
247                                          "path", "")
248                      ), html_nl (),
249                html (html_tag ("div"), webgit_object_commit_parents_parse (commit, repo)), html_nl (),
250                html (html_tag ("div"),
251                      webgit_object_commit_author_name_parse (commit), " ",
252                      webgit_object_commit_author_email_parse (commit), " ",
253                      webgit_pretty_date (webgit_object_commit_author_date_parse (commit, NULL))
254                      ), html_nl (),
255                html (html_tag ("div"),
256                      webgit_object_commit_committer_name_parse (commit), " ",
257                      webgit_object_commit_committer_email_parse (commit), " ",
258                      webgit_pretty_date (webgit_object_commit_committer_date_parse (commit, NULL))
259                      ), html_nl (),
260                html (html_tag ("pre"), webgit_object_commit_message_parse (commit))
261                );
262 }
263
264 Html
265 webgit_object_commit_action (struct webgit_repo_info* repo, unsigned char* sha1)
266 {
267   struct commit* commit = lookup_commit_reference (sha1);
268   parse_commit (commit);
269
270   return html(
271               html (html_tag("div", html_attr ("id", "sub-menu")),
272                     webgit_object_commit_menu_action (repo, sha1, commit)
273                     ), html_nl (),
274               html (html_tag("div", html_attr ("id", "object-commit")),
275                     webgit_object_commit_content_action (repo, sha1, commit)
276                     ), html_nl ()
277               );
278 }
279
280 /*
281 //      Local Variables:
282 //      mode: C
283 //      c-file-style: "gnu"
284 //      indent-tabs-mode: nil
285 //      End:
286 */