tag displaying and handling
authorChristian Thaeter <ct@pipapo.org>
Thu, 17 Jan 2008 21:29:19 +0000 (22:29 +0100)
committerChristian Thaeter <ct@pipapo.org>
Thu, 17 Jan 2008 21:29:19 +0000 (22:29 +0100)
Makefile.am
src/actions.c
src/object.c
src/tag.c [new file with mode: 0644]
src/tag.h [new file with mode: 0644]

index ef5b90c..faef0b3 100644 (file)
@@ -47,6 +47,7 @@ webgit_SOURCES =                              \
        $(webgit_srcdir)/repo.c                 \
        $(webgit_srcdir)/object.c               \
        $(webgit_srcdir)/branch.c               \
+       $(webgit_srcdir)/tag.c                  \
        $(webgit_srcdir)/log.c
 
 noinst_HEADERS =                               \
@@ -59,6 +60,7 @@ noinst_HEADERS =                              \
        $(webgit_srcdir)/repo.h                 \
        $(webgit_srcdir)/object.h               \
        $(webgit_srcdir)/branch.h               \
+       $(webgit_srcdir)/tag.h                  \
        $(webgit_srcdir)/log.h
 
 webgit_DEPENDENCIES = $(abs_top_builddir)/git/libgit.a $(abs_top_builddir)/git/xdiff/lib.a
index 150eb7c..080943d 100644 (file)
@@ -26,6 +26,7 @@
 #include "repo.h"
 #include "age.h"
 #include "branch.h"
+#include "tag.h"
 
 #include "llist.h"
 #include <cwa.h>
@@ -76,7 +77,8 @@ webgit_main_content_action (struct webgit_query* query)
 
       html_list_append (table, html (
                                      html_tag ("tr"),
-                                     html(html_tag ("td"), webgit_summary_link (query, n, html (n->name))),
+                                     html(html_tag ("td"),
+                                          webgit_summary_link (query, n, html (n->name))),
                                      html(html_tag ("td"), n->url ?
                                           html (
                                                 html_tag ("a", html_attr ("href", n->url)),
@@ -223,6 +225,12 @@ webgit_summary_content_action (struct webgit_repo_info* repo)
                     );
 
   /* tags */
+  html_list_append (content,
+                    html (
+                          html (html_tag ("h2"), "Tags"),
+                          webgit_tag_table (repo, NULL, 5 /*TODO: config this*/)
+                          )
+                    );
 
 
   return content;
index 6e0679e..3b80628 100644 (file)
 
 #include "object.h"
 #include "repo.h"
+#include "tag.h"
 
+#define SHA1_HEADER <openssl/sha.h>
+#include "git/tag.h"
 
 Html
 webgit_object_link (struct webgit_query* query,
@@ -615,8 +618,111 @@ webgit_object_blob_action (struct webgit_repo_info* repo, unsigned char* sha1)
 }
 
 
+/*
+  Display Tags
+*/
+static Html
+webgit_object_tag_menu_action (struct webgit_repo_info* repo, struct tag* tag, void *buffer, unsigned long size)
+{
+  (void) repo;
+  (void) tag;
+  (void) buffer;
+  (void) size;
+
+  return html ("TODO: tag-object sidebar");
+}
+
+static Html
+webgit_object_tag_content_action (struct webgit_repo_info* repo, struct tag* tag, void* buf, unsigned long size)
+{
+  /*
+    NAME HEADER
+
+    object | tree
+
+    tagger: Christian ThaeterWed Jan 16 15:55:27 2008
+
+    message
+  */
+
+  struct object* derefed = deref_tag ((struct object*)tag, NULL, 0);
+
+  char type[16];
+
+  webgit_tag_type_parse (type, buf, size);
+
+  char* sha1hex = sha1_to_hex (derefed->sha1);
+
+  struct tm tm;
+  webgit_tag_date_parse (buf, size, &tm);
+  char pretty_date[256];
+  strftime (pretty_date, 255, "%c", &tm);
+
+  Html ret;
+
+  ret= html (
+             html (
+                   html_tag ("h1"),
+                   html_strndup (tag->tag, SIZE_MAX),
+                   " - ",
+                   webgit_tag_header_parse (buf, size)
+                   ),
+             html_fmt ("Type '%s': ", type),
+             webgit_object_link (repo->query,
+                                 repo->name, strlen(repo->name),
+                                 sha1hex, 40,
+                                 NULL,
+                                 NULL,
+                                 html (sha1hex)),
+             !strcmp (type, "commit") ?
+             html (
+                   " ",
+                   webgit_object_link (repo->query,
+                                       repo->name, strlen(repo->name),
+                                       sha1hex, 40,
+                                       NULL,
+                                       "tree",
+                                       html ("Tree"))
+                   ) : html (),
+             html (html_tag ("br")),
+             "Tagger: ",
+             webgit_email_link (
+                                webgit_tag_name_parse (buf, size),
+                                webgit_tag_email_parse (buf, size)
+                                ),
+             html_strndup (pretty_date, 255),
+             html (html_tag ("br")),
+             html (html_tag ("pre"),
+                   webgit_tag_message_parse (buf, size)
+                   )
+             );
+
+
+
+
+
+  return ret;
+}
+
+Html
+webgit_object_tag_action (struct webgit_repo_info* repo, unsigned char* sha1)
+{
+  struct tag* tag = lookup_tag (sha1);
+  enum object_type type;
+  void *buffer;
+  unsigned long size;
+
+  buffer = read_sha1_file (tag->object.sha1, &type, &size);
+
+  if (!tag->object.parsed)
+    parse_tag_buffer (tag, buffer, size);
+
+  parse_tag_buffer (tag, buffer, size);
+
+  return html(
+              html(html_tag("div"), webgit_object_tag_menu_action (repo, tag, buffer, size)), html_nl (),
+              html(html_tag("div"), webgit_object_tag_content_action (repo, tag, buffer, size)), html_nl ()
+              );
+}
 
 
-/*pretty printer for sourcecode*/
-//Html
-//webgit_object_blob_dispatch (struct webgit_query* query, const char *sha1);
diff --git a/src/tag.c b/src/tag.c
new file mode 100644 (file)
index 0000000..b841847
--- /dev/null
+++ b/src/tag.c
@@ -0,0 +1,281 @@
+/*
+    cehtehs git web frontend
+
+  Copyright (C)
+    2007, 2008,         Christian Thaeter <ct@pipapo.org>
+
+  This program is free software; you can redistribute it and/or
+  modify it under the terms of the GNU General Public License as
+  published by the Free Software Foundation; either version 2 of the
+  License, or (at your option) any later version.
+
+  This program is distributed in the hope that it will be useful,
+  but WITHOUT ANY WARRANTY; without even the implied warranty of
+  MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE.  See the
+  GNU General Public License for more details.
+
+  You should have received a copy of the GNU General Public License
+  along with this program; if not, write to the Free Software
+  Foundation, Inc., 675 Mass Ave, Cambridge, MA 02139, USA.
+*/
+
+#include "tag.h"
+#include "object.h"
+#include "age.h"
+#include "log.h"
+
+#include <cwa.h>
+
+#define SHA1_HEADER <openssl/sha.h>
+#include "git/cache.h"
+#include "git/tag.h"
+//#include "git/commit.h"
+#include "git/refs.h"
+
+#include <time.h>
+
+time_t
+webgit_tag_date_parse (void* buffer, unsigned long size, struct tm* tm)
+{
+  struct tm tmp;
+  if (!tm)
+    tm = &tmp;
+
+  char* tagger = cwa_memmem (buffer, size, "tagger ", 7);
+  if (!tagger)
+    return (time_t)-1;
+
+  char* beg = strchr (tagger, '>');
+  if (!beg)
+    return (time_t)-1;
+
+  if (!strptime (beg + 2, "%s %Z", tm))
+    return (time_t)-1;
+
+  return mktime (tm);
+}
+
+
+int
+webgit_tag_type_parse (char* dest, void* buffer, unsigned long size)
+{
+  char* type = cwa_memmem (buffer, size, "type ", 5);
+  if (!type)
+    return -1;
+
+  char* end = strchr (type, '\n');
+  if (!end)
+    return -1;
+
+  return snprintf (dest, 16, "%.*s", end-type-5, type+5);
+}
+
+
+Html
+webgit_tag_name_parse (void* buffer, unsigned long size)
+{
+  char* tagger = cwa_memmem (buffer, size, "tagger ", 7);
+  if (!tagger)
+    return NULL;
+
+  char* end = strchr (tagger, '<');
+  if (!end)
+    return NULL;
+
+  return html_fmt ("%.*s", end-tagger-8, tagger+7);
+}
+
+Html
+webgit_tag_email_parse (void* buffer, unsigned long size)
+{
+  char* tagger = cwa_memmem (buffer, size, "tagger ", 7);
+  if (!tagger)
+    return NULL;
+
+  char* beg = strchr (tagger, '<');
+  if (!beg)
+    return NULL;
+
+  char* end = strchr (beg, '>');
+  if (!end)
+    return NULL;
+
+
+  return html_fmt ("%.*s", end-beg-1, beg+1);
+}
+
+
+Html
+webgit_tag_header_parse (void* buffer, unsigned long size)
+{
+  char* header = cwa_memmem (buffer, size, "\n\n", 2);
+  if (!header)
+    return NULL;
+
+  char* end = strchr (header+2, '\n');
+  if (!end)
+    end = header + strlen (header+2);
+  else
+    --end;
+
+  return html_fmt ("%.*s", end-header, header+2);
+}
+
+
+Html
+webgit_tag_message_parse (void* buffer, unsigned long size)
+{
+  char* header = cwa_memmem (buffer, size, "\n\n", 2);
+  if (!header)
+    return NULL;
+
+  char* beg = strchr (header+2, '\n');
+  if (!beg)
+    return html ();
+
+  return html_strndup (beg+1, size - (beg-header) - 1);
+}
+
+
+struct tag_context
+{
+  struct webgit_repo_info* repo;
+  Html table;
+  Html cont;
+  const char* start;
+  int count;
+};
+
+
+Html
+webgit_tag_link (struct webgit_repo_info* repo, const char* tag, int count, Html text)
+{
+  return html (
+               html_tag ("a",
+                         html_attr ("href", html(
+                                                 html_fmt ("%s?repo=%s&action=tag",
+                                                           repo->query->request->script_name,
+                                                           repo->name),
+                                                 tag ? html_fmt("&ref=%s", tag) : html (),
+                                                 count > 0 ? html_fmt("&count=%d",
+                                                                      count) : html ()
+                                                 )
+                                    )
+                         ),
+               text
+               );
+}
+
+static int
+show_tag_ref (const char *refname, const unsigned char *sha1, int flags, void *data)
+{
+  struct tag_context* ctx = (struct tag_context*) data;
+  struct webgit_repo_info* repo = ctx->repo;
+
+  if (ctx->start)
+    {
+      if (!strcmp (ctx->start, refname))
+        ctx->start = NULL;
+      else
+        return 0;
+    }
+
+  if (!ctx->count--)
+    {
+      /* displayed query->count lines, finish */
+      html_list_append (ctx->cont,
+                        webgit_tag_link (
+                                         repo, refname,
+                                         repo->query->count,
+                                         html ("More..."))
+                        );
+      return 1;
+    }
+
+  struct tag* tag = lookup_tag (sha1);
+
+  enum object_type type;
+  void *buffer;
+  unsigned long size;
+
+  buffer = read_sha1_file (tag->object.sha1, &type, &size);
+
+  if (!tag->object.parsed)
+    parse_tag_buffer (tag, buffer, size);
+
+  unsigned long date =
+    webgit_tag_date_parse (buffer, size, NULL);
+
+  char tagref[256];
+  snprintf (tagref, 256, "refs/tags/%s", refname);
+
+  struct object* derefed = deref_tag ((struct object*)tag, NULL, 0);
+
+  html_list_append (ctx->table,
+                    html (
+                          html_tag ("tr"),
+                          html (
+                                html_tag ("td"),
+                                webgit_object_link (repo->query,
+                                                    repo->name, strlen(repo->name),
+                                                    sha1_to_hex (sha1), 40,
+                                                    NULL,
+                                                    NULL,
+                                                    html_strndup (refname, SIZE_MAX))
+                                ),
+                          html (
+                                html_tag ("td"),
+                                webgit_object_link (repo->query,
+                                                    repo->name, strlen(repo->name),
+                                                    sha1_to_hex (derefed->sha1), 40,
+                                                    NULL,
+                                                    NULL,
+                                                    webgit_pretty_age (repo->query->now - date))
+                                ),
+                          html (
+                                html_tag ("td"),
+                                webgit_email_link (
+                                                   webgit_tag_name_parse (buffer, size),
+                                                   webgit_tag_email_parse (buffer, size)
+                                                   )
+                                ),
+                          html (
+                                html_tag ("td"),
+                                webgit_tag_header_parse (buffer, size)
+                                ),
+                          html (
+                                html_tag ("td"),
+                                webgit_log_link (repo->query,
+                                                 repo->name,
+                                                 tagref,
+                                                 NULL, 0,
+                                                 repo->query->count,
+                                                 html ("Log")),
+                                webgit_object_link (repo->query,
+                                                    repo->name, strlen(repo->name),
+                                                    sha1_to_hex (derefed->sha1), 40,
+                                                    NULL,
+                                                    "tree",
+                                                    html ("Tree")),
+                                " Snapshot"
+                                )
+                          )
+                    );
+  return 0;
+}
+
+
+Html
+webgit_tag_table (struct webgit_repo_info* repo, const char* head, int count)
+{
+  struct tag_context ctx;
+  ctx.repo = repo;
+  ctx.table = html_list ();
+  ctx.cont = html_list ();
+  ctx.count = count;
+  ctx.start = head;
+
+  for_each_tag_ref (show_tag_ref, &ctx);
+
+  return html (html (html_tag ("table"), ctx.table), ctx.cont);
+}
diff --git a/src/tag.h b/src/tag.h
new file mode 100644 (file)
index 0000000..ee5592c
--- /dev/null
+++ b/src/tag.h
@@ -0,0 +1,52 @@
+/*
+    cehtehs git web frontend
+
+  Copyright (C)
+    2007, 2008,         Christian Thaeter <ct@pipapo.org>
+
+  This program is free software; you can redistribute it and/or
+  modify it under the terms of the GNU General Public License as
+  published by the Free Software Foundation; either version 2 of the
+  License, or (at your option) any later version.
+
+  This program is distributed in the hope that it will be useful,
+  but WITHOUT ANY WARRANTY; without even the implied warranty of
+  MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE.  See the
+  GNU General Public License for more details.
+
+  You should have received a copy of the GNU General Public License
+  along with this program; if not, write to the Free Software
+  Foundation, Inc., 675 Mass Ave, Cambridge, MA 02139, USA.
+*/
+#ifndef WEBGIT_TAG_H
+#define WEBGIT_TAG_H
+
+#include "webgit.h"
+
+#include <time.h>
+
+time_t
+webgit_tag_date_parse (void* buffer, unsigned long size, struct tm* tm);
+
+int
+webgit_tag_type_parse (char* dest, void* buffer, unsigned long size);
+
+Html
+webgit_tag_name_parse (void* buffer, unsigned long size);
+
+Html
+webgit_tag_email_parse (void* buffer, unsigned long size);
+
+Html
+webgit_tag_header_parse (void* buffer, unsigned long size);
+
+Html
+webgit_tag_message_parse (void* buffer, unsigned long size);
+
+Html
+webgit_tag_table (struct webgit_repo_info* repo, const char* tag, int count);
+
+Html
+webgit_tag_link (struct webgit_repo_info* repo, const char* tag, int count, Html text);
+
+#endif