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