8bb5f0e7ee2ebe8b9ba1d832807b2f4a3c665294
[webgit] / src / object_tree.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 "actions.h"
23 #include "repo.h"
24 #include "summary.h"
25
26 Html
27 webgit_object_tree_parent_link (struct webgit_query* query, char* fmt)
28 {
29   if (query->path)
30     {
31       char* d = strrchr (query->path, '/');
32       if (d)
33         {
34           size_t len = d - query->path;
35           char* path = cwa_buffer_provide (len+1);
36           strncpy (path, query->path, len);
37           path[len] = '\0';
38
39           return webgit_object_link (query, html (html_fmt (fmt, path), "<br />"),
40                                      "repo", query->repo,
41                                      "ref", query->head,
42                                      "commit", query->commit,
43                                      "path", path);
44         }
45       else if (*query->path)
46         {
47           return webgit_object_link (query, html (html_fmt (fmt, ""), "<br />"),
48                                      "repo", query->repo,
49                                      "ref", query->head,
50                                      "commit", query->commit,
51                                      "path", "");
52         }
53     }
54
55   return html ();
56 }
57
58
59 /*
60   Display trees
61 */
62
63 static Html
64 webgit_object_tree_menu_action (struct webgit_repo_info* repo, unsigned char* sha1, struct tree *tree)
65 {
66   (void) repo;
67   (void) sha1;
68   (void) tree;
69   return html (html_tag ("div"),
70                webgit_repo_logo (repo), "<br />",
71                // TODO: "diff against.. <br />",
72                // TODO: "history <br />",
73                // TODO: "snapshot <br />",
74                // TODO: ,
75                repo->worktree
76                ? html ("TODO worktree actions <br />")
77                : html (),
78                webgit_object_tree_parent_link (repo->query, "<<%s"),
79                webgit_summary_link (repo->query, repo, html("Summary")), "<br />",
80                webgit_main_link (repo->query, html ("Main"))
81                );
82 }
83
84 static const char*
85 pretty_mode (unsigned mode)
86 {
87   if (S_ISGITLINK (mode))
88     return "m---------";
89   else if (S_ISDIR (mode & S_IFMT))
90     return "drwxr-xr-x";
91   else if (S_ISLNK (mode))
92     return "lrwxrwxrwx";
93   else if (S_ISREG (mode))
94     {
95       if (mode & S_IXUSR)
96         return "-rwxr-xr-x";
97       else
98         return "-rw-r--r--";
99     }
100   else
101     return "----------";
102 }
103
104 /* callback has no user-data pointer! */
105 static struct webgit_repo_info* repo_in_flight = NULL;
106 static Html tree_in_flight = NULL;
107
108 static int
109 webgit_html_tree (const unsigned char *sha1, const char *base, int baselen,
110                   const char *name, unsigned mode, int stage)
111 {
112   (void) stage;
113   char pathname[PATH_MAX];
114
115   struct webgit_query* query = repo_in_flight->query;
116
117   snprintf (pathname, PATH_MAX-1, "%.*s%s%s", baselen, base, baselen ? "/": "", name);
118
119   if (S_ISGITLINK(mode))
120     {
121       char* repo = cwa_malloc (strlen (query->repo) + strlen (name) + 2);
122       sprintf (repo, "%s/%s", query->repo, name);
123
124       html_list_append (tree_in_flight,
125                         html (
126                               html (
127                                     html_tag ("tr"),
128                                     html (html_tag ("td"), pretty_mode (mode)),
129                                     html (html_tag ("td"),
130                                           webgit_object_link (query, html_strndup (pathname, SIZE_MAX),
131                                                               "repo", repo,
132                                                               "ref","",
133                                                               "commit", sha1_to_hex (sha1),
134                                                               "path", "")
135                                           ),
136                                     html (html_tag ("td"), "history summary")
137                                     ),
138                               html_nl ()
139                               )
140                         );
141     }
142   else if (S_ISDIR(mode))
143     {
144       html_list_append (tree_in_flight,
145                         html (
146                               html (html_tag ("tr"),
147                                     html (html_tag ("td"), pretty_mode (mode)),
148                                     html (html_tag ("td"),
149                                           webgit_object_link (query, html_strndup (name, SIZE_MAX),
150                                                               "repo", query->repo,
151                                                               "ref", query->head,
152                                                               "commit", query->commit,
153                                                               "path", pathname)
154                                           ),
155                                     html (html_tag ("td"), "history snap")
156                                     ),
157                               html_nl ()
158                               )
159                         );
160     }
161   else
162     {
163       html_list_append (tree_in_flight,
164                         html (
165                               html (html_tag ("tr"),
166                                     html (html_tag ("td"), pretty_mode (mode)),
167                                     html (html_tag ("td"),
168                                           webgit_object_link (query, html_strndup (name, SIZE_MAX),
169                                                               "repo", query->repo,
170                                                               "ref", query->head,
171                                                               "commit", query->commit,
172                                                               "path", pathname)
173                                           ),
174                                     html (html_tag ("td"),
175                                           "history ",
176                                           webgit_object_link (query, html ("raw"),
177                                                               "repo", query->repo,
178                                                               "ref", query->head,
179                                                               "commit", query->commit,
180                                                               "path", pathname,
181                                                               "action", "raw"),
182                                           repo_in_flight->worktree
183                                           ? html (
184                                                   " ",
185                                                   webgit_object_link (query, html ("edit"),
186                                                                       "repo", query->repo,
187                                                                       "ref", query->head,
188                                                                       "commit", query->commit,
189                                                                       "path", pathname,
190                                                                       "action", "edit")
191                                                   )
192                                           : html ()
193                                           )
194                                     ),
195                               html_nl()
196                               )
197                         );
198     }
199
200   return 0;
201 }
202
203
204 static Html
205 webgit_object_tree_content_action (struct webgit_repo_info* repo, unsigned char* sha1, struct tree *tree)
206 {
207   (void) sha1;
208   repo_in_flight = repo;
209   tree_in_flight = html_list ();
210
211   read_tree_recursive (tree, repo->query->path,
212                        repo->query->path ? strlen (repo->query->path) : 0, 0, NULL, webgit_html_tree);
213
214   return html (html_tag ("table", html_attr ("id", "object-tree")), tree_in_flight);
215 }
216
217 Html
218 webgit_object_tree_action (struct webgit_repo_info* repo, unsigned char* sha1)
219 {
220   struct tree *tree;
221
222   tree = parse_tree_indirect (sha1);
223   if (!tree)
224     die("not a tree object");
225
226   return html(
227               html (html_tag ("div",
228                               html_attr("id", "sub-menu")),
229                     webgit_object_tree_menu_action (repo, sha1, tree)),
230               html_nl (),
231               html (html_tag("div",
232                              html_attr("id", "content")),
233                     webgit_object_tree_content_action (repo, sha1, tree)),
234               html_nl ()
235               );
236 }
237
238
239 /*
240 //      Local Variables:
241 //      mode: C
242 //      c-file-style: "gnu"
243 //      indent-tabs-mode: nil
244 //      End:
245 */